Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 25 May 1998 00:23:42 -0700 (PDT)
From:      ovg@nusun.jinr.ru
To:        freebsd-gnats-submit@FreeBSD.ORG
Subject:   kern/6747: bad rpc call to nfs crashes system
Message-ID:  <199805250723.AAA11830@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         6747
>Category:       kern
>Synopsis:       bad rpc call to nfs crashes system
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon May 25 00:20:00 PDT 1998
>Last-Modified:
>Originator:     Vladimir Olshevsky
>Organization:
Joint Institute for Nuclear Research
>Release:        FreeBSD 2.2.6
>Environment:
FreeBSD nuraid.jinr.ru 2.2.6-RELEASE FreeBSD 2.2.6-RELEASE #1: 
Fri May 22 19:00:11 MSD 1998     
ovg@nuraid.jinr.ru:/usr/src/sys/compile/NURAID  i386
>Description:
Issuing an rpc call to nfs with negative procedure number
crashes system. Here is a kgdb  session:

nuraid#>gdb -k
(kgdb) symbol-file kernel.debug.3
Reading symbols from kernel.debug.3...done
(kgdb) exec-file kernel.3
(kgdb) core-file vmcore.3
IdlePTD 208000
current pcb at 1ec9ac
panic: page fault
#0  boot (howto=256) at ../../kern/kern_shutdown.c:266
266                                     dumppcb.pcb_cr3 = rcr3();
(kgdb) where
#0  boot (howto=256) at ../../kern/kern_shutdown.c:266
#1  0xf0110f92 in panic (fmt=0xf01bb3df "page fault")
    at ../../kern/kern_shutdown.c:390
#2  0xf01bbf86 in trap_fatal (frame=0xefbffd10) at ../../i386/i386/trap.c:770
#3  0xf01bba74 in trap_pfault (frame=0xefbffd10, usermode=0)
    at ../../i386/i386/trap.c:677
#4  0xf01bb717 in trap (frame={tf_es = 16, tf_ds = 16, tf_edi = -227143168,
      tf_esi = -241365248, tf_ebp = -272630364, tf_isp = -272630472, 
      tf_ebx = -241365144, tf_edx = -241365248, tf_ecx = 2, 
      tf_eax = -1995291404, tf_trapno = 12, tf_err = 0, tf_eip = -266941659, 
      tf_cs = 8, tf_eflags = 66118, tf_esp = -227143168, tf_ss = -241365248})
    at ../../i386/i386/trap.c:324
#5  0xf016cb25 in nfs_getreq (nd=0xf2761200, nfsd=0xf2537c00, has_header=1)
    at ../../nfs/nfs_socket.c:1980
#6  0xf016c8dc in nfsrv_dorec (slp=0xf2500000, nfsd=0xf2537c00, ndp=0xefbffe34)
    at ../../nfs/nfs_socket.c:1894
#7  0xf01715e6 in nfssvc_nfsd (nsd=0xefbffe8c, argp=0x1770c "", p=0xf252f600)
    at ../../nfs/nfs_syscalls.c:520
#8  0xf01710e8 in nfssvc (p=0xf252f600, uap=0xefbfff94, retval=0xefbfff84)
    at ../../nfs/nfs_syscalls.c:344
#9  0xf01bc1c3 in syscall (frame={tf_es = 39, tf_ds = 39, tf_edi = 8, 
      tf_esi = 0, tf_ebp = -272638388, tf_isp = -272629788, tf_ebx = 1, 
      tf_edx = -272638564, tf_ecx = 0, tf_eax = 155, tf_trapno = 12, 
      tf_err = 7, tf_eip = 10805, tf_cs = 31, tf_eflags = 658, 
      tf_esp = -272638556, tf_ss = 39}) at ../../i386/i386/trap.c:918
#10 0x2a35 in ?? ()
#11 0x107e in ?? ()
(kgdb) up 5
#5  0xf016cb25 in nfs_getreq (nd=0xf2761200, nfsd=0xf2537c00, has_header=1)
    at ../../nfs/nfs_socket.c:1980
1980                    nd->nd_procnum = nfsv3_procid[nd->nd_procnum];
(kgdb) print nd->nd_procnum
$1 = -1995291404
(kgdb) 

>How-To-Repeat:
Issue an rpc call to nfs with negative procedure 
number ... Analyze crash dump 
>Fix:
The problem is in comparison of signed variable with 
maximum procedure number in nfs_socket.c:1972 - there is no 
check on (invalid) negative value in nd->nd_procnum

To fix it, apply a following patch:
*** /sys/nfs/nfs_socket.c.orig  Wed May 14 12:19:28 1997
--- /sys/nfs/nfs_socket.c       Mon May 25 11:21:39 1998
***************
*** 1969,1977 ****
        nd->nd_procnum = fxdr_unsigned(u_long, *tl++);
        if (nd->nd_procnum == NFSPROC_NULL)
                return (0);
!       if (nd->nd_procnum >= NFS_NPROCS ||
!               (!nqnfs && nd->nd_procnum >= NQNFSPROC_GETLEASE) ||
!               (!nd->nd_flag && nd->nd_procnum > NFSV2PROC_STATFS)) {
                nd->nd_repstat = EPROCUNAVAIL;
                nd->nd_procnum = NFSPROC_NOOP;
                return (0);
--- 1969,1977 ----
        nd->nd_procnum = fxdr_unsigned(u_long, *tl++);
        if (nd->nd_procnum == NFSPROC_NULL)
                return (0);
!       if ((unsigned)nd->nd_procnum >= NFS_NPROCS ||
!               (!nqnfs && (unsigned)nd->nd_procnum >= NQNFSPROC_GETLEASE) ||
!               (!nd->nd_flag && (unsigned)nd->nd_procnum > NFSV2PROC_STATFS)) {
                nd->nd_repstat = EPROCUNAVAIL;
                nd->nd_procnum = NFSPROC_NOOP;
                return (0);

>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199805250723.AAA11830>