When the python bindings are installed to a destdir with pip install
--prefix= --root=, pip tries to uninstall the existing root-owned
package and fails
Fixes:
running build_ext
python3 -m pip install --prefix=/usr `test -n "/tmp/selinux-release//build-master" && echo --root /tmp/selinux-release//build-master` .
Processing /tmp/selinux-release/selinux-master/libselinux/src
Preparing metadata (setup.py) ... done
Building wheels for collected packages: selinux
Building wheel for selinux (setup.py) ... done
Created wheel for selinux: filename=selinux-3.4-cp310-cp310-linux_x86_64.whl size=725511 sha256=b35e9cdb2a6efce389eeece45446826b4ac6b41f81fdc128893f947036f27e8e
Stored in directory: /tmp/pip-ephem-wheel-cache-kemjh99e/wheels/ca/2d/1e/d1ab52426d9add92931471cfa0d2558bcbeed89084af2388c9
Successfully built selinux
Installing collected packages: selinux
Attempting uninstall: selinux
Found existing installation: selinux 3.4
Uninstalling selinux-3.4:
ERROR: Could not install packages due to an OSError: [Errno 13] Permission denied: '__init__.cpython-310.pyc'
Consider using the `--user` option or check the permissions.
Signed-off-by: Jason Zaman <jason@perfinion.com>
Acked-by: Petr Lautrbach <lautrbach@redhat.com>
Fixes:
/usr/lib/python3.11/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
Signed-off-by: Petr Lautrbach <lautrbach@redhat.com>
Acked-by: James Carter <jwcart2@gmail.com>
Add return check for regex_data_create() to avoid NULL reference of regex_data
(gdb) bt
#0 0x00007fbde5caec14 in pthread_mutex_init () from /usr/lib64/libc.so.6
#1 0x00007fbde5e3a489 in regex_data_create () at regex.c:260
#2 0x00007fbde5e3a4af in regex_prepare_data (regex=regex@entry=0x7fbde4613770, pattern_string=pattern_string@entry=0x563c6799a820 "^/home$", errordata=errordata@entry=0x7ffeb83fa950) at regex.c:76
#3 0x00007fbde5e32fe6 in compile_regex (errbuf=0x0, spec=0x7fbde4613748) at label_file.h:407
#4 lookup_all (key=0x563c679974e5 "/var/log/kadmind.log", type=<optimized out>, partial=partial@entry=false, match_count=match_count@entry=0x0, rec=<optimized out>, rec=<optimized out>)
at label_file.c:949
#5 0x00007fbde5e33350 in lookup (rec=<optimized out>, key=<optimized out>, type=<optimized out>) at label_file.c:1092
#6 0x00007fbde5e31878 in selabel_lookup_common (rec=0x563c67998cc0, translating=1, key=<optimized out>, type=<optimized out>) at label.c:167
Signed-off-by: Jie Lu <lujie54@huawei.com>
Acked-by: James Carter <jwcart2@gmail.com>
Fixes:
/usr/lib/python3.11/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
Signed-off-by: Petr Lautrbach <lautrbach@redhat.com>
Acked-by: James Carter <jwcart2@gmail.com>
1. check the return of strdup to avoid a potential NULL reference.
2. make sure line_buf is freed.
Signed-off-by: Jie Lu <lujie54@huawei.com>
Acked-by: James Carter <jwcart2@gmail.com>
Boolean names, taken by security_get_boolean_pending(3),
security_get_boolean_active(3) and security_set_boolean(3), as well as
user names, taken by security_get_initial_context(3), are used in path
constructions. Ensure they do not contain path separators to avoid
unwanted path traversal.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Bail out if computed paths based on user input are being truncated, to
avoid wrong files to be opened.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Using strndup(3) instead of malloc(3) followed by strncpy(3) simplifies
the code and pleases GCC:
In file included from /usr/include/string.h:535,
from context.c:2:
In function ‘strncpy’,
inlined from ‘context_new’ at context.c:74:3:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:95:10: error: ‘__builtin_strncpy’ destination unchanged after copying no bytes [-Werror=stringop-truncation]
95 | return __builtin___strncpy_chk (__dest, __src, __len,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
96 | __glibc_objsize (__dest));
| ~~~~~~~~~~~~~~~~~~~~~~~~~
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
The internal variable avc_netlink_trouble is only assigned but never
read from.
Unused since the initial commit 13cd4c8960 ("initial import from svn
trunk revision 2950").
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Use strdup(3)/strndup(3) instead of allocating memory and then manually
copying the content.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
selinux_check_access relies on string_to_security_class to resolve the
class index from its char* argument. There is no input validation done
on the string provided. It is possible to supply an argument containing
trailing backslashes (i.e., "sock_file//////") so that the paths built
in discover_class get truncated. The processing will then reference the
same permission file multiple time (e.g., perms/watch_reads will be
truncated to perms/watch). This will leak the memory allocated when
strdup'ing the permission name. The discover_class_cache will end up in
an invalid state (but not corrupted).
Ensure that the class provided does not contain any path separator.
Signed-off-by: Thiébaud Weksteen <tweek@google.com>
Acked-by: James Carter <jwcart2@gmail.com>
Currently "-i" only ignores a file whose parent directory exists. Start also
ignoring paths with missing components.
Fixes:
# restorecon -i -v -R /var/log/missingdir/missingfile; echo $?
255
restorecon: SELinux: Could not get canonical path for /var/log/missingdir/missingfile restorecon: No such file or directory.
Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
Acked-by: James Carter <jwcart2@gmail.com>
The distutils package is deprecated and scheduled to be removed in
Python 3.12. Use the setuptools and sysconfig modules instead.
Signed-off-by: James Carter <jwcart2@gmail.com>
Acked-by: Petr Lautrbach <plautrba@redhat.com>
Support passing an optional object name to compute_create for name
based type transitions.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Test .gitignore and make clean distclean
error: missing .gitignore entry for libselinux/src/selinux.egg-info/
error: missing .gitignore entry for python/sepolicy/sepolicy.egg-info/
Error: Process completed with exit code 1.
error: "make clean distclean" did not remove libselinux/src/selinux.egg-info/PKG-INFO
error: "make clean distclean" did not remove libselinux/src/selinux.egg-info/SOURCES.txt
error: "make clean distclean" did not remove libselinux/src/selinux.egg-info/dependency_links.txt
error: "make clean distclean" did not remove libselinux/src/selinux.egg-info/top_level.txt
error: "make clean distclean" did not remove python/sepolicy/sepolicy.egg-info/PKG-INFO
error: "make clean distclean" did not remove python/sepolicy/sepolicy.egg-info/SOURCES.txt
error: "make clean distclean" did not remove python/sepolicy/sepolicy.egg-info/dependency_links.txt
error: "make clean distclean" did not remove python/sepolicy/sepolicy.egg-info/top_level.txt
Error: Process completed with exit code 1.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
When the O_PATH emulation fails due to getxattr(2)/setxattr(2) failing
with ENOENT, e.g. because no procfs being available, override the errno
value to EBADF. This avoids confusion to the caller as it would suggest
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@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
The variable `curcon` is NULL in case the file has no current security
context. Most C standard libraries handle it fine, avoid it nonetheless
for standard conformance.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
security_load_policy(3) takes a read-only memory address for a binary
policy to be loaded.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
The following interfaces are documented but do not have a redirection:
- context_str(3)
- security_get_checkreqprot(3)
- security_set_boolean_list(3)
- selinux_sepgsql_context_path(3)
- setexecfilecon(3)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
To copy string safely, by always NULL-terminating them, and provide an
easy way to check for truncation introduce the nonstandard function
strlcpy(3). Use the system implementation if available.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
In case the function __policy_init() gets called with a NULL pointer,
the stack variable path remains uninitialized (except at its last
index). If parsing the binary policy fails in sepol_policydb_read() the
error branch would access those uninitialized memory.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
libselinux implements a cache mechanism for get*con() functions, such
that when a thread calls setcon(...) then getcon(...), the context is
directly returned. Unfortunately, getpidcon(pid, &context) uses the same
cached variable, so when a program uses setcon("something"), all later
calls to getpidcon(pid, ...) returns "something". This is a bug.
Here is a program which illustrates this bug:
#include <stdio.h>
#include <selinux/selinux.h>
int main() {
char *context = "";
if (getpidcon(1, &context) < 0) {
perror("getpidcon(1)");
}
printf("getpidcon(1) = %s\n", context);
if (getcon(&context) < 0) {
perror("getcon()");
}
printf("getcon() = %s\n", context);
if (setcon(context) < 0) {
perror("setcon()");
}
if (getpidcon(1, &context) < 0) {
perror("getpidcon(1)");
}
printf("getpidcon(1) = %s\n", context);
return 0;
}
On an Arch Linux system using unconfined user, this program displays:
getpidcon(1) = system_u:system_r:init_t
getcon() = unconfined_u:unconfined_r:unconfined_t
getpidcon(1) = unconfined_u:unconfined_r:unconfined_t
With this commit, this program displays:
getpidcon(1) = system_u:system_r:init_t
getcon() = unconfined_u:unconfined_r:unconfined_t
getpidcon(1) = system_u:system_r:init_t
This bug was present in the first commit of
https://github.com/SELinuxProject/selinux git history. It was reported
in https://lore.kernel.org/selinux/20220121084012.GS7643@suse.com/ and a
patch to fix it was sent in
https://patchwork.kernel.org/project/selinux/patch/20220127130741.31940-1-jsegitz@suse.de/
without a clear explanation. This patch added pid checks, which made
sense but were difficult to read. Instead, it is possible to change the
way the functions are called so that they directly know which cache
variable to use.
Moreover, as the code is not clear at all (I spent too much time trying
to understand what the switch did and what the thread-local variable
contained), this commit also reworks libselinux/src/procattr.c to:
- not use hard-to-understand switch/case constructions on strings (they
are replaced by a new argument filled by macros)
- remove getpidattr_def macro (it was only used once, for pidcon, and
the code is clearer with one less macro)
- remove the pid parameter of setprocattrcon() and setprocattrcon_raw()
(it is always zero)
Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
Cc: Johannes Segitz <jsegitz@suse.de>
This reverts commit 7e979b56fd.
The reverted commit broke `setfiles` when it's run from a chroot
without /proc mounted, e.g.
# chroot /mnt/sysimage
chroot# setfiles -e /proc -e /sys /sys /etc/selinux/targeted/contexts/files/file_contexts /
[strace]
openat(AT_FDCWD, "/", O_RDONLY|O_EXCL|O_NOFOLLOW|O_PATH) = 3
newfstatat(3, "", {st_mode=S_IFDIR|0555, st_size=4096, ...}, AT_EMPTY_PATH) = 0
mmap(NULL, 2101248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1697c91000
fgetxattr(3, "security.selinux", 0x55be8881d3f0, 255) = -1 EBADF (Bad file descriptor)
fcntl(3, F_GETFL) = 0x220000 (flags O_RDONLY|O_NOFOLLOW|O_PATH)
getxattr("/proc/self/fd/3", "security.selinux", 0x55be8881d3f0, 255) = -1 ENOENT (No such file or directory)
[/strace]
setfiles: Could not set context for /: No such file or directory
Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
Acked-by: James Carter <jwcart2@gmail.com>
context_str(3) returns a string representation of the given context.
This string is owned by the context and free'd on context_free(3).
Declare it const, as already done in the man page, since it must not be
free'd by the caller.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: Nicolas Iooss <nicolas.iooss@m4x.org>
The family of setfilecon(3) functions take the context as a read-only
`const char *` parameter.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Print error description on failure after functions known to set errno.
Also mention the library function name in getenforce, policyvers and
setenforce instead of the program name twice.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
selinux_log() is used in many error branches, where the caller might
expect errno to bet set, e.g. label_file.c::lookup_all():
if (match_count) {
*match_count = 0;
result = calloc(data->nspec, sizeof(struct spec*));
} else {
result = calloc(1, sizeof(struct spec*));
}
if (!result) {
selinux_log(SELINUX_ERROR, "Failed to allocate %zu bytes of data\n",
data->nspec * sizeof(struct spec*));
goto finish;
}
Preserve errno in the macro wrapper itself, also preventing accidental
errno modifications in client specified SELINUX_CB_LOG callbacks.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
In case the allocation for the filename fails, free the memory of the context.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Pin the file to operate on in restorecon_sb() to prevent symlink attacks
in between the label database lookup, the current context query and the
final context write. Also don't use the file information from
fts_read(3), which might also be out of sync.
Due to querying file information twice, one in fts_read(3) needed for
the cross device check and one on the pinned file descriptor for the
database lookup, there is a slight slowdown:
[current]
Time (mean ± σ): 14.456 s ± 0.306 s [User: 45.863 s, System: 4.463 s]
Range (min … max): 14.275 s … 15.294 s 10 runs
[changed]
Time (mean ± σ): 15.843 s ± 0.045 s [User: 46.274 s, System: 9.495 s]
Range (min … max): 15.787 s … 15.916 s 10 runs
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
selabel_lookup_raw(3) can fail for other reasons than no corresponding
context found, e.g. ENOMEM or EINVAL for invalid key or type.
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
* mark read-only parameters const
* check for overflow when adding exclude directory
* use 64 bit integer for file counting
* avoid implicit conversions
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Operating on a file descriptor avoids TOCTOU issues and one opened via
O_PATH avoids the requirement of having read access to the file. Since
Linux does not natively support file descriptors opened via O_PATH in
fgetxattr(2) and at least glibc and musl does not emulate O_PATH support
in their implementations, fgetfilecon(3) and fsetfilecon(3) also do not
currently support file descriptors opened with O_PATH.
Inspired by CVE-2013-4392: https://github.com/systemd/systemd/pull/8583
Implementation adapted from: 2825f10b7f%5E%21/
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Acked-by: James Carter <jwcart2@gmail.com>
Currently, if the SELINUX_RESTORECON_ABORT_ON_ERROR flag is clear, then
selinux_restorecon[_parallel]() does not abort the file tree walk upon an
error, but the function itself fails the same, with the same (-1) return
value. This in turn is reported by the setfiles(8) utility to its parent
process with the same exit code (255).
In libguestfs we want to proceed after setfiles(8) fails *at most* with
such errors that occur during the file tree walk. We need setfiles(8) to
exit with a distinct exit status in that situation.
For this, introduce the SELINUX_RESTORECON_COUNT_ERRORS flag, and the
corresponding selinux_restorecon_get_skipped_errors() function, for
selinux_restorecon[_parallel]() to count, but otherwise ignore, errors
during the file tree walk. When no other kind of error occurs, the
relabeling functions will return zero, and the caller can fetch the number
of errors ignored during the file tree walk with
selinux_restorecon_get_skipped_errors().
Importantly, when at least one such error is skipped, we don't write
partial match digests for subdirectories, as any masked error means that
any subdirectory may not have been completely relabeled.
Cc: "Richard W.M. Jones" <rjones@redhat.com>
Cc: Petr Lautrbach <plautrba@redhat.com>
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1794518
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
The internal Sha1Update() functions only handles buffers up to a size of
UINT32_MAX, due to its usage of the type uint32_t. This causes issues
when processing more than UINT32_MAX bytes, e.g. with a specfile larger
than 4G. 0aa974a4 ("libselinux: limit has buffer size") tried to
address this issue, but failed since the overflow check
if (digest->hashbuf_size + buf_len < digest->hashbuf_size) {
will be done in the widest common type, which is size_t, the type of
`buf_len`.
Revert the type of `hashbuf_size` to size_t and instead process the data
in blocks of supported size.
Acked-by: James Carter <jwcart2@gmail.com>
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Reverts: 0aa974a4 ("libselinux: limit has buffer size")
If selabel_open(3) fails, e.g. when a specfile has the wrong file
permissions, free the memory allocated for digests.
Fixes: e40bbea9 ("libselinux: Add selabel_digest function")
Acked-by: James Carter <jwcart2@gmail.com>
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
selabel_open(3) takes an `unsigned int` as backend parameter.
Acked-by: James Carter <jwcart2@gmail.com>
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
The `struct selabel_digest` member `hashbuf_size` is used to compute
hashes via `Sha1Update()`, which takes uint32_t as length parameter
type. Use that same type for `hashbuf_size` to avoid potential value
truncations, as the overflow check in `digest_add_specfile()` on
`hashbuf_size` is based on it.
label_support.c: In function ‘digest_gen_hash’:
label_support.c:125:53: warning: conversion from ‘size_t’ {aka ‘long unsigned int’} to ‘uint32_t’ {aka ‘unsigned int’} may change value [-Wconversion]
125 | Sha1Update(&context, digest->hashbuf, digest->hashbuf_size);
| ~~~~~~^~~~~~~~~~~~~~
Acked-by: James Carter <jwcart2@gmail.com>
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
Return more detailed error messages when the supplied contexts are
invalid.
Acked-by: James Carter <jwcart2@gmail.com>
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>