File util-linux-libmount-fix-and-improve-utab-on-ms_move.patch of Package util-linux

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

openSUSE Build Service is sponsored by