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が、平民には利用 できない、裏金もとえ、エリアになります。さて、東京都の利権争奪戦が始ま るな。願わくば、令和版の渋沢栄一が生まれる事を望む。


This year's Index

Home