Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

With Elixir 1.18, only a single user may compile a project #14168

Closed
jiegillet opened this issue Jan 10, 2025 · 1 comment · Fixed by #14171
Closed

With Elixir 1.18, only a single user may compile a project #14168

jiegillet opened this issue Jan 10, 2025 · 1 comment · Fixed by #14171

Comments

@jiegillet
Copy link

jiegillet commented Jan 10, 2025

Elixir and Erlang/OTP versions

Erlang/OTP 27 [erts-15.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [dtrace]

Elixir 1.18.1 (compiled with Erlang/OTP 27)

Operating system

MacOS

Current behavior

In Elixir 1.18, on compilation a temporary folder is being created in /tmp/mix_pubsub (or potentially in some other temporary directory).
However, due to systems permissions, if that folder was created by a user a, a user b (with the same temporary directory) will not be allowed be re-create the folder and attempting to compile a project will crash.
Here is an example I ran on my machine:

~ whoami
jie_old
➜  ~ elixir -v                             
Erlang/OTP 27 [erts-15.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [dtrace]

Elixir 1.18.1 (compiled with Erlang/OTP 27)
➜  ~ elixir -e "IO.puts(System.tmp_dir!())"
/tmp
➜  ~ ls -l /tmp/mix_*
zsh: no matches found: /tmp/mix_*~ mix new project1 && cd project1      
* creating README.md
* creating .formatter.exs
* creating .gitignore
* creating mix.exs
* creating lib
* creating lib/project1.ex
* creating test
* creating test/test_helper.exs
* creating test/project1_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

    cd project1
    mix test

Run "mix help" for more commands.
➜  project1 mix compile
Compiling 1 file (.ex)
Generated project1 app
➜  project1 ls -l /tmp/mix_*                      
/tmp/mix_lock:
total 0
drwxr-xr-x  4 jie_old  wheel  128 Jan 10 21:03 tARo6JLGiDoBf2MhoMm72g

/tmp/mix_pubsub:
total 0
drwxr-xr-x  3 jie_old  wheel  96 Jan 10 21:03 tARo6JLGiDoBf2MhoMm72g
➜  project1 
➜  project1 su - jie
Password:
➜  ~ whoami
jie
➜  ~ elixir -v                             
Erlang/OTP 27 [erts-15.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Elixir 1.18.1 (compiled with Erlang/OTP 27)
➜  ~ elixir -e "IO.puts(System.tmp_dir!())"
/tmp
➜  ~ mix new project2 && cd project2
* creating README.md
* creating .formatter.exs
* creating .gitignore
* creating mix.exs
* creating lib
* creating lib/project2.ex
* creating test
* creating test/test_helper.exs
* creating test/project2_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

    cd project2
    mix test

Run "mix help" for more commands.
➜  project2 mix compile

21:04:17.346 [error] GenServer Mix.Sync.PubSub terminating
** (File.Error) could not make directory (with -p) "/tmp/mix_pubsub/VNbrPlEkR_STXjO2E53Uug": permission denied
    (elixir 1.18.1) lib/file.ex:346: File.mkdir_p!/1
    (mix 1.18.1) lib/mix/sync/pubsub.ex:222: Mix.Sync.PubSub.create_subscription_file/2
    (mix 1.18.1) lib/mix/sync/pubsub.ex:142: Mix.Sync.PubSub.handle_call/3
    (stdlib 6.0) gen_server.erl:2209: :gen_server.try_handle_call/4
    (stdlib 6.0) gen_server.erl:2238: :gen_server.handle_msg/6
    (stdlib 6.0) proc_lib.erl:329: :proc_lib.init_p_do_apply/3
Last message (from Mix.PubSub.Subscriber): {:subscribe, #PID<0.110.0>, "/Users/jie/project2/_build/dev"}
State: %{port: nil, hash_to_pids: %{}}
Client Mix.PubSub.Subscriber is alive

    (stdlib 6.0) gen.erl:241: :gen.do_call/4
    (elixir 1.18.1) lib/gen_server.ex:1125: GenServer.call/3
    (mix 1.18.1) lib/mix/sync/pubsub.ex:44: Mix.Sync.PubSub.subscribe/1
    (mix 1.18.1) lib/mix/pubsub/subscriber.ex:21: Mix.PubSub.Subscriber.init/1
    (stdlib 6.0) gen_server.erl:2057: :gen_server.init_it/2
    (stdlib 6.0) gen_server.erl:2012: :gen_server.init_it/6
    (stdlib 6.0) proc_lib.erl:329: :proc_lib.init_p_do_apply/3

21:04:17.355 [notice] Application mix exited: shutdown
** (ArgumentError) errors were found at the given arguments:

  * 1st argument: the table identifier does not refer to an existing ETS table

    (stdlib 6.0) :ets.lookup(Mix.State, :debug)
    (mix 1.18.1) lib/mix/state.ex:26: Mix.State.get/2
    (mix 1.18.1) lib/mix/cli.ex:112: Mix.CLI.run_task/2
    /Users/jie/.asdf/installs/elixir/1.18.1-otp-27/bin/mix:2: (file)

We realized this in the context of updating the Exercism test runner. The test runner runs user code and formats the result in a particular way. The app was built in a Docker container by the root user, and then used by some other user, and with 1.18 it started crashing. Once we realized the cause, it was easy enough to fix, but I thought I would signal this.

Expected behavior

I would expect several users on a machine to be able to compile projects.

@josevalim
Copy link
Member

I will release v1.18.2 in the following days, so you can update exercism. Thank you for your contributions! ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants