selinux/libselinux
Nicolas Iooss c8ba7968b3 libselinux: do not return the cached prev_current value when using getpidcon()
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>
2022-06-06 16:16:17 -04:00
..
include libselinux: declare return value of context_str(3) const 2022-06-02 08:29:01 -04:00
man libselinux: update man page of setfilecon(3) family about context parameter 2022-05-17 13:52:31 +02:00
src libselinux: do not return the cached prev_current value when using getpidcon() 2022-06-06 16:16:17 -04:00
utils libselinux/utils: print errno on failure 2022-05-16 10:31:15 -04:00
LICENSE initial import from svn trunk revision 2950 2008-08-19 15:30:36 -04:00
Makefile libselinux: use PCRE2 by default 2021-12-09 11:07:00 -05:00
VERSION Update VERSIONs to 3.4 for release. 2022-05-18 16:51:03 +02:00