If you're fiddling with SELinux policies, you will eventually notice that the reference policy by default hides certain privilege requests (which are denied). One of them is noatsecure. But what is noatsecure? To describe noatsecure, I first need to describe what atsecure is. And to describe what that is, we first need to give a small talk about ELF auxiliary vectors.
As you probably know, when an application instantiates another
application, it calls the execve
function right after fork'ing to load
the new application in memory. The actual task to load the new
application in memory is done by the C library, more specifically the
binary loader. For Linux, this is the ELF loader. Now, ELF auxiliary
vectors are parameters or flags that are set (or at least managed) by
the ELF loader to allow the application and program interpreter to get
some OS-specific information. Examples of such vectors are AT_UID
and
AT_EUID
(real uid and effective uid) and AT_PAGESZ
(system page
size).
One of the vectors that glibc supports is AT_SECURE
. This particular
parameter (which is either "0" (default) or "1") tells the ELF dynamic
linker to unset various environment
variables
that are considered potentially harmful for your system. One of these is
LD_PRELOAD
(I mention this one specifically because it was the source
of my small investigation). Normally, this environment sanitation is
done when a setuid/setgid application is called (to prevent the obvious
vulnerabilities). However, SELinux enhances the use of this
sanitation...
Whenever an application is called which triggers a domain transition in
SELinux (say sysadm_t
to mozilla_t
through a binary labelled
mozilla_exec_t
), SELinux sets the AT_SECURE
flag for the loaded
application (in the example, mozilla/firefox). In other words, every
time a domain transition occurs, the environment for this application is
sanitized.
As you can imagine now the noatsecure
permission disables the
environment sanitation activity for a particular transition. You can do
this through the following allow statement (applied to the above
example):
allow sysadm_t mozilla_t:process { noatsecure };
if every domain transition for which this permission isn't allowed would
log its denial, our audit logs would be filled with noise. That is why
the reference policy by default hides (dontaudit
) these calls. But
knowing what they are for is important, because you might sometimes come
into contact with it, like I did:
>>> Installing (1 of 1) net-dns/host-991529
>>> Setting SELinux security labels
ERROR: ld.so: object 'libsandbox.so' from LD_PRELOAD cannot be preloaded: ignored.
This error message is when Portage (running in portage_t
) wants to
relabel the files that it just placed on the system through setfiles
(which will run in setfiles_t
). As this involves a domain transition,
AT_SECURE
is set for setfiles, but LD_PRELOAD
was set as part of
Portage' sandboxing feature. This environment variable is disabled, and
the loader warns the user that it cannot preload libsandbox.so
.
Although we can just set noatsecure here, it would open up a (small) window for exploits (although they would need to be provided through Portage, because when a user calls Portage, a domain transition is done there as well so the user-provided environment variables are already sanitized by then). By not allowing noatsecure, we are disabling a few functionalities provided by the libsandbox.so library for the file labeling activity (this is very important to understand: it does not disable the sandboxing for the builds and merges, only for the file relabeling). As we already run setfiles in its own, confined domain, I believe that we are best served by keeping the secure environment sanitation here. That does mean that the warning will stay as we cannot control that from within SELinux.
If you want to allow noatsecure here, create a simple module and load it:
~# cat > portage_noatsecure.te << EOF
module portage_noatsecure 1.0;
require {
type portage_t;
type setfiles_t;
class process { noatsecure };
}
allow portage_t setfiles_t:process { noatsecure };
EOF
~# checkmodule -m -o portage_noatsecure.mod portage_noatsecure.te
~# semodule_package -o portage_noatsecure.pp -m portage_noatsecure.mod
~# semodule -i portage_noatsecure.pp