NetBSD Problem Report #41494

From avl@osu.zhtw.org.ru  Wed May 27 13:51:46 2009
Return-Path: <avl@osu.zhtw.org.ru>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by www.NetBSD.org (Postfix) with ESMTP id 260AD63C267
	for <gnats-bugs@gnats.NetBSD.org>; Wed, 27 May 2009 13:51:46 +0000 (UTC)
Message-Id: <20090527135141.3E418D47D@osu.zhtw.org.ru>
Date: Wed, 27 May 2009 17:51:41 +0400 (MSD)
From: avl@osu.zhtw.org.ru
Reply-To: a@zhtw.org.ru
To: gnats-bugs@gnats.NetBSD.org
Subject: mount_sysctlfs dumps core
X-Send-Pr-Version: 3.95

>Number:         41494
>Category:       bin
>Synopsis:       mount_sysctlfs dumps core when net/inet/ip/<smth> is accessed
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    njoly
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed May 27 13:55:00 +0000 2009
>Closed-Date:    Sun May 31 13:06:20 +0000 2009
>Last-Modified:  Sun May 31 13:06:20 +0000 2009
>Originator:     Alexey Lebedev
>Release:        NetBSD 5.0
>Organization:

>Environment:


System: NetBSD osu.zhtw.org.ru 5.0 NetBSD 5.0 (GENERIC) #0: Sun Apr 26 06:32:14 UTC 2009 builds@b6.netbsd.org:/home/builds/ab/netbsd-5-0-RELEASE/amd64/200904260229Z-obj/home/builds/ab/netbsd-5-0-RELEASE/src/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:
mount_sysctlfs dumps core when net/inet/ip/<smth> is read.

>How-To-Repeat:
$ sudo mount_sysctlfs sysctlfs /sys
$ cat /sys/net/inet/ip/forwarding
0
cat: /sys/net/inet/ip/forwarding: Device not configured
$ ls -l /sys/
$ ls -lh mount_sysctlfs.core 
-rw-------  1 root  users  174K May 27 17:49 mount_sysctlfs.core


>Fix:
Don't know


>Release-Note:

>Audit-Trail:
From: Antti Kantee <pooka@cs.hut.fi>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/41494
Date: Wed, 27 May 2009 17:12:22 +0300

 Not for me:

 pain-rustique:15:~> cat /sysctl/net/inet/ip/forwarding
 0
 pain-rustique:16:~> 

 I don't really have a clue as to what is going wrong.  Any chance you
 could provide a stack backtrace and/or run mount_sysctlfs with
 "mount_sysctlfs -o dump flop /sys" and copypaste the output?
 Also, what does "sysctl net.inet.ip.forwarding" show?

From: Nicolas Joly <njoly@pasteur.fr>
To: gnats-bugs@NetBSD.org
Cc: gnats-admin@netbsd.org, netbsd-bugs@netbsd.org, a@zhtw.org.ru
Subject: Re: kern/41494
Date: Wed, 27 May 2009 17:23:01 +0200

 On Wed, May 27, 2009 at 02:15:04PM +0000, Antti Kantee wrote:
 [...]
 >  I don't really have a clue as to what is going wrong.  Any chance you
 >  could provide a stack backtrace and/or run mount_sysctlfs with
 >  "mount_sysctlfs -o dump flop /sys" and copypaste the output?
 >  Also, what does "sysctl net.inet.ip.forwarding" show?

 I can reproduce it on my -current amd64 machines ... with some other
 nodes such as `kern.ostype':

 njoly@lanfeust [~]> sudo mount_sysctlfs -o dump sysctlfs /mnt
         reqid: 0, opclass 2, optype: PUFFS_VN_LOOKUP, cookie: 0x7f7ffd601100,
                 aux: 0x7f7ffd611038, auxlen: 1224, pid: 3990, lwpid: 1
                 puffs_cn: "kern", len 4 op LOOKUP (flags 0x84054)
                 since previous call: 1243435876.732998
                 new node 0x7f7ffd601200, type 0x2,
                 size 0x0, dev 0x0
         RV reqid: 0, result: 0 
         reqid: 1, opclass 2, optype: PUFFS_VN_LOOKUP, cookie: 0x7f7ffd601200,
                 aux: 0x7f7ffd617038, auxlen: 1224, pid: 3990, lwpid: 1
                 puffs_cn: "ostype", len 6 op LOOKUP (flags 0xc054)
                 since previous call: 0.000256
                 new node 0x7f7ffd601300, type 0x1,
                 size 0x0, dev 0x0
         RV reqid: 1, result: 0 
         reqid: 2, opclass 2, optype: PUFFS_VN_READ, cookie: 0x7f7ffd601300,
                 aux: 0x7f7ffd617038, auxlen: 4264, pid: 3990, lwpid: 1
                 offset: 0, resid 4096, ioflag 0x0
                 since previous call: 0.000311
                 resid after op: 4089
         RV reqid: 2, result: 0 
         reqid: 3, opclass 2, optype: PUFFS_VN_READ, cookie: 0x7f7ffd601300,
                 aux: 0x7f7ffd617038, auxlen: 4264, pid: 3990, lwpid: 1
                 offset: 7, resid 4096, ioflag 0x0
                 since previous call: 0.000211
                 resid after op: 0
         RV reqid: 3, result: 0 
         reqid: 4, opclass 2, optype: PUFFS_VN_READ, cookie: 0x7f7ffd601300,
                 aux: 0x7f7ffd617038, auxlen: 4264, pid: 3990, lwpid: 1
                 offset: 4103, resid 4096, ioflag 0x0
                 since previous call: 0.000497
                 resid after op: 0
         RV reqid: 4, result: 0 
         reqid: 5, opclass 2, optype: PUFFS_VN_READ, cookie: 0x7f7ffd601300,
                 aux: 0x7f7ffd617038, auxlen: 4264, pid: 3990, lwpid: 1
                 offset: 8199, resid 4096, ioflag 0x0
                 since previous call: 0.000478
 zsh: segmentation fault (core dumped)  sudo  -o dump sysctlfs /mnt

 For some reason the offset value in sysctlfs_node_read() exceed the
 localbuf buffer size, leading to an out-of-bound access with
 memcopy...

 njoly@lanfeust [~]> gdb mount_sysctlfs mount_sysctlfs.core
 GNU gdb 6.5
 Copyright (C) 2006 Free Software Foundation, Inc.
 [...]
 Program terminated with signal 11, Segmentation fault.
 #0  0x0000000000402eed in sysctlfs_node_read (pu=0x7f7ffd605800, 
     opc=0x7f7ffd601300, buf=0x7f7ffd6170a4 "", offset=8199, 
     resid=0x7f7ffd617098, pcr=0x7f7ffd617038, ioflag=0)
     at /local/src/NetBSD/src/usr.sbin/puffs/mount_sysctlfs/sysctlfs.c:635
 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

 -- 
 Nicolas Joly

 Biological Software and Databanks.
 Institut Pasteur, Paris.

From: Antti Kantee <pooka@NetBSD.org>
To: Nicolas Joly <njoly@pasteur.fr>
Cc: gnats-bugs@NetBSD.org, a@zhtw.org.ru
Subject: Re: kern/41494
Date: Wed, 27 May 2009 19:13:26 +0300

 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:

 Index: sysctlfs.c
 ===================================================================
 RCS file: /cvsroot/src/usr.sbin/puffs/mount_sysctlfs/sysctlfs.c,v
 retrieving revision 1.10
 diff -p -u -r1.10 sysctlfs.c
 --- sysctlfs.c  18 Jan 2009 10:10:47 -0000      1.10
 +++ sysctlfs.c  27 May 2009 16:06:41 -0000
 @@ -627,9 +627,12 @@ 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)
 +       if (xfer < 0)
                 return 0;

         memcpy(buf, localbuf + offset, xfer);

From: Nicolas Joly <njoly@pasteur.fr>
To: Antti Kantee <pooka@NetBSD.org>
Cc: netbsd-bugs@netbsd.org, a@zhtw.org.ru
Subject: Re: kern/41494
Date: Wed, 27 May 2009 18:50:17 +0200

 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.

Responsible-Changed-From-To: bin-bug-people->njoly
Responsible-Changed-By: njoly@NetBSD.org
Responsible-Changed-When: Thu, 28 May 2009 09:54:32 +0000
Responsible-Changed-Why:
I'll handle it.


From: Nicolas Joly <njoly@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/41494 CVS commit: src/usr.sbin/puffs/mount_sysctlfs
Date: Thu, 28 May 2009 10:07:06 +0000

 Module Name:	src
 Committed By:	njoly
 Date:		Thu May 28 10:07:06 UTC 2009

 Modified Files:
 	src/usr.sbin/puffs/mount_sysctlfs: sysctlfs.c

 Log Message:
 Fix a crash while trying to read nodes on amd64, reported in PR/41494,
 by not doing any transfert when offset exceed the actual data length.

 From and ok by pooka@.


 To generate a diff of this commit:
 cvs rdiff -u -r1.10 -r1.11 src/usr.sbin/puffs/mount_sysctlfs/sysctlfs.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->pending-pullups
State-Changed-By: njoly@NetBSD.org
State-Changed-When: Thu, 28 May 2009 10:15:54 +0000
State-Changed-Why:
Fixed in -current. netbsd-5 pullup requested.


From: Soren Jacobsen <snj@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/41494 CVS commit: [netbsd-5-0] src/usr.sbin/puffs/mount_sysctlfs
Date: Sat, 30 May 2009 16:47:30 +0000

 Module Name:	src
 Committed By:	snj
 Date:		Sat May 30 16:47:30 UTC 2009

 Modified Files:
 	src/usr.sbin/puffs/mount_sysctlfs [netbsd-5-0]: sysctlfs.c

 Log Message:
 Pull up following revision(s) (requested by njoly in ticket #783):
 	usr.sbin/puffs/mount_sysctlfs/sysctlfs.c: revision 1.11
 Fix a crash while trying to read nodes on amd64, reported in PR/41494,
 by not doing any transfert when offset exceed the actual data length.
 From and ok by pooka@.


 To generate a diff of this commit:
 cvs rdiff -u -r1.9 -r1.9.6.1 src/usr.sbin/puffs/mount_sysctlfs/sysctlfs.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: Soren Jacobsen <snj@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/41494 CVS commit: [netbsd-5] src/usr.sbin/puffs/mount_sysctlfs
Date: Sat, 30 May 2009 16:49:35 +0000

 Module Name:	src
 Committed By:	snj
 Date:		Sat May 30 16:49:35 UTC 2009

 Modified Files:
 	src/usr.sbin/puffs/mount_sysctlfs [netbsd-5]: sysctlfs.c

 Log Message:
 Pull up following revision(s) (requested by njoly in ticket #783):
 	usr.sbin/puffs/mount_sysctlfs/sysctlfs.c: revision 1.11
 Fix a crash while trying to read nodes on amd64, reported in PR/41494,
 by not doing any transfert when offset exceed the actual data length.
 From and ok by pooka@.


 To generate a diff of this commit:
 cvs rdiff -u -r1.9 -r1.9.4.1 src/usr.sbin/puffs/mount_sysctlfs/sysctlfs.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: pending-pullups->closed
State-Changed-By: njoly@NetBSD.org
State-Changed-When: Sun, 31 May 2009 13:06:20 +0000
State-Changed-Why:
Fixed and pulled up to netbsd 5
Thanks for your PR.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.