Merge pull request #257 from giuseppe/stat-override-containers

main: honor user.containers.override_stat
This commit is contained in:
Daniel J Walsh 2020-11-06 11:35:01 -05:00 committed by GitHub
commit 15a04643b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 41 additions and 14 deletions

View File

@ -194,9 +194,11 @@ direct_load_data_source (struct ovl_layer *l, const char *opaque, const char *pa
}
if (fgetxattr (l->fd, XATTR_PRIVILEGED_OVERRIDE_STAT, tmp, sizeof (tmp)) >= 0)
l->has_privileged_stat_override = 1;
l->stat_override_mode = STAT_OVERRIDE_PRIVILEGED;
else if (fgetxattr (l->fd, XATTR_OVERRIDE_STAT, tmp, sizeof (tmp)) >= 0)
l->has_stat_override = 1;
l->stat_override_mode = STAT_OVERRIDE_USER;
else if (fgetxattr (l->fd, XATTR_OVERRIDE_CONTAINERS_STAT, tmp, sizeof (tmp)) >= 0)
l->stat_override_mode = STAT_OVERRIDE_CONTAINERS;
return 0;
}

View File

@ -104,6 +104,14 @@ struct ovl_data
struct ovl_plugin_context *plugins_ctx;
};
enum stat_override_mode
{
STAT_OVERRIDE_NONE,
STAT_OVERRIDE_USER,
STAT_OVERRIDE_PRIVILEGED,
STAT_OVERRIDE_CONTAINERS,
};
struct ovl_layer
{
struct ovl_layer *next;
@ -114,8 +122,7 @@ struct ovl_layer
bool low;
void *data_source_private_data;
unsigned int has_stat_override : 1;
unsigned int has_privileged_stat_override : 1;
int stat_override_mode;
};
/* a data_source defines the methods for accessing a lower layer. */

14
main.c
View File

@ -2708,7 +2708,7 @@ create_directory (struct ovl_data *lo, int dirfd, const char *name, const struct
if (ret < 0)
goto out;
if (uid != lo->uid || gid != lo->gid || get_upper_layer (lo)->has_stat_override || get_upper_layer (lo)->has_privileged_stat_override)
if (uid != lo->uid || gid != lo->gid || get_upper_layer (lo)->stat_override_mode != STAT_OVERRIDE_NONE)
{
ret = do_fchown (lo, dfd, uid, gid, mode);
if (ret < 0)
@ -2937,7 +2937,7 @@ copyup (struct ovl_data *lo, struct ovl_node *node)
if (dfd < 0)
goto exit;
if (st.st_uid != lo->uid || st.st_gid != lo->gid || get_upper_layer (lo)->has_stat_override || get_upper_layer (lo)->has_privileged_stat_override)
if (st.st_uid != lo->uid || st.st_gid != lo->gid || get_upper_layer (lo)->stat_override_mode != STAT_OVERRIDE_NONE)
{
ret = do_fchown (lo, dfd, st.st_uid, st.st_gid, mode);
if (ret < 0)
@ -3393,7 +3393,7 @@ direct_create_file (struct ovl_layer *l, int dirfd, const char *path, uid_t uid,
int ret;
/* try to create directly the file if it doesn't need to be chowned. */
if (uid == lo->uid && gid == lo->gid && !l->has_stat_override && !l->has_privileged_stat_override)
if (uid == lo->uid && gid == lo->gid && l->stat_override_mode == STAT_OVERRIDE_NONE)
{
ret = TEMP_FAILURE_RETRY (safe_openat (get_upper_layer (lo)->fd, path, flags, mode));
if (ret >= 0)
@ -3407,7 +3407,7 @@ direct_create_file (struct ovl_layer *l, int dirfd, const char *path, uid_t uid,
fd = TEMP_FAILURE_RETRY (safe_openat (lo->workdir_fd, wd_tmp_file_name, flags, mode));
if (fd < 0)
return -1;
if (uid != lo->uid || gid != lo->gid || l->has_stat_override || l->has_privileged_stat_override)
if (uid != lo->uid || gid != lo->gid || l->stat_override_mode != STAT_OVERRIDE_NONE)
{
if (do_fchown (lo, fd, uid, gid, mode) < 0)
{
@ -4106,7 +4106,7 @@ direct_symlinkat (struct ovl_layer *l, const char *target, const char *linkpath,
if (ret < 0)
return ret;
if (uid != lo->uid || gid != lo->gid || l->has_stat_override || l->has_privileged_stat_override)
if (uid != lo->uid || gid != lo->gid || l->stat_override_mode != STAT_OVERRIDE_NONE)
{
ret = do_fchownat (lo, lo->workdir_fd, wd_tmp_file_name, uid, gid, 0755, AT_SYMLINK_NOFOLLOW);
if (ret < 0)
@ -5522,12 +5522,12 @@ main (int argc, char *argv[])
ssize_t s;
if (lo.xattr_permissions == 1)
{
get_upper_layer (&lo)->has_privileged_stat_override = 1;
get_upper_layer (&lo)->stat_override_mode = STAT_OVERRIDE_PRIVILEGED;
name = XATTR_PRIVILEGED_OVERRIDE_STAT;
}
else if (lo.xattr_permissions == 2)
{
get_upper_layer (&lo)->has_stat_override = 1;
get_upper_layer (&lo)->stat_override_mode = STAT_OVERRIDE_USER;
name = XATTR_OVERRIDE_STAT;
}
else

23
utils.c
View File

@ -240,10 +240,27 @@ override_mode (struct ovl_layer *l, int fd, const char *abs_path, const char *pa
cleanup_close int cleanup_fd = -1;
const char *xattr_name;
if (l->has_stat_override == 0 && l->has_privileged_stat_override == 0)
return 0;
switch (l->stat_override_mode)
{
case STAT_OVERRIDE_NONE:
return 0;
xattr_name = l->has_privileged_stat_override ? XATTR_PRIVILEGED_OVERRIDE_STAT : XATTR_OVERRIDE_STAT;
case STAT_OVERRIDE_USER:
xattr_name = XATTR_OVERRIDE_STAT;
break;
case STAT_OVERRIDE_PRIVILEGED:
xattr_name = XATTR_PRIVILEGED_OVERRIDE_STAT;
break;
case STAT_OVERRIDE_CONTAINERS:
xattr_name = XATTR_OVERRIDE_CONTAINERS_STAT;
break;
default:
errno = EINVAL;
return -1;
}
if (fd >= 0)
{

View File

@ -33,6 +33,7 @@
# define XATTR_OVERRIDE_STAT "user.fuseoverlayfs.override_stat"
# define XATTR_PRIVILEGED_OVERRIDE_STAT "security.fuseoverlayfs.override_stat"
# define XATTR_OVERRIDE_CONTAINERS_STAT "user.containers.override_stat"
void cleanup_freep (void *p);
void cleanup_filep (FILE **f);