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

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