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

Fix Dockerfile to create Images with no git safe directory restrictions (IDFGH-11511) #12636

Closed
wants to merge 3 commits into from

Conversation

timoxd7
Copy link
Contributor

@timoxd7 timoxd7 commented Nov 21, 2023

Problem

If a folder is mounted to the docker container that is not owned by the running user, git disallows the direct access without explicit set of a safe directory. This can happen for example if using wsl on Windows while using a repository on the Windows Filesystem.

Fix

Just set every folder as safe for git, as this implies no security risk in a docker container, solving the issue to not be able to access certain git repositories.

Reference

The github action for ESP-IDF Builds solved this by adding the command before running the actual action command (See espressif/esp-idf-ci-action#27)

Backport

We use ESP-IDF v5.1.x, so a backport would be great.

@CLAassistant
Copy link

CLAassistant commented Nov 21, 2023

CLA assistant check
All committers have signed the CLA.

Copy link

github-actions bot commented Nov 21, 2023

Messages
📖 You might consider squashing your 3 commits (simplifying branch history).

👋 Welcome timoxd7, thank you for your first contribution to espressif/esp-idf project!

📘 Please check Contributions Guide for the contribution checklist, information regarding code and documentation style, testing and other topics.

🖊️ Please also make sure you have read and signed the Contributor License Agreement for espressif/esp-idf project.

Pull request review and merge process you can expect

Espressif develops the ESP-IDF project in an internal repository (Gitlab). We do welcome contributions in the form of bug reports, feature requests and pull requests via this public GitHub repository.

  1. An internal issue has been created for the PR, we assign it to the relevant engineer
  2. They review the PR and either approve it or ask you for changes or clarifications
  3. Once the Github PR is approved, we synchronize it into our internal git repository
  4. In the internal git repository we do the final review, collect approvals from core owners and make sure all the automated tests are passing
    • At this point we may do some adjustments to the proposed change, or extend it by adding tests or documentation.
  5. If the change is approved and passes the tests it is merged into the master branch
  6. On next sync from the internal git repository merged change will appear in this public Github repository

🔁 You can re-run automatic PR checks by retrying the DangerJS action

Generated by 🚫 dangerJS against 0e61aa2

@espressif-bot espressif-bot added the Status: Opened Issue is new label Nov 21, 2023
@github-actions github-actions bot changed the title Fix Dockerfile to create Images with no git safe directory restrictions Fix Dockerfile to create Images with no git safe directory restrictions (IDFGH-11511) Nov 21, 2023
@igrr
Copy link
Member

igrr commented Nov 21, 2023

@timoxd7 could you please give an example of a docker run command and project structure which results in this issue?

@timoxd7
Copy link
Contributor Author

timoxd7 commented Nov 21, 2023

@igrr I updated the comment on the pull request as i had it wrongly in my mind, sorry for the confusion. The problem happens if the user inside the docker container does not match the one in the filesystem (.git parent folder). Might happen during WSL usage or in CI.

@timoxd7
Copy link
Contributor Author

timoxd7 commented Nov 21, 2023

@igrr Example Output:

$ docker run --rm -v "${PWD}":/project -w /project -it espressif/idf:latest
Detecting the Python interpreter
Checking "python3" ...
Python 3.10.12
"python3" has been detected
Checking Python compatibility
Checking other ESP-IDF version.
Adding ESP-IDF tools to PATH...
Checking if Python packages are up to date...
Requirement files:
 - /opt/esp/idf/tools/requirements/requirements.core.txt
Python being checked: /opt/esp/python_env/idf5.2_py3.10_env/bin/python
Python requirements are satisfied.
Added the following directories to PATH:
  /opt/esp/idf/components/espcoredump
  /opt/esp/idf/components/partition_table
  /opt/esp/idf/components/app_update
  /opt/esp/tools/xtensa-esp-elf-gdb/12.1_20221002/xtensa-esp-elf-gdb/bin
  /opt/esp/tools/riscv32-esp-elf-gdb/12.1_20221002/riscv32-esp-elf-gdb/bin
  /opt/esp/tools/xtensa-esp32-elf/esp-12.2.0_20230208/xtensa-esp32-elf/bin
  /opt/esp/tools/xtensa-esp32s2-elf/esp-12.2.0_20230208/xtensa-esp32s2-elf/bin
  /opt/esp/tools/xtensa-esp32s3-elf/esp-12.2.0_20230208/xtensa-esp32s3-elf/bin
  /opt/esp/tools/riscv32-esp-elf/esp-12.2.0_20230208/riscv32-esp-elf/bin
  /opt/esp/tools/esp32ulp-elf/2.35_20220830/esp32ulp-elf/bin
  /opt/esp/tools/cmake/3.24.0/bin
  /opt/esp/tools/openocd-esp32/v0.12.0-esp32-20230419/openocd-esp32/bin
  /opt/esp/python_env/idf5.2_py3.10_env/bin
  /opt/esp/idf/tools
Done! You can now compile ESP-IDF projects.
Go to the project directory and run:

  idf.py build

root@76277e23dee1:/project# git status
fatal: detected dubious ownership in repository at '/project'
To add an exception for this directory, call:

        git config --global --add safe.directory /project
root@76277e23dee1:/project#

@dobairoland
Copy link
Collaborator

Related to #12389

@dobairoland dobairoland requested a review from fhrbata November 21, 2023 12:51
@timoxd7
Copy link
Contributor Author

timoxd7 commented Nov 21, 2023

@dobairoland Thank you, haven't seen that it has been fixed a few lines below mine addition, but it only fixes the issue for the ESP-IDF repo itself, not for a project with a different owner. I will add a commit, removing the line down below, as it is obsolete if this pr would be merged.

However, i don't think configuring every folder inside the docker container as safe repository implies any security risks, as it is not on a local machine with other things going on, but only an isolated container. Also, everything going into the container is explicitly mounted, e.g. every repository brought into the container is already kind of "owned", making the safe directory redundant. What do you think about this?

@fhrbata
Copy link
Collaborator

fhrbata commented Nov 21, 2023

Hello @timoxd7 ,

first thank you for this contribution.

However, i don't think configuring every folder inside the docker container as safe repository implies any security risks, as it is not on a local machine with other things going on, but only an isolated container. Also, everything going into the container is explicitly mounted, e.g. every repository brought into the container is already kind of "owned", making the safe directory redundant. What do you think about this?

IIUC the safe.directory git config option was added by 8959555cee7ec045958f9b6dd62e541affb7e7d9 to address CVE-2022-24765.

I think that with this change we would make it possible to exploit this vulnerability again. For example user starting the container can bind mount some shared drive with plenty of git projects owned by different users. IMHO with safe.directory '*' it would be still possible to start an arbitrary command if someone created a rogue .git directory in some parent directory and set e.g. core.fsmonitor.

Thank you

@fhrbata
Copy link
Collaborator

fhrbata commented Nov 22, 2023

I would probably avoid setting safe.directory '*' by default in our image, but I guess we can make it conditional with some additional info in our docs about the possible security impact, so users can easily build their custom image with setting. Thoughts?

@dobairoland
Copy link
Collaborator

Good idea @fhrbata. Perhaps a variable which defaults to IDF_PATH which could be overwritten to *. The official images won't change and we wouldn't even need to explain the * case because it won't be in our dockerfiles.

@timoxd7
Copy link
Contributor Author

timoxd7 commented Nov 22, 2023

@fhrbata You are right, i mainly had a CI/CD in mind, but users could still use it in private systems and other setups this could potentially be a problem as you stated out.

@dobairoland I had this kind of variable also in mind, which will not solve the problem if the official image is used. Maybe a documentation entry for the docker image would be great, informing the user to add the project's repository to the docker internal git safe directories.
A variable defaulting to IDF_PATH would also be good, but i would suggest to have a variable like IDF_GIT_SAFE_DIR that will add all listed additional dirs to git's safe directory list. With this, the IDF_PATH will always be a safe directory for git.

If you both agree, i could make a new pull request with this variable while closing this one.

@fhrbata
Copy link
Collaborator

fhrbata commented Nov 22, 2023

Hello @timoxd7 ,

thank you for the additional input!

@dobairoland I had this kind of variable also in mind, which will not solve the problem if the official image is used. Maybe a documentation entry for the docker image would be great, informing the user to add the project's repository to the docker internal git safe directories. A variable defaulting to IDF_PATH would also be good, but i would suggest to have a variable like IDF_GIT_SAFE_DIR that will add all listed additional dirs to git's safe directory list. With this, the IDF_PATH will always be a safe directory for git.

If you both agree, i could make a new pull request with this variable while closing this one.

This is just me thinking out loud, but maybe we can move setting the safe.directory into the entrypoint.sh, maybe based on an environmental variable passed to docker run. Or maybe passing it as argument to entrypoint via CMD. Meaning it would not be hardcoded in the image, but could be customized per container instance.

docker run --rm -v "${PWD}":/project -w /project -it -e IDF_GIT_SAFE_DIR=<dirs> espressif/idf:latest

and entrypoint.sh would set it. I haven't tested this yet, so it's possible that I'm completely missing something.

@fhrbata
Copy link
Collaborator

fhrbata commented Nov 22, 2023

Hello @timoxd7 , @dobairoland

do you see any problem with the following approach? I quickly tested it and it seems to be working.

Thank you

   diff --git a/tools/docker/entrypoint.sh b/tools/docker/entrypoint.sh                                                                 
index 7cf15f1917e1..513b3ba00d28 100755                                                                                              
--- a/tools/docker/entrypoint.sh                                                                                                     
+++ b/tools/docker/entrypoint.sh                                                                                                     
@@ -1,6 +1,20 @@                                                                                                                     
 #!/usr/bin/env bash                                                                                                                 
 set -e                                                                                                                              
                                                                                                                                     
+# IDF_GIT_SAFE_DIR has the same format as system PATH environment variable.                                                         
+# All path specified in IDF_GIT_SAFE_DIR will be added to user's                                                                    
+# global git config as safe.directory paths. For more information                                                                   
+# see git-config manual page.                                                                                                       
+if [ -n "${IDF_GIT_SAFE_DIR+x}" ]                                                                                                   
+then                                                                                                                                
+       echo "Adding following directories into git's safe.directory"                                                                
+       echo "$IDF_GIT_SAFE_DIR" | tr ':' '\n' | while read -r dir                                                                   
+       do                                                                                                                           
+               git config --global --add safe.directory "$dir"                                                                      
+               echo "  $dir"                                                                                                        
+       done                                                                                                                         
+fi                                                                                                                                  
+                                                                                                                                    
 . $IDF_PATH/export.sh                                                                                                               
                                                                                                                                     
 exec "$@"                                                                                                                           

usage
docker run -it --rm -v /home/fhrbata/tmp/hello_world:/project -w /project -e IDF_GIT_SAFE_DIR='/project' idf-custom
or
docker run -it --rm -v /home/fhrbata/tmp/hello_world:/project -w /project -e IDF_GIT_SAFE_DIR='*' idf-custom

@dobairoland
Copy link
Collaborator

@fhrbata LGTM

@espressif-bot espressif-bot added Status: Selected for Development Issue is selected for development Status: Reviewing Issue is being reviewed and removed Status: Opened Issue is new Status: Selected for Development Issue is selected for development labels Nov 23, 2023
@timoxd7
Copy link
Contributor Author

timoxd7 commented Nov 27, 2023

@fhrbata Looks good, if it is tested and works then i think it is the best solution. If it would be documented to be needed in the official documentation would make it perfect and easier to solve the versioning problem for someone first experiencing the problem.

@fhrbata
Copy link
Collaborator

fhrbata commented Nov 27, 2023

Hello @timoxd7 ,

thank you very much for your feedback.

@fhrbata Looks good, if it is tested and works then i think it is the best solution. If it would be documented to be needed in the official documentation would make it perfect and easier to solve the versioning problem for someone first experiencing the problem.

I've already created a MR for this and once it's approved and merged, it will be synced into the github. It also contains a note about this possibility in the Building a Project with CMake section.

When the mounted directory, /project, contains a git repository owned by a different user (UID) than the one running the Docker container, git commands executed within /project might fail, displaying an error message fatal: detected dubious ownership in repository at '/project'. To resolve this issue, you can designate the /project directory as safe by setting the IDF_GIT_SAFE_DIR environment variable during the docker container startup. For instance, you can achieve this by including -e IDF_GIT_SAFE_DIR='/project' as a parameter. Additionally, multiple directories can be specified by using a : separator. To entirely disable this git security check, * can be used.

Hopefully it will be useful.

Thank you

@espressif-bot espressif-bot added Status: Done Issue is done internally and removed Status: Reviewing Issue is being reviewed labels Dec 1, 2023
@espressif-bot espressif-bot added Resolution: NA Issue resolution is unavailable Resolution: Done Issue is done internally and removed Resolution: NA Issue resolution is unavailable labels Dec 1, 2023
espressif-bot pushed a commit that referenced this pull request Dec 2, 2023
With 8959555cee7e[1] ("setup_git_directory(): add an owner check for the top..")
git added an ownership check of the git directory and refuses to
run any git commands, even parsing the config file, if the git directory
is not owned by the current user. The "fatal: detected dubious ownership in repository"
is reported.

This fixes CVE-2022-24765[2], which allows to compromise user account. On a
multi-user system or e.g. on a shared file system, one user may create a "rogue"
git repository with e.g. core.fsmonitor set to an arbitrary command. Other user
may unwillingly execute this command by running e.g. git-diff or
git-status within the "rogue" git repository, which may be in one of the parent
directories. If e.g. PS1 is set to display information about a git
repository in CWD, as suggested in Git in Bash[3], the user do not need to run
any git command to trigger this, just entering some subdirectory under
this "rogue" git repository is enough, because the git command will be
started transparently through the script used in PS1. The core.fsmonitor
can be set to arbitrary command. It's purpose is to help git to identify changed files
and speed up the scanning for changed files.

rogue
├── .git     # owned by user1
└── dir1     # owned by user2
    ├── dir2 # owned by user2
    └── .git # owned by user2

user1 sets core.fsmonitor for git repository in rogue directory
$ git config --add core.fsmonitor "bash -c 'rm -rf \$HOME'"

user2 enters dir1 and runs e.g. git diff and triggers the core.fsmonitor command.

The ownership check may cause problems when running git commands in
ESP-IDF Docker container. For example user may run the container as
root, but the mounted project may be owned by a particular user.

In this case git will refuse to execute any git command within the
"/project" directory, because it's not owned by root. To overcome this,
git allows to set safe.directories, for which the ownership check is
skipped. The security check may be completely disabled by setting
safe.directories to "*". This solution was proposed in PR 12636[4], but
it would allow make it possible to exploit this vulnerability again.

This fix allows user to specify git's safe.directory in IDF_GIT_SAFE_DIR
environmental variable, which may be set during container startup.

The IDF_GIT_SAFE_DIR has same format as PATH and multiple directories can be
specified by using a ":" separator. To entirely disable this git security check
within the container, user may set IDF_GIT_SAFE_DIR='*'. This might be
heplfull in CI.

Closes #12636

[1] - git/git@8959555
[2] - https://nvd.nist.gov/vuln/detail/cve-2022-24765
[3] - https://git-scm.com/book/en/v2/Appendix-A%3A-Git-in-Other-Environments-Git-in-Bash
[4] - #12636

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
igrr pushed a commit that referenced this pull request Dec 6, 2023
With 8959555cee7e[1] ("setup_git_directory(): add an owner check for the top..")
git added an ownership check of the git directory and refuses to
run any git commands, even parsing the config file, if the git directory
is not owned by the current user. The "fatal: detected dubious ownership in repository"
is reported.

This fixes CVE-2022-24765[2], which allows to compromise user account. On a
multi-user system or e.g. on a shared file system, one user may create a "rogue"
git repository with e.g. core.fsmonitor set to an arbitrary command. Other user
may unwillingly execute this command by running e.g. git-diff or
git-status within the "rogue" git repository, which may be in one of the parent
directories. If e.g. PS1 is set to display information about a git
repository in CWD, as suggested in Git in Bash[3], the user do not need to run
any git command to trigger this, just entering some subdirectory under
this "rogue" git repository is enough, because the git command will be
started transparently through the script used in PS1. The core.fsmonitor
can be set to arbitrary command. It's purpose is to help git to identify changed files
and speed up the scanning for changed files.

rogue
├── .git     # owned by user1
└── dir1     # owned by user2
    ├── dir2 # owned by user2
    └── .git # owned by user2

user1 sets core.fsmonitor for git repository in rogue directory
$ git config --add core.fsmonitor "bash -c 'rm -rf \$HOME'"

user2 enters dir1 and runs e.g. git diff and triggers the core.fsmonitor command.

The ownership check may cause problems when running git commands in
ESP-IDF Docker container. For example user may run the container as
root, but the mounted project may be owned by a particular user.

In this case git will refuse to execute any git command within the
"/project" directory, because it's not owned by root. To overcome this,
git allows to set safe.directories, for which the ownership check is
skipped. The security check may be completely disabled by setting
safe.directories to "*". This solution was proposed in PR 12636[4], but
it would allow make it possible to exploit this vulnerability again.

This fix allows user to specify git's safe.directory in IDF_GIT_SAFE_DIR
environmental variable, which may be set during container startup.

The IDF_GIT_SAFE_DIR has same format as PATH and multiple directories can be
specified by using a ":" separator. To entirely disable this git security check
within the container, user may set IDF_GIT_SAFE_DIR='*'. This might be
heplfull in CI.

Closes #12636

[1] - git/git@8959555
[2] - https://nvd.nist.gov/vuln/detail/cve-2022-24765
[3] - https://git-scm.com/book/en/v2/Appendix-A%3A-Git-in-Other-Environments-Git-in-Bash
[4] - #12636

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
espressif-bot pushed a commit that referenced this pull request Dec 20, 2023
With 8959555cee7e[1] ("setup_git_directory(): add an owner check for the top..")
git added an ownership check of the git directory and refuses to
run any git commands, even parsing the config file, if the git directory
is not owned by the current user. The "fatal: detected dubious ownership in repository"
is reported.

This fixes CVE-2022-24765[2], which allows to compromise user account. On a
multi-user system or e.g. on a shared file system, one user may create a "rogue"
git repository with e.g. core.fsmonitor set to an arbitrary command. Other user
may unwillingly execute this command by running e.g. git-diff or
git-status within the "rogue" git repository, which may be in one of the parent
directories. If e.g. PS1 is set to display information about a git
repository in CWD, as suggested in Git in Bash[3], the user do not need to run
any git command to trigger this, just entering some subdirectory under
this "rogue" git repository is enough, because the git command will be
started transparently through the script used in PS1. The core.fsmonitor
can be set to arbitrary command. It's purpose is to help git to identify changed files
and speed up the scanning for changed files.

rogue
├── .git     # owned by user1
└── dir1     # owned by user2
    ├── dir2 # owned by user2
    └── .git # owned by user2

user1 sets core.fsmonitor for git repository in rogue directory
$ git config --add core.fsmonitor "bash -c 'rm -rf \$HOME'"

user2 enters dir1 and runs e.g. git diff and triggers the core.fsmonitor command.

The ownership check may cause problems when running git commands in
ESP-IDF Docker container. For example user may run the container as
root, but the mounted project may be owned by a particular user.

In this case git will refuse to execute any git command within the
"/project" directory, because it's not owned by root. To overcome this,
git allows to set safe.directories, for which the ownership check is
skipped. The security check may be completely disabled by setting
safe.directories to "*". This solution was proposed in PR 12636[4], but
it would allow make it possible to exploit this vulnerability again.

This fix allows user to specify git's safe.directory in IDF_GIT_SAFE_DIR
environmental variable, which may be set during container startup.

The IDF_GIT_SAFE_DIR has same format as PATH and multiple directories can be
specified by using a ":" separator. To entirely disable this git security check
within the container, user may set IDF_GIT_SAFE_DIR='*'. This might be
heplfull in CI.

Closes #12636

[1] - git/git@8959555
[2] - https://nvd.nist.gov/vuln/detail/cve-2022-24765
[3] - https://git-scm.com/book/en/v2/Appendix-A%3A-Git-in-Other-Environments-Git-in-Bash
[4] - #12636

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants