Browse Source

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>
pull/1678/head
Karel Zak 2 months ago
parent
commit
1ec32f426c
  1. 41
      libmount/src/tab_update.c

41
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);

Loading…
Cancel
Save