Linux で setuid したバイナリで検証作業している時に知った /edtc/suid-debug について調べた内容です。
なぜ こんなことを調べているのですか?
まず、setuid-sleep という setuid したバイナリがあリます。これは sleep するだけの setuid 検証用のバイナリです。
$ ls -hal setuid-sleep -rwsr-xr-x 1 root hiboma 16K Jun 6 10:50 setuid-sleep $ stat setuid-sleep File: setuid-sleep Size: 15960 Blocks: 32 IO Block: 4096 regular file Device: fc02h/64514d Inode: 135566 Links: 1 Access: (4755/-rwsr-xr-x) Uid: ( 0/ root) Gid: ( 1000/ hiboma) Access: 2023-06-06 10:56:50.342504983 +0900 Modify: 2023-06-06 10:50:08.884304931 +0900 Change: 2023-06-06 10:56:46.206522908 +0900 Birth: 2023-06-06 10:50:08.872304965 +0900 # 環境は Ubuntu Jammy です $ uname -a Linux vps 5.15.0-60-generic #66-Ubuntu SMP Fri Jan 20 14:29:49 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
strace をとると access(2) で /etc/suid-debug の有無を確認しているのを発見しました。
$ strace -f ./setuid-sleep execve("./setuid-sleep", ["./setuid-sleep"], 0x7ffc7af04528 /* 23 vars */) = 0 🔥 access("/etc/suid-debug", F_OK) = -1 ENOENT (No such file or directory) brk(NULL) = 0x55653bde3000 arch_prctl(0x3001 /* ARCH_??? */, 0x7ffd013de010) = -1 EINVAL (Invalid argument) fcntl(0, F_GETFD) = 0 fcntl(1, F_GETFD) = 0 fcntl(2, F_GETFD) = 0 🔥 access("/etc/suid-debug", F_OK) = -1 ENOENT (No such file or directory)
おっと /etc/suid-debug ファイルはなんだろう? 🤔 ... となって調べた次第です。
調べてみた
Google で調べて man にたどりつきました。
ld-linux.so(8) — manpages — Debian testing — Debian Manpages
Since glibc 2.3.4, LD_DEBUG is ignored in secure-execution mode, unless the file /etc/suid-debug exists (the content of the file is irrelevant).
- setuid していると LD_DEBUG が無視される (
secure-execution mode) - /etc/suid-debug があれば、LD_DEBUG が有効なままになる
ということらしいです。
LD_DEBUG とは?
LD_DEBUG については下記の説明を引用します
LD_DEBUG
(glibc 2.1 以降) 動的リンカーの詳細なデバッグ情報を出力する。 all に設定した場合、全ての動的リンカーが持つデバッグ情報を表示する。 help に設定した場合、この環境変数で指定されるカテゴリーのヘルプ情報を表示する。 glibc 2.3.4 以降、 set-user-ID/set-group-ID されたバイナリでは LD_DEBUG は無視される。
実験: /etc/suid-debug の有無で LD_DEBUG のふるまいを観察する
/etc/suid-debug がないと何もでないですね
$ LD_DEBUG=symbols ./setuid-sleep
次に、 /etc/suid-debug を touch(3) で作成して、再度実行します。するとデバッグのログがたくさん出てきた!
$ sudo touch /etc/suid-debug $ LD_DEBUG=symbols ./setuid-sleep 963912: symbol=__vdso_clock_gettime; lookup in file=linux-vdso.so.1 [0] 963912: symbol=__vdso_gettimeofday; lookup in file=linux-vdso.so.1 [0] 963912: symbol=__vdso_time; lookup in file=linux-vdso.so.1 [0] 963912: symbol=__vdso_getcpu; lookup in file=linux-vdso.so.1 [0] 963912: symbol=__vdso_clock_getres; lookup in file=linux-vdso.so.1 [0] 963912: symbol=_res; lookup in file=./setuid-sleep [0] 963912: symbol=_res; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 963912: symbol=svc_max_pollfd; lookup in file=./setuid-sleep [0] 963912: symbol=svc_max_pollfd; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 963912: symbol=obstack_alloc_failed_handler; lookup in file=./setuid-sleep [0] 963912: symbol=obstack_alloc_failed_handler; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 963912: symbol=__ctype_toupper; lookup in file=./setuid-sleep [0] 963912: symbol=__ctype_toupper; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 963912: symbol=loc1; lookup in file=./setuid-sleep [0] 963912: symbol=loc1; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 963912: symbol=_dl_argv; lookup in file=./setuid-sleep [0] 963912: symbol=_dl_argv; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 963912: symbol=_dl_argv; lookup in file=/lib64/ld-linux-x86-64.so.2 [0] ... 略
感想
- strace してると「あれ なんだこれ? 」って発見がある
- もともと調べたいことではなくて、脇道にそれてしまう 🌝
参考
- KMC Staff Blog:環境変数でLinuxのglibc動的リンカにログを出力させる
- ld-linux.so(8) — manpages — Debian testing — Debian Manpages
LD_DEBUG で指定できるオプションは下記の通りです。
LD_DEBUG (since glibc 2.1)
Output verbose debugging information about operation of the dynamic linker. The content of this variable is one of more of the following categories, separated by colons, commas, or (if the value is quoted) spaces:
help
Specifying help in the value of this variable does not run the specified program, and displays a help message about which categories can be specified in this environment variable.
all
Print all debugging information (except statistics and unused; see below).
bindings
Display information about which definition each symbol is bound to.
files
Display progress for input file.
libs
Display library search paths.
reloc
Display relocation processing.
scopes
Display scope information.
statistics
Display relocation statistics.
symbols
Display search paths for each symbol look-up.
unused
Determine unused DSOs.
versions
Display version dependencies.
Since glibc 2.3.4, LD_DEBUG is ignored in secure-execution mode, unless the file /etc/suid-debug exists (the content of the file is irrelevant).
`