Skip to content

[bug] conan will remove execute permission in rootless containers #18337

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

Open
gabeblack opened this issue May 21, 2025 · 3 comments
Open

[bug] conan will remove execute permission in rootless containers #18337

gabeblack opened this issue May 21, 2025 · 3 comments

Comments

@gabeblack
Copy link
Contributor

Describe the bug

The industry is moving towards rootless containers. However, when running in a rootless container, the user/group presented to the user is "root", but it really isn't "root" under-the-hood. The prompt may indicate root and whoami may say you are root, but the subid/subgid host mapping will map to the normal user running the rootless container.

We use build containers to keep our build environment consistent. However, when moving to a "rootless" container, all the binaries that conan installs withing the rootless container (i.e. after running conan install) have their execute bit removed. I have verified that the execute-bit is indeed set in the conan_package.tgz -- so conan is changing it. I've manually extracted the conan_package.tgz in //d/conan_package.tgz using tar -xvf just in case there was something going on with the container or the volume housing the conan packages and the execute bit remains.

I've read the docs and I don't see a way to tell conan install to not muck with the permissions of the package. Is there a workaround/way to have conan not mess with the permissions in the case of running in a rootless container?

$ conan --version
Conan version 2.16.1

How to reproduce it

No response

@memsharded
Copy link
Member

Hi @gabeblack

Thanks for your feedback.

I am not sure where Conan would be doing this. The code to uncompress the conan_package.tgz is pretty simple:

def uncompress_file(src_path, dest_folder, scope=None):
    try:
        filesize = os.path.getsize(src_path)
        big_file = filesize > 10000000  # 10 MB
        if big_file:
            hs = human_size(filesize)
            ConanOutput(scope=scope).info(f"Decompressing {hs} {os.path.basename(src_path)}")
        with open(src_path, mode='rb') as file_handler:
            tar_extract(file_handler, dest_folder)

Which calls:

def tar_extract(fileobj, destination_dir):
    the_tar = tarfile.open(fileobj=fileobj)
    # NOTE: The errorlevel=2 has been removed because it was failing in Win10, it didn't allow to
    # "could not change modification time", with time=0
    # the_tar.errorlevel = 2  # raise exception if any error
    the_tar.extraction_filter = (lambda member, path: member)  # fully_trusted, avoid Py3.14 break
    the_tar.extractall(path=destination_dir)
    the_tar.close()

So it is not that Conan is removing any permissions from things packaged inside the conan_package.tgz

@gabeblack
Copy link
Contributor Author

gabeblack commented May 21, 2025

Thanks for the quick response. I created a test.py file with the same code as tar_extract:

import tarfile

tar = tarfile.open('conan_package.tgz')
tar.extraction_filter = (lambda member, path: member)
tar.extractall(path='out')
tar.close()

Python version: 3.9.21

Within rootless container:

  • Above script causes execute permissions to be removed.
  • Running tar -xvf conan_package.tgz in the same 'out' folder keeps the execute permissions!

Outside the container (same version of python):

  • Above script preserves execute permissions
  • Running above script as root user also keeps execute permissions
  • Running tar -xvf conan_package.tgz keeps permissions

The conan_package.tgz was created with user permissions (not within a rootless container). Therefore, it doesn't have root:root permissions. This made me wonder if that had something to do with it, so I repackaged the conan_package.tgz with root:root permissions, and lo and behold, the extraction script didn't change the execute permissions when running in a rootless container!

Conclusion: conan packages must have ownership root:root to work properly in a rootless container

I guess this will eventually resolve itself when we rebuild all our conan packages in a rootless container and thus all the conan_package.tgz will contain files with root:root permissions rather than the jenkins:build permissions.

I wonder though, when building the packages from the recipes (as a normal user), is there a way to package it up as root:root instead of the normal user? It seems that that is required in order to have a package that will work properly in rootless containers....

Aside -- I don't know what is different about python's tarfile package that makes it behave differently than the tar command line, but it seems that conan is indirectly affected by its behavior.

@memsharded
Copy link
Member

Thanks for the feedback.

Python recently changed some behavior regarding the extraction of tarfiles, see for example https://discuss.python.org/t/policies-for-tarfile-extractall-a-k-a-fixing-cve-2007-4559/23149

The default will be 'warn' in Python 3.12-3.13, and change to 'data' in Python 3.14.

This is why Conan recently added:

the_tar.extraction_filter = (lambda member, path: member)  # fully_trusted, avoid Py3.14 break

the extraction_filter definition to allow moving to Python 3.13 and 3.14 without warnings and breakages.

The "data" filter in tarfile in https://docs.python.org/3/library/tarfile.html#tarfile.data_filter

For regular files, including hard links:

Set the owner read and write permissions (S_IRUSR | S_IWUSR).

Remove the group & other executable permission (S_IXGRP | S_IXOTH) if the owner doesn’t have it (S_IXUSR).

Though apparently this shouldn't be the default behavior, I think that Python 3.9 should still behave the same, but maybe it is worth to do a quick check with latest Python

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

No branches or pull requests

2 participants