ping コマンドの file capability(1)
(いまさらのお話とは思いますが自分用のメモに)
Linux の Capability、何度も理解しようとして完全に理解できないままなんですが、ちょっとした理由で File capability を調べてます。最近は ambient capability なんてのもあって理解が遠のいてます。:-p
file capability といえば、まず登場するのはこのコマンドではないでしょうか?(違う?) Ubuntu 18.04.3 では次のように setuid されています。file capability は特に設定されていません。
$ ls -l /bin/ping -rwsr-xr-x 1 root root 64424 Jun 28 20:05 /bin/ping $ getcap /bin/ping $
これは想定通りだったんですが、先日リリースしたばかりの CentOS 8 で見てみると、
$ ls -l /bin/ping -rwxr-xr-x. 1 root root 69160 May 11 23:22 /bin/ping $ getcap /bin/ping /bin/ping = cap_net_admin,cap_net_raw+p
setuid されておらず file capability が設定されていて、「おお、イマドキのセキュアな設定っぽい」と思いました(CentOS 7 からそうだったようなので今更感満載です)。でも +p
と設定されています。あれ? +ep
でじゃないとマズくない? +e
がないと実行できなくない? 例のあのややこしい条件式からいっても。
$ man 7 capabilities : (snip) P'(ambient) = (file is privileged) ? 0 : P(ambient) P'(permitted) = (P(inheritable) & F(inheritable)) | (F(permitted) & P(bounding)) | P'(ambient) P'(effective) = F(effective) ? P'(permitted) : P'(ambient) P'(inheritable) = P(inheritable) [i.e., unchanged] P'(bounding) = P(bounding) [i.e., unchanged]
それはそのとおりなのですが、CentOS で採用されている ping が含まれている iputils のコードを確認するとその理由がわかります(たぶん)。
#ifdef HAVE_LIBCAP int modify_capability(cap_value_t cap, cap_flag_value_t on) { cap_t cap_p = cap_get_proc(); cap_flag_value_t cap_ok; int rc = -1; if (!cap_p) { error(0, errno, "cap_get_proc"); goto out; } cap_ok = CAP_CLEAR; cap_get_flag(cap_p, cap, CAP_PERMITTED, &cap_ok); if (cap_ok == CAP_CLEAR) { rc = on ? -1 : 0; goto out; } cap_set_flag(cap_p, CAP_EFFECTIVE, 1, &cap, on); if (cap_set_proc(cap_p) < 0) { error(0, errno, "cap_set_proc"); goto out; } cap_free(cap_p); cap_p = NULL; rc = 0; out: if (cap_p) cap_free(cap_p); return rc; }
(https://github.com/iputils/iputils/blob/4b0a0ab7898b093ef55c4a8cacea9a21c37a451f/ping_common.c#L189)
CAP_PERMITTED
を確認して、付与されていれば CAP_EFFECTIVE
を設定してます(と思う)。
これで +ep
でなく +p
な理由がわかりました。ping
コマンド自体で +p
が付いていれば(というか付いている結果として permitted が設定されていれば、かな?)必要な capability を設定してシステムコールを呼ぶプログラムになっているからでした。
とはいえこれでは +e
が不要な理由はわかりましたが、付けておいてマズい理由はわかりません。ま、セキュリティ観点から不要な権限は付けておく理由はない、というだけでも理由になりますが。
(続く)