mirror of
https://github.com/systemd/systemd.git
synced 2024-10-31 16:21:26 +03:00
namespace: store and use original MountEntry paths when prefixing
Some paths (eg: mount_tmpfs) simply assumed that prefixing always happens and it always stores the original path in path_const, and the prefixed path in path_malloc. But if a MountEntry is set up in a helper function and thus uses only _malloc struct members, this assumption doesn't hold and there's a crash. Refactor so that prefixing is done with a helper which stores the original path in a separate struct member, and accessing it also uses a helper which does the right thing.
This commit is contained in:
parent
b850a9b29f
commit
809ceb8217
@ -72,6 +72,8 @@ typedef struct MountEntry {
|
||||
bool exec:1; /* Shall clear MS_NOEXEC on the mount itself */
|
||||
bool applied:1; /* Already applied */
|
||||
char *path_malloc; /* Use this instead of 'path_const' if we had to allocate memory */
|
||||
const char *unprefixed_path_const; /* If the path was amended with a prefix, these will save the original */
|
||||
char *unprefixed_path_malloc;
|
||||
const char *source_const; /* The source path, for bind mounts or images */
|
||||
char *source_malloc;
|
||||
const char *options_const;/* Mount options for tmpfs */
|
||||
@ -231,6 +233,29 @@ static const char *mount_entry_path(const MountEntry *p) {
|
||||
return p->path_malloc ?: p->path_const;
|
||||
}
|
||||
|
||||
static const char *mount_entry_unprefixed_path(const MountEntry *p) {
|
||||
assert(p);
|
||||
|
||||
/* Returns the unprefixed path (ie: before prefix_where_needed() ran), if any */
|
||||
|
||||
return p->unprefixed_path_malloc ?: p->unprefixed_path_const ?: mount_entry_path(p);
|
||||
}
|
||||
|
||||
static void mount_entry_consume_prefix(MountEntry *p, char *new_path) {
|
||||
assert(p);
|
||||
assert(p->path_malloc || p->path_const);
|
||||
assert(new_path);
|
||||
|
||||
/* Saves current path in unprefixed_ variable, and takes over new_path */
|
||||
|
||||
free_and_replace(p->unprefixed_path_malloc, p->path_malloc);
|
||||
/* If we didn't have a path on the heap, then it's a static one */
|
||||
if (!p->unprefixed_path_malloc)
|
||||
p->unprefixed_path_const = p->path_const;
|
||||
p->path_malloc = new_path;
|
||||
p->has_prefix = true;
|
||||
}
|
||||
|
||||
static bool mount_entry_read_only(const MountEntry *p) {
|
||||
assert(p);
|
||||
|
||||
@ -265,6 +290,7 @@ static void mount_entry_done(MountEntry *p) {
|
||||
assert(p);
|
||||
|
||||
p->path_malloc = mfree(p->path_malloc);
|
||||
p->unprefixed_path_malloc = mfree(p->unprefixed_path_malloc);
|
||||
p->source_malloc = mfree(p->source_malloc);
|
||||
p->options_malloc = mfree(p->options_malloc);
|
||||
p->image_options = mount_options_free_all(p->image_options);
|
||||
@ -492,8 +518,7 @@ static int prefix_where_needed(MountEntry *m, size_t n, const char *root_directo
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
free_and_replace(m[i].path_malloc, s);
|
||||
m[i].has_prefix = true;
|
||||
mount_entry_consume_prefix(&m[i], s);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -946,7 +971,7 @@ static int mount_tmpfs(const MountEntry *m) {
|
||||
assert(m);
|
||||
|
||||
entry_path = mount_entry_path(m);
|
||||
inner_path = m->path_const;
|
||||
inner_path = mount_entry_unprefixed_path(m);
|
||||
|
||||
/* First, get rid of everything that is below if there is anything. Then, overmount with our new tmpfs */
|
||||
|
||||
@ -1017,8 +1042,7 @@ static int follow_symlink(
|
||||
|
||||
log_debug("Followed mount entry path symlink %s → %s.", mount_entry_path(m), target);
|
||||
|
||||
free_and_replace(m->path_malloc, target);
|
||||
m->has_prefix = true;
|
||||
mount_entry_consume_prefix(m, TAKE_PTR(target));
|
||||
|
||||
m->n_followed ++;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user