linuxstrace

what is the use case for arch_prctl


When I run strace on something fairly simple as below, there are 2 calls to arch_prctl. What do they do?

$ strace echo "testing 123"
execve("/usr/bin/echo", ["echo", "testing 123"], 0x7ffd396e6c78 /* 61 vars */) = 0
brk(NULL)                               = 0x55e988289000
arch_prctl(0x3001 /* ARCH_??? */, 0x7fff0c166400) = -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
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=114959, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 114959, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f5c04879000
close(3)                                = 0
openat(AT_FDCWD, "/lib64/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 \203\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
newfstatat(3, "", {st_mode=S_IFREG|0755, st_size=2250400, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5c04877000
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
mmap(NULL, 1973104, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f5c04695000
mmap(0x7f5c046bb000, 1441792, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x26000) = 0x7f5c046bb000
mmap(0x7f5c0481b000, 319488, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x186000) = 0x7f5c0481b000
mmap(0x7f5c04869000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1d3000) = 0x7f5c04869000
mmap(0x7f5c0486f000, 31600, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f5c0486f000
close(3)                                = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5c04692000
arch_prctl(ARCH_SET_FS, 0x7f5c04692740) = 0
... <more syscalls>

Solution

  • TL;DR - They are doing deep mysterious things that you most likely don't need to understand.


    According to the manual entry for arch_prctl

    arch_prctl - set architecture-specific thread state

    ARCH_SET_FS - Set the 64-bit base for the FS register to addr.

    EINVAL - code is not a valid subcommand.

    So, the second arch_prctl syscall is setting the FS register. Refer to the following for an explanation of the significance of the FS register:

    On the other hand, the first call appears to be making a request with an unrecognized subcommand. The strace output doesn't seem to know what the subcommand means, and it is not defined in the <linux/prctl.h> header file. In short, it is actually doing nothing in this context.

    UPDATE

    Apparently 0x3001 means ARCH_CET_STATUS which is explained in Control-flow Enforcement Technology (CET) Shadow Stack. And my guess is that the EINVAL means that CET is not implemented on the platform you are running on.