Skip to content

Instantly share code, notes, and snippets.

@daurnimator daurnimator/main.c
Created Jun 1, 2015

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.

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.

@Shirk

This comment has been minimized.

Copy link

Shirk commented Nov 25, 2015

@wahern - it's part of libkeyutils-dev

@dw

This comment has been minimized.

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
You can’t perform that action at this time.