Date: Sun, 13 Feb 2005 19:55:41 GMT From: "Wojciech A. Koszek" <dunstan@freebsd.czest.pl> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/77463: [PATCH] Local DoS from user-space in NFS client (uid == 0 needed) Message-ID: <200502131955.j1DJtf7d006738@freebsd.czest.pl> Resent-Message-ID: <200502132000.j1DK0iZj050610@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 77463 >Category: kern >Synopsis: [PATCH] Local DoS from user-space in NFS client (uid == 0 needed) >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Feb 13 20:00:34 GMT 2005 >Closed-Date: >Last-Modified: >Originator: Wojciech A. Koszek >Release: FreeBSD 5.3-STABLE i386 >Organization: >Environment: System: FreeBSD dunstan.freebsd.czest.pl 5.3-STABLE FreeBSD 5.3-STABLE #0: Sat Feb 12 11:15:23 CET 2005 root@dunstan.freebsd.czest.pl:/usr/obj/usr/src/sys/HOME6 i386 Tested on: -- kern.ostype: FreeBSD kern.osrelease: 5.3-STABLE kern.osrevision: 199506 kern.version: FreeBSD 5.3-STABLE #0: Sat Feb 12 11:15:23 CET 2005 root@dunstan.freebsd.czest.pl:/usr/obj/usr/src/sys/HOME6 -- kern.ostype: FreeBSD kern.osrelease: 6.0-CURRENT kern.osrevision: 199506 kern.version: FreeBSD 6.0-CURRENT #2: Sat Feb 12 10:43:18 UTC 2005 root@:/usr/obj/usr/src/sys/GENERIC -- >Description: There is a bug in NFS client code (/usr/src/sys/nfs4client/nfs4_dev.c, function nfs4dev_reply(caddr_t addr)). This file is used to build nfsclient and nfs4client. Both are vulnerable. FreeBSD kernel panics when trying to call ioctl(fd, NFS4DEVIOCPUT, &m) where m is pointer to nfs4dev_msg structure containg msg_len variable set to weird values (1,2,3,...). These lengts doesn't make sense, since other data (bigger than for example 1 byte) have to be kept in that structure. uid == 0 is needed (/dev/nfs4 has to be opened in read/write mode). >How-To-Repeat: Make sure your system has NFS support. Line: [..] options NFSCLIENT [..] Should appear in your kernel config file. You may also load nfs*client support as kernel module: # cd /usr/src/sys/modules/nfsclient && make load After running attached code [nfstest.c] kernel will panic: $ gcc nfstest.c -o nfstest Usage: ./nfstest <digit> Example: # ./nfstest 2 >Fix: I've decided to limit minimal size of msg_len to sizeof(struct nfs4dev_msg) - NFS4DEV_MSG_MAX_DATALEN (which is size of internal array placed in that structure). Packet with smaller length doesn't make sense (we have to get other values: msg_vers, msg_type, msg_len, but 1 byte is to small to handle them). --- nfstest.c begins here --- #include <sys/param.h> #include <sys/ioctl.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include </sys/nfs4client/nfs4_dev.h> int main (int argc, char **argv) { int fd; int error = 0; struct nfs4dev_msg m; if (argc < 2) { fprintf(stderr, "usage number\n"); exit(1); } fd = open("/dev/nfs4", O_RDWR); if (fd == -1) exit(111); bzero(&m ,sizeof(m)); m.msg_vers = NFS4DEV_VERSION; m.msg_type = 1; /* XXX You may change this */ m.msg_len = atoi(*++argv); error = ioctl(fd, NFS4DEVIOCPUT, &m); if (error) errx(error, "ioctl!:%s\n", strerror(errno)); _exit(0); } --- nfstest.c ends here --- --- diff.0.nfs4client begins here --- diff -upr /usr/src/sys/nfs4client/nfs4_dev.c src/sys/nfs4client/nfs4_dev.c --- /usr/src/sys/nfs4client/nfs4_dev.c Thu Nov 11 12:34:17 2004 +++ src/sys/nfs4client/nfs4_dev.c Sun Nov 14 23:49:05 2004 @@ -152,11 +152,12 @@ nfs4dev_reply(caddr_t addr) return EINVAL; } - if (m->msg_len == 0 || m->msg_len > NFS4DEV_MSG_MAX_DATALEN) { + if (m->msg_len < sizeof(m) - NFS4DEV_MSG_MAX_DATALEN || + m->msg_len > NFS4DEV_MSG_MAX_DATALEN) { NFS4DEV_DEBUG("bad message length\n"); return EINVAL; } - + /* match the reply with a request */ mtx_lock(&nfs4dev_waitq_mtx); TAILQ_FOREACH(u, &nfs4dev_waitq, up_entry) { --- diff.0.nfs4client ends here --- >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200502131955.j1DJtf7d006738>