Blame SOURCES/0185-lib-canonicalize-make-DM-canonicalization-more-robus.patch

05ad79
From 36e285eb912c86b607b752964c85aa6ee4bc25ea Mon Sep 17 00:00:00 2001
05ad79
From: Karel Zak <kzak@redhat.com>
05ad79
Date: Tue, 20 May 2014 10:11:57 +0200
05ad79
Subject: [PATCH 185/185] lib/canonicalize: make DM canonicalization more
05ad79
 robust
05ad79
05ad79
The current code cares about filenames, but it's too fragile, we have
05ad79
to check the path is really path to the block device.
05ad79
05ad79
Addresses: https://github.com/karelzak/util-linux/issues/83
05ad79
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1678451
05ad79
Upstream: http://github.com/karelzak/util-linux/commit/1dbbd85b9498536ab38758a03c9ec20362f1c572
05ad79
Signed-off-by: Karel Zak <kzak@redhat.com>
05ad79
---
05ad79
 lib/canonicalize.c | 35 ++++++++++++++++++++++++++---------
05ad79
 1 file changed, 26 insertions(+), 9 deletions(-)
05ad79
05ad79
diff --git a/lib/canonicalize.c b/lib/canonicalize.c
05ad79
index 548e29b75..814ee3dd8 100644
05ad79
--- a/lib/canonicalize.c
05ad79
+++ b/lib/canonicalize.c
05ad79
@@ -26,6 +26,8 @@
05ad79
 #include <unistd.h>
05ad79
 #include <errno.h>
05ad79
 #include <stdlib.h>
05ad79
+#include <sys/types.h>
05ad79
+#include <sys/stat.h>
05ad79
 
05ad79
 #include "canonicalize.h"
05ad79
 
05ad79
@@ -170,10 +172,28 @@ canonicalize_dm_name(const char *ptname)
05ad79
 	return res;
05ad79
 }
05ad79
 
05ad79
+static int is_dm_devname(char *canonical, char **name)
05ad79
+{
05ad79
+	struct stat sb;
05ad79
+	char *p = strrchr(canonical, '/');
05ad79
+
05ad79
+	*name = NULL;
05ad79
+
05ad79
+	if (!p
05ad79
+	    || strncmp(p, "/dm-", 4) != 0
05ad79
+	    || !isdigit(*(p + 4))
05ad79
+	    || stat(canonical, &sb) != 0
05ad79
+	    || !S_ISBLK(sb.st_mode))
05ad79
+		return 0;
05ad79
+
05ad79
+	*name = p + 1;
05ad79
+	return 1;
05ad79
+}
05ad79
+
05ad79
 char *
05ad79
 canonicalize_path(const char *path)
05ad79
 {
05ad79
-	char canonical[PATH_MAX+2];
05ad79
+	char canonical[PATH_MAX+2], *dmname;
05ad79
 	char *p;
05ad79
 
05ad79
 	if (!path || !*path)
05ad79
@@ -182,10 +202,8 @@ canonicalize_path(const char *path)
05ad79
 	if (!myrealpath(path, canonical, PATH_MAX+1))
05ad79
 		return strdup(path);
05ad79
 
05ad79
-
05ad79
-	p = strrchr(canonical, '/');
05ad79
-	if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) {
05ad79
-		p = canonicalize_dm_name(p+1);
05ad79
+	if (is_dm_devname(canonical, &dmname)) {
05ad79
+		p = canonicalize_dm_name(dmname);
05ad79
 		if (p)
05ad79
 			return p;
05ad79
 	}
05ad79
@@ -196,7 +214,7 @@ canonicalize_path(const char *path)
05ad79
 char *
05ad79
 canonicalize_path_restricted(const char *path)
05ad79
 {
05ad79
-	char canonical[PATH_MAX+2];
05ad79
+	char canonical[PATH_MAX+2], *dmname;
05ad79
 	char *p = NULL;
05ad79
 	int errsv;
05ad79
 	uid_t euid;
05ad79
@@ -215,9 +233,8 @@ canonicalize_path_restricted(const char *path)
05ad79
 	errsv = errno = 0;
05ad79
 
05ad79
 	if (myrealpath(path, canonical, PATH_MAX+1)) {
05ad79
-		p = strrchr(canonical, '/');
05ad79
-		if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4)))
05ad79
-			p = canonicalize_dm_name(p+1);
05ad79
+		if (is_dm_devname(canonical, &dmname))
05ad79
+			p = canonicalize_dm_name(dmname);
05ad79
 		else
05ad79
 			p = NULL;
05ad79
 		if (!p)
05ad79
-- 
05ad79
2.20.1
05ad79