From 23c7e1b6bd1dca3c94691a321c209b9b02b323f1 Mon Sep 17 00:00:00 2001 From: Petr Lautrbach Date: Tue, 31 May 2022 16:25:00 +0200 Subject: [PATCH] libselinux-3.4-3 - Revert "libselinux: restorecon: pin file to avoid TOCTOU issues" --- ...x-restorecon-pin-file-to-avoid-TOCTO.patch | 170 ++++++++++++++++++ libselinux.spec | 6 +- 2 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 0002-Revert-libselinux-restorecon-pin-file-to-avoid-TOCTO.patch diff --git a/0002-Revert-libselinux-restorecon-pin-file-to-avoid-TOCTO.patch b/0002-Revert-libselinux-restorecon-pin-file-to-avoid-TOCTO.patch new file mode 100644 index 0000000..9e9568e --- /dev/null +++ b/0002-Revert-libselinux-restorecon-pin-file-to-avoid-TOCTO.patch @@ -0,0 +1,170 @@ +From 35b6ca70efca88e849e27a5c5524394da5f47693 Mon Sep 17 00:00:00 2001 +From: Petr Lautrbach +Date: Tue, 31 May 2022 13:37:12 +0200 +Subject: [PATCH] Revert "libselinux: restorecon: pin file to avoid TOCTOU + issues" +Content-type: text/plain + +This reverts commit 7e979b56fd2cee28f647376a7233d2ac2d12ca50. + +The reverted commit broke `setfiles` when it was run from a chroot +without /proc mounted, e.g. + + # 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 +--- + libselinux/src/selinux_restorecon.c | 43 ++++++++++++----------------- + 1 file changed, 18 insertions(+), 25 deletions(-) + +diff --git a/libselinux/src/selinux_restorecon.c b/libselinux/src/selinux_restorecon.c +index dc222b425c95..a50005353265 100644 +--- a/libselinux/src/selinux_restorecon.c ++++ b/libselinux/src/selinux_restorecon.c +@@ -623,13 +623,13 @@ out: + return rc; + } + +-static int restorecon_sb(const char *pathname, struct rest_flags *flags, bool first) ++static int restorecon_sb(const char *pathname, const struct stat *sb, ++ struct rest_flags *flags, bool first) + { + char *newcon = NULL; + char *curcon = NULL; + char *newtypecon = NULL; +- int fd = -1, rc; +- struct stat stat_buf; ++ int rc; + bool updated = false; + const char *lookup_path = pathname; + float pc; +@@ -644,21 +644,13 @@ static int restorecon_sb(const char *pathname, struct rest_flags *flags, bool fi + lookup_path += rootpathlen; + } + +- fd = open(pathname, O_PATH | O_NOFOLLOW | O_EXCL); +- if (fd < 0) +- goto err; +- +- rc = fstat(fd, &stat_buf); +- if (rc < 0) +- goto err; +- + if (rootpath != NULL && lookup_path[0] == '\0') + /* this is actually the root dir of the alt root. */ + rc = selabel_lookup_raw(fc_sehandle, &newcon, "/", +- stat_buf.st_mode); ++ sb->st_mode); + else + rc = selabel_lookup_raw(fc_sehandle, &newcon, lookup_path, +- stat_buf.st_mode); ++ sb->st_mode); + + if (rc < 0) { + if (errno == ENOENT) { +@@ -667,10 +659,10 @@ static int restorecon_sb(const char *pathname, struct rest_flags *flags, bool fi + "Warning no default label for %s\n", + lookup_path); + +- goto out; /* no match, but not an error */ ++ return 0; /* no match, but not an error */ + } + +- goto err; ++ return -1; + } + + if (flags->progress) { +@@ -690,17 +682,19 @@ static int restorecon_sb(const char *pathname, struct rest_flags *flags, bool fi + } + + if (flags->add_assoc) { +- rc = filespec_add(stat_buf.st_ino, newcon, pathname, flags); ++ rc = filespec_add(sb->st_ino, newcon, pathname, flags); + + if (rc < 0) { + selinux_log(SELINUX_ERROR, + "filespec_add error: %s\n", pathname); +- goto out1; ++ freecon(newcon); ++ return -1; + } + + if (rc > 0) { + /* Already an association and it took precedence. */ +- goto out; ++ freecon(newcon); ++ return 0; + } + } + +@@ -708,7 +702,7 @@ static int restorecon_sb(const char *pathname, struct rest_flags *flags, bool fi + selinux_log(SELINUX_INFO, "%s matched by %s\n", + pathname, newcon); + +- if (fgetfilecon_raw(fd, &curcon) < 0) { ++ if (lgetfilecon_raw(pathname, &curcon) < 0) { + if (errno != ENODATA) + goto err; + +@@ -741,7 +735,7 @@ static int restorecon_sb(const char *pathname, struct rest_flags *flags, bool fi + } + + if (!flags->nochange) { +- if (fsetfilecon(fd, newcon) < 0) ++ if (lsetfilecon(pathname, newcon) < 0) + goto err; + updated = true; + } +@@ -766,8 +760,6 @@ static int restorecon_sb(const char *pathname, struct rest_flags *flags, bool fi + out: + rc = 0; + out1: +- if (fd >= 0) +- close(fd); + freecon(curcon); + freecon(newcon); + return rc; +@@ -865,6 +857,7 @@ static void *selinux_restorecon_thread(void *arg) + FTSENT *ftsent; + int error; + char ent_path[PATH_MAX]; ++ struct stat ent_st; + bool first = false; + + if (state->parallel) +@@ -962,11 +955,11 @@ loop_body: + /* fall through */ + default: + strcpy(ent_path, ftsent->fts_path); +- ++ ent_st = *ftsent->fts_statp; + if (state->parallel) + pthread_mutex_unlock(&state->mutex); + +- error = restorecon_sb(ent_path, &state->flags, ++ error = restorecon_sb(ent_path, &ent_st, &state->flags, + first); + + if (state->parallel) { +@@ -1162,7 +1155,7 @@ static int selinux_restorecon_common(const char *pathname_orig, + goto cleanup; + } + +- error = restorecon_sb(pathname, &state.flags, true); ++ error = restorecon_sb(pathname, &sb, &state.flags, true); + goto cleanup; + } + +-- +2.36.1 + diff --git a/libselinux.spec b/libselinux.spec index 085d9fe..e4daa82 100644 --- a/libselinux.spec +++ b/libselinux.spec @@ -4,7 +4,7 @@ Summary: SELinux library and simple utilities Name: libselinux Version: 3.4 -Release: 2%{?dist} +Release: 3%{?dist} License: Public Domain # https://github.com/SELinuxProject/selinux/wiki/Releases Source0: https://github.com/SELinuxProject/selinux/releases/download/3.4/libselinux-3.4.tar.gz @@ -17,6 +17,7 @@ Url: https://github.com/SELinuxProject/selinux/wiki # $ i=1; for j in 00*patch; do printf "Patch%04d: %s\n" $i $j; i=$((i+1));done # Patch list start Patch0001: 0001-Use-SHA-2-instead-of-SHA-1.patch +Patch0002: 0002-Revert-libselinux-restorecon-pin-file-to-avoid-TOCTO.patch # Patch list end BuildRequires: gcc make BuildRequires: ruby-devel ruby libsepol-static >= %{libsepolver} swig pcre2-devel xz-devel @@ -213,6 +214,9 @@ rm -f %{buildroot}%{_mandir}/man8/togglesebool* %{ruby_vendorarchdir}/selinux.so %changelog +* Tue May 31 2022 Petr Lautrbach - 3.4-3 +- Revert "libselinux: restorecon: pin file to avoid TOCTOU issues" + * Wed May 25 2022 Petr Lautrbach - 3.4-2 - rebuilt