⬢ DragonFlyBSD Kernel Audit
DF-5033 / harness_prelude.h
← back to finding ↓ download raw
/* Build-time prelude injected in place of linux_idr.c's USERLAND_TEST block.
 *
 * The generated idr_test_core.c keeps EVERY algorithm line of
 * sys/libkern/linux_idr.c byte-identical; only the two #ifdef branches at the
 * top of the file are replaced by this header, which provides the same stubs
 * the file's own USERLAND_TEST block provides (kmalloc/kfree/lwkt_*), but
 * with an allocation tracker + poison-on-free so that a lockless idr_find()
 * reading a freed idr_nodes[] array is DETECTED deterministically.
 *
 * IDR_FIXED_BUILD additionally maps lwkt_gettoken/reltoken onto a real
 * pthread mutex (this is exactly what a fixed kernel idr_find would hold)
 * to validate that serializing idr_find against idr_grow kills the race.
 */
#ifndef HARNESS_PRELUDE_H
#define HARNESS_PRELUDE_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <sys/types.h>

#include <sys/idr.h>		/* harness replica of sys/sys/idr.h */

#define MALLOC_DEFINE(a, b, c)

#ifdef IDR_FIXED_BUILD
#define lwkt_gettoken(x)	pthread_mutex_lock(&(x)->m)
#define lwkt_reltoken(x)	pthread_mutex_unlock(&(x)->m)
#define lwkt_token_init(a, b)	pthread_mutex_init(&(a)->m, NULL)
#define lwkt_token_uninit(a)	pthread_mutex_destroy(&(a)->m)
#else
/* Matches the real kernel: idr_find() takes NO token. */
#define lwkt_gettoken(x)
#define lwkt_reltoken(x)
#define lwkt_token_init(a, b)
#define lwkt_token_uninit(a)
#endif

#define KKASSERT(a)		assert(a)
#define panic(...)		do { \
	fprintf(stderr, "linux_idr panic: " __VA_ARGS__); abort(); \
} while (0)
#define min(a, b)	(((a) < (b)) ? (a) : (b))
#define max(a, b)	(((a) > (b)) ? (a) : (b))

/* kernel-isms used by linux_idr.c outside its test block */
struct mycpu_s { int gd_spinlocks; };
extern struct mycpu_s mycpu_stub;
#define mycpu		(&mycpu_stub)
#define bcopy(a, b, c)	memcpy((b), (a), (c))
#define bzero(p, c)	memset((p), 0, (c))

/* instrumented allocators (see idr_race.c) */
void	*xmalloc(size_t bytes);
void	xkfree(void *ptr);

#define kmalloc(bytes, zone, flags)	xmalloc(bytes)
#define kfree(ptr, flags)		xkfree(ptr)

#endif /* HARNESS_PRELUDE_H */