Skip to content

Instantly share code, notes, and snippets.

@daurnimator
Created June 1, 2015 04:17
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daurnimator/dfdbaef3c255bdc11531 to your computer and use it in GitHub Desktop.
Save daurnimator/dfdbaef3c255bdc11531 to your computer and use it in GitHub Desktop.
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
Copy link

wahern commented Jun 1, 2015

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

@HealsCodes
Copy link

@wahern - it's part of libkeyutils-dev

@dw
Copy link

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