util-linux/util-linux-libmount-fix-and-improve-utab-on-ms_move.patch
2024-02-09 18:07:47 +08:00

95 lines
2.5 KiB
Diff

From 1ec32f426c0f4705ea4e6e33b812b3b4c2c47faa Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Wed, 4 May 2022 12:13:08 +0200
Subject: [PATCH 2/2] libmount: fix and improve utab update on MS_MOVE
* avoid double '//'
* don't update /fooxxx when /foo update requested (make sure that
startswith() returns path terminated by '/')
* canonicalize only once the new path -- all in utab/mtab is already
canonicalized, so after MS_MOVE we need to care about the new path
only
* use asprintf() rather than strcpy() and strcat(), don't compose a
new path from prefix and subdir when replace entire path
Addresses: https://github.com/util-linux/util-linux/pull/1660
Signed-off-by: Karel Zak <kzak@redhat.com>
---
libmount/src/tab_update.c | 41 +++++++++++++++++++++------------------
1 file changed, 22 insertions(+), 19 deletions(-)
diff --git a/libmount/src/tab_update.c b/libmount/src/tab_update.c
index 51f2fae26..3a22e7188 100644
--- a/libmount/src/tab_update.c
+++ b/libmount/src/tab_update.c
@@ -767,33 +767,34 @@ static int update_modify_target(struct libmnt_update *upd, struct libmnt_lock *l
const char *upd_target = mnt_fs_get_target(upd->fs);
struct libmnt_iter itr;
struct libmnt_fs *fs;
+ char *cn_target = mnt_resolve_path(upd_target, NULL);
+
+ if (!cn_target) {
+ rc = -ENOMEM;
+ goto done;
+ }
mnt_reset_iter(&itr, MNT_ITER_BACKWARD);
- while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
- char *p, *e;
- size_t len;
+ while (mnt_table_next_fs(tb, &itr, &fs) == 0) {
+ char *p;
+ const char *e;
e = startswith(mnt_fs_get_target(fs), upd_source);
- if (!e)
+ if (!e || (*e && *e != '/'))
continue;
+ if (*e == '/')
+ e++; /* remove extra '/' */
- len = strlen(upd_target) + strlen(e) + 2;
- p = malloc(len);
- if (!p)
- rc = -ENOMEM;
- else {
- char *cn;
-
- strcpy(p, upd_target);
- strcat(p, "/");
- strcat(p, e);
-
- cn = mnt_resolve_path(p, NULL);
- rc = mnt_fs_set_target(fs, cn);
+ /* no subdirectory, replace entire path */
+ if (!*e)
+ rc = mnt_fs_set_target(fs, cn_target);
- free(cn);
+ /* update start of the path, keep subdirectory */
+ else if (asprintf(&p, "%s/%s", cn_target, e) > 0) {
+ rc = mnt_fs_set_target(fs, p);
free(p);
- }
+ } else
+ rc = -ENOMEM;
if (rc < 0)
break;
@@ -801,8 +802,10 @@ static int update_modify_target(struct libmnt_update *upd, struct libmnt_lock *l
if (!rc)
rc = update_table(upd, tb);
+ free(cn_target);
}
+done:
if (lc)
mnt_unlock_file(lc);
--
2.35.1