Skip to content

Instantly share code, notes, and snippets.

@teknoraver
Last active July 16, 2025 18:07
Show Gist options
  • Save teknoraver/92f27cbc456e4ab4a508943eb93958b8 to your computer and use it in GitHub Desktop.
Save teknoraver/92f27cbc456e4ab4a508943eb93958b8 to your computer and use it in GitHub Desktop.
Sample tool to create a BPF token
/* run as:
* gcc -O2 -Wall bpf_token.c -o bpf_token -lbpf
* sudo strace -f -e fsopen,fsconfig,fspick,fsmount,move_mount,unshare,bpf ./bpf_token
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <sched.h>
#include <sys/syscall.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <bpf/bpf.h>
#define pexit(msg) do { perror(msg); exit(1); } while (0)
#define BPFFS_MOUNT "/sys/fs/bpf"
static int sendfd(int sockfd, int fd)
{
struct cmsghdr *cmsg;
int err;
union {
char buf[CMSG_SPACE(sizeof(fd))];
struct cmsghdr align;
} u;
struct msghdr msg = {
.msg_control = u.buf,
.msg_controllen = sizeof(u.buf),
};
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
err = sendmsg(sockfd, &msg, 0);
if (err < 0)
err = -errno;
if (err != msg.msg_iovlen) {
perror("sendmsg");
return -EINVAL;
}
return 0;
}
static int recvfd(int sockfd)
{
struct cmsghdr *cmsg;
int err;
int fd;
union {
char buf[CMSG_SPACE(sizeof(fd))];
struct cmsghdr align;
} u;
struct msghdr msg = {
.msg_control = u.buf,
.msg_controllen = sizeof(u.buf),
};
err = recvmsg(sockfd, &msg, 0);
if (err < 0)
return -errno;
cmsg = CMSG_FIRSTHDR(&msg);
if (!cmsg ||
cmsg->cmsg_len != CMSG_LEN(sizeof(fd)) ||
cmsg->cmsg_level != SOL_SOCKET ||
cmsg->cmsg_type != SCM_RIGHTS)
return -EINVAL;
memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
return fd;
}
void parent(int sock_fd)
{
int fs_fd, mnt_fd, bpffs_fd, token_fd;
int r;
if (unshare(CLONE_NEWUSER) < 0)
pexit("unshare");
if (unshare(CLONE_NEWNS) < 0)
pexit("unshare");
r = mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, 0);
if (r < 0)
pexit("mount");
fs_fd = fsopen("bpf", FSOPEN_CLOEXEC);
if (fs_fd < 0)
pexit("fsopen");
r = sendfd(sock_fd, fs_fd);
if (r < 0)
pexit("sendfd");
close(fs_fd);
fs_fd = recvfd(sock_fd);
if (fs_fd < 0)
pexit("recvfd");
mnt_fd = fsmount(fs_fd, 0, 0);
if (mnt_fd < 0)
pexit("fsmount");
close(fs_fd);
mkdir(BPFFS_MOUNT, 0755);
r = move_mount(mnt_fd, "", AT_FDCWD, BPFFS_MOUNT, MOVE_MOUNT_F_EMPTY_PATH);
if (r < 0)
pexit("move_mount");
bpffs_fd = openat(mnt_fd, ".", O_RDONLY);
if (bpffs_fd < 0)
pexit("openat");
token_fd = bpf_token_create(bpffs_fd, NULL);
if (token_fd < 0)
pexit("bpf_token_create");
printf("BPF token fd: %d\n", token_fd);
}
void child(int sock_fd)
{
int fs_fd;
int r;
fs_fd = recvfd(sock_fd);
if (fs_fd < 0)
pexit("recvfd");
r = fsconfig(fs_fd, FSCONFIG_SET_STRING, "delegate_cmds", "any", 0);
if (r < 0)
pexit("fsconfig");
r = fsconfig(fs_fd, FSCONFIG_SET_STRING, "delegate_maps", "any", 0);
if (r < 0)
pexit("fsconfig");
r = fsconfig(fs_fd, FSCONFIG_SET_STRING, "delegate_progs", "any", 0);
if (r < 0)
pexit("fsconfig");
r = fsconfig(fs_fd, FSCONFIG_SET_STRING, "delegate_attachs", "any", 0);
if (r < 0)
pexit("fsconfig");
r = fsconfig(fs_fd, FSCONFIG_CMD_CREATE, NULL, NULL, 0);
if (r < 0)
pexit("fsconfig");
r = sendfd(sock_fd, fs_fd);
if (r < 0)
pexit("sendfd");
exit(0);
}
int main(void)
{
int token_fds[2];
int r;
r = socketpair(AF_UNIX, SOCK_SEQPACKET, 0, token_fds);
if (r < 0)
pexit("socketpair");
if (fork())
parent(token_fds[0]);
else
child(token_fds[1]);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment