NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/41494



On Wed, May 27, 2009 at 04:15:04PM +0000, Antti Kantee wrote:
>  On Wed, May 27, 2009 at 05:23:01PM +0200, Nicolas Joly wrote:
>  > For some reason the offset value in sysctlfs_node_read() exceed the
>  > localbuf buffer size, leading to an out-of-bound access with
>  > memcopy...
>  > 
>  > 635             memcpy(buf, localbuf + offset, xfer);
>  > (gdb) p localbuf
>  > $1 = "NetBSD", '\0' <repeats 8185 times>
>  > (gdb) p offset
>  > $2 = 8199
>  > (gdb) p sizeof(localbuf)
>  > $3 = 8192
>  > (gdb) p xfer
>  > $4 = 4096
>  
>  Uh oh ... ok, I think this is what happening:
>  
>          int xfer;
>          xfer = MIN(*resid, strlen(localbuf) - offset);
>  
>  On i386 size_t (from strlen) is smaller than off_t (offset), hence
>  it is widened to signed and the result the calculation is
>  signed (64) - signed(64) ==> signed.  On amd64 where size_t is the
>  same size as off_t, the calculation is unsigned - signed (converted
>  to unsigned) ==> unsigned and hence *resid is always smaller when
>  offset is larger than the file size without the trailing \n.
>  
>  .... *blink blink*.  I must confess I didn't see that one coming
>  when I wrote the code.
>  
>  Try if this helps this:

No luck ... But this slightly modified version make the following
command successful.

        find /mnt -type f | xargs cat

Index: sysctlfs.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/puffs/mount_sysctlfs/sysctlfs.c,v
retrieving revision 1.10
diff -u -p -r1.10 sysctlfs.c
--- sysctlfs.c  18 Jan 2009 10:10:47 -0000      1.10
+++ sysctlfs.c  27 May 2009 16:41:29 -0000
@@ -627,7 +627,10 @@ sysctlfs_node_read(struct puffs_usermoun
                return EISDIR;
 
        doprint(sfs, &pn->pn_po, localbuf, sizeof(localbuf));
-       xfer = MIN(*resid, strlen(localbuf) - offset);
+       if (strlen(localbuf) < offset)
+               xfer = 0;
+       else
+               xfer = MIN(*resid, strlen(localbuf) - offset);
 
        if (xfer <= 0)
                return 0;


-- 
Nicolas Joly

Biological Software and Databanks.
Institut Pasteur, Paris.


Home | Main Index | Thread Index | Old Index