Open9

system temporary path is world-writable: /tmp/tmp is world-writable: /tmp

Matsukura YukiMatsukura Yuki

bundleを実行したらエラーが出るようになってしまった。

root@406b7f0636e3:/app# bundle exec rails db:migrate
system temporary path is world-writable: /tmp
/tmp is world-writable: /tmp
/usr/local/bundle/gems/spring-4.1.1/lib/spring/client/run.rb:26:in `initialize': Operation not supported - connect(2) for /app/spring-0/dd8a5fc4ec68a287140deded829e3a66 (Errno::ENOTSUP)
	from /usr/local/bundle/gems/spring-4.1.1/lib/spring/client/run.rb:26:in `open'
	from /usr/local/bundle/gems/spring-4.1.1/lib/spring/client/run.rb:26:in `connect'
	from /usr/local/bundle/gems/spring-4.1.1/lib/spring/client/run.rb:31:in `call'
	from /usr/local/bundle/gems/spring-4.1.1/lib/spring/client/command.rb:7:in `call'
	from /usr/local/bundle/gems/spring-4.1.1/lib/spring/client/rails.rb:24:in `call'
	from /usr/local/bundle/gems/spring-4.1.1/lib/spring/client/command.rb:7:in `call'
	from /usr/local/bundle/gems/spring-4.1.1/lib/spring/client.rb:30:in `run'
	from /usr/local/bundle/gems/spring-4.1.1/bin/spring:49:in `<top (required)>'
	from /usr/local/bundle/gems/spring-4.1.1/lib/spring/binstub.rb:11:in `load'
	from /usr/local/bundle/gems/spring-4.1.1/lib/spring/binstub.rb:11:in `<top (required)>'
	from <internal:/usr/local/lib/ruby/site_ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:86:in `require'
	from <internal:/usr/local/lib/ruby/site_ruby/3.0.0/rubygems/core_ext/kernel_require.rb>:86:in `require'
	from /app/bin/spring:10:in `block in <top (required)>'
	from <internal:kernel>:90:in `tap'
	from /app/bin/spring:7:in `<top (required)>'
	from bin/rails:2:in `load'
	from bin/rails:2:in `<main>'

使っているdocker imageは ruby:3.0.3-buster

よくよく調べてみると、/tmp の権限がなぜか0777。本来なら、user sticky bitが立っていないといけないので、 1777 にならないといけない。

root@406b7f0636e3:/app# ls -ald /tmp/
drwxrwxrwx 2 root root 40 Oct 16 04:00 /tmp/
Matsukura YukiMatsukura Yuki

問題の原因を探るために、元のimageを起動してみたらimageの初期状態で 1777 でした。

# docker run --rm -it ruby:3.0.3-buster bash
root@d4676cb2cb7e:/# ls -ald /tmp
drwxrwxrwt 2 root root 4096 Mar 28  2022 /tmp

元のimageでチェックしてみても、 1777 なので元々この設定のようです。

% docker run --rm -it debian:10 ls -ald /tmp
drwxrwxrwt 2 root root 4096 Oct  9 00:00 /tmp

Ubuntuの最新でも同じです。

% docker run --rm -it ubuntu:latest ls -ald /tmp
drwxrwxrwt 2 root root 4096 Jan 26  2023 /tmp
Matsukura YukiMatsukura Yuki

chmod 1777 /tmp で回避はできることはできますが、毎回やるのが面倒です。
テンポラリディレクトリ周りで何かしら不具合が置きていて、 spring-0 というディレクトリがカレントディレクトリに作られてしまいます。本来ならば、 /tmp/ に作成されるべきもの。

再度調べたら、rubygem起因の様子。
https://github.com/rubygems/rubygems/issues/4466

要経過観察。

snakasnaka

違うシチュエーションですが、同様の問題に遭遇したためこちらの Scrap が参考になりました。
ありがとうございます。

ちなみに

spring-0 というディレクトリがカレントディレクトリに作られてしまいます。本来ならば、 /tmp/ に作成されるべきもの。

こちら、推測ですが Ruby の tmpdir ライブラリの挙動として、/tmp など ( TMPDIR 環境変数で示された PATH なども含む ) が利用できなかった場合、最終的にカレントディレクトリを利用するようなロジックになっているのが原因と思われます。

https://github.com/ruby/ruby/blob/fd974f5d740b9b5af63ecfdef3ee092b69e437a3/lib/tmpdir.rb#L29-L47

snakasnaka

ちなみに、手元の環境で ruby:3.0.3-buster/tmp ディレクトリを見た感じ sticky bit がセットされてて問題なさそうに見えました。

$ docker run --rm -it ruby:3.0.3-buster ls -ald /tmp/
drwxrwxrwt 2 root root 4096 Mar 28  2022 /tmp/

同じイメージでも利用しているコンテナランタイムによって挙動が違う可能性? があるかも... (このあたりよくわかっていないです 🙇 )

手元の環境は

  • macOS: 13.6.7(22G720)Ventura
  • CPU: Apple M2
  • コンテナ実行環境
    • Docker Desktop 4.21.1 (114176)
docker version
$ docker version
Client:
 Cloud integration: v1.0.35
 Version:           24.0.2
 API version:       1.43
 Go version:        go1.20.4
 Git commit:        cb74dfc
 Built:             Thu May 25 21:51:16 2023
 OS/Arch:           darwin/arm64
 Context:           desktop-linux

Server: Docker Desktop 4.21.1 (114176)
 Engine:
  Version:          24.0.2
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.4
  Git commit:       659604f
  Built:            Thu May 25 21:50:59 2023
  OS/Arch:          linux/arm64
  Experimental:     false
 containerd:
  Version:          1.6.21
  GitCommit:        3dce8eb055cbb6872793272b4f20ed16117344f8
 runc:
  Version:          1.1.7
  GitCommit:        v1.1.7-0-g860f061
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

関係あるか不明ですが runc において tempfs の sticky bit が立っていないという Issue を見かけましたが... runc は使ったことが無く、これが関係しているかどうかは全くわかっていません 🙏

https://github.com/opencontainers/runc/issues/3952

Matsukura YukiMatsukura Yuki

ありがとうございます。
手元の環境でも再現を試みましたが、再現しなくなってしまってました。
(そして、以前のコメントで誤認識があったので一部修正しました)

元のimageの方はsticky-bitが立っているので、その後の処理またはDocker側でなにかしているのかもしれませんね。

snakasnaka

なるほどです。

ちなみに私が遭遇したは、 AWS Lambda の Ruby ランタイムで Dir.tmpdir を呼び出すとエラーになる現象でした。

https://zenn.dev/link/comments/9fe5085ff48d61

で、調べてみたら /tmp に sticky bit が立っていないということが判明したのでした...