Skip to content

Commit

Permalink
Skip directories and symlinks when mounting libraries
Browse files Browse the repository at this point in the history
This ensures that only actual libraries from the compat folders are
mounted into the container.

Signed-off-by: Evan Lezar <[email protected]>
  • Loading branch information
elezar committed Sep 11, 2024
1 parent 4c2494f commit db0263c
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/nvc_container.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ find_library_paths(struct error *err, struct nvc_container *cnt)
{
char path[PATH_MAX];
glob_t gl;
mode_t mode;
int rv = -1;
char **ptr;

Expand Down
19 changes: 15 additions & 4 deletions src/nvc_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,10 @@ mount_with_flags(struct error *err, const char *src, const char *dst, uid_t uid,
static char **
mount_files(struct error *err, const char *root, const struct nvc_container *cnt, const char *dir, char *paths[], size_t size)
{
char dummy[PATH_MAX];
char src[PATH_MAX];
char dst[PATH_MAX];
mode_t mode;
mode_t mode, dst_mode;
char *src_end, *dst_end, *file;
char **mnt, **ptr;

Expand All @@ -124,13 +125,23 @@ mount_files(struct error *err, const char *root, const struct nvc_container *cnt
continue;
if (path_append(err, src, paths[i]) < 0)
goto fail;
if (path_append(err, dst, file) < 0)
if (file_mode_nofollow(err, src, &mode) < 0)
goto fail;
if (file_mode(err, src, &mode) < 0)
// If we encounter resolved directories or symlinks here, we raise an error.
if (S_ISDIR(mode) || S_ISLNK(mode)) {
error_setx(err, "unexpected source file mode %o for %s", mode, paths[i]);
goto fail;
}
if (path_append(err, dst, file) < 0)
goto fail;
if (file_mode_nofollow(err, src, &dst_mode) == 0) {
if (S_ISDIR(dst_mode) || S_ISLNK(dst_mode)) {
error_setx(err, "unexpected destination file mode %o for %s", dst_mode, file);
goto fail;
}
};
if (file_create(err, dst, NULL, cnt->uid, cnt->gid, mode) < 0)
goto fail;

log_infof("mounting %s at %s", src, dst);
if (xmount(err, src, dst, NULL, MS_BIND, NULL) < 0)
goto fail;
Expand Down
19 changes: 17 additions & 2 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,9 +542,9 @@ file_create(struct error *err, const char *path, const char *data, uid_t uid, gi
int rv = -1;

// We check whether the file already exists with the required mode and skip the creation.
if (data == NULL && file_mode(err, path, &perm) == 0) {
if (data == NULL && file_mode_nofollow(err, path, &perm) == 0) {
if (perm == mode) {
log_errf("The path %s already exists with the required mode; skipping create", path);
log_warnf("The path %s already exists with the required mode; skipping create", path);
return (0);
}
}
Expand Down Expand Up @@ -677,6 +677,21 @@ file_mode(struct error *err, const char *path, mode_t *mode)
return (0);
}

// file_mode_nofollow implements the same functionality as file_mode except that
// in that case of a symlink, the file is not followed and the mode of the
// original file is returned.
int
file_mode_nofollow(struct error *err, const char *path, mode_t *mode)
{
struct stat s;
int rv;

if ((rv = xlstat(err, path, &s)) < 0)
return (-1);
*mode = s.st_mode;
return (0);
}

int
file_read_line(struct error *err, const char *path, char *buf, size_t size)
{
Expand Down
1 change: 1 addition & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ int file_remove(struct error *, const char *);
int file_exists(struct error *, const char *);
int file_exists_at(struct error *, const char *, const char *);
int file_mode(struct error *, const char *, mode_t *);
int file_mode_nofollow(struct error *, const char *, mode_t *);
int file_read_line(struct error *, const char *, char *, size_t);
int file_read_text(struct error *, const char *, char **);
int file_read_uint32(struct error *, const char *, uint32_t *);
Expand Down
11 changes: 11 additions & 0 deletions src/xfuncs.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ static inline void xclose(int);
static inline int xopen(struct error *, const char *, int);
static inline void *xcalloc(struct error *, size_t, size_t);
static inline int xstat(struct error *, const char *, struct stat *);
static inline int xlstat(struct error *, const char *, struct stat *);
static inline FILE *xfopen(struct error *, const char *, const char *);
static inline char *xstrdup(struct error *, const char *);
static inline int xasprintf(struct error *, char **, const char *, ...)
Expand Down Expand Up @@ -74,6 +75,16 @@ xstat(struct error *err, const char *path, struct stat *buf)
return (rv);
}

static inline int
xlstat(struct error *err, const char *path, struct stat *buf)
{
int rv;

if ((rv = lstat(path, buf)) < 0)
error_set(err, "stat failed: %s", path);
return (rv);
}

static inline FILE *
xfopen(struct error *err, const char *path, const char *mode)
{
Expand Down

0 comments on commit db0263c

Please sign in to comment.