Linux: 0, 1, 2 のファイルディスクリプタを閉じて setuid したバイナリ実行の挙動を調べる
以下の記事を読んで setuid したバイナリを実行する挙動で新たに知ったことがあった
以下に引用する
Some OSes (e.g., OpenBSD) protect against this by opening /dev/null on any unused FDs in the 0-2 range when execing a setuid program. As far as I can tell, Linux does not (but maybe I'm missing something...). This behavior is permitted in POSIX.1-2001, but not before.
いくつかの OS (たとえば OpenBSD) は、setuid プログラムを実行するときに、0-2 の範囲の未使用の FD で /dev/null をオープンして、この問題を防いでいます。私の知る限り、Linuxはそうではありません(しかし、もしかしたら私は何かを見逃しているかもしれません...)。この動作はPOSIX.1-2001では許可されているが、それ以前は許可されていない。
DeepL 翻訳
OpenBSD の execve(2) の man にも 下記の説明が付いている
In the case of a new setuid or setgid executable being exe- cuted, if file descriptors 0, 1, or 2 (representing stdin, stdout, and stderr) are currently unallocated, these descriptors will be opened to point to some system file like /dev/null. The intent is to ensure these descriptors are not unallocated, since many libraries make assumptions about the use of these 3 file descriptors.
なるほどなー 。実際にどうなんだろうと Linux で試した。
実験環境
Ubuntu Jammy で実験をします
hiboma@vps:~$ 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 hiboma@vps:~$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04 LTS Release: 22.04 Codename: jammy
実験用のコード
C のコードで sleep するだけの setuid バイナリを用意します。
#include <unistd.h> int main() { sleep(100); }
以下の手順で setuid なバイナリとします。
$ gcc setuid-sleep.c -o setuid-sleep $ sudo chown root.root setuid-sleep $ sudo chmod 4755 setuid-sleep $ ls -hal setuid-sleep -rwsr-xr-x 1 root root 16K Jun 7 10:24 setuid-sleep
0, 1, 2 のファイルディスクリプタを閉じてから 1 setuid なバイナリを実行する bash のシェルスクリプトも用意します
#!/bin/bash exec 0<&- exec 1<&- exec 2<&- exec ./setuid-sleep
実験
シェルスクリプトを実行します。これで 0, 1, 2 のデスクリプタを閉じて setuid したバイナリを exec できます。
$ ./test.sh
setuid したバイナリを実行しているプロセスの lsof をとって見ます。
$ sudo lsof -p $(pgrep setuid-sleep) COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME setuid-sl 1120951 root cwd DIR 252,2 4096 134434 /home/hiboma setuid-sl 1120951 root rtd DIR 252,2 4096 2 / setuid-sl 1120951 root txt REG 252,2 15968 135566 /home/hiboma/setuid-sleep setuid-sl 1120951 root mem REG 252,2 2216304 4337 /usr/lib/x86_64-linux-gnu/libc.so.6 setuid-sl 1120951 root mem REG 252,2 240936 194 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 setuid-sl 1120951 root 0w CHR 1,7 0t0 8 /dev/full 👈 setuid-sl 1120951 root 1r CHR 1,3 0t0 5 /dev/null 👈 setuid-sl 1120951 root 2r CHR 1,3 0t0 5 /dev/null 👈
/dev/full, /dev/null を開いていますね!
/dev/full, /dev/null を open するのはどこ?
strace をとって調べて見たところ、ld-linux-x86-64.so.2 っぽい。
openat(AT_FDCWD, "/dev/full", O_WRONLY|O_NOFOLLOW) = 0 > /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2(_dl_catch_error+0x9748) [0x26b38] > /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2(_dl_catch_error+0x903e) [0x2642e] > /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2(_dl_catch_error+0x24a5) [0x1f895] > /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2(_dl_catch_error+0x41c8) [0x215b8] > /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2(_dl_catch_error+0x2ec8) [0x202b8] ... 略 openat(AT_FDCWD, "/dev/null", O_RDONLY|O_NOFOLLOW) = 1 > /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2(_dl_catch_error+0x9748) [0x26b38] > /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2(_dl_catch_error+0x907e) [0x2646e] > /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2(_dl_catch_error+0x24a5) [0x1f895] > /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2(_dl_catch_error+0x41c8) [0x215b8] > /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2(_dl_catch_error+0x2ec8) [0x202b8] ... 略 openat(AT_FDCWD, "/dev/null", O_RDONLY|O_NOFOLLOW) = 2 > /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2(_dl_catch_error+0x9748) [0x26b38] > /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2(_dl_catch_error+0x90c2) [0x264b2] > /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2(_dl_catch_error+0x24a5) [0x1f895] > /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2(_dl_catch_error+0x41c8) [0x215b8] > /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2(_dl_catch_error+0x2ec8) [0x202b8]
ソースは?
_dl_catch_errorは、GNU Cライブラリ (glibc) の内部で使用される関数です。この関数は、動的リンカーによる共有ライブラリのロードやシンボルの解決中に発生するエラーをキャッチ(捉え)する役割を果たします。
具体的には、
_dl_catch_error
は以下のような機能を提供します: 1. エラーハンドラの設定: エラーが発生した際に呼び出される関数を設定できます。これにより、バリエーションに富むエラーハンドリングを行うことができます。
エラーの発生処理: _dl_catch_error は、エラーが発生した際にエラーメッセージを生成し、設定されたエラーハンドラに渡します。これにより、詳細なエラー情報が収集され、適切なエラー処理が行われます。
エラーハンドラのリセット: エラーが捉えられた後には、元の状態に戻します。_dl_catch_errorはビルトインのエラー処理機能を提供することで、動的リンカーによる共有ライブラリのロードやシンボルの解決を安全かつ信頼性の高いものにする役割を果たします
実験の補足
ファイルディスクリプタを閉じずに setuid バイナリを実行すると、0, 1, 2 のファイルディスクリプタは /dev/pts
を指していました
~$ sudo lsof -p $(pgrep setuid-sleep) COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME setuid-sl 1125289 root cwd DIR 252,2 4096 134434 /home/hiboma setuid-sl 1125289 root rtd DIR 252,2 4096 2 / setuid-sl 1125289 root txt REG 252,2 15968 135566 /home/hiboma/setuid-sleep setuid-sl 1125289 root mem REG 252,2 2216304 4337 /usr/lib/x86_64-linux-gnu/libc.so.6 setuid-sl 1125289 root mem REG 252,2 240936 194 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 setuid-sl 1125289 root 0u CHR 136,1 0t0 4 /dev/pts/1 setuid-sl 1125289 root 1u CHR 136,1 0t0 4 /dev/pts/1 setuid-sl 1125289 root 2u CHR 136,1 0t0 4 /dev/pts/1
感想
- 細かいプロセスの挙動ではまだまだ知らないことがある
- /dev/full, /dev/null を open する実装がどこにあるのか気になる
関連エントリ
strace の -k オプションでスタックトレースを出す - 2023 Ubuntu Jammy 版
以前こんなエントリを書いていた
strace で -k を指定すると システムコール呼び出しのスタックトレースを採取できるのを知った。v4.9 から使える experimental 扱いのオプション
という内容のエントリでした。
しかしながら
CentOS7.4 の strace-4.12-4.el7 ではサポートされていない機能だ。ざんねーん ちなみに Ubuntu Xenial もだめだー。とほほー
当時、私が業務で扱っていた Linux ディストリビューションではサポートされていなかったのでした。
で、この内容を改めて思い出して、 Ubuntu Jammy で strace -k
を試してみたら 動く!
hiboma@vps:~$ strace -k -P /etc/passwd -y id openat(AT_FDCWD</home/hiboma>, "/etc/passwd", O_RDONLY|O_CLOEXEC) = 3</etc/passwd> > /usr/lib/x86_64-linux-gnu/libc.so.6(__open64_nocancel+0x4c) [0x119bcc] > /usr/lib/x86_64-linux-gnu/libc.so.6(_IO_file_open+0xd5) [0x8c1e5] > /usr/lib/x86_64-linux-gnu/libc.so.6(_IO_file_fopen+0x292) [0x8c492] > /usr/lib/x86_64-linux-gnu/libc.so.6(fopen+0x7e) [0x7f72e] > /usr/lib/x86_64-linux-gnu/libc.so.6(__nss_files_fopen+0x12) [0x154e32] > /usr/lib/x86_64-linux-gnu/libc.so.6(_nss_files_getpwuid_r+0x3e) [0x15ab4e] > /usr/lib/x86_64-linux-gnu/libc.so.6(getpwuid_r+0x11f) [0xe9e0f] > /usr/lib/x86_64-linux-gnu/libc.so.6(getpwuid+0xa3) [0xe9683] > /usr/bin/id() [0x621e] > /usr/bin/id() [0x2fc5] > /usr/lib/x86_64-linux-gnu/libc.so.6(__libc_init_first+0x90) [0x29d90] > /usr/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) [0x29e40] > /usr/bin/id() [0x32e5] newfstatat(3</etc/passwd>, "", {st_mode=S_IFREG|0644, st_size=1889, ...}, AT_EMPTY_PATH) = 0 > /usr/lib/x86_64-linux-gnu/libc.so.6(fstatat+0xe) [0x113eee] > /usr/lib/x86_64-linux-gnu/libc.so.6(_IO_file_doallocate+0x63) [0x7ebf3] > /usr/lib/x86_64-linux-gnu/libc.so.6(_IO_doallocbuf+0x50) [0x8dd60] > /usr/lib/x86_64-linux-gnu/libc.so.6(_IO_file_seekoff+0x135) [0x8aa95] > /usr/lib/x86_64-linux-gnu/libc.so.6(fseeko+0x63) [0x88d53] > /usr/lib/x86_64-linux-gnu/libc.so.6(__nss_files_fopen+0x2c) [0x154e4c] > /usr/lib/x86_64-linux-gnu/libc.so.6(_nss_files_getpwuid_r+0x3e) [0x15ab4e] > /usr/lib/x86_64-linux-gnu/libc.so.6(getpwuid_r+0x11f) [0xe9e0f] > /usr/lib/x86_64-linux-gnu/libc.so.6(getpwuid+0xa3) [0xe9683] > /usr/bin/id() [0x621e] > /usr/bin/id() [0x2fc5] > /usr/lib/x86_64-linux-gnu/libc.so.6(__libc_init_first+0x90) [0x29d90] > /usr/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) [0x29e40] > /usr/bin/id() [0x32e5] lseek(3</etc/passwd>, 0, SEEK_SET) = 0 > /usr/lib/x86_64-linux-gnu/libc.so.6(llseek+0xb) [0x114acb] > /usr/lib/x86_64-linux-gnu/libc.so.6(_IO_file_seekoff+0x22d) [0x8ab8d] > /usr/lib/x86_64-linux-gnu/libc.so.6(fseeko+0x63) [0x88d53] > /usr/lib/x86_64-linux-gnu/libc.so.6(__nss_files_fopen+0x2c) [0x154e4c] > /usr/lib/x86_64-linux-gnu/libc.so.6(_nss_files_getpwuid_r+0x3e) [0x15ab4e] > /usr/lib/x86_64-linux-gnu/libc.so.6(getpwuid_r+0x11f) [0xe9e0f] > /usr/lib/x86_64-linux-gnu/libc.so.6(getpwuid+0xa3) [0xe9683] > /usr/bin/id() [0x621e] > /usr/bin/id() [0x2fc5] > /usr/lib/x86_64-linux-gnu/libc.so.6(__libc_init_first+0x90) [0x29d90] > /usr/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) [0x29e40] > /usr/bin/id() [0x32e5] read(3</etc/passwd>, "root:x:0:0:root:/root:/bin/bash\n"..., 4096) = 1889 > /usr/lib/x86_64-linux-gnu/libc.so.6(__read_nocancel+0x8) [0x119cd8] > /usr/lib/x86_64-linux-gnu/libc.so.6(_IO_file_underflow+0x186) [0x8ccb6] > /usr/lib/x86_64-linux-gnu/libc.so.6(_IO_default_uflow+0x36) [0x8de16] > /usr/lib/x86_64-linux-gnu/libc.so.6(_IO_getline_info+0xac) [0x8049c] > /usr/lib/x86_64-linux-gnu/libc.so.6(fgets_unlocked+0x45) [0x8a3b5] > /usr/lib/x86_64-linux-gnu/libc.so.6(__nss_readline+0x4b) [0x154ecb] > /usr/lib/x86_64-linux-gnu/libc.so.6(_nss_files_getpwuid_r+0x82) [0x15ab92] > /usr/lib/x86_64-linux-gnu/libc.so.6(getpwuid_r+0x11f) [0xe9e0f] > /usr/lib/x86_64-linux-gnu/libc.so.6(getpwuid+0xa3) [0xe9683] > /usr/bin/id() [0x621e] > /usr/bin/id() [0x2fc5] > /usr/lib/x86_64-linux-gnu/libc.so.6(__libc_init_first+0x90) [0x29d90] > /usr/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) [0x29e40] > /usr/bin/id() [0x32e5] close(3</etc/passwd>) = 0 > /usr/lib/x86_64-linux-gnu/libc.so.6(__close_nocancel+0xb) [0x119a1b] > /usr/lib/x86_64-linux-gnu/libc.so.6(_IO_file_close_it+0x70) [0x8bf80] > /usr/lib/x86_64-linux-gnu/libc.so.6(_IO_fclose+0x11f) [0x7ee0f] > /usr/lib/x86_64-linux-gnu/libc.so.6(_nss_files_getpwuid_r+0xd5) [0x15abe5] > /usr/lib/x86_64-linux-gnu/libc.so.6(getpwuid_r+0x11f) [0xe9e0f] > /usr/lib/x86_64-linux-gnu/libc.so.6(getpwuid+0xa3) [0xe9683] > /usr/bin/id() [0x621e] > /usr/bin/id() [0x2fc5] > /usr/lib/x86_64-linux-gnu/libc.so.6(__libc_init_first+0x90) [0x29d90] > /usr/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) [0x29e40] > /usr/bin/id() [0x32e5] uid=1000(hiboma) gid=1000(hiboma) groups=1000(hiboma),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev) +++ exited with 0 +++
やったー! すぐにつかえる!
動作環境
hiboma@vps:~$ 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
hiboma@vps:~$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04 LTS Release: 22.04 Codename: jammy hiboma@vps:~$
感想
- 見慣れないオプションがたくさんあるから もうちょい調べてみたい
- 最近は strace 使ってあれこれ調べるって機会、減ったなぁ
Linux: /dev/full と カーネルのソースリーディング #3分で
注) /dev/null じゃなくて /dev/full に関するエントリです。
/dev/full は何ですか?
write(2) すると必ず ENOSPC を返すキャラクタデバイスです。
$ echo hello > /dev/full -bash: echo: write error: No space left on device
「そういえば、こんなキャラクタデバイスあったな〜」と思って、Linux カーネルのソースを読み直しました
ChatGPT に聞いてソースを調べる
grep や GNU Global でシュっと見つからないので、slack-gpt に カーネルのソースがどこかと聞いたら一発で正解を出してくれた
こちらが slack-gpt が教えてくれた URL です
/dev/full のソース
/dev/full の write を処理するコードは write_full
でした。
static const struct file_operations full_fops = { .llseek = full_lseek, .read_iter = read_iter_zero, .write = write_full, 🤏 };
必ず -ENOSPC をかえす実装になっています。おもしろいですね
static ssize_t write_full(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { return -ENOSPC; 🤏 }
なお、/dev/full デバイスの定義は下記の通り。デバイスの初期化コードは長くなりそうなので スキップ
static const struct memdev { const char *name; umode_t mode; const struct file_operations *fops; fmode_t fmode; } devlist[] = { #ifdef CONFIG_DEVMEM [DEVMEM_MINOR] = { "mem", 0, &mem_fops, FMODE_UNSIGNED_OFFSET }, #endif [3] = { "null", 0666, &null_fops, FMODE_NOWAIT }, #ifdef CONFIG_DEVPORT [4] = { "port", 0, &port_fops, 0 }, #endif [5] = { "zero", 0666, &zero_fops, FMODE_NOWAIT }, [7] = { "full", 0666, &full_fops, 0 }, 🤏 [8] = { "random", 0666, &random_fops, FMODE_NOWAIT }, [9] = { "urandom", 0666, &urandom_fops, FMODE_NOWAIT }, #ifdef CONFIG_PRINTK [11] = { "kmsg", 0644, &kmsg_fops, 0 }, #endif };
感想
- シンプルな実装で面白い。自分でも作れそう
- 「ソース読むか ... でもどこだろう ...? 」と迷子になったが、ChatGPT のガイドでたどり着けた。
参考
💡 slack-gpt は同僚の P山さんが開発している ChatGPT Slack ボットです
setuid したバイナリの strace を取ると /etc/suid-debug を access(2) でみている - LD_DEBUG の制御に使うファイルだった
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). `
deb パッケージ がどんな configure オプションでビルドされたかを調べる
このエントリの続きです。 deb パッケージの configure オプションはどうやって確かめるんだったかな? と調べた次第
環境
Ubuntu jammy の docker で作業した
1. deb の source パッケージを取得、ファイルシステムで展開する
いろいろ調べたところ apt source で source パッケージをダウンロードできると知りました。
apt source を使うには /etc/apt/sources.list で deb-src の URL を記述する必要があります。ftp.riken.jp のミラーをお借りします。
deb-src http://ftp.riken.jp/Linux/ubuntu/ jammy-updates main restricted universe multiverse deb-src http://ftp.riken.jp/Linux/ubuntu/ jammy-security main restricted universe multiverse deb-src http://ftp.riken.jp/Linux/ubuntu/ jammy-backports main restricted universe multiverse deb-src http://ftp.riken.jp/Linux/ubuntu/ jammy partner
curl で試してみます
root@7073a24a73ad:/workspace# apt source curl Reading package lists... Done NOTICE: 'curl' packaging is maintained in the 'Git' version control system at: https://salsa.debian.org/debian/curl.git Please use: git clone https://salsa.debian.org/debian/curl.git to retrieve the latest (possibly unreleased) updates to the package. Need to get 4257 kB of source archives. Get:1 http://ftp.riken.jp/Linux/ubuntu jammy-updates/main curl 7.81.0-1ubuntu1.10 (dsc) [3143 B] Get:2 http://ftp.riken.jp/Linux/ubuntu jammy-updates/main curl 7.81.0-1ubuntu1.10 (tar) [4188 kB] Get:3 http://ftp.riken.jp/Linux/ubuntu jammy-updates/main curl 7.81.0-1ubuntu1.10 (asc) [488 B] Get:4 http://ftp.riken.jp/Linux/ubuntu jammy-updates/main curl 7.81.0-1ubuntu1.10 (diff) [65.2 kB] Fetched 4257 kB in 1s (4613 kB/s) dpkg-source: info: extracting curl in curl-7.81.0 dpkg-source: info: unpacking curl_7.81.0.orig.tar.gz dpkg-source: info: unpacking curl_7.81.0-1ubuntu1.10.debian.tar.xz dpkg-source: info: using patch list from debian/patches/series dpkg-source: info: applying 04_workaround_as_needed_bug.patch dpkg-source: info: applying 06_always-disable-valgrind.patch dpkg-source: info: applying 08_enable-zsh.patch dpkg-source: info: applying 11_omit-directories-from-config.patch dpkg-source: info: applying 13_fix-man-formatting.patch dpkg-source: info: applying CVE-2022-22576.patch dpkg-source: info: applying CVE-2022-27774-1.patch dpkg-source: info: applying CVE-2022-27774-2.patch dpkg-source: info: applying CVE-2022-27774-3.patch dpkg-source: info: applying CVE-2022-27775.patch dpkg-source: info: applying CVE-2022-27776.patch dpkg-source: info: applying CVE-2022-27780.patch dpkg-source: info: applying CVE-2022-27781.patch dpkg-source: info: applying CVE-2022-27782.patch dpkg-source: info: applying CVE-2022-32205.patch dpkg-source: info: applying CVE-2022-32206.patch dpkg-source: info: applying CVE-2022-32207.patch dpkg-source: info: applying CVE-2022-32208.patch dpkg-source: info: applying CVE-2022-35252.patch dpkg-source: info: applying CVE-2022-32221.patch dpkg-source: info: applying CVE-2022-42915.patch dpkg-source: info: applying CVE-2022-42916.patch dpkg-source: info: applying CVE-2022-43551.patch dpkg-source: info: applying CVE-2022-43552.patch dpkg-source: info: applying CVE-2023-23914_5-1.patch dpkg-source: info: applying CVE-2023-23914_5-2.patch dpkg-source: info: applying CVE-2023-23914_5-3.patch dpkg-source: info: applying CVE-2023-23914_5-4.patch dpkg-source: info: applying CVE-2023-23914_5-5.patch dpkg-source: info: applying CVE-2023-23916-pre1.patch dpkg-source: info: applying CVE-2023-23916.patch dpkg-source: info: applying CVE-2023-27533.patch dpkg-source: info: applying CVE-2023-27534-pre1.patch dpkg-source: info: applying CVE-2023-27534.patch dpkg-source: info: applying CVE-2023-27538.patch dpkg-source: info: applying CVE-2023-27535-pre1.patch dpkg-source: info: applying CVE-2023-27536.patch dpkg-source: info: applying CVE-2023-27535.patch dpkg-source: info: applying 90_gnutls.patch dpkg-source: info: applying 99_nss.patch
2. debian/rules をみる
展開されたディレクトリの debian/rules に configure 設定が書いてあります
root@7073a24a73ad:/workspace# ls -hal curl-7.81.0/debian/rules -rwxr-xr-x 1 root root 5.1K Jan 5 2022 curl-7.81.0/debian/rules
CONFIGURE_ARGS = -- --disable-dependency-tracking \ --disable-symbol-hiding --enable-versioned-symbols \ --enable-threaded-resolver --with-lber-lib=lber \ --with-gssapi=/usr --with-nghttp2 \ --includedir=/usr/include/$(DEB_HOST_MULTIARCH) \ --with-zsh-functions-dir=/usr/share/zsh/vendor-completions # disable libssh2 on Ubuntu (see #888449) ifeq ($(shell dpkg-vendor --derives-from Ubuntu && echo yes),yes) CONFIGURE_ARGS += --with-libssh --without-libssh2 else CONFIGURE_ARGS += --without-libssh --with-libssh2 endif %: dh $@ override_dh_auto_configure: mkdir -p debian/build debian/build-gnutls debian/build-nss # pop the last patch (nss) quilt pop # pop the second last patch (gnutls) quilt pop # get the source without nss and gnutls patches tar -cf - --exclude=debian/build* --exclude=.pc . \ | tar -xf - -C debian/build # push the second last patch which must be gnutls quilt push # get the source with gnutls patch applied tar -cf - --exclude=debian/build* --exclude=.pc . \ | tar -xf - -C debian/build-gnutls # push the last patch which must be nss quilt push # get the source with nss patch applied tar -cf - --exclude=debian/build* --exclude=.pc . \ | tar -xf - -C debian/build-nss # run buildconf and make sure to copy the patched ltmain.sh for flavour in build build-gnutls build-nss; do \ (cd debian/$$flavour && ./buildconf && cp ../../ltmain.sh .) \ done cd debian/build && dh_auto_configure ${CONFIGURE_ARGS} --with-openssl \ --with-ca-path=/etc/ssl/certs \ --with-ca-bundle=/etc/ssl/certs/ca-certificates.crt cd debian/build-gnutls && dh_auto_configure ${CONFIGURE_ARGS} --with-gnutls \ --with-ca-path=/etc/ssl/certs \ --without-ssl --with-gnutls cd debian/build-nss && dh_auto_configure ${CONFIGURE_ARGS} --with-nss \ --without-ssl --with-nss
感想
- deb パッケージを自前でビルドするのは あんまりやったことが無くて 知識がない
- override_dh_auto_configure がよくわからない。後で調べる
- deb-src のミラーを参照せずに、任意の URL から source パッケージをもってきて調べる方法? 後で調べる
参考
RPM がどんな configure オプションでビルドされたかを調べる
とある RPM パッケージの configure を調べたい用事があったので、手順をエントリとして書き起こします。
環境
- CentOS7 の docker で作業した
1. SRPM をファイルシステムで展開する
今回は対象の SRPM を rpm で直接 GET して展開します。vault.centos.org の SRPM を使います。
# rpm -ivh https://vault.centos.org/7.9.2009/updates/Source/SPackages/curl-7.29.0-59.el7_9.1.src.rpm
~/rpmbuild/SPECS
に spec ファイルが展開されます。
# ls -hal ~/rpmbuild/SPECS/curl.spec -rw-rw-r-- 1 root root 58K Nov 16 2020 /root/rpmbuild/SPECS/curl.spec
spec ファイルの %configure を確かめます
%configure --disable-static \ --enable-hidden-symbols \ --enable-ipv6 \ --enable-ldaps \ --enable-manual \ --enable-threaded-resolver \ --with-ca-bundle=%{_sysconfdir}/pki/tls/certs/ca-bundle.crt \ --with-gssapi${KRB5_PREFIX} \ --with-libidn \ --with-libssh2 \ --without-ssl --with-nss
これで終わりです
感想
- 久々に SRPM を調べる機会があったので思い出しつつ書き留めた
- 簡単な手順ではあるけど、知らないと調べるのもひと手間かかりますよね
- 会社の同僚で知らん人もおるだろうから 書いておこうという気分
TechFeed Experts Night#19 - トラブルシューティングから Linux カーネルに潜り込む の発表をしました
トラブルシューティングから Linux カーネルに潜り込む をタイトルに発表をしました
Linux カーネルのコードを読む動機は人によって様々と思いますが、私の場合はトラブルシューティングが大きく占めている感じです。
今回の発表は
- 業務で遭遇したトラブル事例を紹介
- トラブルシューティングから Linux カーネルに潜り込むことについて考えてたこと
を LT してみました。
持ち時間が短かったので 問題をどう調査していったかまでは全然説明できていないです。また別の機会にどこかで取り上げられたらいいかなと思っています。
謝辞
イベントの開催・運営・登壇の機会をご提供いただいた 株式会社テックフィード様 ありがとうございました!
また、登壇を推薦していただいた TenForward さん (id:defiant さん) ありがとうございました! ( 社外で発表しないとな〜と思っていたところでお声がけいただいてタイミングもバッチリでした )
sat さん、udzura さんも発表者として ご一緒できてよかったです。 いろんな角度で Linux カーネルの話を聞けてよいイベントでしたね。