DragonFlyBSD Kernel Audit
DF-0859 / mount_rw.c
← back to finding ↓ download raw
/*
 * DF-0859 — RW HPFS mount helper.
 *
 * DragonFly's mount_hpfs(8) unconditionally forces MNT_RDONLY on every
 * mount (sbin/mount_hpfs/mount_hpfs.c:107).  To exercise the DF-0859
 * write-path overflow (hpfs_addextent -> hpfs_alblk2alsec) we must mount
 * the crafted image READ-WRITE, so we call mount(2) directly without
 * setting MNT_RDONLY.
 *
 * Usage:  ./mount_rw /dev/vn1 /mnt
 *
 * Build:  cc -o mount_rw mount_rw.c
 * (root only — mount(2) requires root unless vfs.usermount=1)
 */
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <vfs/hpfs/hpfsmount.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int
main(int argc, char **argv)
{
	struct hpfs_args args;
	struct stat sb;
	const char *dev, *dir;
	int mntflags = 0;     /* deliberately NOT setting MNT_RDONLY */

	if (argc != 3) {
		fprintf(stderr, "usage: %s <dev> <dir>\n", argv[0]);
		return 2;
	}
	dev = argv[1];
	dir = argv[2];

	memset(&args, 0, sizeof(args));
	args.fspec = (char *)dev;
	if (stat(dir, &sb) == -1)
		err(1, "stat %s", dir);
	args.uid = sb.st_uid;
	args.gid = sb.st_gid;
	args.mode = sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);

	if (mount("hpfs", dir, mntflags, &args) < 0)
		err(1, "mount(hpfs, %s, %s)", dev, dir);

	printf("mounted %s on %s (RW)\n", dev, dir);
	return 0;
}