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

Rust: Permissions Question #851

Open
CodeMan99 opened this issue Nov 14, 2023 · 10 comments
Open

Rust: Permissions Question #851

CodeMan99 opened this issue Nov 14, 2023 · 10 comments
Assignees
Labels
dependency-upgrade Tracks new image support or EOL

Comments

@CodeMan99
Copy link

Scenario

The rust image currently has umask 022 set.

$ docker run -it --rm --user root mcr.microsoft.com/devcontainers/rust:1-1-bullseye
root ➜ / $ umask
0022
root ➜ / $ grep ^rustlang /etc/group
rustlang:x:999:vscode

Should a build step, such as a feature use cargo install the resulting permissions prevent group write usage.

root ➜ / $ cargo install --quiet bacon
root ➜ / $ ls -ld $CARGO_HOME/registry
drwxr-sr-x 5 root rustlang 4096 Nov 14 19:04 /usr/local/cargo/registry

Which then in turn breaks user-level usage of other cargo commands.

root ➜ / $ su vscode
vscode ➜ / $ cd
vscode ➜ ~ $ cargo install cargo-watch
    Updating crates.io index
  Downloaded cargo-watch v8.4.1
error: failed to download replaced source registry `crates-io`

Caused by:
  failed to open `/usr/local/cargo/registry/cache/index.crates.io-6f17d22bba15001f/cargo-watch-8.4.1.crate`

Caused by:
  Permission denied (os error 13)

Question

What is the correct course of action?

  1. Set umask 002 here, at the image level? Perhaps in /etc/profile?
  2. Set umask 002 inside feature install.sh scripts?
@samruddhikhandale
Copy link
Member

Hi 👋

Thanks for opening a detailed issue.

What is the correct course of action?

As cargo is installed by the Rust Feature, it makes sense to update permissions in the Feature. However, looking at https://github.com/devcontainers/features/blob/main/src/rust/install.sh#L156, I do see umask 0002 set. However, I think there's a bug in this line https://github.com/devcontainers/features/blob/main/src/rust/install.sh#L163, it updates permissions only for the specific directory, instead of doing that recursively.

I believe, updating chmod g+r+w+s "${RUSTUP_HOME}" "${CARGO_HOME}" to 👇 should help.

chmod -R g+r+w+s "${RUSTUP_HOME}" "${CARGO_HOME}"

@CodeMan99 Let me know if that makes sense to you, thanks!

@samruddhikhandale
Copy link
Member

Opened devcontainers/features#754

@CodeMan99
Copy link
Author

Let me know if that makes sense to you, thanks!

I am not completely sure to be honest. I don't think the feature creates $CARGO_HOME/regitstry. I believe that folder is only created after usage of cargo install.

So the rust feature still isn't responsible for the creation of the problem directory.

@samruddhikhandale
Copy link
Member

I think I missed the part where you switch the users between running cargo install command. As the registry is created by the root user, it won't automatically allow the vscode user to use it unless the permissions are updated.

Curious, @CodeMan99 why do you switch users? I believe these Features/images were created hoping that the same user is been used for lifecycle of the dev container. Else, it would cause permission issues as seen in this issue ^

@CodeMan99
Copy link
Author

Curious, @CodeMan99 why do you switch users? I believe these Features/images were created hoping that the same user is been used for lifecycle of the dev container. Else, it would cause permission issues as seen in this issue ^

Usage of root is build-like usage. For example, using cargo install inside a feature install.sh. My understanding that executing that script will always be root. Is that an incorrect assumption?

Then, during development cargo will need write access to that folder. Including cargo build. The $CARGO_HOME/registry folder is created with the correct group (rustlang) in my example.

@samruddhikhandale
Copy link
Member

My understanding that executing that script will always be root. Is that an incorrect assumption?

Yes, that is correct. All Feature's install scripts are run with the root user.

With the Rust Feature, CARGO_HOME directory is correctly owned by the vscode user. However, as you are running cargo commands with the root user, it creates the registry folder with root permissions. The non-root user cannot modify the files that were created by root as basically you can't mix something like sudo cargo install and cargo install.

Hence, I believe you should do either of the following to fix the issue -

  • Always stick with a single user vscode or root, else, you will run into this issue
    • Else, manually give permissions for the registry directory to the vscode user
  • When running with root, make sure to run commands as vscode user (eg. vscode -c "cargo install bacon")

@CodeMan99
Copy link
Author

However, as you are running cargo commands with the root user, it creates the registry folder with root permissions.

The folder is created with exactly these permissions.

root ➜ / $ cargo install --quiet bacon
root ➜ / $ ls -ld $CARGO_HOME/registry
drwxr-sr-x 5 root rustlang 4096 Nov 14 19:04 /usr/local/cargo/registry

The vscode user is added to the rustlang group by the rust feature. The only thing that needs to change is the write permissions for the group.

  • Always stick with a single user vscode or root, else, you will run into this issue

This advice does not resolve the issue. Example devcontainer.json file:

{
     "image": "mcr.microsoft.com/devcontainers/rust:1-1-bullseye",
     "features": {
         "ghcr.io/lee-orr/rusty-dev-containers/bacon:0": {}
     }
}

This very simple configuration creates the problem:

  1. cargo install bacon is run in the install.sh of the feature.
  2. The remoteUser is vscode.

So again, what is the correct course of action?

Use of umask 002 in the image's /etc/profile file? Or use of umask 002 in the install.sh script of any given feature?

@CodeMan99
Copy link
Author

Let me clarify a little - "the course of action" is a question of who needs to own this knowledge.

  1. Setting the umask 002 in /etc/profile would be an image-wide change, affecting all system user's default. Only image maintainers would be required to have knowledge.
  2. Setting the umask 002 in any given feature is a very specific change that requires documentation. Both documentation maintainers and community feature maintainers are required to have knowledge.
  3. Just providing a guideline puts the ownership of this issue in the hands of any user that wants to use cargo install as a build step (Dockerfile or using a feature).

@GKMWD
Copy link

GKMWD commented Nov 29, 2023

A configuração de umask influencia as permissões padrão atribuídas a novos arquivos e diretórios criados pelos processos no sistema. O valor padrão, umask 022, significa que as permissões padrão são 755 para diretórios e 644 para arquivos. Se você deseja alterar o valor padrão do umask, pode fazer isso no arquivo de perfil (como .bashrc ou .bash_profile) do usuário ou no script de inicialização do contêiner.

Aqui está um exemplo de como você poderia configurar o umask em um arquivo de perfil (por exemplo, .bashrc) no Dockerfile:

FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye

Configurando o umask no perfil do usuário

RUN echo "umask 022" >> /etc/skel/.bashrc

Configurando o umask para o usuário existente 'vscode'

RUN echo "umask 022" >> /home/vscode/.bashrc

Dockerfile

Copy code
FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye

Configurando o umask no perfil do usuário

RUN echo "umask 022" >> /etc/skel/.bashrc

Configurando o umask para o usuário existente 'vscode'

RUN echo "umask 022" >> /home/vscode/.bashrc
Este Dockerfile adiciona a linha umask 022 ao final do arquivo .bashrc no diretório /etc/skel (um esqueleto usado para criar novos usuários) e ao arquivo .bashrc do usuário existente 'vscode'. Isso garantirá que o umask seja configurado corretamente para qualquer novo usuário que seja criado e para o usuário existente.

Lembre-se de que esta é uma sugestão geral, e a configuração específica pode depender dos requisitos e das práticas recomendadas em sua organização. Certifique-se de ajustar conforme necessário para atender às suas necessidades específicas.

Parece que o problema está relacionado às permissões do diretório /usr/local/cargo/registry. Você pode otimizar isso ajustando as permissões para garantir que o usuário vscode tenha as permissões apropriadas para acessar e gravar nesse diretório. Uma abordagem possível seria adicionar o usuário vscode ao grupo rustlang e ajustar as permissões do diretório.

Aqui estão as etapas que você pode adicionar ao seu Dockerfile:

FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye

# Adiciona o usuário 'vscode' ao grupo 'rustlang'
RUN usermod -aG rustlang vscode

# Define as permissões do diretório '/usr/local/cargo/registry'
RUN chown root:rustlang /usr/local/cargo/registry && chmod 775 /usr/local/cargo/registry

# Configura o umask no perfil do usuário
RUN echo "umask 022" >> /etc/skel/.bashrc
RUN echo "umask 022" >> /home/vscode/.bashrc

FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye

# Adiciona o usuário 'vscode' ao grupo 'rustlang'
RUN usermod -aG rustlang vscode

# Define as permissões do diretório '/usr/local/cargo/registry'
RUN chown root:rustlang /usr/local/cargo/registry && chmod 775 /usr/local/cargo/registry

# Configura o umask no perfil do usuário
RUN echo "umask 022" >> /etc/skel/.bashrc
RUN echo "umask 022" >> /home/vscode/.bashrc

Estas são as principais alterações:

  1. usermod -aG rustlang vscode: Adiciona o usuário vscode ao grupo rustlang.
  2. chown root:rustlang /usr/local/cargo/registry: Define o proprietário do diretório /usr/local/cargo/registry como root e o grupo como rustlang.
  3. chmod 775 /usr/local/cargo/registry: Define as permissões do diretório como 775, permitindo que o grupo rustlang também escreva no diretório.

Depois de adicionar essas linhas ao seu Dockerfile e reconstruir a imagem, o usuário vscode deve ter as permissões adequadas para instalar pacotes Cargo sem erros de permissão. Certifique-se de que essas alterações atendam aos requisitos específicos do seu ambiente.

Peço desculpas pela confusão anterior. Parece que mesmo após adicionar o usuário vscode ao grupo rustlang e ajustar as permissões do diretório, ainda ocorrem problemas de permissão.

A solução proposta anteriormente para alterar as permissões do diretório pode não ser suficiente. É possível que as permissões específicas do arquivo index.crates.io-6f17d22bba15001f/cargo-watch-8.4.1.crate não estejam permitindo que o usuário vscode acesse.

Uma solução mais robusta pode ser garantir que todos os arquivos e diretórios dentro de /usr/local/cargo/registry tenham as permissões adequadas para o grupo rustlang. Você pode fazer isso recursivamente usando o comando chmod:

FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye

# Adiciona o usuário 'vscode' ao grupo 'rustlang'
RUN usermod -aG rustlang vscode

# Define as permissões do diretório '/usr/local/cargo/registry'
RUN chown -R root:rustlang /usr/local/cargo/registry && chmod -R 775 /usr/local/cargo/registry

# Configura o umask no perfil do usuário
RUN echo "umask 022" >> /etc/skel/.bashrc
RUN echo "umask 022" >> /home/vscode/.bashrc

FROM mcr.microsoft.com/devcontainers/rust:1-1-bullseye

# Adiciona o usuário 'vscode' ao grupo 'rustlang'
RUN usermod -aG rustlang vscode

# Define as permissões do diretório '/usr/local/cargo/registry'
RUN chown -R root:rustlang /usr/local/cargo/registry && chmod -R 775 /usr/local/cargo/registry

# Configura o umask no perfil do usuário
RUN echo "umask 022" >> /etc/skel/.bashrc
RUN echo "umask 022" >> /home/vscode/.bashrc

Nesta versão, a alteração chmod -R 775 /usr/local/cargo/registry é usada para aplicar as permissões recursivamente a todos os arquivos e subdiretórios dentro de /usr/local/cargo/registry. Isso deve garantir que o usuário vscode tenha acesso suficiente para instalar pacotes Cargo sem problemas de permissão.

Após fazer essas alterações e reconstruir a imagem, tente novamente instalar o cargo-watch como o usuário vscode. Isso deve resolver os problemas de permissão.

@gamife
Copy link

gamife commented May 22, 2024

Opened devcontainers/features#754

This PR is what I want.
Now I have an error using the cargo build command due to permission being denied. Perhaps it's because I used cargo to install some tools in the dockerfile before run rust feature script, so the gid in the registry directory is root

non-root@702362714ab7:~$ ls -l $CARGO_HOME
total 24
drwxrwxrwx 1 root root     4096 May 22 08:04 bin
-rwxr-xr-x 1 root rustlang  690 May 21 16:06 config.toml
-rw-rw-rw- 1 root root      308 May 14 03:57 env
drwxrwxr-x 1 root root     4096 May 22 08:04 registry

non-root@702362714ab7:~$ ls -l $RUSTUP_HOME
total 20
drwxrwxrwx 1 root root 4096 May 22 09:04 downloads
-rw-rw-rw- 1 root root  151 May 14 03:58 settings.toml
drwxrwxrwx 1 root root 4096 May 22 09:04 tmp
drwxrwxrwx 1 root root 4096 May 22 09:04 toolchains
drwxrwxrwx 1 root root 4096 May 22 09:04 update-hashes

Can this PR be merged?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependency-upgrade Tracks new image support or EOL
Projects
None yet
Development

No branches or pull requests

5 participants
@CodeMan99 @samruddhikhandale @gamife @GKMWD and others