namei
Table of Contents
ktrace/kdump
ちょっと復習になるけど、アプリの挙動を追跡する時は、いきなりgdbじゃな くて、ktrace/kdumpが便利だ。これリナで言うstraceね。
何度も出てきてる、chroot /tmp/MINE の挙動を追うなら、
ob# ktrace chroot /tmp/MINE : ob# kdump >LOG
chrootの前に、ktraceを付加して、syscallのログを採取。アプリが終了した ら、kdumpを使って、ログをテキスト化。ログ名は、特に指定しなけれ ば、~/ktrace.outっていうバイナリーファイルだ。
上でのLOGは317行だった。ただ眺めていても得る事が少ないと思うので
ob$ grep NAMI LOG 66095 ktrace NAMI "/usr/bin/chroot" 66095 ktrace NAMI "/bin/chroot" 66095 ktrace NAMI "/usr/sbin/chroot" 66095 chroot NAMI "/tmp/MINE" 66095 chroot NAMI "/" 66095 chroot NAMI "/bin/ksh" 66095 ksh NAMI "/root/.terminfo" 66095 ksh NAMI "/usr/share/terminfo" 66095 ksh NAMI "/usr/local/share/terminfo" 66095 ksh NAMI "none" 66095 ksh NAMI "/tmp" 66095 ksh NAMI "/" 66095 ksh NAMI "/dev/tty"
まずは、NAMIってキーワードで検索してみるのが良い。どんなファイルをリク エストしたかが抽出できるんだ。第二フィールドは、それを要求したアプリ名 だ。
ktraceは、色々な場所にあるかも知れない、chrootを探してる。 /usr/sbin/chrootが発見できたんで、それを使おうと決定したんだな。 そして、chrootが起動して、/tmp/MINEやらの引数を探す(何とかする)。 最後にkshが起動させられて、その初期化が実施される。こんな粗筋で物語は 進行する。
こんな風にして、登場人物を把握しておくのが解析の第一歩だろう。細かく見 るなら、less LOGとかして、NAMIをキーワードにして、周辺を当たるのが良い と思う。例えば、こんな風にね。
66095 chroot NAMI "/bin/ksh" 66095 chroot ARGS [0] = "/bin/ksh" [1] = "-i" 66095 ksh RET execve JUSTRETURN 66095 ksh CALL issetugid() 66095 ksh RET issetugid 0
kshを起動する時は、引数に、-i をつけるんか。これって、インタラクティブ・ モードでお願いしますって事だな、なんて想像できる。
namei
上で出てきたキーワードのNAMIは、前回だったか、調べがついていて、
vfs_lookup.c
の中の、nameiと言う関数の中で、ktraceにより採取されてい
た。よって、namei関数は、カーネルの中でも、重要な物と見做されている。
こういう重要な関数は、マニュアルの第9セクションにて説明されてる事が多 い。namei(9)
NAMEI(9) Kernel Developer's Manual NAMEI(9) NAME namei, vfs_lookup, vfs_relookup, NDINIT, NDINITAT - pathname lookup FUNCTIONS namei(ndp) Convert a pathname into a pointer to a vnode. The pathname is specified by ndp->ni_dirp and is of length ndp->ni_pathlen. The ndp->segflg flag defines whether the name in ndp->ni_dirp is an address in kernel space (UIO_SYSSPACE) or an address in user space (UIO_USERSPACE). The vnode for the pathname is referenced and returned in ndp->ni_vp. If ndp->ni_cnd.cn_flags has the FOLLOW flag set then symbolic links are followed when they occur at the end of the name translation process. Symbolic links are always followed for all other pathname components other than the last. If the LOCKLEAF flag is set, a locked vnode is returned.
マニュアルが有るか無いかは、多分に運任せな所が有るけれど、もしヒットす れば、それは重要な関数で間違いは無い。疑問に思ったら、man -S 9 xxx し てみよう。-S 9 なクラスターには、184個が集っていたぞ。
対抗でFreeBSDは幾つあるかと数えたら、何と2446個も有った。細分化で水増 ししてるのかな? リナは、一つも無い状況。OSの特色が、こんな所にも潜ん でいるな。横断的に見るって、刺激的。
カーネルの中でも難解と言われているアレをチェック。
sakae@fb:/usr/share/man/man9 $ man mbuf | wc 717 4384 43309 ob$ man mbuf | wc 549 2946 30198
つらつら眺めていたら、ラジオなんて楽しそうなのを発見。
NAME radio - interface between low and high level radio drivers DESCRIPTION The radio device driver is divided into a high level, hardware independent layer, and a low level hardware dependent layer. The interface between these is the radio_hw_if structure. struct radio_hw_if { int (*open)(void *, int, int, struct proc *); int (*close)(void *, int, int, struct proc *); int (*get_info)(void *, struct radio_info *); int (*set_info)(void *, struct radio_info *); int (*search)(void *, int); };
ラジオって事は、アマチュア無線の憧れ、 コリンズ75S3B とかと、I/F できるのかな? 無理無理、昭和のマシンですか ら。
ktrace(2)
ktraceのmanには(1)(2)(9)の3種類が有る。(2)には
The trpoints parameter specifies the trace points of interest. The defined trace points are: KTRFAC_SYSCALL Trace system calls. KTRFAC_SYSRET Trace return values from system calls. KTRFAC_NAMEI Trace name lookup operations. KTRFAC_GENIO Trace all I/O (note that this option can generate much output). KTRFAC_PSIG Trace posted signals. KTRFAC_STRUCT Trace various structs. KTRFAC_USER Trace user data coming from utrace(2) calls. KTRFAC_EXECARGS Trace argument vector in execve(2) calls. KTRFAC_EXECENV Trace environment vector in execve(2) calls. KTRFAC_PLEDGE Trace violations of pledge(2) restrictions. KTRFAC_INHERIT Inherit tracing to future children.
(9)には、こんなのが列挙されてる。完全に 1:1 で、対応してる訳ではなさ そうである。
ktrgenio(struct proc *p, int fd, enum uio_rw rw, struct iovec *iov, int len, int error); ktrnamei(struct proc *p, char *path); ktrpsig(struct proc *p, int sig, sig_t action, int mask, int code, siginfo_t *si); ktrsyscall(struct proc *p, register_t code, size_t argsize, register_t args[]); ktrsysret(struct proc *p, register_t code, int error, register_t retval);
お誂え向けのktrnameiが有るので、そこでBPしてみる。尚、冒頭のktraceの 結果のようになるはずだって、頭の片隅に入れておく。 さて、実行するぞ。
ob$ gdb -q bsd.gdb Reading symbols from bsd.gdb... acpicpu_idle () at /usr/src/sys/dev/acpi/acpicpu.c:1207 1207 break; (gdb) b ktrnamei Breakpoint 1 at 0xd06e68b5: file /usr/src/sys/kern/kern_ktrace.c, line 215. (gdb) c Continuing. Breakpoint 1, ktrnamei (p=0xd149b1ac, path=0xf1b32c00 "/sbin/chroot") at /usr/src/sys/kern/kern_ktrace.c:215 215 atomic_setbits_int(&p->p_flag, P_INKTR); (gdb) bt #0 ktrnamei (p=0xd149b1ac, path=0xf1b32c00 "/sbin/chroot") at /usr/src/sys/kern/kern_ktrace.c:215 #1 0xd057650c in namei (ndp=0xf1b35790) at /usr/src/sys/kern/vfs_lookup.c:170 #2 0xd0a674e4 in check_exec (p=0xd149b1ac, epp=0xf1b357f0) at /usr/src/sys/kern/kern_exec.c:136 #3 0xd0a67c0c in sys_execve (p=0xd149b1ac, v=0xf1b35a64, retval=0xf1b35a5c) at /usr/src/sys/kern/kern_exec.c:316 #4 0xd068ba01 in mi_syscall (p=0xd149b1ac, code=59, indirect=0, callp=0xd0d0f3a4 <sysent+708>, argp=0xf1b35a64, retval=0xf1b35a5c) at /usr/src/sys/sys/syscall_mi.h:110 #5 0xd068b604 in syscall (frame=0xf1b35aa0) at /usr/src/sys/arch/i386/i386/trap.c:574 #6 0xd071a135 in Xsyscall_untramp () #7 0xf1b35aa0 in ?? () #8 0x1a979d5f in ?? () Backtrace stopped: previous frame inner to this frame (corrupt stack?)
少し先に進む
(gdb) bt #0 ktrnamei (p=0xd149b1ac, path=0xf1b32c00 "MINE") at /usr/src/sys/kern/kern_ktrace.c:215 #1 0xd057650c in namei (ndp=0xf1b3594c) at /usr/src/sys/kern/vfs_lookup.c:170 #2 0xd02fff39 in change_dir (ndp=0xf1b3594c, p=0xd149b1ac) at /usr/src/sys/kern/vfs_syscalls.c:842 #3 0xd0300064 in sys_chroot (p=0xd149b1ac, v=0xf1b35a64, retval=0xf1b35a5c) at /usr/src/sys/kern/vfs_syscalls.c:814
shが起動する所。
(gdb) bt 4 #0 ktrnamei (p=0xd149b1ac, path=0xf1b32c00 "/bin/ksh") at /usr/src/sys/kern/kern_ktrace.c:215 #1 0xd057650c in namei (ndp=0xf1b35790) at /usr/src/sys/kern/vfs_lookup.c:170 #2 0xd0a674e4 in check_exec (p=0xd149b1ac, epp=0xf1b357f0) at /usr/src/sys/kern/kern_exec.c:136 #3 0xd0a67c0c in sys_execve (p=0xd149b1ac, v=0xf1b35a64, retval=0xf1b35a5c) at /usr/src/sys/kern/kern_exec.c:316
こういう見方も有るんですねぇ。
doas for FreeBSD
ネットを見てたら、FreeBSDにdoasを導入してる方がいた。オイラーもつ られて、pkg install doas したよ。
sakae@fb:~ $ cat /usr/local/etc/doas.conf permit :wheel
エイリアスにも反応する様に、設定。
alias nt='ntpdate pool.ntp.org' alias doas='doas '
sakae@fb:~ $ doas nt Password: 19 Jun 06:26:08 ntpdate[12213]: adjust time server 133.243.238.243 offset +0.009967 sec
usb drive
最近、女房が断舎利とか言い出した。終活の事ね。そのせいで、インクが入手 できなくなったプリンターとか、性能が劣化した魔法瓶とかを粗大ごみの日に 出している。
目をつけられた候補品に、Windows7時代にバックアップとして使っていた、 USB Driveが有った。ごみの日に出して良い物か悩む前に、オイラー的には、 情報漏洩が心配だ。物理的に破壊してしまうのが、一番の策だろうけど、どう したものだろう。トイレの洗剤に、10日間ぐらい浸漬する刑がいいかな? この方法だと、ドリル優子には、負けてしまうけど。ドリルは確実性と即効性 が有りますから。
まて、パソコンに接続して、少しは遊んでみよう。OpenBSDなマシンに接続し てみた。
Jun 18 05:38:37 ob /bsd: umass0 at uhub0 port 2 configuration 1 interface 0 "BUFFALO INC. USB2-IDE Bridge" rev 2.00/1.06 addr 2 Jun 18 05:38:37 ob /bsd: umass0: using SCSI over Bulk-Only Jun 18 05:38:37 ob /bsd: scsibus4 at umass0: 2 targets, initiator 0 Jun 18 05:38:43 ob /bsd: sd1 at scsibus4 targ 1 lun 0: <USB-HS, SAMSUNG SP1604N, 0.01> serial.0411002a000001112523 Jun 18 05:38:43 ob /bsd: sd1: 152627MB, 512 bytes/sector, 312581808 sectors
こんな代物だった。側はバッファローで、中身はサムソン製ね。fdisk sd1し たら、きっちりとNTFSの区画になってた。
とりあえず、OpenBSDで使用できる用に区画整理してから、全面をクリアして みるか。
fdisk -e sd1 reinit mbr write quit disklabel -Aw sd1 newfs /dev/rsd1c mount /dev/sd1c /mnt
fdiskで区画を作成。disklabelでパーテションを作成。全エリアを対象に newfsしてから、mount。これでやっとOS上から使用可能となる。
ob# dd if=/dev/zero of=g bs=1M count=10000 10000+0 records in 10000+0 records out 10485760000 bytes transferred in 905.368 secs (11581761 bytes/sec)
後は、細々とクリアしていく。なんで細々か? 一遍にやるとDISKが加熱して しまい、USB毎エラーになってしまう為。冷却期間を置きながら、少しづつっ て事です。夏は人間が辛い季節だけど、ハードウェアも同様です。熱中症にな らない様に注意しましょう。そう言えば、外で仕事をする土方(差別用語と言 わないで)の人は、全員、ふっくらしたベストを着用してたな。良く見たら、 ベストに排気口が付いてた。空冷ベストなんだな。ご苦労様です。
ob$ df -h /mnt Filesystem Size Used Avail Capacity Mounted on /dev/sd1c 144G 74.3G 62.8G 55% /mnt
チマチマやってて、やっと半分を越えた。頑張れUSB君。
次の使命は、FreeBSDの置き場になる事だからね。 前回やった、qemu用のゲストOS作成方法が、OpenBSD上で再現できるかの検証。 FreeBSDがホストOSだった場合、gpartが利用できたけど、OpenBSDには、そん なコマンドは用意されていない。fdisk/disklabelだけを使って、よそのOS用 HDDを作成できるか。興味ある所です。
Index of /pub/FreeBSD/releases/i386/14.1-RELEASE
まずは、この素材だけを使って、なんとか出来るかだな? もし駄目なら、
Index of /pub/FreeBSD/releases/ISO-IMAGES/14.1
こちらのFreeBSD-14.1-RELEASE-i386-memstick.imgを使うかだな。 これだと、負けた気分になるけど。
ob$ df -h /mnt Filesystem Size Used Avail Capacity Mounted on /dev/sd1c 144G 144G -7.2G 106% /mnt
石の上にも三年で、やっと全面書き込み終了。rootさんは、リソースを余す所 なく利用できる特権を持っています。うえの例だと、-7.2Gが、平民には利用 できない、裏金もとえ、エリアになります。さて、東京都の利権争奪戦が始ま るな。願わくば、令和版の渋沢栄一が生まれる事を望む。