gnome-pty-helperを読んでみた
GNOME端末を使っていると、gnome-pty-helperという謎のプロセスが立ち上がっているのに気づく。このプロセスは一体何をやっているのだろうか。
gnome-pty-helper は次の処理を行うヘルパープログラムだ。
- 擬似端末を確保する。
- 擬似端末の権限を適切に設定する。
- utmp エントリを更新し、wtmp エントリを追加する。 (ログイン)
- セッションをキープする。
- utmp エントリを更新し、wtmp エントリを追加する。 (ログアウト)
- (擬似端末の権限を元に戻す) ← どこ?
2. 6. の操作に pty デバイスノードの所有者の権限が必要なのと、3. 5. の操作に utmp / wtmp を更新できる権限が必要だが、GNOME端末を起動したユーザ権限でそれらが行えるとは限らないのでヘルパーが必要になるというわけ。
gnome-pty-helper は 2. の操作が行えるように suid されていることがあるけど、これは devpts の導入により不要になる。devpts が適切な権限の設定されたノードをアトミックに生成できるからだ。また同様に 3. と 5. の操作が行えるよう wtmp グループなどに sgid されている。
ここで gnome-pty-helper が端末のディスクリプタを確保するのはいいとして、一体どうやって呼出元のGNOME端末にそれを渡すのかという疑問が生じるが、なんと、というか、やはりというか、 sendmsg() を使ってディスクリプタを渡しているのだ。
Author: Miguel de Icaza (miguel@ぐにゅー.org)
Parent application talks to us via a couple of sockets that are strategically placed on file descriptors 0 and 1 (STDIN_FILENO and STDOUT_FILENO).
We use the STDIN_FILENO to read and write the protocol information and we use the STDOUT_FILENO to pass the file descriptors (we need two different file descriptors as using a socket for both data transfers and file descriptor passing crashes some BSD kernels according to Theo de Raadt)
A sample protocol is used:
OPEN_PTY => 1
=> 0CLOSE_PTY
=> void
<tag> is a pointer. If tag is NULL, then the ptys were not allocated.
ptys are passed using file descriptor passing on the stdin file descriptorWe use as little as possible external libraries.
gnome-pty-helper.c上部のコメントより
ところで気になるのは 6. の操作。OpenSSH では pty_release (sshpty.c) で元に戻しているよう見受けられるけど、gnome-pty-helper の場合はどこなんだろう?
追記: Konsole の場合はどうしているか調べてみたところ
- grantpt() が動くならそれを利用する。
- 素の openpty() が自動的に権限を適切に設定できるなら (grantpt() / revoke() を使って) それを利用する。
- 以上だめなら konsole_grantpt というヘルパーに頼る。
のようになっているようだ。ちなみに utmp / wtmp の書き出しは端末エミュレータ本体がやっている模様。
なお、grantpt() の実装は NetBSD の場合次のようになっていた。ioctl() を使った権限管理って結構見掛けるけど、ちょっとこわい。
pty.c*1:
int grantpt(int fildes) { return ioctl(fildes, TIOCGRANTPT, 0); }
追記2: pseudo terminal は擬似端末と書くのが正しいのについつい「仮想端末」と書いてしまったので置き換えました。混乱した方すみませんでした。
*1:全くの余談、File Descriptor => fildes の略が結構好き。「モテるオヤジは全員FILDESを装着」とか書いても違和感がないところが特に。