aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile23
-rw-r--r--afl-analyze.c40
-rw-r--r--afl-as.h46
-rw-r--r--afl-fuzz.c57
-rw-r--r--afl-showmap.c41
-rw-r--r--afl-tmin.c45
-rw-r--r--llvm_mode/Makefile2
-rw-r--r--llvm_mode/afl-llvm-rt.o.c27
-rw-r--r--sharedmem.c139
-rw-r--r--sharedmem.h6
10 files changed, 262 insertions, 164 deletions
diff --git a/Makefile b/Makefile
index 1d8d819f..4f85b53a 100644
--- a/Makefile
+++ b/Makefile
@@ -30,12 +30,12 @@ SH_PROGS = afl-plot afl-cmin afl-whatsup afl-system-config
CFLAGS ?= -O3 -funroll-loops
CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \
-DAFL_PATH=\"$(HELPER_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\" \
- -DBIN_PATH=\"$(BIN_PATH)\"
+ -DBIN_PATH=\"$(BIN_PATH)\" -DUSEMMAP=1
PYTHON_INCLUDE ?= /usr/include/python2.7
ifneq "$(filter Linux GNU%,$(shell uname))" ""
- LDFLAGS += -ldl
+ LDFLAGS += -ldl -lrt
endif
ifeq "$(findstring clang, $(shell $(CC) --version 2>/dev/null))" ""
@@ -92,17 +92,20 @@ afl-as: afl-as.c afl-as.h $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS)
ln -sf afl-as as
-afl-fuzz: afl-fuzz.c $(COMM_HDR) | test_x86
- $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS) $(PYFLAGS)
+sharedmem.o : sharedmem.c
+ $(CC) $(CFLAGS) -c sharedmem.c
-afl-showmap: afl-showmap.c $(COMM_HDR) | test_x86
- $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS)
+afl-fuzz: afl-fuzz.c sharedmem.o $(COMM_HDR) | test_x86
+ $(CC) $(CFLAGS) $@.c sharedmem.o -o $@ $(LDFLAGS) $(PYFLAGS)
-afl-tmin: afl-tmin.c $(COMM_HDR) | test_x86
- $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS)
+afl-showmap: afl-showmap.c sharedmem.o $(COMM_HDR) | test_x86
+ $(CC) $(CFLAGS) $@.c sharedmem.o -o $@ $(LDFLAGS)
-afl-analyze: afl-analyze.c $(COMM_HDR) | test_x86
- $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS)
+afl-tmin: afl-tmin.c sharedmem.o $(COMM_HDR) | test_x86
+ $(CC) $(CFLAGS) $@.c sharedmem.o -o $@ $(LDFLAGS)
+
+afl-analyze: afl-analyze.c sharedmem.o $(COMM_HDR) | test_x86
+ $(CC) $(CFLAGS) $@.c sharedmem.o -o $@ $(LDFLAGS)
afl-gotcpu: afl-gotcpu.c $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS)
diff --git a/afl-analyze.c b/afl-analyze.c
index 44be73f9..834a0357 100644
--- a/afl-analyze.c
+++ b/afl-analyze.c
@@ -26,6 +26,7 @@
#include "debug.h"
#include "alloc-inl.h"
#include "hash.h"
+#include "sharedmem.h"
#include <stdio.h>
#include <unistd.h>
@@ -47,7 +48,7 @@
static s32 child_pid; /* PID of the tested program */
-static u8* trace_bits; /* SHM with instrumentation bitmap */
+ u8* trace_bits; /* SHM with instrumentation bitmap */
static u8 *in_file, /* Analyzer input test case */
*prog_in, /* Targeted program input file */
@@ -64,8 +65,7 @@ static u32 in_len, /* Input data length */
static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
-static s32 shm_id, /* ID of the SHM region */
- dev_null_fd = -1; /* FD to /dev/null */
+static s32 dev_null_fd = -1; /* FD to /dev/null */
static u8 edges_only, /* Ignore hit counts? */
use_hex_offsets, /* Show hex offsets? */
@@ -76,6 +76,7 @@ static volatile u8
child_timed_out; /* Child timed out? */
+
/* Constants used for describing byte behavior. */
#define RESP_NONE 0x00 /* Changing byte is a no-op. */
@@ -141,37 +142,11 @@ static inline u8 anything_set(void) {
}
-/* Get rid of shared memory and temp files (atexit handler). */
+/* Get rid of temp files (atexit handler). */
-static void remove_shm(void) {
+static void at_exit_handler(void) {
unlink(prog_in); /* Ignore errors */
- shmctl(shm_id, IPC_RMID, NULL);
-
-}
-
-
-/* Configure shared memory. */
-
-static void setup_shm(void) {
-
- u8* shm_str;
-
- shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600);
-
- if (shm_id < 0) PFATAL("shmget() failed");
-
- atexit(remove_shm);
-
- shm_str = alloc_printf("%d", shm_id);
-
- setenv(SHM_ENV_VAR, shm_str, 1);
-
- ck_free(shm_str);
-
- trace_bits = shmat(shm_id, NULL, 0);
-
- if (!trace_bits) PFATAL("shmat() failed");
}
@@ -1036,7 +1011,8 @@ int main(int argc, char** argv) {
use_hex_offsets = !!getenv("AFL_ANALYZE_HEX");
- setup_shm();
+ setup_shm(0);
+ atexit(at_exit_handler);
setup_signal_handlers();
set_up_environment();
diff --git a/afl-as.h b/afl-as.h
index ebd57109..90944614 100644
--- a/afl-as.h
+++ b/afl-as.h
@@ -220,6 +220,29 @@ static const u8* main_payload_32 =
" testl %eax, %eax\n"
" je __afl_setup_abort\n"
"\n"
+#ifdef USEMMAP
+ " pushl $384 /* shm_open mode 0600 */\n"
+ " pushl $2 /* flags O_RDWR */\n"
+ " pushl %eax /* SHM file path */\n"
+ " call shm_open\n"
+ " addl $12, %esp\n"
+ "\n"
+ " cmpl $-1, %eax\n"
+ " je __afl_setup_abort\n"
+ "\n"
+ " pushl $0 /* mmap off */\n"
+ " pushl %eax /* shm fd */\n"
+ " pushl $1 /* mmap flags */\n"
+ " pushl $3 /* mmap prot */\n"
+ " pushl $"STRINGIFY(MAP_SIZE)" /* mmap len */\n"
+ " pushl $0 /* mmap addr */\n"
+ " call mmap\n"
+ " addl $12, %esp\n"
+ "\n"
+ " cmpl $-1, %eax\n"
+ " je __afl_setup_abort\n"
+ "\n"
+#else
" pushl %eax\n"
" call atoi\n"
" addl $4, %esp\n"
@@ -233,6 +256,7 @@ static const u8* main_payload_32 =
" cmpl $-1, %eax\n"
" je __afl_setup_abort\n"
"\n"
+#endif
" /* Store the address of the SHM region. */\n"
"\n"
" movl %eax, __afl_area_ptr\n"
@@ -501,6 +525,27 @@ static const u8* main_payload_64 =
" testq %rax, %rax\n"
" je __afl_setup_abort\n"
"\n"
+#ifdef USEMMAP
+ " movl $384, %edx /* shm_open mode 0600 */\n"
+ " movl $2, %esi /* flags O_RDWR */\n"
+ " movq %rax, %rdi /* SHM file path */\n"
+ CALL_L64("shm_open")
+ "\n"
+ " cmpq $-1, %rax\n"
+ " je __afl_setup_abort\n"
+ "\n"
+ " movl $0, %r9d\n"
+ " movl %eax, %r8d\n"
+ " movl $1, %ecx\n"
+ " movl $3, %edx\n"
+ " movl $"STRINGIFY(MAP_SIZE)", %esi\n"
+ " movl $0, %edi\n"
+ CALL_L64("mmap")
+ "\n"
+ " cmpq $-1, %rax\n"
+ " je __afl_setup_abort\n"
+ "\n"
+#else
" movq %rax, %rdi\n"
CALL_L64("atoi")
"\n"
@@ -512,6 +557,7 @@ static const u8* main_payload_64 =
" cmpq $-1, %rax\n"
" je __afl_setup_abort\n"
"\n"
+#endif
" /* Store the address of the SHM region. */\n"
"\n"
" movq %rax, %rdx\n"
diff --git a/afl-fuzz.c b/afl-fuzz.c
index 6db99acf..af507c88 100644
--- a/afl-fuzz.c
+++ b/afl-fuzz.c
@@ -31,6 +31,7 @@
#include "debug.h"
#include "alloc-inl.h"
#include "hash.h"
+#include "sharedmem.h"
#include <stdio.h>
#include <unistd.h>
@@ -163,7 +164,7 @@ static s32 forksrv_pid, /* PID of the fork server */
child_pid = -1, /* PID of the fuzzed program */
out_dir_fd = -1; /* FD of the lock file */
-EXP_ST u8* trace_bits; /* SHM with instrumentation bitmap */
+ u8* trace_bits; /* SHM with instrumentation bitmap */
EXP_ST u8 virgin_bits[MAP_SIZE], /* Regions yet untouched by fuzzing */
virgin_tmout[MAP_SIZE], /* Bits we haven't seen in tmouts */
@@ -171,8 +172,6 @@ EXP_ST u8 virgin_bits[MAP_SIZE], /* Regions yet untouched by fuzzing */
static u8 var_bytes[MAP_SIZE]; /* Bytes that appear to be variable */
-static s32 shm_id; /* ID of the SHM region */
-
static volatile u8 stop_soon, /* Ctrl-C pressed? */
clear_screen = 1, /* Window resized? */
child_timed_out; /* Traced process timed out? */
@@ -1444,15 +1443,6 @@ static inline void classify_counts(u32* mem) {
#endif /* ^__x86_64__ */
-/* Get rid of shared memory (atexit handler). */
-
-static void remove_shm(void) {
-
- shmctl(shm_id, IPC_RMID, NULL);
-
-}
-
-
/* Compact trace bytes into a smaller bitmap. We effectively just drop the
count information here. This is called only sporadically, for some
new paths. */
@@ -1606,40 +1596,6 @@ static void cull_queue(void) {
}
-/* Configure shared memory and virgin_bits. This is called at startup. */
-
-EXP_ST void setup_shm(void) {
-
- u8* shm_str;
-
- if (!in_bitmap) memset(virgin_bits, 255, MAP_SIZE);
-
- memset(virgin_tmout, 255, MAP_SIZE);
- memset(virgin_crash, 255, MAP_SIZE);
-
- shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600);
-
- if (shm_id < 0) PFATAL("shmget() failed");
-
- atexit(remove_shm);
-
- shm_str = alloc_printf("%d", shm_id);
-
- /* If somebody is asking us to fuzz instrumented binaries in dumb mode,
- we don't want them to detect instrumentation, since we won't be sending
- fork server commands. This should be replaced with better auto-detection
- later on, perhaps? */
-
- if (!dumb_mode) setenv(SHM_ENV_VAR, shm_str, 1);
-
- ck_free(shm_str);
-
- trace_bits = shmat(shm_id, NULL, 0);
-
- if (!trace_bits) PFATAL("shmat() failed");
-
-}
-
/* Load postprocessor, if available. */
@@ -7466,8 +7422,10 @@ EXP_ST void check_binary(u8* fname) {
#else
+#if !defined(__arm__) && !defined(__arm64__)
if (f_data[0] != 0xCF || f_data[1] != 0xFA || f_data[2] != 0xED)
FATAL("Program '%s' is not a 64-bit Mach-O binary", target_path);
+#endif
#endif /* ^!__APPLE__ */
@@ -8639,7 +8597,12 @@ int main(int argc, char** argv) {
check_cpu_governor();
setup_post();
- setup_shm();
+ setup_shm(dumb_mode);
+
+ if (!in_bitmap) memset(virgin_bits, 255, MAP_SIZE);
+ memset(virgin_tmout, 255, MAP_SIZE);
+ memset(virgin_crash, 255, MAP_SIZE);
+
init_count_class16();
setup_dirs_fds();
diff --git a/afl-showmap.c b/afl-showmap.c
index 316490d8..a5d7568a 100644
--- a/afl-showmap.c
+++ b/afl-showmap.c
@@ -28,6 +28,7 @@
#include "debug.h"
#include "alloc-inl.h"
#include "hash.h"
+#include "sharedmem.h"
#include <stdio.h>
#include <unistd.h>
@@ -48,7 +49,7 @@
static s32 child_pid; /* PID of the tested program */
-static u8* trace_bits; /* SHM with instrumentation bitmap */
+ u8* trace_bits; /* SHM with instrumentation bitmap */
static u8 *out_file, /* Trace output file */
*doc_path, /* Path to docs */
@@ -59,8 +60,6 @@ static u32 exec_tmout; /* Exec timeout (ms) */
static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
-static s32 shm_id; /* ID of the SHM region */
-
static u8 quiet_mode, /* Hide non-essential messages? */
edges_only, /* Ignore hit counts? */
cmin_mode, /* Generate output in afl-cmin mode? */
@@ -72,6 +71,7 @@ static volatile u8
child_timed_out, /* Child timed out? */
child_crashed; /* Child crashed? */
+
/* Classify tuple counts. Instead of mapping to individual bits, as in
afl-fuzz.c, we map to more user-friendly numbers between 1 and 8. */
@@ -126,39 +126,6 @@ static void classify_counts(u8* mem, const u8* map) {
}
-/* Get rid of shared memory (atexit handler). */
-
-static void remove_shm(void) {
-
- shmctl(shm_id, IPC_RMID, NULL);
-
-}
-
-
-/* Configure shared memory. */
-
-static void setup_shm(void) {
-
- u8* shm_str;
-
- shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600);
-
- if (shm_id < 0) PFATAL("shmget() failed");
-
- atexit(remove_shm);
-
- shm_str = alloc_printf("%d", shm_id);
-
- setenv(SHM_ENV_VAR, shm_str, 1);
-
- ck_free(shm_str);
-
- trace_bits = shmat(shm_id, NULL, 0);
-
- if (!trace_bits) PFATAL("shmat() failed");
-
-}
-
/* Write results. */
static u32 write_results(void) {
@@ -741,7 +708,7 @@ int main(int argc, char** argv) {
if (optind == argc || !out_file) usage(argv[0]);
- setup_shm();
+ setup_shm(0);
setup_signal_handlers();
set_up_environment();
diff --git a/afl-tmin.c b/afl-tmin.c
index a42be6e9..b9dbb2b5 100644
--- a/afl-tmin.c
+++ b/afl-tmin.c
@@ -26,6 +26,7 @@
#include "debug.h"
#include "alloc-inl.h"
#include "hash.h"
+#include "sharedmem.h"
#include <stdio.h>
#include <unistd.h>
@@ -50,8 +51,8 @@ static s32 forksrv_pid, /* PID of the fork server */
static s32 fsrv_ctl_fd, /* Fork server control pipe (write) */
fsrv_st_fd; /* Fork server status pipe (read) */
-static u8 *trace_bits, /* SHM with instrumentation bitmap */
- *mask_bitmap; /* Mask for trace bits (-B) */
+ u8 *trace_bits; /* SHM with instrumentation bitmap */
+static u8 *mask_bitmap; /* Mask for trace bits (-B) */
static u8 *in_file, /* Minimizer input test case */
*out_file, /* Minimizer output file */
@@ -73,8 +74,7 @@ static u32 in_len, /* Input data length */
static u64 mem_limit = MEM_LIMIT; /* Memory limit (MB) */
-static s32 shm_id, /* ID of the SHM region */
- dev_null_fd = -1; /* FD to /dev/null */
+static s32 dev_null_fd = -1; /* FD to /dev/null */
static u8 crash_mode, /* Crash-centric mode? */
exit_crash, /* Treat non-zero exit as crash? */
@@ -159,42 +159,12 @@ static inline u8 anything_set(void) {
}
+/* Get rid of temp files (atexit handler). */
-/* Get rid of shared memory and temp files (atexit handler). */
-
-static void remove_shm(void) {
-
+static void at_exit_handler(void) {
if (prog_in) unlink(prog_in); /* Ignore errors */
- shmctl(shm_id, IPC_RMID, NULL);
-
-}
-
-
-/* Configure shared memory. */
-
-static void setup_shm(void) {
-
- u8* shm_str;
-
- shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600);
-
- if (shm_id < 0) PFATAL("shmget() failed");
-
- atexit(remove_shm);
-
- shm_str = alloc_printf("%d", shm_id);
-
- setenv(SHM_ENV_VAR, shm_str, 1);
-
- ck_free(shm_str);
-
- trace_bits = shmat(shm_id, NULL, 0);
-
- if (!trace_bits) PFATAL("shmat() failed");
-
}
-
/* Read initial file. */
static void read_initial_file(void) {
@@ -1245,7 +1215,8 @@ int main(int argc, char** argv) {
if (optind == argc || !in_file || !out_file) usage(argv[0]);
- setup_shm();
+ setup_shm(0);
+ atexit(at_exit_handler);
setup_signal_handlers();
set_up_environment();
diff --git a/llvm_mode/Makefile b/llvm_mode/Makefile
index 6b277536..0cb2e1c5 100644
--- a/llvm_mode/Makefile
+++ b/llvm_mode/Makefile
@@ -33,7 +33,7 @@ endif
CFLAGS ?= -O3 -funroll-loops
CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
- -DVERSION=\"$(VERSION)\"
+ -DVERSION=\"$(VERSION)\" -DUSEMMAP=1 -lrt
ifdef AFL_TRACE_PC
CFLAGS += -DUSE_TRACE_PC=1
endif
diff --git a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c
index 342dcc90..debde204 100644
--- a/llvm_mode/afl-llvm-rt.o.c
+++ b/llvm_mode/afl-llvm-rt.o.c
@@ -44,6 +44,9 @@
# define CONST_PRIO 0
#endif /* ^USE_TRACE_PC */
+#include <sys/mman.h>
+#include <fcntl.h>
+
/* Globals needed by the injected instrumentation. The __afl_area_initial region
is used for instrumentation output before __afl_map_shm() has a chance to run.
@@ -71,10 +74,34 @@ static void __afl_map_shm(void) {
hacky .init code to work correctly in projects such as OpenSSL. */
if (id_str) {
+#ifdef USEMMAP
+ const char *shm_file_path = id_str;
+ int shm_fd = -1;
+ unsigned char *shm_base = NULL;
+
+ /* create the shared memory segment as if it was a file */
+ shm_fd = shm_open(shm_file_path, O_RDWR, 0600);
+ if (shm_fd == -1) {
+ printf("shm_open() failed\n");
+ exit(1);
+ }
+
+ /* map the shared memory segment to the address space of the process */
+ shm_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
+ if (shm_base == MAP_FAILED) {
+ close(shm_fd);
+ shm_fd = -1;
+ printf("mmap() failed\n");
+ exit(2);
+ }
+
+ __afl_area_ptr = shm_base;
+#else
u32 shm_id = atoi(id_str);
__afl_area_ptr = shmat(shm_id, NULL, 0);
+#endif
/* Whooooops. */
diff --git a/sharedmem.c b/sharedmem.c
new file mode 100644
index 00000000..23cc8984
--- /dev/null
+++ b/sharedmem.c
@@ -0,0 +1,139 @@
+/*
+
+ */
+
+#define AFL_MAIN
+
+#include "config.h"
+#include "types.h"
+#include "debug.h"
+#include "alloc-inl.h"
+#include "hash.h"
+#include "sharedmem.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <signal.h>
+#include <dirent.h>
+#include <fcntl.h>
+
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+
+#include <sys/mman.h>
+#include <fcntl.h>
+
+extern unsigned char*trace_bits;
+
+#ifdef USEMMAP
+/* ================ Proteas ================ */
+int g_shm_fd = -1;
+unsigned char *g_shm_base = NULL;
+char g_shm_file_path[L_tmpnam];
+/* ========================================= */
+#else
+static s32 shm_id; /* ID of the SHM region */
+#endif
+
+/* Get rid of shared memory (atexit handler). */
+
+void remove_shm(void) {
+#ifdef USEMMAP
+ if (g_shm_base != NULL) {
+ munmap(g_shm_base, MAP_SIZE);
+ g_shm_base = NULL;
+ }
+
+ if (g_shm_fd != -1) {
+ close(g_shm_fd);
+ g_shm_fd = -1;
+ }
+#else
+ shmctl(shm_id, IPC_RMID, NULL);
+#endif
+}
+
+
+/* Configure shared memory. */
+
+void setup_shm(unsigned char dumb_mode) {
+#ifdef USEMMAP
+ /* generate random file name for multi instance */
+ memset(g_shm_file_path, 0x0, L_tmpnam);
+
+ char *result = tmpnam(g_shm_file_path);
+ if (result == 0)
+ PFATAL("cannot generate filename for shared memory");
+
+ /* get rid of second slash in /tmp/blabla */
+ g_shm_file_path[4] = '_';
+
+ /* create the shared memory segment as if it was a file */
+ g_shm_fd = shm_open(g_shm_file_path, O_CREAT | O_RDWR | O_EXCL, 0600);
+ if (g_shm_fd == -1) {
+ PFATAL("shm_open() failed");
+ }
+
+ /* configure the size of the shared memory segment */
+ if (ftruncate(g_shm_fd, MAP_SIZE)) {
+ PFATAL("setup_shm(): ftruncate() failed");
+ }
+
+ /* map the shared memory segment to the address space of the process */
+ g_shm_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, g_shm_fd, 0);
+ if (g_shm_base == MAP_FAILED) {
+ close(g_shm_fd);
+ g_shm_fd = -1;
+ PFATAL("mmap() failed");
+ }
+
+ atexit(remove_shm);
+
+ /* If somebody is asking us to fuzz instrumented binaries in dumb mode,
+ we don't want them to detect instrumentation, since we won't be sending
+ fork server commands. This should be replaced with better auto-detection
+ later on, perhaps? */
+
+ if (!dumb_mode) setenv(SHM_ENV_VAR, g_shm_file_path, 1);
+
+ trace_bits = g_shm_base;
+
+ if (!trace_bits) PFATAL("mmap() failed");
+
+#else
+ u8* shm_str;
+
+ shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600);
+
+ if (shm_id < 0) PFATAL("shmget() failed");
+
+ atexit(remove_shm);
+
+ shm_str = alloc_printf("%d", shm_id);
+
+ setenv(SHM_ENV_VAR, shm_str, 1);
+
+ /* If somebody is asking us to fuzz instrumented binaries in dumb mode,
+ we don't want them to detect instrumentation, since we won't be sending
+ fork server commands. This should be replaced with better auto-detection
+ later on, perhaps? */
+
+ if (!dumb_mode) setenv(SHM_ENV_VAR, shm_str, 1);
+
+ ck_free(shm_str);
+
+ trace_bits = shmat(shm_id, NULL, 0);
+
+ if (!trace_bits) PFATAL("shmat() failed");
+
+#endif
+}
+
diff --git a/sharedmem.h b/sharedmem.h
new file mode 100644
index 00000000..9300ccf1
--- /dev/null
+++ b/sharedmem.h
@@ -0,0 +1,6 @@
+#ifndef SHAREDMEM
+#define SHAREDMEM
+
+void setup_shm(unsigned char dumb_mode);
+void remove_shm(void);
+#endif