From 8ced2eeb03f10c83e749e625f189e02228cd493b Mon Sep 17 00:00:00 2001 From: Kui Li Date: Wed, 19 Jun 2024 09:08:39 +0800 Subject: [PATCH] fix file executable permissions check error on macos in docker container On macOS Sonoma v14.5, it was discovered that when using avocado in a Docker container to run scripts without execute permissions, they are considered to have executable permissions. By directly reading the file's permission bits, the stat method can provide more accurate permission check results, especially in cases where user context and file system characteristics might affect the behavior of os.access. This method is closer to the underlying implementation of the file system, thus providing consistent results across different environments (such as inside and outside Docker containers). After entering the container using docker exec -it container bash, use the stat command to check the file permission bits. Reference: #5945 Signed-off-by: Kui Li --- avocado/core/resolver.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/avocado/core/resolver.py b/avocado/core/resolver.py index 681d5b890c..0accae1218 100644 --- a/avocado/core/resolver.py +++ b/avocado/core/resolver.py @@ -18,6 +18,7 @@ import glob import os +import stat from enum import Enum from avocado.core.enabled_extension_manager import EnabledExtensionManager @@ -196,11 +197,32 @@ def check_file( info=f'File "{path}" does not exist or is not a {type_name}', ) - if not os.access(path, access_check): + st = os.stat(path) + + user_permissions = st.st_mode & (stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR) + + # Initialize required permissions to 0, indicating no permissions are needed yet + required_permissions = 0 + + # Build the required permissions based on access_check + if access_check & os.R_OK: + # If read access needs to be checked, set the corresponding user read permission bit + required_permissions |= stat.S_IRUSR + if access_check & os.W_OK: + # If write access needs to be checked, set the corresponding user write permission bit + required_permissions |= stat.S_IWUSR + if access_check & os.X_OK: + # If execute access needs to be checked, set the corresponding user execute permission bit + required_permissions |= stat.S_IXUSR + + # Check if the user has the required permissions + if (user_permissions & required_permissions) != required_permissions: + # If the bitwise AND of user permissions and required permissions is not equal to required permissions, + # it means the user is missing some permissions return ReferenceResolution( reference, ReferenceResolutionResult.NOTFOUND, - info=f'File "{path}" does not exist or is not {access_name}', + info=f'File "{path}" does not have the required {access_name} permissions', ) return True