[PATCH 1/2] libselinux: restorecon: add fallback for pre 3.6 Linux

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



fstat(2) on file descriptors obtained via O_PATH is supported since
Linux 3.6. Fallback on older systems to lstat(2).

Fixes: 7e979b56 ("libselinux: restorecon: pin file to avoid TOCTOU issues")

Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx>
---
 libselinux/src/selinux_restorecon.c | 29 +++++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/libselinux/src/selinux_restorecon.c b/libselinux/src/selinux_restorecon.c
index 9dd6be81..1a185ced 100644
--- a/libselinux/src/selinux_restorecon.c
+++ b/libselinux/src/selinux_restorecon.c
@@ -89,10 +89,22 @@ struct rest_flags {
 	bool count_errors;
 };
 
+/* Linux version for availability tests. */
+static struct utsname uts;
+
 static void restorecon_init(void)
 {
 	struct selabel_handle *sehandle = NULL;
 
+	if (uname(&uts) < 0) {
+		/*
+		 * utsname(2) should never fail, but assume oldest supported
+		 * LTS release as backup
+		 */
+		strncpy(uts.release, "4.9", sizeof(uts.release));
+		uts.release[sizeof(uts.release) - 1] = '\0';
+	}
+
 	if (!fc_sehandle) {
 		sehandle = selinux_restorecon_default_handle();
 		selinux_restorecon_set_sehandle(sehandle);
@@ -238,7 +250,6 @@ static uint64_t file_system_count(const char *name)
  */
 static uint64_t exclude_non_seclabel_mounts(void)
 {
-	struct utsname uts;
 	FILE *fp;
 	size_t len;
 	int index = 0, found = 0;
@@ -247,7 +258,7 @@ static uint64_t exclude_non_seclabel_mounts(void)
 	char *buf = NULL, *item;
 
 	/* Check to see if the kernel supports seclabel */
-	if (uname(&uts) == 0 && strverscmp(uts.release, "2.6.30") < 0)
+	if (strverscmp(uts.release, "2.6.30") < 0)
 		return 0;
 	if (is_selinux_enabled() <= 0)
 		return 0;
@@ -648,9 +659,19 @@ static int restorecon_sb(const char *pathname, struct rest_flags *flags, bool fi
 	if (fd < 0)
 		goto err;
 
+	/*
+	 * fstat(2) on file descriptors obtained via O_PATH are supported
+	 * since Linux 3.6, see man:open(2).
+	 * Test fstat(2) first, support might have been backported.
+	 */
 	rc = fstat(fd, &stat_buf);
-	if (rc < 0)
-		goto err;
+	if (rc < 0) {
+		if (errno == EBADF && strverscmp(uts.release, "3.6") < 0)
+			rc = lstat(pathname, &stat_buf);
+
+		if (rc < 0)
+			goto err;
+	}
 
 	if (rootpath != NULL && lookup_path[0] == '\0')
 		/* this is actually the root dir of the alt root. */
-- 
2.36.1




[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux