Search code examples
ebpfbpfxdp-bpf

BPF / XDP: 'bpftool batch file' returns 'Error: reading batch file failed: Operation not permitted'


I have a docker container with an XDP program loaded on it. I also have a batch file for the bpftool to run. When I run bpftool batch file tmp_bpftool.txt, I get Error: reading batch file failed: Operation not permitted. I am the root in the container. So, what could possibly be the problem?

The batch file is as below: (512 updates on map 59 and 1 update on map 58)

map update id 59 key 0 0 00 00 00 00 00 00 value 10 0 0 1 10 89 0 4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0 0 0 0 0 4 00 00 
map update id 59 key 1 0 00 00 00 00 00 00 value 10 0 0 1 10 89 0 4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0 0 0 0 0 4 00 00
.
.
.
map update id 59 key 255 0 00 00 00 00 00 00 value 10 0 0 1 10 89 0 4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0 0 0 0 0 4 00 00 
map update id 59 key 0 1 00 00 00 00 00 00 value 10 0 0 1 10 89 0 4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0 0 0 0 0 4 00 00
map update id 59 key 1 1 00 00 00 00 00 00 value 10 0 0 1 10 89 0 4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0 0 0 0 0 4 00 00
.
. // All the way down to ... (512 entries for id 59)
.
map update id 59 key 254 1 00 00 00 00 00 00 value 10 0 0 1 10 89 0 4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0 0 0 0 0 4 00 00 
map update id 59 key 255 1 00 00 00 00 00 00 value 10 0 0 1 10 89 0 4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0 0 0 0 0 4 00 00 
map update id 58 key 10 89 0 4 00 00 00 00 value 0 0 00 00 00 00 00 00

UPDATE: Here is the output of the strace bpftool batch file command:

execve("/usr/sbin/bpftool", ["bpftool", "batch", "file", "tmp_bpftool.txt"], 0x7fffdb7d3a98 /* 9 vars */) = 0
brk(NULL)                               = 0x558ee931c000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffd7cb85610) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=13993, ...}) = 0
mmap(NULL, 13993, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9c4c69f000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libtinfo.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\240\346\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=192032, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9c4c69d000
mmap(NULL, 194944, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f9c4c66d000
mmap(0x7f9c4c67b000, 61440, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xe000) = 0x7f9c4c67b000
mmap(0x7f9c4c68a000, 57344, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1d000) = 0x7f9c4c68a000
mmap(0x7f9c4c698000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2a000) = 0x7f9c4c698000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \22\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=18816, ...}) = 0
mmap(NULL, 20752, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f9c4c667000
mmap(0x7f9c4c668000, 8192, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1000) = 0x7f9c4c668000
mmap(0x7f9c4c66a000, 4096, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f9c4c66a000
mmap(0x7f9c4c66b000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f9c4c66b000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360A\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\237\333t\347\262\27\320l\223\27*\202C\370T\177"..., 68, 880) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=2029560, ...}) = 0
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\237\333t\347\262\27\320l\223\27*\202C\370T\177"..., 68, 880) = 68
mmap(NULL, 2037344, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f9c4c475000
mmap(0x7f9c4c497000, 1540096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f9c4c497000
mmap(0x7f9c4c60f000, 319488, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19a000) = 0x7f9c4c60f000
mmap(0x7f9c4c65d000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f9c4c65d000
mmap(0x7f9c4c663000, 13920, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f9c4c663000
close(3)                                = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9c4c472000
arch_prctl(ARCH_SET_FS, 0x7f9c4c472740) = 0
mprotect(0x7f9c4c65d000, 16384, PROT_READ) = 0
mprotect(0x7f9c4c66b000, 4096, PROT_READ) = 0
mprotect(0x7f9c4c698000, 16384, PROT_READ) = 0
mprotect(0x558ee85e3000, 16384, PROT_READ) = 0
mprotect(0x7f9c4c6d0000, 4096, PROT_READ) = 0
munmap(0x7f9c4c69f000, 13993)           = 0
openat(AT_FDCWD, "/dev/tty", O_RDWR|O_NONBLOCK) = 3
close(3)                                = 0
brk(NULL)                               = 0x558ee931c000
brk(0x558ee933d000)                     = 0x558ee933d000
getuid()                                = 0
getgid()                                = 0
geteuid()                               = 0
getegid()                               = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
ioctl(-1, TIOCGPGRP, 0x7ffd7cb85464)    = -1 EBADF (Bad file descriptor)
sysinfo({uptime=1021, loads=[43680, 55104, 39616], totalram=8066469888, freeram=1033973760, sharedram=594358272, bufferram=135041024, totalswap=2147479552, freeswap=2147479552, procs=1331, totalhigh=0, freehigh=0, mem_unit=1}) = 0
rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
rt_sigaction(SIGQUIT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGQUIT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
rt_sigaction(SIGTSTP, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTSTP, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
rt_sigaction(SIGTTIN, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTTIN, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
rt_sigaction(SIGTTOU, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGTTOU, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
rt_sigaction(SIGQUIT, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
uname({sysname="Linux", nodename="balancer", ...}) = 0
stat("/xdp", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat(".", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("/xdp", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
getpid()                                = 177
getppid()                               = 174
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3
connect(3, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
close(3)                                = 0
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3
connect(3, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
close(3)                                = 0
openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=494, ...}) = 0
read(3, "# /etc/nsswitch.conf\n#\n# Example"..., 4096) = 494
read(3, "", 4096)                       = 0
close(3)                                = 0
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=13993, ...}) = 0
mmap(NULL, 13993, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9c4c69f000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\3005\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=51832, ...}) = 0
mmap(NULL, 79672, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f9c4c45e000
mmap(0x7f9c4c461000, 28672, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f9c4c461000
mmap(0x7f9c4c468000, 8192, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xa000) = 0x7f9c4c468000
mmap(0x7f9c4c46a000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xb000) = 0x7f9c4c46a000
mmap(0x7f9c4c46c000, 22328, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f9c4c46c000
close(3)                                = 0
mprotect(0x7f9c4c46a000, 4096, PROT_READ) = 0
munmap(0x7f9c4c69f000, 13993)           = 0
openat(AT_FDCWD, "/etc/passwd", O_RDONLY|O_CLOEXEC) = 3
lseek(3, 0, SEEK_CUR)                   = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=976, ...}) = 0
read(3, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 976
close(3)                                = 0
getpid()                                = 177
getpgrp()                               = 174
ioctl(2, TIOCGPGRP, [174])              = 0
rt_sigaction(SIGCHLD, {sa_handler=0x558ee8529aa0, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
prlimit64(0, RLIMIT_NPROC, NULL, {rlim_cur=30509, rlim_max=30509}) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
openat(AT_FDCWD, "/usr/sbin/bpftool", O_RDONLY) = 3
stat("/usr/sbin/bpftool", {st_mode=S_IFREG|0755, st_size=1622, ...}) = 0
ioctl(3, TCGETS, 0x7ffd7cb853f0)        = -1 ENOTTY (Inappropriate ioctl for device)
lseek(3, 0, SEEK_CUR)                   = 0
read(3, "#!/bin/bash\nfull_version=`uname "..., 80) = 80
lseek(3, 0, SEEK_SET)                   = 0
prlimit64(0, RLIMIT_NOFILE, NULL, {rlim_cur=1024, rlim_max=512*1024}) = 0
fcntl(255, F_GETFD)                     = -1 EBADF (Bad file descriptor)
dup2(3, 255)                            = 255
close(3)                                = 0
fcntl(255, F_SETFD, FD_CLOEXEC)         = 0
fcntl(255, F_GETFL)                     = 0x8000 (flags O_RDONLY|O_LARGEFILE)
fstat(255, {st_mode=S_IFREG|0755, st_size=1622, ...}) = 0
lseek(255, 0, SEEK_CUR)                 = 0
read(255, "#!/bin/bash\nfull_version=`uname "..., 1622) = 1622
pipe([3, 4])                            = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
lseek(255, -1586, SEEK_CUR)             = 36
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f9c4c472a10) = 178
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigaction(SIGCHLD, {sa_handler=0x558ee8529aa0, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=0x558ee8529aa0, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
close(4)                                = 0
read(3, "5.13.0-35-generic\n", 128)     = 18
read(3, "", 128)                        = 0
close(3)                                = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=178, si_uid=0, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG, NULL) = 178
wait4(-1, 0x7ffd7cb847d0, WNOHANG, NULL) = -1 ECHILD (No child processes)
rt_sigreturn({mask=[]})                 = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGINT, {sa_handler=0x558ee8526480, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=0x558ee8526480, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
read(255, "\n# First check for a fully quali"..., 1622) = 1586
pipe([3, 4])                            = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
lseek(255, -1484, SEEK_CUR)             = 138
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f9c4c472a10) = 179
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigaction(SIGCHLD, {sa_handler=0x558ee8529aa0, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=0x558ee8529aa0, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
close(4)                                = 0
read(3, "bpftool\n", 128)               = 8
read(3, "", 128)                        = 0
close(3)                                = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=179, si_uid=0, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG, NULL) = 179
wait4(-1, 0x7ffd7cb84710, WNOHANG, NULL) = -1 ECHILD (No child processes)
rt_sigreturn({mask=[]})                 = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGINT, {sa_handler=0x558ee8526480, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=0x558ee8526480, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
read(255, "if [ -f \"$this\" ]; then\n\texec \"$"..., 1622) = 1484
stat("/usr/lib/linux-tools/5.13.0-35-generic/bpftool", {st_mode=S_IFREG|0755, st_size=1650632, ...}) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
rt_sigaction(SIGQUIT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
rt_sigaction(SIGCHLD, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f9c4c4b80c0}, {sa_handler=0x558ee8529aa0, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f9c4c4b80c0}, 8) = 0
lseek(255, -1438, SEEK_CUR)             = 184
execve("/usr/lib/linux-tools/5.13.0-35-generic/bpftool", ["/usr/lib/linux-tools/5.13.0-35-g"..., "batch", "file", "tmp_bpftool.txt"], 0x558ee9325940 /* 8 vars */) = 0
brk(NULL)                               = 0x556ccae20000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffd8177b850) = -1 EINVAL (Invalid argument)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=13993, ...}) = 0
mmap(NULL, 13993, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9c039c5000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libelf.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\2005\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=109200, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9c039c3000
mmap(NULL, 110976, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f9c039a7000
mmap(0x7f9c039aa000, 73728, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7f9c039aa000
mmap(0x7f9c039bc000, 20480, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0x7f9c039bc000
mmap(0x7f9c039c1000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19000) = 0x7f9c039c1000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libz.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\"\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=108936, ...}) = 0
mmap(NULL, 110776, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f9c0398b000
mprotect(0x7f9c0398d000, 98304, PROT_NONE) = 0
mmap(0x7f9c0398d000, 69632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f9c0398d000
mmap(0x7f9c0399e000, 24576, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x13000) = 0x7f9c0399e000
mmap(0x7f9c039a5000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19000) = 0x7f9c039a5000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300#\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=31120, ...}) = 0
mmap(NULL, 33112, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f9c03982000
mprotect(0x7f9c03984000, 20480, PROT_NONE) = 0
mmap(0x7f9c03984000, 12288, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f9c03984000
mmap(0x7f9c03987000, 4096, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x5000) = 0x7f9c03987000
mmap(0x7f9c03989000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7f9c03989000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360A\2\0\0\0\0\0"..., 832) = 832
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\237\333t\347\262\27\320l\223\27*\202C\370T\177"..., 68, 880) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=2029560, ...}) = 0
pread64(3, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 784, 64) = 784
pread64(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32, 848) = 32
pread64(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\237\333t\347\262\27\320l\223\27*\202C\370T\177"..., 68, 880) = 68
mmap(NULL, 2037344, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f9c03790000
mmap(0x7f9c037b2000, 1540096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f9c037b2000
mmap(0x7f9c0392a000, 319488, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19a000) = 0x7f9c0392a000
mmap(0x7f9c03978000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7f9c03978000
mmap(0x7f9c0397e000, 13920, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f9c0397e000
close(3)                                = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9c0378e000
arch_prctl(ARCH_SET_FS, 0x7f9c0378eb80) = 0
mprotect(0x7f9c03978000, 16384, PROT_READ) = 0
mprotect(0x7f9c03989000, 4096, PROT_READ) = 0
mprotect(0x7f9c039a5000, 4096, PROT_READ) = 0
mprotect(0x7f9c039c1000, 4096, PROT_READ) = 0
mprotect(0x556cc8e27000, 12288, PROT_READ) = 0
mprotect(0x7f9c039f6000, 4096, PROT_READ) = 0
munmap(0x7f9c039c5000, 13993)           = 0
prctl(PR_CAPBSET_READ, CAP_MAC_OVERRIDE) = 1
prctl(PR_CAPBSET_READ, 0x30 /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, 0x28 /* CAP_??? */) = 0
prctl(PR_CAPBSET_READ, 0x2c /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, 0x2a /* CAP_??? */) = -1 EINVAL (Invalid argument)
prctl(PR_CAPBSET_READ, 0x29 /* CAP_??? */) = -1 EINVAL (Invalid argument)
brk(NULL)                               = 0x556ccae20000
brk(0x556ccae41000)                     = 0x556ccae41000
openat(AT_FDCWD, "tmp_bpftool.txt", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=70140, ...}) = 0
read(3, "map update id 15 key 0 0 00 00 0"..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, "00 00 00 00 00 00 value 10 0 0 1"..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, "0 value 10 0 0 1 10 89 0 4 00 00"..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, " 10 89 0 4 00 00 00 00 00 00 00 "..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, "0 0 1 10 89 0 4 00 00 00 00 00 0"..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, "0 00 value 10 0 0 1 10 89 0 4 00"..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, " 00 00 00 00 00 00 value 10 0 0 "..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, "d 15 key 210 0 00 00 00 00 00 00"..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, " \nmap update id 15 key 240 0 00 "..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, "te id 15 key 14 1 00 00 00 00 00"..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, "1 00 00 00 00 00 00 value 10 0 0"..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, " 00 value 10 0 0 1 10 89 0 4 00 "..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, "0 0 0 1 10 89 0 4 00 00 00 00 00"..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, " 00 00 value 10 0 0 1 10 89 0 4 "..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, " 1 00 00 00 00 00 00 value 10 0 "..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, " id 15 key 194 1 00 00 00 00 00 "..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, "00 \nmap update id 15 key 224 1 0"..., 4096) = 4096
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, " 0 0 0 0 6 00 00 \nmap update id "..., 4096) = 508
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=15, next_id=0, open_flags=0}, 120) = 4
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=4, info_len=80, info=0x7ffd81753730}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=4, key=0x556ccae21490, value=0x556ccae214b0, flags=BPF_ANY}, 120) = 0
close(4)                                = 0
read(3, "", 4096)                       = 0
write(2, "Error: ", 7)                  = 7
write(2, "reading batch file failed: Opera"..., 50) = 50
write(2, "\n", 1)                       = 1
close(3)                                = 0
exit_group(-1)                          = ?
+++ exited with 255 +++

Solution

  • TL;DR: Your map update works fine. The message is a bug in bpftool.

    Bpftool updates the maps just as you would expect; and then, after processing all the batch file, it checks errno. If errno is 0, it supposes that everything went fine, and it's good. If not, it prints strerror(errno) so you can see what went wrong when processing the file.

    errno being set is not due to your map updates. I'm not entirely sure of what's happening to it. The bug was seemingly introduced with commit cf9bf714523d ("tools: bpftool: Allow unprivileged users to probe features"), where we manipulate process capabilities with libcap. Having a call to cap_get_proc() in feature.c is apparently enough for the executable to pick it up and to run some checks on capabilities that are supported, or not, on the system even if we're not doing any probing. I'm observing the following calls with strace:

    # strace -e prctl ./bpftool batch file /tmp/batch
    prctl(PR_CAPBSET_READ, CAP_MAC_OVERRIDE) = 1
    prctl(PR_CAPBSET_READ, 0x30 /* CAP_??? */) = -1 EINVAL (Invalid argument)
    prctl(PR_CAPBSET_READ, CAP_CHECKPOINT_RESTORE) = 1
    prctl(PR_CAPBSET_READ, 0x2c /* CAP_??? */) = -1 EINVAL (Invalid argument)
    prctl(PR_CAPBSET_READ, 0x2a /* CAP_??? */) = -1 EINVAL (Invalid argument)
    prctl(PR_CAPBSET_READ, 0x29 /* CAP_??? */) = -1 EINVAL (Invalid argument)
    Error: reading batch file failed: Operation not permitted
    +++ exited with 255 +++
    

    This seems to be coming from cap_get_bound() in libcap, where the -1 returned is negated and passed to errno, thus becoming 1, Operation not permitted. I'm not sure what the capability numbers passed to prctl() correspond to.

    I'm not sure what's the cleanest way to fix this. A simple workaround consists in resetting errno at the beginning of the main() function; we can submit that and see if the reviewers have a better idea. Let me know if you would like to send a patch yourself, otherwise I'll do it when I have a moment.

    [EDIT August 2022] Fixed in libcap 2.63 and also in bpf-next for bpftool.