TUCoPS :: BSD :: b1a-1156.htm

FreeBSD kernel NFS client local vulnerabilities
CVE-2010-2020: FreeBSD kernel NFS client local vulnerabilities
CVE-2010-2020: FreeBSD kernel NFS client local vulnerabilities

Census ID:          census-2010-0001
CVE ID:             CVE-2010-2020
Affected Products:  FreeBSD 8.0-RELEASE, 7.3-RELEASE, 7.2-RELEASE
Class:              Improper Input Validation (CWE-20)
Remote:             No
Discovered by:      Patroklos Argyroudis

We have discovered two improper input validation vulnerabilities in the
FreeBSD kernel's NFS client-side implementation (FreeBSD 8.0-RELEASE,
7.3-RELEASE and 7.2-RELEASE) that allow local unprivileged users to
escalate their privileges, or to crash the system by performing a denial
of service attack.


FreeBSD (http://www.freebsd.org/) is an advanced operating system which 
focuses on reliability and performance. More information about its
features can be found at http://www.freebsd.org/about.html. 

FreeBSD 8.0-RELEASE, 7.3-RELEASE and 7.2-RELEASE employ an improper input
validation method in the kernel's NFS client-side implementation.
Specifically, the first vulnerability is in function nfs_mount() (file
src/sys/nfsclient/nfs_vfsops.c) which is reachable from the mount(2) and
nmount(2) system calls. In order for them to be enabled for unprivileged
users the sysctl(8) variable vfs.usermount must be set to a non-zero

The function nfs_mount() employs an insufficient input validation method
for copying data passed in a structure of type nfs_args from userspace to
kernel. Specifically, the file handle buffer to be mounted (args.fh) and
its size (args.fhsize) are completely user-controllable. The unbounded copy
operation is in file src/sys/nfsclient/nfs_vfsops.c (the excerpts are from

1094:      if (!has_fh_opt) {
1095:            error = copyin((caddr_t)args.fh, (caddr_t)nfh,
1096:                 args.fhsize);
1097:          if (error) {
1098:               goto out;
1099:            }

The declaration of the variables args and nfh is at:

786: static int
787: nfs_mount(struct mount *mp)
788: {
789:         struct nfs_args args = {
790:             .version = NFS_ARGSVERSION,
820:         u_char nfh[NFSX_V3FHMAX];

This vulnerability can cause a kernel stack overflow which leads to
privilege escalation on FreeBSD 7.3-RELEASE and 7.2-RELEASE. On FreeBSD
8.0-RELEASE the result is a kernel crash/denial of service due to the
SSP/ProPolice kernel stack-smashing protection which is enabled by
default. Versions 7.1-RELEASE and earlier do not appear to be
vulnerable since the bug was introduced in 7.2-RELEASE. In order to
demonstrate the impact of the vulnerability we have developed a
proof-of-concept privilege escalation exploit:


A sample run of the exploit follows:

[argp@julius ~]$ uname -rsi
[argp@julius ~]$ sysctl vfs.usermount
vfs.usermount: 1
[argp@julius ~]$ id
uid=1001(argp) gid=1001(argp) groups=1001(argp)
[argp@julius ~]$ gcc -Wall nfs_mount_ex.c -o nfs_mount_ex
[argp@julius ~]$ ./nfs_mount_ex
[*] calling nmount()
[!] nmount error: -1030740736
nmount: Unknown error: -1030740736
[argp@julius ~]$ id
uid=0(root) gid=0(wheel) egid=1001(argp) groups=1001(argp)

The second vulnerability exists in the function mountnfs() that is called
from function nfs_mount():

1119: error = mountnfs(&args, mp, nam, args.hostname, &vp,
1120:     curthread->td_ucred);

The function mountnfs() is reachable from the mount(2) and nmount(2) system
calls by unprivileged users. As with the nfs_mount() case above, this
requires the sysctl(8) variable vfs.usermount to be set to a non-zero value.

The file handle to be mounted (argp->fh) and its size (argp->fhsize)
are passed to function mountnfs() from function nfs_mount() and are
user-controllable. These are subsequently used in an unbounded bcopy()
call (file src/sys/nfsclient/nfs_vfsops.c):

1219: bcopy((caddr_t)argp->fh, (caddr_t)nmp->nm_fh, argp->fhsize);

The above can cause a kernel heap overflow when argp->fh is bigger than 128
bytes (the size of nmp->nm_fh) since nmp is an allocated item on the
Universal Memory Allocator (UMA, the FreeBSD kernel's heap allocator)
zone nfsmount_zone (again from src/sys/nfsclient/nfs_vfsops.c):

1160: static int
1161: mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
1162:     char *hst, struct vnode **vpp, struct ucred *cred)
1163: {
1164:         struct nfsmount *nmp;
1165:         struct nfsnode *np;
1166:         int error;
1167:         struct vattr attrs;
1169:         if (mp->mnt_flag &MNT_UPDATE) {
1170:                 nmp = VFSTONFS(mp);
1171:                 printf("%s: MNT_UPDATE is no longer handled here\n",
1172:                 free(nam, M_SONAME);
1173:                 return (0);
1174:         } else {
1175:                 nmp = uma_zalloc(nfsmount_zone, M_WAITOK);

This kernel heap overflow can lead on FreeBSD 8.0-RELEASE, 7.3-RELEASE and
7.2-RELEASE to privilege escalation and/or a kernel crash/denial of
service attack. Similarly to the first vulnerability, FreeBSD 7.1-RELEASE
and earlier versions do not appear to be vulnerable. We have developed a
proof-of-concept DoS exploit to demonstrate the vulnerability:


Furthermore, we have also developed a privilege escalation exploit for this
second vulnerability which will not be released at this point.

FreeBSD has released an official advisory and a patch to address both


All affected parties are advised to follow the upgrade instructions
included in the advisory and patch their systems.

Patroklos Argyroudis

TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH