|
|
05ad79 |
From 5d238002ff22241a7d04608102a2182aa74d2b69 Mon Sep 17 00:00:00 2001
|
|
|
05ad79 |
From: Karel Zak <kzak@redhat.com>
|
|
|
05ad79 |
Date: Wed, 8 Nov 2017 16:47:40 +0100
|
|
|
05ad79 |
Subject: [PATCH] libmount: fix access() utab write test
|
|
|
05ad79 |
|
|
|
05ad79 |
The commit c08396c7691e1e6a04b6b45892e7e4612ceed8d7 replaces
|
|
|
05ad79 |
open(O_CREATE) with ecaccess(). Unfortunately, another code depends on
|
|
|
05ad79 |
the original behavior.
|
|
|
05ad79 |
|
|
|
05ad79 |
* let's make utab when really necessary rather than in the try_write() test
|
|
|
05ad79 |
|
|
|
05ad79 |
* __mnt_new_table_from_file() returns NULL if tab-file does not
|
|
|
05ad79 |
exists. This is incorrect for tab_update.c stuff. We need empty table
|
|
|
05ad79 |
in this case.
|
|
|
05ad79 |
|
|
|
05ad79 |
* we can check /run/mount/ directory for write access if
|
|
|
05ad79 |
eaccess(filename) return ENOENT (because file does not exist)
|
|
|
05ad79 |
|
|
|
05ad79 |
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1499760
|
|
|
05ad79 |
Upstream: http://github.com/karelzak/util-linux/commit/06ff935ec3ad2290025b555ff32b590680af565f
|
|
|
05ad79 |
Signed-off-by: Karel Zak <kzak@redhat.com>
|
|
|
05ad79 |
---
|
|
|
05ad79 |
libmount/src/mountP.h | 2 +-
|
|
|
05ad79 |
libmount/src/tab_parse.c | 11 +++++++----
|
|
|
05ad79 |
libmount/src/tab_update.c | 9 +++++----
|
|
|
05ad79 |
libmount/src/utils.c | 42 +++++++++++++++++++++++++++++++-----------
|
|
|
05ad79 |
4 files changed, 44 insertions(+), 20 deletions(-)
|
|
|
05ad79 |
|
|
|
05ad79 |
diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h
|
|
|
05ad79 |
index 6cabcedeb..8b3f92e17 100644
|
|
|
05ad79 |
--- a/libmount/src/mountP.h
|
|
|
05ad79 |
+++ b/libmount/src/mountP.h
|
|
|
05ad79 |
@@ -278,7 +278,7 @@ struct libmnt_table {
|
|
|
05ad79 |
struct list_head ents; /* list of entries (libmnt_fs) */
|
|
|
05ad79 |
};
|
|
|
05ad79 |
|
|
|
05ad79 |
-extern struct libmnt_table *__mnt_new_table_from_file(const char *filename, int fmt);
|
|
|
05ad79 |
+extern struct libmnt_table *__mnt_new_table_from_file(const char *filename, int fmt, int empty_for_enoent);
|
|
|
05ad79 |
|
|
|
05ad79 |
/*
|
|
|
05ad79 |
* Tab file format
|
|
|
05ad79 |
diff --git a/libmount/src/tab_parse.c b/libmount/src/tab_parse.c
|
|
|
05ad79 |
index 987e671fa..c629c67ad 100644
|
|
|
05ad79 |
--- a/libmount/src/tab_parse.c
|
|
|
05ad79 |
+++ b/libmount/src/tab_parse.c
|
|
|
05ad79 |
@@ -714,7 +714,7 @@ int mnt_table_parse_dir(struct libmnt_table *tb, const char *dirname)
|
|
|
05ad79 |
return __mnt_table_parse_dir(tb, dirname);
|
|
|
05ad79 |
}
|
|
|
05ad79 |
|
|
|
05ad79 |
-struct libmnt_table *__mnt_new_table_from_file(const char *filename, int fmt)
|
|
|
05ad79 |
+struct libmnt_table *__mnt_new_table_from_file(const char *filename, int fmt, int empty_for_enoent)
|
|
|
05ad79 |
{
|
|
|
05ad79 |
struct libmnt_table *tb;
|
|
|
05ad79 |
struct stat st;
|
|
|
05ad79 |
@@ -723,7 +723,8 @@ struct libmnt_table *__mnt_new_table_from_file(const char *filename, int fmt)
|
|
|
05ad79 |
if (!filename)
|
|
|
05ad79 |
return NULL;
|
|
|
05ad79 |
if (stat(filename, &st))
|
|
|
05ad79 |
- return NULL;
|
|
|
05ad79 |
+ return empty_for_enoent ? mnt_new_table() : NULL;
|
|
|
05ad79 |
+
|
|
|
05ad79 |
tb = mnt_new_table();
|
|
|
05ad79 |
if (tb) {
|
|
|
05ad79 |
tb->fmt = fmt;
|
|
|
05ad79 |
@@ -748,8 +749,10 @@ struct libmnt_table *__mnt_new_table_from_file(const char *filename, int fmt)
|
|
|
05ad79 |
*/
|
|
|
05ad79 |
struct libmnt_table *mnt_new_table_from_file(const char *filename)
|
|
|
05ad79 |
{
|
|
|
05ad79 |
- assert(filename);
|
|
|
05ad79 |
- return __mnt_new_table_from_file(filename, MNT_FMT_GUESS);
|
|
|
05ad79 |
+ if (!filename)
|
|
|
05ad79 |
+ return NULL;
|
|
|
05ad79 |
+
|
|
|
05ad79 |
+ return __mnt_new_table_from_file(filename, MNT_FMT_GUESS, 0);
|
|
|
05ad79 |
}
|
|
|
05ad79 |
|
|
|
05ad79 |
/**
|
|
|
05ad79 |
diff --git a/libmount/src/tab_update.c b/libmount/src/tab_update.c
|
|
|
05ad79 |
index 1e7f32be0..5f503cad7 100644
|
|
|
05ad79 |
--- a/libmount/src/tab_update.c
|
|
|
05ad79 |
+++ b/libmount/src/tab_update.c
|
|
|
05ad79 |
@@ -567,6 +567,7 @@ leave:
|
|
|
05ad79 |
|
|
|
05ad79 |
unlink(uq); /* be paranoid */
|
|
|
05ad79 |
free(uq);
|
|
|
05ad79 |
+ DBG(UPDATE, mnt_debug_h(upd, "%s: done [rc=%d]", upd->filename, rc));
|
|
|
05ad79 |
return rc;
|
|
|
05ad79 |
}
|
|
|
05ad79 |
|
|
|
05ad79 |
@@ -600,7 +601,7 @@ static int update_add_entry(struct libmnt_update *upd, struct libmnt_lock *lc)
|
|
|
05ad79 |
return rc;
|
|
|
05ad79 |
|
|
|
05ad79 |
tb = __mnt_new_table_from_file(upd->filename,
|
|
|
05ad79 |
- upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB);
|
|
|
05ad79 |
+ upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB, 1);
|
|
|
05ad79 |
if (tb)
|
|
|
05ad79 |
rc = add_file_entry(tb, upd);
|
|
|
05ad79 |
if (lc)
|
|
|
05ad79 |
@@ -626,7 +627,7 @@ static int update_remove_entry(struct libmnt_update *upd, struct libmnt_lock *lc
|
|
|
05ad79 |
return rc;
|
|
|
05ad79 |
|
|
|
05ad79 |
tb = __mnt_new_table_from_file(upd->filename,
|
|
|
05ad79 |
- upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB);
|
|
|
05ad79 |
+ upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB, 1);
|
|
|
05ad79 |
if (tb) {
|
|
|
05ad79 |
struct libmnt_fs *rem = mnt_table_find_target(tb, upd->target, MNT_ITER_BACKWARD);
|
|
|
05ad79 |
if (rem) {
|
|
|
05ad79 |
@@ -656,7 +657,7 @@ static int update_modify_target(struct libmnt_update *upd, struct libmnt_lock *l
|
|
|
05ad79 |
return rc;
|
|
|
05ad79 |
|
|
|
05ad79 |
tb = __mnt_new_table_from_file(upd->filename,
|
|
|
05ad79 |
- upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB);
|
|
|
05ad79 |
+ upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB, 1);
|
|
|
05ad79 |
if (tb) {
|
|
|
05ad79 |
struct libmnt_fs *cur = mnt_table_find_target(tb,
|
|
|
05ad79 |
mnt_fs_get_srcpath(upd->fs), MNT_ITER_BACKWARD);
|
|
|
05ad79 |
@@ -693,7 +694,7 @@ static int update_modify_options(struct libmnt_update *upd, struct libmnt_lock *
|
|
|
05ad79 |
return rc;
|
|
|
05ad79 |
|
|
|
05ad79 |
tb = __mnt_new_table_from_file(upd->filename,
|
|
|
05ad79 |
- upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB);
|
|
|
05ad79 |
+ upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB, 1);
|
|
|
05ad79 |
if (tb) {
|
|
|
05ad79 |
struct libmnt_fs *cur = mnt_table_find_target(tb,
|
|
|
05ad79 |
mnt_fs_get_target(fs),
|
|
|
05ad79 |
diff --git a/libmount/src/utils.c b/libmount/src/utils.c
|
|
|
05ad79 |
index a275d0a0e..fa33bd9a1 100644
|
|
|
05ad79 |
--- a/libmount/src/utils.c
|
|
|
05ad79 |
+++ b/libmount/src/utils.c
|
|
|
05ad79 |
@@ -651,18 +651,37 @@ done:
|
|
|
05ad79 |
return rc;
|
|
|
05ad79 |
}
|
|
|
05ad79 |
|
|
|
05ad79 |
-static int try_write(const char *filename)
|
|
|
05ad79 |
+static int try_write(const char *filename, const char *directory)
|
|
|
05ad79 |
{
|
|
|
05ad79 |
int rc = 0;
|
|
|
05ad79 |
|
|
|
05ad79 |
if (!filename)
|
|
|
05ad79 |
return -EINVAL;
|
|
|
05ad79 |
|
|
|
05ad79 |
+ DBG(UTILS, mnt_debug("try write %s dir: %s", filename, directory));
|
|
|
05ad79 |
+
|
|
|
05ad79 |
#ifdef HAVE_EACCESS
|
|
|
05ad79 |
- if (eaccess(filename, R_OK|W_OK) != 0)
|
|
|
05ad79 |
- rc = -errno;
|
|
|
05ad79 |
-#else
|
|
|
05ad79 |
+ /* Try eaccess() first, because open() is overkill, may be monitored by
|
|
|
05ad79 |
+ * audit and we don't want to fill logs by our checks...
|
|
|
05ad79 |
+ */
|
|
|
05ad79 |
+ if (eaccess(filename, R_OK|W_OK) == 0) {
|
|
|
05ad79 |
+ DBG(UTILS, mnt_debug(" access OK"));
|
|
|
05ad79 |
+ return 0;
|
|
|
05ad79 |
+ } else if (errno != ENOENT) {
|
|
|
05ad79 |
+ DBG(UTILS, mnt_debug(" access FAILED"));
|
|
|
05ad79 |
+ return -errno;
|
|
|
05ad79 |
+ } else if (directory) {
|
|
|
05ad79 |
+ /* file does not exist; try if directory is writable */
|
|
|
05ad79 |
+ if (eaccess(directory, R_OK|W_OK) != 0)
|
|
|
05ad79 |
+ rc = -errno;
|
|
|
05ad79 |
+
|
|
|
05ad79 |
+ DBG(UTILS, mnt_debug(" access %s [%s]", rc ? "FAILED" : "OK", directory));
|
|
|
05ad79 |
+ return rc;
|
|
|
05ad79 |
+ } else
|
|
|
05ad79 |
+#endif
|
|
|
05ad79 |
{
|
|
|
05ad79 |
+ DBG(UTILS, mnt_debug(" doing open-write test"));
|
|
|
05ad79 |
+
|
|
|
05ad79 |
int fd = open(filename, O_RDWR|O_CREAT|O_CLOEXEC,
|
|
|
05ad79 |
S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH);
|
|
|
05ad79 |
if (fd < 0)
|
|
|
05ad79 |
@@ -670,7 +689,6 @@ static int try_write(const char *filename)
|
|
|
05ad79 |
else
|
|
|
05ad79 |
close(fd);
|
|
|
05ad79 |
}
|
|
|
05ad79 |
-#endif
|
|
|
05ad79 |
return rc;
|
|
|
05ad79 |
}
|
|
|
05ad79 |
|
|
|
05ad79 |
@@ -704,7 +722,7 @@ int mnt_has_regular_mtab(const char **mtab, int *writable)
|
|
|
05ad79 |
/* file exist */
|
|
|
05ad79 |
if (S_ISREG(st.st_mode)) {
|
|
|
05ad79 |
if (writable)
|
|
|
05ad79 |
- *writable = !try_write(filename);
|
|
|
05ad79 |
+ *writable = !try_write(filename, NULL);
|
|
|
05ad79 |
return 1;
|
|
|
05ad79 |
}
|
|
|
05ad79 |
goto done;
|
|
|
05ad79 |
@@ -712,7 +730,7 @@ int mnt_has_regular_mtab(const char **mtab, int *writable)
|
|
|
05ad79 |
|
|
|
05ad79 |
/* try to create the file */
|
|
|
05ad79 |
if (writable) {
|
|
|
05ad79 |
- *writable = !try_write(filename);
|
|
|
05ad79 |
+ *writable = !try_write(filename, NULL);
|
|
|
05ad79 |
if (*writable)
|
|
|
05ad79 |
return 1;
|
|
|
05ad79 |
}
|
|
|
05ad79 |
@@ -750,7 +768,7 @@ int mnt_has_regular_utab(const char **utab, int *writable)
|
|
|
05ad79 |
/* file exist */
|
|
|
05ad79 |
if (S_ISREG(st.st_mode)) {
|
|
|
05ad79 |
if (writable)
|
|
|
05ad79 |
- *writable = !try_write(filename);
|
|
|
05ad79 |
+ *writable = !try_write(filename, NULL);
|
|
|
05ad79 |
return 1;
|
|
|
05ad79 |
}
|
|
|
05ad79 |
goto done; /* it's not regular file */
|
|
|
05ad79 |
@@ -767,11 +785,13 @@ int mnt_has_regular_utab(const char **utab, int *writable)
|
|
|
05ad79 |
rc = mkdir(dirname, S_IWUSR|
|
|
|
05ad79 |
S_IRUSR|S_IRGRP|S_IROTH|
|
|
|
05ad79 |
S_IXUSR|S_IXGRP|S_IXOTH);
|
|
|
05ad79 |
- free(dirname);
|
|
|
05ad79 |
- if (rc && errno != EEXIST)
|
|
|
05ad79 |
+ if (rc && errno != EEXIST) {
|
|
|
05ad79 |
+ free(dirname);
|
|
|
05ad79 |
goto done; /* probably EACCES */
|
|
|
05ad79 |
+ }
|
|
|
05ad79 |
|
|
|
05ad79 |
- *writable = !try_write(filename);
|
|
|
05ad79 |
+ *writable = !try_write(filename, dirname);
|
|
|
05ad79 |
+ free(dirname);
|
|
|
05ad79 |
if (*writable)
|
|
|
05ad79 |
return 1;
|
|
|
05ad79 |
}
|
|
|
05ad79 |
--
|
|
|
05ad79 |
2.13.6
|
|
|
05ad79 |
|