<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "http://sourceware.org/bugzilla/bugzilla.dtd">

<bugzilla version="4.0.10"
          urlbase="http://sourceware.org/bugzilla/"
          
          maintainer="overseers@sourceware.org"
>

    <bug>
          <bug_id>14</bug_id>
          
          <creation_ts>2004-02-09 15:07:00 +0000</creation_ts>
          <short_desc>Bug (+fix) in readdir() due to getdents()</short_desc>
          <delta_ts>2012-03-08 04:38:33 +0000</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>glibc</product>
          <component>libc</component>
          <version>unspecified</version>
          <rep_platform>All</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>INVALID</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>testsuite</keywords>
          <priority>P1</priority>
          <bug_severity>critical</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Dan Tsafrir">dan.tsafrir</reporter>
          <assigned_to name="GOTO Masanori">gotom</assigned_to>
          <cc>carlos</cc>
    
    <cc>glibc-bugs</cc>
          <cf_gcchost>i686-libranet-gnu-linux</cf_gcchost>
          <cf_gcctarget></cf_gcctarget>
          <cf_gccbuild></cf_gccbuild>
          

      

      

      

          <long_desc isprivate="0">
            <commentid>32</commentid>
            <who name="Dan Tsafrir">dan.tsafrir</who>
            <bug_when>2004-02-09 15:07:14 +0000</bug_when>
            <thetext>- This bug report was already posted in libc-alpha@sources.redhat.com
  I&apos;m resubmitting it here at the request of Andreas Jaeger.

- All the following relates to the file:

     glibc-2.3.2/sysdeps/unix/sysv/linux/getdents.c

  I report more than one bug in getdents() so please bare with me :&gt; (the
  description is actually much longer than the patch). In a nutshell, the
  following program might (nondeterministically) enter an endless-loop:

      DIR           *dir = opendir(&quot;some-autofs-directory&quot;);
      struct dirent *e;
      while( (e = readdir(dir)) != NULL ) // might never return null
          printf(&quot;ino=%d name=%s\n&quot;, e-&gt;d_ino, e-&gt;d_name)

- In the implementation of getdents(), the `d_off&apos; field (belonging to the
  linux kernel&apos;s dirent structure) is falsely assumed to contain the *byte*
  offset to the next dirent.
  Note that the linux manual of the readdir system-call states that d_off
  is the &quot;offset to *this* dirent&quot; while glibc&apos;s getdents treats it as the
  offset to the *next* dirent.

- In practice, both of the above are wrong/misleading. The `d_off&apos; field
  may contain illegal negative values, 0 (should also never happen as the
  &quot;next&quot; dirent&apos;s offset must always be bigger then 0), or positive values
  that are bigger than the size of the directory-file itself:

  o We&apos;re not sure what the Linux kernel intended to place in this field,
    but our experience shows that on &quot;real&quot; file systems (that actually
    reside on some disk) the offset seems to be a simple (not necessarily
    continuous) counter: e.g. first entry may have d_off=1, second: d_off=2,
    third: d_off=4096, fourth=d_off=4097 etc. We conjecture this is the
    serial of the dirent record within the directory (and so, this is indeed
    the &quot;offset&quot;, but counted in records out of which some were already
    removed).

  o For file systems that are maintained by the amd automounter (automount,
    directories) the d_off seems to be arbitrary (and may be negative, zero
    or beyond the scope of a 32bit integer). We conjecture the amd doesn&apos;t
    assign this field and the received values are simply garbage.

- Fortunately, there is actually no need to use d_off as all the needed
  information is embedded in the d_reclen field (dirents are consecutive
  and the &quot;next&quot; dirent is found exactly after the &quot;current&quot; dirent).
  And indeed, glibc&apos;s getdents() uses the above technique most of the time.
  But, there are certain exceptional-conditions that might trigger
  getdents() to stop using on the dependable d_reclen and start using
  the unreliable d_off (Furthermore, these exceptional-conditions are
  identified based on the unreliable information held by d_off).

- One aspect of this bug was actually reported in 2001:
      http://mail.gnu.org/archive/html/bug-glibc/2001-03/msg00048.html
  but was wrongly (IMHO) dismissed by Ulrich Drepper who claimed that the
  bug is actually in the linux-kernel. The linux-kernel folks do not intend
  to change the data of their &apos;struct dirent&apos;. They want it just the way it
  is and don&apos;t care if the glibc folks &quot;wrongly&quot; interpret the `d_off&apos; field.

- The bug in glibc only occurs when an &quot;overflow&quot; is *wrongly* detected
  (see lines: 176-183 in getdents.c).
  Overflow might happen when the kernel uses `kernel_dirent64&apos; that contains
  64bit wide fields (d_ino &amp; d_off), while the user uses `struct dirent&apos;
  through readdir(3) (rather than `struct dirent64&apos; through readdir64).
  in which the corresponding fields are 32bit wide.
  [ This is of course a legal scenario: the user shouldn&apos;t know nor care
    how the kernel implements its readdir ]

- In such an &quot;overflow&quot; situation, getdents() tries to lseek (the
  directory-fd) to the end of the last-legal-dirent that getdents()
  has successfully read.
  This offset is supposedly held by the local variable `last_offset&apos;.
  But, since `last_offset&apos; is assigned with `d_off&apos; on each iteration,
  and since as mentioned above `d_off&apos; usually holds an incorrect value,
  the lseek is not performed to the correct place.
  getdents() then returns the number of bytes successfully read.

- This situation of course causes the next invocation of readdir() to
  return erroneous data due to the incorrect offset associated with
  the fd.
  Furthermore, it often happens (for autofs directories that serve as
  automount points and are maintained by the amd) that the first dirent-entry
  has d_off=0 and the second dirent causes a wrong &quot;overflow&quot;.
  In this case getdents() will return the number of bytes composing
  the first successfully read dirent, and will wrongly lseek to 0: the
  beginning of the file.
  This means that the next invocation of readdir(3) will return (again)
  the first dirent, and so on (never returning NULL), causing any
  program that uses readdir(3) to enter into an endless loop!


How to fix (the above bug + another two):
########################################

1:---------------------------------------------------------------------
Instead of line 193:
        last_offset = d_off;
write:
        if( last_offset == -1 )
                last_offset = 0;
        last_offset += old_reclen;

    [  This makes `last_offset&apos; hold the *real* last offset, and prevents
       the wrong lseek() when an &quot;overflow&quot; occurs. It works since the
       `d_reclen&apos; is reliable and correct, as reflected by the manner
       getdents() uses `old_reclen&apos;  ]


2:---------------------------------------------------------------------
The condition that identifies an &quot;overflow&quot; situation should also be
changed:
Instead of lines 176-179:
        if ((sizeof (outp-&gt;u.d_ino) != sizeof (inp-&gt;k.d_ino)
             &amp;&amp; outp-&gt;u.d_ino != d_ino)
            || (sizeof (outp-&gt;u.d_off) != sizeof (inp-&gt;k.d_off)
                &amp;&amp; outp-&gt;u.d_off != d_off))
only write:
        if ( sizeof (outp-&gt;u.d_ino) != sizeof (inp-&gt;k.d_ino)
             &amp;&amp; outp-&gt;u.d_ino != d_ino )

    [  I removed the right-side of the `or&apos;: since the `d_off&apos; field is
       buggy and unusable, don&apos;t include it in the check for overflow.
       The alterative is that programs reading the content of a directory
       maintained by the amd using readdir(3), will usually fail due to
       overflow, even though the directory is prefectly fine.  ]


3:---------------------------------------------------------------------
The following is another bug I think you have (which is unrelated
to the above).
Instead of line 120:
        &amp;&amp; nbytes &lt;= sizeof (DIRENT_TYPE))
write:
        &amp;&amp; nbytes &lt;= sizeof (struct kernel_dirent64))

    [  The above condition decides whether the user gave a large enough
       buffer in which `struct kernel_dirent64&apos; will fit (`nbytes&apos; is the
       size of the user&apos;s `buf&apos;). If `buf&apos; is too small, a bigger buffer
       is allocated (lines 122-124) so as to be able to hold `struct
       kernel_dirent64&apos;  ]


4:---------------------------------------------------------------------
I think the following is also an (unrelated) bug:
In lines 216-221:

        red_nbytes = MIN (nbytes
                      - ((nbytes / (offsetof (DIRENT_TYPE, d_name) + 14))
                         * size_diff),
                      nbytes - size_diff);

        skdp = kdp = __alloca (red_nbytes);

It is obvious that `red_nbytes&apos; may be negative (or rather, wrapped-around),
since `nbytes&apos; is a value given by the user (and may even be 0).
-----------------------------------------------------------------------


The above patch is given below (your interface doesn&apos;t allow attachments),
it was generated using diff -u.
This patch was applied to our installation of glibc and is successfully
used for a few months now by hundreds of of machines.
Thanks,
    --Dan 


--- getdents.c.orig	2003-12-04 19:11:38.000000000 +0200
+++ getdents.c	2003-12-04 19:38:06.000000000 +0200
@@ -117,7 +117,7 @@
       size_t kbytes = nbytes;
       if (offsetof (DIRENT_TYPE, d_name)
 	  &lt; offsetof (struct kernel_dirent64, d_name)
-	  &amp;&amp; nbytes &lt;= sizeof (DIRENT_TYPE))
+	  &amp;&amp; nbytes &lt;= sizeof (kernel_dirent64))
 	{
 	  kbytes = nbytes + offsetof (struct kernel_dirent64, d_name)
 		   - offsetof (DIRENT_TYPE, d_name);
@@ -175,8 +175,7 @@
 	      outp-&gt;u.d_off = d_off;
 	      if ((sizeof (outp-&gt;u.d_ino) != sizeof (inp-&gt;k.d_ino)
 		   &amp;&amp; outp-&gt;u.d_ino != d_ino)
-		  || (sizeof (outp-&gt;u.d_off) != sizeof (inp-&gt;k.d_off)
-		      &amp;&amp; outp-&gt;u.d_off != d_off))
+		  )
 		{
 		  /* Overflow.  If there was at least one entry
 		     before this one, return them without error,
@@ -190,7 +189,10 @@
 		  return -1;
 		}
 
-	      last_offset = d_off;
+	      if( last_offset == -1 )
+		last_offset = 0;
+	      last_offset += old_reclen;
+
 	      outp-&gt;u.d_reclen = new_reclen;
 	      outp-&gt;u.d_type = d_type;
 
@@ -213,6 +215,7 @@
     const size_t size_diff = (offsetof (DIRENT_TYPE, d_name)
 			      - offsetof (struct kernel_dirent, d_name));
 
+    /* bug? (nbytes might be smaller than right side of minus) */
     red_nbytes = MIN (nbytes
 		      - ((nbytes / (offsetof (DIRENT_TYPE, d_name) + 14))
 			 * size_diff),</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>8564</commentid>
            <who name="Dwayne Grant McConnell">decimal</who>
            <bug_when>2006-02-21 16:27:00 +0000</bug_when>
            <thetext>This patch applies cleanly to sysdeps/unix/sysv/linux/getdents.c in the trunk.

I have created a first pass at a testcase but it requires an autofs filesystem
and is non-deterministic according to the bug comments so I have not actually
reproduced yet.
</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>8567</commentid>
              <attachid>876</attachid>
            <who name="Dwayne Grant McConnell">decimal</who>
            <bug_when>2006-02-21 16:33:04 +0000</bug_when>
            <thetext>Created attachment 876
Patch taken from bug comments.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>8568</commentid>
              <attachid>877</attachid>
            <who name="Dwayne Grant McConnell">decimal</who>
            <bug_when>2006-02-21 16:33:44 +0000</bug_when>
            <thetext>Created attachment 877
Preliminary testcase adapted from bug comments.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>8569</commentid>
              <attachid>878</attachid>
            <who name="Dwayne Grant McConnell">decimal</who>
            <bug_when>2006-02-21 16:47:56 +0000</bug_when>
            <thetext>Created attachment 878
Standalone preliminary testcase adapted from bug comments.

Here is a standalone testcase as well if someone happens to have a system with
autofs to reproduce this and to refine the testcase.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>43427</commentid>
            <who name="Petr Baudis">pasky</who>
            <bug_when>2010-06-01 03:23:03 +0000</bug_when>
            <thetext>AFAICS, current kernel does put_user(file-&gt;f_pos, &amp;lastdirent-&gt;d_off), thus
d_off should have well-defined meaning nowadays.
</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>43448</commentid>
            <who name="Dan Tsafrir">dan.tsafrir</who>
            <bug_when>2010-06-01 09:15:15 +0000</bug_when>
            <thetext>Petr, your reason for closing this bug is invalid:

(1) If you read the original bug report you&apos;ll notice that it&apos;s not
enough for d_off to have a &quot;well defined meaning&quot;. What you really
need is for that meaning to be the same in both the kernel and in
libc. This bug report specifically points out the fact that the
meaning is different.

(2) Also, if you search for put_user(file-&gt;f_pos,&amp;lastdirent-&gt;d_off)
in the kernel code you&apos;d see that it existed many, many years before
this bug was submitted (the line is there since Linux-1.3.0, no
less). Thus, having this line in the kernel doesn&apos;t prove or disprove
anything.
</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>53288</commentid>
            <who name="Joseph Myers">jsm28</who>
            <bug_when>2012-02-18 19:51:29 +0000</bug_when>
            <thetext>I do not believe there is a glibc bug here.

* The bug report quotes a manpage for the readdir system call as saying that d_off refers to the current dirent rather than the next dirent.  That is correct, but irrelevant.  The readdir system call is a backwards compatibility one using a very old version of the dirent structure.  With the getdents and getdents64 syscalls, different structures are used, and in those structures the semantics are that d_off refers to the next dirent, as you will see if you refer to the kernel sources or the getdents manpage.  The getdents64 syscalls is the relevant one here.

* The bug report claims there is an assumption that d_off contains a byte offset.  Actually, there is no such assumption.  The only requirement is that the kernel does not use -1 as an offset.  Otherwise, the offsets are used as opaque values, stored, copied, converted to the userspace type (with the result only compared for equality, not used for arithmetic) and used as an argument for __lseek64.  Using as an argument for __lseek64 (with SEEK_SET) is not using the value as a byte offset; it&apos;s up to each filesystem in the kernel to implement seeking on directories correctly so that it works with the opaque d_off values provided by the kernel.  Some filesystems may use byte offsets and some use other values involving a more complicated implementation of that seek operation in the kernel.

* Various different filesystems have been used for automounting (e.g. autofs / autofs4) and this report is not specific about exactly what filesystem, with what kernel version, is used in the problem situations.  (Kernels before 2.6.0 are in any case not in practice relevant to current glibc, although some support code for them has yet to be removed.)  But if a filesystem did not handle seeking with values provided in d_off, that would be a bug in the filesystem.

* It is certainly not correct to seek with byte offsets computed by glibc, since offsets for seeking in a directory are the same sort of opaque cookie provided in d_off and only those values may be passed to the kernel as a position to which to seek.  So the patch here cannot be correct.

* Finally, there is a concern about the conversion of d_off from 64-bit to 32-bit.  It&apos;s true that some applications may not use this value (used for telldir/seekdir), but the same applies to any other value returned by the kernel (inode numbers in particular); glibc cannot know what values the application wants and so must return EOVERFLOW if any value from the kernel cannot be represented in the userspace type.  The way for applications to avoid this is to be built with _FILE_OFFSET_BITS=64 so that the 64-bit interfaces are used, and this is the normal practice nowadays for most applications given the desire to support files over 2GB on 32-bit systems.

Regarding the other issues described with the source code, note that nbytes is not provided by the user of glibc since getdents is an internal-only interface.  There may well be issues there, but on any given system they would either be latent or appear every time the relevant code in getdents is executed, so it seems unlikely they affect any current system.  In any case, please always avoid mixing different issues in a single bug; file separate issues for these separate problems if you think they are still present.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>53302</commentid>
            <who name="Dan Tsafrir">dan.tsafrir</who>
            <bug_when>2012-02-19 14:36:28 +0000</bug_when>
            <thetext>Joseph,

It seems you&apos;ve mistakenly misread the bug report as claiming that
making assumptions regarding the offset is somehow correct/justified,
whereas, conversely, the bug reports just points to *glibc code* that
makes the erroneous assumption.

Hence, the report does not need to specify the filesystem on which the
bug was triggered, because it points to *glibc code* that suffers from
what you yourself acknowledge is a serious problem.</thetext>
          </long_desc>
          <long_desc isprivate="0">
            <commentid>53304</commentid>
            <who name="Joseph Myers">jsm28</who>
            <bug_when>2012-02-19 16:03:04 +0000</bug_when>
            <thetext>Dan,

Please read my comments in more detail.  Because offsets in directories are opaque cookies (if you look at the autofs sources in the kernel, you&apos;ll see that they are hash values for autofs, for example), and because the __lseek64 call&apos;s offset ends up being passed to the filesystem&apos;s llseek method which expects just such an opaque cookies, it can never be correct to pass a value calculated by adding up record lengths to __lseek64 on a file descriptor for a directory - and so those parts of your patch (adjusting how last_offset is computed) cannot be correct since last_offset is (only) used to pass to __lseek64 for such a file descriptor.  Maybe last_offset should be renamed to make clear that in normal terms it is not an offset; it&apos;s an opaque value on which no arithmetic is valid.

I do not see any glibc code (without your patch) that does any arithmetic on the offset values; it only copies them.  If you see any code that assumes that d_off values are meaningful in arithmetic (as opposed to being opaque values that can be used later to seek to a particular point in a directory), what specific lines of code (in current git master) are they?

For reference, &quot;grep last_offset getdents.c&quot; shows the following for me, none of which treat last_offset as anything other than an opaque value.

  off64_t last_offset = -1;
                  if (last_offset != -1)
                      __lseek64 (fd, last_offset, SEEK_SET);
              last_offset = d_off;
            assert (last_offset != -1);
            __lseek64 (fd, last_offset, SEEK_SET);
        last_offset = kdp-&gt;d_off;

Similarly, d_off is purely treated as opaque.

The second and third issues are likely bugs (albeit latent bugs), but *different* bugs, and one issue in the tracker should only ever be used for a single issue with the library.  Thus, those second and third issues (relating to nbytes, not d_off) should be filed as two separate tracker issues.</thetext>
          </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="1"
              isprivate="0"
              isurl="0"
          >
            <attachid>876</attachid>
            <date>2006-02-21 16:33:00 +0000</date>
            <delta_ts>2006-02-21 16:33:04 +0000</delta_ts>
            <desc>Patch taken from bug comments.</desc>
            <filename>glibc-bug-14.patch</filename>
            <type>text/plain</type>
            <size>1343</size>
            <attacher>decimal</attacher>
            
              <data encoding="base64">LS0tIGdldGRlbnRzLmMub3JpZwkyMDAzLTEyLTA0IDE5OjExOjM4LjAwMDAwMDAwMCArMDIwMAor
KysgZ2V0ZGVudHMuYwkyMDAzLTEyLTA0IDE5OjM4OjA2LjAwMDAwMDAwMCArMDIwMApAQCAtMTE3
LDcgKzExNyw3IEBACiAgICAgICBzaXplX3Qga2J5dGVzID0gbmJ5dGVzOwogICAgICAgaWYgKG9m
ZnNldG9mIChESVJFTlRfVFlQRSwgZF9uYW1lKQogCSAgPCBvZmZzZXRvZiAoc3RydWN0IGtlcm5l
bF9kaXJlbnQ2NCwgZF9uYW1lKQotCSAgJiYgbmJ5dGVzIDw9IHNpemVvZiAoRElSRU5UX1RZUEUp
KQorCSAgJiYgbmJ5dGVzIDw9IHNpemVvZiAoa2VybmVsX2RpcmVudDY0KSkKIAl7CiAJICBrYnl0
ZXMgPSBuYnl0ZXMgKyBvZmZzZXRvZiAoc3RydWN0IGtlcm5lbF9kaXJlbnQ2NCwgZF9uYW1lKQog
CQkgICAtIG9mZnNldG9mIChESVJFTlRfVFlQRSwgZF9uYW1lKTsKQEAgLTE3NSw4ICsxNzUsNyBA
QAogCSAgICAgIG91dHAtPnUuZF9vZmYgPSBkX29mZjsKIAkgICAgICBpZiAoKHNpemVvZiAob3V0
cC0+dS5kX2lubykgIT0gc2l6ZW9mIChpbnAtPmsuZF9pbm8pCiAJCSAgICYmIG91dHAtPnUuZF9p
bm8gIT0gZF9pbm8pCi0JCSAgfHwgKHNpemVvZiAob3V0cC0+dS5kX29mZikgIT0gc2l6ZW9mIChp
bnAtPmsuZF9vZmYpCi0JCSAgICAgICYmIG91dHAtPnUuZF9vZmYgIT0gZF9vZmYpKQorCQkgICkK
IAkJewogCQkgIC8qIE92ZXJmbG93LiAgSWYgdGhlcmUgd2FzIGF0IGxlYXN0IG9uZSBlbnRyeQog
CQkgICAgIGJlZm9yZSB0aGlzIG9uZSwgcmV0dXJuIHRoZW0gd2l0aG91dCBlcnJvciwKQEAgLTE5
MCw3ICsxODksMTAgQEAKIAkJICByZXR1cm4gLTE7CiAJCX0KIAotCSAgICAgIGxhc3Rfb2Zmc2V0
ID0gZF9vZmY7CisJICAgICAgaWYoIGxhc3Rfb2Zmc2V0ID09IC0xICkKKwkJbGFzdF9vZmZzZXQg
PSAwOworCSAgICAgIGxhc3Rfb2Zmc2V0ICs9IG9sZF9yZWNsZW47CisKIAkgICAgICBvdXRwLT51
LmRfcmVjbGVuID0gbmV3X3JlY2xlbjsKIAkgICAgICBvdXRwLT51LmRfdHlwZSA9IGRfdHlwZTsK
IApAQCAtMjEzLDYgKzIxNSw3IEBACiAgICAgY29uc3Qgc2l6ZV90IHNpemVfZGlmZiA9IChvZmZz
ZXRvZiAoRElSRU5UX1RZUEUsIGRfbmFtZSkKIAkJCSAgICAgIC0gb2Zmc2V0b2YgKHN0cnVjdCBr
ZXJuZWxfZGlyZW50LCBkX25hbWUpKTsKIAorICAgIC8qIGJ1Zz8gKG5ieXRlcyBtaWdodCBiZSBz
bWFsbGVyIHRoYW4gcmlnaHQgc2lkZSBvZiBtaW51cykgKi8KICAgICByZWRfbmJ5dGVzID0gTUlO
IChuYnl0ZXMKIAkJICAgICAgLSAoKG5ieXRlcyAvIChvZmZzZXRvZiAoRElSRU5UX1RZUEUsIGRf
bmFtZSkgKyAxNCkpCiAJCQkgKiBzaXplX2RpZmYpLAo=
</data>

          </attachment>
          <attachment
              isobsolete="0"
              ispatch="0"
              isprivate="0"
              isurl="0"
          >
            <attachid>877</attachid>
            <date>2006-02-21 16:33:00 +0000</date>
            <delta_ts>2006-02-21 16:33:44 +0000</delta_ts>
            <desc>Preliminary testcase adapted from bug comments.</desc>
            <filename>glibc-bug-14-test.c</filename>
            <type>text/plain</type>
            <size>818</size>
            <attacher>decimal</attacher>
            
              <data encoding="base64">I2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8ZGlyZW50Lmg+CiNpbmNsdWRlIDxzdGRp
by5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgovKiBYWFg6IFRoaXMgdGVzdGNhc2UgaXMgbm90IHJl
YWxseSBzZWxmLXN1ZmZpY2llbnQgYmVjYXVzZSBpdCBkZXBlbmRzCm9uIHRoZSBhdmFpbGFiaWxp
dHkgb2YgYW4gYXV0b2ZzIGZpbGVzeXN0ZW0gd2l0aCBhIGRpcmVjdG9yeS4gRXZlbgp0aGVuIHRo
ZSBidWcgaXMgbm9uLWRldGVybWluaXN0aWMgc28gbWF5IHJlcXVpcmUgZnVydGhlcgpzcGVjaWZp
Y2F0aW9uLiAqLwoKLyogVGhpcyBuZWVkcyB0byBiZSBjaGFuZ2VkIHRvIHBvaW50IHRvIGEgZGly
ZWN0b3J5IGluIGFuIGF1dG9mcyBmaWxlc3lzdGVtLiAqLwojZGVmaW5lIFNPTUVfQVVUT0ZTX0RJ
UkVDVE9SWSAiL21udC9hdXRvZnMvZGlyIgoKc3RhdGljIGludApkb190ZXN0ICh2b2lkKQp7CiAg
RElSICpkaXIgPSBvcGVuZGlyKFNPTUVfQVVUT0ZTX0RJUkVDVE9SWSk7CiAgaWYgKCFkaXIpCiAg
ICB7CiAgICAgIHByaW50ZigiQ291bGQgbm90IG9wZW4gIiBTT01FX0FVVE9GU19ESVJFQ1RPUlkg
Ii5cbiIpOwogICAgICByZXR1cm4gMTsKICAgIH0KCiAgc3RydWN0IGRpcmVudCAqZTsKICB3aGls
ZSggKGUgPSByZWFkZGlyKGRpcikpICE9IE5VTEwgKSAvLyBtaWdodCBuZXZlciByZXR1cm4gbnVs
bAogICAgcHJpbnRmKCJpbm89JWQgbmFtZT0lc1xuIiwgZS0+ZF9pbm8sIGUtPmRfbmFtZSk7Cgog
IHJldHVybiAwOwp9CgojZGVmaW5lIFRFU1RfRlVOQ1RJT04gZG9fdGVzdCAoKQojaW5jbHVkZSAi
Li4vdGVzdC1za2VsZXRvbi5jIgo=
</data>

          </attachment>
          <attachment
              isobsolete="0"
              ispatch="0"
              isprivate="0"
              isurl="0"
          >
            <attachid>878</attachid>
            <date>2006-02-21 16:47:00 +0000</date>
            <delta_ts>2006-02-21 16:47:56 +0000</delta_ts>
            <desc>Standalone preliminary testcase adapted from bug comments.</desc>
            <filename>glibc-bug-14-standalone.c</filename>
            <type>text/plain</type>
            <size>775</size>
            <attacher>decimal</attacher>
            
              <data encoding="base64">I2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8ZGlyZW50Lmg+CiNpbmNsdWRlIDxzdGRp
by5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgovKiBYWFg6IFRoaXMgdGVzdGNhc2UgaXMgbm90IHJl
YWxseSBzZWxmLXN1ZmZpY2llbnQgYmVjYXVzZSBpdCBkZXBlbmRzCm9uIHRoZSBhdmFpbGFiaWxp
dHkgb2YgYW4gYXV0b2ZzIGZpbGVzeXN0ZW0gd2l0aCBhIGRpcmVjdG9yeS4gRXZlbgp0aGVuIHRo
ZSBidWcgaXMgbm9uLWRldGVybWluaXN0aWMgc28gbWF5IHJlcXVpcmUgZnVydGhlcgpzcGVjaWZp
Y2F0aW9uLiAqLwoKLyogVGhpcyBuZWVkcyB0byBiZSBjaGFuZ2VkIHRvIHBvaW50IHRvIGEgZGly
ZWN0b3J5IGluIGFuIGF1dG9mcyBmaWxlc3lzdGVtLiAqLwojZGVmaW5lIFNPTUVfQVVUT0ZTX0RJ
UkVDVE9SWSAiL21udC9hdXRvZnMvZGlyIgoKaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKmFyZ3Zb
XSwgY2hhciAqZW52cFtdKQp7CiAgRElSICpkaXIgPSBvcGVuZGlyKFNPTUVfQVVUT0ZTX0RJUkVD
VE9SWSk7CiAgaWYgKCFkaXIpCiAgICB7CiAgICAgIHByaW50ZigiQ291bGQgbm90IG9wZW4gIiBT
T01FX0FVVE9GU19ESVJFQ1RPUlkgIi5cbiIpOwogICAgICByZXR1cm4gMTsKICAgIH0KCiAgc3Ry
dWN0IGRpcmVudCAqZTsKICB3aGlsZSggKGUgPSByZWFkZGlyKGRpcikpICE9IE5VTEwgKSAvLyBt
aWdodCBuZXZlciByZXR1cm4gbnVsbAogICAgcHJpbnRmKCJpbm89JWQgbmFtZT0lc1xuIiwgZS0+
ZF9pbm8sIGUtPmRfbmFtZSk7CgogIHJldHVybiAwOwp9Cg==
</data>

          </attachment>
      

    </bug>

</bugzilla>