7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CentOS7 で CGI が /var/tmp に書き込みできなくなった件 (systemd の PrivateTmp)

Last updated at Posted at 2017-06-13

何があったか

超絶古い C の CGI をパブリッククラウドへ移行させる作業の中で、その CGI が mkstemp() 関数を使ってテンポラリファイルを作成しようとしてエラーになりました。以下は頑張って strace して取得したシステムコールです。

open("/var/tmp/hoge/temp_k6KF97", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 ENOENT (No such file or directory)

以前の環境は CentOS5.5 の Apache2.2 で、新しい環境は CentOS7.1 の Apache2.2 です。
(本当は Apache2.4 を使いたかったのですが諸般の事情で 2.2 をソースインストールすることに)

書き込みディレクトリのオーナーやパーミッションは問題ない (apache ユーザーが書き込みできる) のにエラーが出ます。

試行錯誤

試しにディレクトリのパーミッションをフルアクセスにして、mkstemp() 関数を使ったテストプログラムを作ってターミナル上で叩いてみたところ、問題なくテンポラリファイルが作成できました。
しかしこれをWebサーバーから叩ける場所に置いて、CGI としてブラウザーから実行させるとやはりファイルが作成されません。ファイルディスクリプタが獲得できないのです。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
 
int main(void)
{
        char filename[] = "/var/tmp/hoge/temp_XXXXXX";
        int i = 30;
        int fd;
 
        sleep(i);
        fd = mkstemp(filename);
        printf("Content-type: text/plain\n\n");
        printf("result: fd: %d\n", fd);
}

解決策が見つかる

ログイン権限を持たないユーザーが /var/tmp に書き込みできないのだろうか…とか途方に暮れてあれこれ調べていたところ、「Yahoo!知恵袋」の質疑応答にあたりました。

これを読んでいてハッと気づきました。そういえば CentOS7 でソースインストールした Apache2.2 を systemd でコントロールできるようにするために、なんかファイルを置いたんだった!
慌てて /etc/systemd/system/httpd.service を覗くと、果たして上記のページに書かれていた設定がありました。

[Unit]
Description=Apache Web Server 2.2
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
ExecStart=/usr/local/apache2/bin/apachectl -k start
ExecReload=/usr/local/apache2/bin/apachectl graceful
ExecStop=/usr/local/apache2/bin/apachectl -k stop
PrivateTmp=true  # <- これ
LimitNOFILE=infinity

[Install]
WantedBy=multi-user.target

これを、

  • PrivateTmp=false にする。
  • sudo systemctl daemon-reload
  • sudo systemctl restart httpd

してから改めて CGI を動かしたところ、テンポラリファイルが /var/tmp 配下に作成されました。

systemd の定義ファイルを見よう見まねで作っていて、各項目の意味をちゃんと理解していなかったのがハマった原因です。ちゃんと勉強します…。

要するにどういうことか

CentOS7 から採用された systemd で、登録したサービスが使う /tmp/var/tmp を、OS標準のものではなくサービス専用のものを用意して提供してくれる仕組みです。別プロセスからこの配下のファイルを操作されてしまうとセキュリティの問題が発生することがあるため、それを避けるための対策として提供された機能のようです。
(参考: テンポラリファイルの扱いについてまとめた記事: 情報セキュリティ技術動向調査(2008 年下期):IPA 独立行政法人 情報処理推進機構)

インターネット側から不特定多数の人が叩くプログラムでテンポラリ領域を使うのは危険、ということのようです。

その他参考資料

7
7
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
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?