When the O_PATH emulation fails override the errno value to EBADF instead of retaining the one from getxattr(2)/setxattr(2). For example in the case of no procfs being mounted, e.g. inside of a chroot, getxattr(2)/setxattr(2) fail with ENOENT. This is confusing to the caller as it seems the target of the operation does not exist, which is not the case: setfiles: Could not set context for /: No such file or directory Fixes: a782abf2 ("libselinux: emulate O_PATH support in fgetfilecon/fsetfilecon") Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx> --- libselinux/src/fgetfilecon.c | 8 +++++--- libselinux/src/fsetfilecon.c | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/libselinux/src/fgetfilecon.c b/libselinux/src/fgetfilecon.c index baf38ec1..4c440df3 100644 --- a/libselinux/src/fgetfilecon.c +++ b/libselinux/src/fgetfilecon.c @@ -10,7 +10,7 @@ static ssize_t fgetxattr_wrapper(int fd, const char *name, void *value, size_t size) { char buf[40]; - int fd_flag, saved_errno = errno; + int fd_flag; ssize_t ret; ret = fgetxattr(fd, name, value, size); @@ -25,8 +25,10 @@ static ssize_t fgetxattr_wrapper(int fd, const char *name, void *value, size_t s } snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd); - errno = saved_errno; - return getxattr(buf, name, value, size); + ret = getxattr(buf, name, value, size); + if (ret < 0) + errno = EBADF; + return ret; } int fgetfilecon_raw(int fd, char ** context) diff --git a/libselinux/src/fsetfilecon.c b/libselinux/src/fsetfilecon.c index be821c7a..374dc627 100644 --- a/libselinux/src/fsetfilecon.c +++ b/libselinux/src/fsetfilecon.c @@ -10,7 +10,7 @@ static int fsetxattr_wrapper(int fd, const char* name, const void* value, size_t size, int flags) { char buf[40]; - int rc, fd_flag, saved_errno = errno; + int rc, fd_flag; rc = fsetxattr(fd, name, value, size, flags); if (rc == 0 || errno != EBADF) @@ -24,8 +24,10 @@ static int fsetxattr_wrapper(int fd, const char* name, const void* value, size_t } snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd); - errno = saved_errno; - return setxattr(buf, name, value, size, flags); + rc = setxattr(buf, name, value, size, flags); + if (rc < 0) + errno = EBADF; + return rc; } int fsetfilecon_raw(int fd, const char * context) -- 2.36.1