質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

3回答

10603閲覧

linuxのsuidを設定した実行ファイルで、実行者が所有者にならない

ryuuinn

総合スコア75

CentOS

CentOSは、主にRed Hat Enterprise Linux(RHEL)をベースにした、フリーのソフトウェアオペレーティングシステムです。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

0グッド

0クリップ

投稿2015/08/24 15:44

はじめまして。
linuxを使っていてわからないことがあったので教えて下さい。

ファイルのパーミションについて学んでいた時に、SUIDというものに出会ったので、
早速実験してみましたが、参考にした情報どおりの挙動にならなかったので原因が分かりましたらご教示頂きたいです。

OS: CentOS 6.5

実験手順

1. 実験に使う実行ファイルをつくる(744)

bash

1[riki permTest]$ cat hello 2#/bin/bash 3 4# 実行者のUIDとユーザ名を表示する 5echo $UID $USER 6 7[riki permTest]$ ls -la . 8合計 16 9drwxrwsr-x 2 riki riki 4096 825 00:25 2015 . 10drwxr-sr-x 31 riki riki 4096 825 00:25 2015 .. 11-rwxr--r-- 1 riki riki 29 825 00:25 2015 hello 12

2. 所有者が実行してみる

[riki permTest]$ ./hello 503 riki

これは意図どおりです。

3. 他のユーザが実行してみる

hogeユーザで実行してみる

[hoge permTest]$ ./hello -bash: ./hello: 許可がありません

実行権限を与えてないので、これも意図どおり。

4. 他のユーザに実行権限を与えて、他のユーザが実行してみる

他のユーザにもhelloに実行権限を与える

[riki permTest]$ chmod o+x hello [riki permTest]$ ls -la . 合計 16 drwxrwsr-x 2 riki riki 4096 8月 25 00:25 2015 . drwxr-sr-x 31 riki riki 4096 8月 25 00:25 2015 .. -rwxr--r-x 1 riki riki 29 8月 25 00:25 2015 hello

もう一回hogeで実行

[hoge permTest]$ ./hello 500 hoge

実行出来ました。そしてhogeが実行したことになってます。
これも意図どおり。

5. uidを設定して、hogeで実行してみる

いよいよ本題です。helloにsuidを設定してみます。

[riki permTest]$ chmod u+s hello [riki permTest]$ ls -la . 合計 16 drwxrwsr-x 2 riki riki 4096 8月 25 00:25 2015 . drwxr-sr-x 31 riki riki 4096 8月 25 00:25 2015 .. -rwsr--r-x 1 riki riki 29 8月 25 00:25 2015 hello

suidが設定された状態でhogeが実行(503 rikiと表示されるハズ)

[hoge permTest]$ ./hello 500 hoge

これが意図と違いました。

質問

参考にしたサイト

上記のサイトを見て、suidが設定された実行ファイルは、他のユーザが実行しても実行ユーザがファイルの所有者になると思い、今回のような実験をしてみました。

期待していた結果としては、suidを設定したhelloスクリプトはhogeユーザが実行した時も503 rikiと表示してくると思っていましたが、普通に500 hogeとなってしまいました。。

何か私の認識で勘違いしている部分があるのでしょうか・・><
期待通りの結果になっていない原因をご教示いただけますと幸いです!

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

(シェバング行が書かれた)ただのスクリプトだと、実行可能でも setuid は効きません。
実行可能なバイナリである必要があります。

c

1#include <stdio.h> 2#include <unistd.h> 3#include <sys/types.h> 4#include <pwd.h> 5 6int main() 7{ 8 uid_t uid = geteuid(); 9 struct passwd *pw = getpwuid(uid); 10 printf("%d %s\n", uid, pw->pw_name); 11 return 0; 12}

sh

1gcc a.c -o hello 2./hello # 500 ore 3sudo chown daemon hello 4sudo chmod u+s hello 5./hello # 2 daemon

投稿2015/08/24 16:15

ngyuki

総合スコア4514

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

otnさんのご説明の通り、セキュリティー上の理由で、スクリプトにはsetuidは効きません。
しかしシステム(カーネル)の設定によっては、例外的にperlスクリプトのみsetuid/gidの仕組みを利用できます。
(参考)
(もっとも、カーネルの設定で禁止されている場合にはどうしようもありません。)

どうしても特定のスクリプトでsetuid/gidの仕組みを利用したい場合には、そのスクリプトを呼び出すラッパーをcか何かで作成し、ラッパー側にsetuidを設定、スクリプト側にはシェバン行に-pオプションを付加し「特権モード」を有効化することで、目的を達成することができます。

自分は、以前、業務上の必要に迫られて以下のようなラッパーを使用して実際に使用していたことがあります。引数も普通にシェルスクリプトへ渡せます。
(古い記憶を頼りに記載したので、誤記があったらごめんなさい…)

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <errno.h> 5#include <sys/wait.h> 6 7extern char **environ; 8 9int main(int argc, char *argv[]) { 10 int pid; 11 int status; 12 int i; 13 int rc = 1; 14 char command[256]; 15 16 /* 実行スクリプト設定 */ 17 strcpy(command, "/path/to/script"); // 対象スクリプトの絶対パスを設定 18 19 pid = fork(); 20 21 switch(pid) { 22 case 0: 23 /* 子プロセス */ 24 /* スクリプト実行 */ 25 setgid( ggg ); // setuidを設定したいユーザーのgid 26 setuid( uuu ); // setuidを設定したいユーザーのuid 27 if (execve(command, argv, environ) < 0) { 28 exit(EXIT_FAILURE); 29 } 30 break; 31 case -1: 32 /* 失敗 */ 33 exit(EXIT_FAILURE); 34 break; 35 default: 36 /* 親プロセス */ 37 /* 子プロセスの完了を待つ */ 38 waitpid(pid, &status, 0); 39 if (WIFEXITED(status)) { 40 rc = WEXITSTATUS(status); 41 } 42 break; 43 } 44 45 return(rc); 46}

このプログラムを普通にgccでコンパイルし、望みのユーザーにsetuidします。
一方、呼び出されるスクリプト側はシェバン行に-pオプションを指定し特権モードを有効にしておきます。

bash

1#!/bin/bash -p 2 3# 任意の処理 4

スクリプト本体のオーナー・パーミッションは、ラッパーから実行可能であれば大丈夫だったと思います。

セキュリティー上のリスクを伴うので、慎重に使用してください。


ちょっと補足します。

実行ユーザがファイルの所有者になると思い…

と記載されていましたが、setuidを利用しても「実ユーザー」自体は変わりません。「実効ユーザー」の権限で実効可能になるということです。実効ユーザーという概念が(自分にとっては最初)ちょっと紛らわしかったので、補足しておきます。
(参考)

投稿2015/08/24 21:09

編集2015/08/24 21:20
pi-chan

総合スコア5936

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

セキュリティ上の理由でスクリプトにsetuidは効きません。下記参照。
1990年代からあるUnix FAQ

追記:
本題から逸れますが、実効ユーザーの確認は、UID、USERでは出来ません。
bashの場合、実効ユーザーIDは、EUID です。また、USERは /etc/profileで設定されてたりするものなので、単にbashを起動しただけではユーザーが異なっても再設定されないでしょう。
シェルスクリプトからの実効ユーザーの確認にはidコマンドを使ってください。

投稿2015/08/24 16:22

編集2015/08/25 02:31
otn

総合スコア84423

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問