Instantly share code, notes, and snippets.

Embed
What would you like to do?
Linux fork detection using thread specific keyrings.
$ gcc main.c -lkeyutils && ./a.out
15904 1
15904 0
15904 0
15904 0
15905 1
15906 1
15905 0
15906 0
15907 1
15905 0
15908 1
15909 1
15910 1
15908 0
15911 1
#include <stddef.h> /* NULL */
#include <errno.h> /* errno, ENOKEY */
#include <sys/types.h> /* needed for keyutils.h */
#include <keyutils.h> /* request_key, add_key, KEY_SPEC_THREAD_KEYRING */
int hasforked() {
key_serial_t key;
key = request_key("user", "random", NULL, KEY_SPEC_THREAD_KEYRING);
if (key != -1) return 0;
else if (errno == ENOKEY) {
key = add_key("user", "random", "" , 1, KEY_SPEC_THREAD_KEYRING);
}
if (key == -1) return -1;
return 1;
}
#include <stdio.h> /* printf */
#include <unistd.h> /* getpid, fork */
int main() {
printf("%d %d\n", getpid(), hasforked());
fork();
printf("%d %d\n", getpid(), hasforked());
fork();
printf("%d %d\n", getpid(), hasforked());
fork();
printf("%d %d\n", getpid(), hasforked());
}
@wahern

This comment has been minimized.

wahern commented Jun 1, 2015

There's no keyutils.h on my Ubuntu 14.04 box. It appears to be a separate library.

@Shirk

This comment has been minimized.

Shirk commented Nov 25, 2015

@wahern - it's part of libkeyutils-dev

@dw

This comment has been minimized.

dw commented Nov 10, 2018

For an even cheaper method, you can create a single-page mmap() filled with ones, marke it madvise(MADV_WIPEONFORK) (Linux) or minherit(INHERIT_ZERO) (BSD), then testing for fork becomes a simple matter of checking whether the first byte of the page has become zero. No system calls required

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment