2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

NetBSDAdvent Calendar 2024

Day 11

所有者とグループを考慮したハードリンク作成制限機能の実装をソースコードから調べてみる

Posted at

NetBSD Advent Calendar 2024 11日目の記事です。
今日は8日目の記事で紹介した、所有者とグループを考慮したハードリンク作成制限機能について、ソースコードレベルでの処理がどうなっているかを見てみようと思います。

ハードリンク作成時のuid,gidチェック

ハードリンク作成制限は、sysctl(8)security.models.extensions.hardlink_check_* というMIB(Management Information Base)エントリの値を設定することで実現できます。

hardlink_check_ というキーワードで grep してみます。どうやら /usr/src/sys/secmodel/extensions/secmodel_extensions.c というファイルでMIB用の変数定義と値の参照が行われているようです。

$ find /usr/src/sys -type f | xargs grep hardlink_check
/usr/src/sys/secmodel/extensions/secmodel_extensions.c:static int hardlink_check_uid;
/usr/src/sys/secmodel/extensions/secmodel_extensions.c:static int hardlink_check_gid;
/usr/src/sys/secmodel/extensions/secmodel_extensions.c:                CTLTYPE_INT, "hardlink_check_uid",
/usr/src/sys/secmodel/extensions/secmodel_extensions.c:                &hardlink_check_uid, 0,
/usr/src/sys/secmodel/extensions/secmodel_extensions.c:                CTLTYPE_INT, "hardlink_check_gid",
/usr/src/sys/secmodel/extensions/secmodel_extensions.c:                &hardlink_check_gid, 0,
/usr/src/sys/secmodel/extensions/secmodel_extensions.c: if (hardlink_check_uid && kauth_cred_geteuid(cred) != va.va_uid)
/usr/src/sys/secmodel/extensions/secmodel_extensions.c: if (hardlink_check_gid && kauth_cred_groupmember(cred, va.va_gid) != 0)

ファイル所有者以外のハードリンク作成を制限する機能について見てみます。

52行目で hardlink_check_uid というMIBエントリの値を保持する変数が宣言され( static 宣言されているのでデフォルト値は 0)、157~164行目で sysctl にMIBエントリが追加されています。

 52 static int hardlink_check_uid;
 ...
157     sysctl_createv(clog, 0, &rnode, NULL,
158                CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
159                CTLTYPE_INT, "hardlink_check_uid",
160                SYSCTL_DESCR("Whether unprivileged users can hardlink "\
161                 "to files they don't own"),
162                sysctl_extensions_user_handler, 0,
163                &hardlink_check_uid, 0,
164                CTL_CREATE, CTL_EOL);

hardlink_check_uid の値がどのように参照されているか見てみます。548行目で hardlink_check_uid が真、かつ取得したuidが自分( kauth_cred_t で渡したクレデンシャル経由で取得しているっぽい)と異なる場合に checkroot: ラベルにジャンプし、 root ユーザでない場合はuidが異なる場合のハードリンク作成制限に該当するため、 KAUTH_RESULT_DENY を返すという挙動になっています。

gidをチェックする場合もほぼ同じ処理になっており、 root ユーザかどうかのチェックは共通化できるため、 checkroot: ラベルにジャンプするという実装になっているようです。

533 static int
534 secmodel_extensions_vnode_cb(kauth_cred_t cred, kauth_action_t action,
535     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
536 {
537     int error;
538     bool isroot;
539     struct vattr va;
...
544     error = VOP_GETATTR((vnode_t *)arg0, &va, cred);
...
548     if (hardlink_check_uid && kauth_cred_geteuid(cred) != va.va_uid)
549         goto checkroot;
...
554     return KAUTH_RESULT_DEFER;
555 checkroot:
556     error = secmodel_eval("org.netbsd.secmodel.suser", "is-root",
557         cred, &isroot);
558     if (error || !isroot)
559         return KAUTH_RESULT_DENY;
560
561     return KAUTH_RESULT_DEFER;
562 }

まとめ

所有者とグループを考慮したハードリンク作成制限機能について、ソースコードレベルでの処理を見てみました。基本的には sysctl で機能が有効・無効であるかを判定し、有効な場合は然るべき判定処理(uidが違う場合は root ユーザかどうかをチェック)するという、シンプルな実装になっていました。ただ、これらの処理はsecmodel(9)というフレームワークを使用しており、secmodel(9)の利用により実装しやすくなっているという側面もあるようです。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?