mirror of
https://github.com/containers/fuse-overlayfs.git
synced 2025-08-03 09:55:57 -04:00
main: use extended override xattr
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
parent
8d33894c48
commit
6bbd62bb13
72
main.c
72
main.c
@ -508,43 +508,26 @@ node_dirfd (struct ovl_node *n)
|
||||
return n->layer->fd;
|
||||
}
|
||||
|
||||
static bool
|
||||
has_prefix (const char *str, const char *pref)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
if (*pref == '\0')
|
||||
return true;
|
||||
if (*str == '\0')
|
||||
return false;
|
||||
if (*pref != *str)
|
||||
return false;
|
||||
str++;
|
||||
pref++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
can_access_xattr (const struct ovl_layer *l, const char *name)
|
||||
{
|
||||
return ! (has_prefix (name, XATTR_PREFIX)
|
||||
|| has_prefix (name, PRIVILEGED_XATTR_PREFIX)
|
||||
|| has_prefix (name, UNPRIVILEGED_XATTR_PREFIX)
|
||||
|| (l->stat_override_mode == STAT_OVERRIDE_CONTAINERS &&
|
||||
has_prefix (name, XATTR_SECURITY_PREFIX)));
|
||||
|| (l->stat_override_mode == STAT_OVERRIDE_CONTAINERS && has_prefix (name, XATTR_SECURITY_PREFIX)));
|
||||
}
|
||||
|
||||
static bool encoded_xattr_name (const struct ovl_layer *l, const char *name)
|
||||
static bool
|
||||
encoded_xattr_name (const struct ovl_layer *l, const char *name)
|
||||
{
|
||||
return has_prefix (name, XATTR_CONTAINERS_OVERRIDE_PREFIX) &&
|
||||
! can_access_xattr (l, name + sizeof(XATTR_CONTAINERS_OVERRIDE_PREFIX) - 1);
|
||||
return has_prefix (name, XATTR_CONTAINERS_OVERRIDE_PREFIX) && ! can_access_xattr (l, name + sizeof (XATTR_CONTAINERS_OVERRIDE_PREFIX) - 1);
|
||||
}
|
||||
|
||||
static const char *decode_xattr_name (const struct ovl_layer *l, const char *name)
|
||||
static const char *
|
||||
decode_xattr_name (const struct ovl_layer *l, const char *name)
|
||||
{
|
||||
if (encoded_xattr_name (l, name))
|
||||
return name + sizeof(XATTR_CONTAINERS_OVERRIDE_PREFIX) - 1;
|
||||
return name + sizeof (XATTR_CONTAINERS_OVERRIDE_PREFIX) - 1;
|
||||
|
||||
if (can_access_xattr (l, name))
|
||||
return name;
|
||||
@ -552,18 +535,18 @@ static const char *decode_xattr_name (const struct ovl_layer *l, const char *nam
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *encode_xattr_name (const struct ovl_layer *l, char *buf,
|
||||
const char *name)
|
||||
static const char *
|
||||
encode_xattr_name (const struct ovl_layer *l, char *buf,
|
||||
const char *name)
|
||||
{
|
||||
if (can_access_xattr (l, name))
|
||||
return name;
|
||||
|
||||
if (l->stat_override_mode != STAT_OVERRIDE_CONTAINERS ||
|
||||
strlen(name) > XATTR_NAME_MAX + 1 - sizeof(XATTR_CONTAINERS_OVERRIDE_PREFIX))
|
||||
if (l->stat_override_mode != STAT_OVERRIDE_CONTAINERS || strlen (name) > XATTR_NAME_MAX + 1 - sizeof (XATTR_CONTAINERS_OVERRIDE_PREFIX))
|
||||
return NULL;
|
||||
|
||||
strcpy(buf, XATTR_CONTAINERS_OVERRIDE_PREFIX);
|
||||
strcpy(buf + sizeof(XATTR_CONTAINERS_OVERRIDE_PREFIX) - 1, name);
|
||||
strcpy (buf, XATTR_CONTAINERS_OVERRIDE_PREFIX);
|
||||
strcpy (buf + sizeof (XATTR_CONTAINERS_OVERRIDE_PREFIX) - 1, name);
|
||||
|
||||
return buf;
|
||||
}
|
||||
@ -2645,8 +2628,7 @@ filter_xattrs_list (struct ovl_layer *l, char *buf, ssize_t len)
|
||||
{
|
||||
char *next = it;
|
||||
|
||||
next += encoded_xattr_name (l, it) ?
|
||||
sizeof(XATTR_CONTAINERS_OVERRIDE_PREFIX) - 1 : it_len;
|
||||
next += encoded_xattr_name (l, it) ? sizeof (XATTR_CONTAINERS_OVERRIDE_PREFIX) - 1 : it_len;
|
||||
|
||||
memmove (it, next, buf + len - next);
|
||||
len -= it_len;
|
||||
@ -2742,7 +2724,7 @@ ovl_getxattr (fuse_req_t req, fuse_ino_t ino, const char *name, size_t size)
|
||||
}
|
||||
|
||||
name = encode_xattr_name (node->layer, name_buf, name);
|
||||
if (!name)
|
||||
if (! name)
|
||||
{
|
||||
fuse_reply_err (req, ENODATA);
|
||||
return;
|
||||
@ -3551,12 +3533,12 @@ ovl_setxattr (fuse_req_t req, fuse_ino_t ino, const char *name,
|
||||
return;
|
||||
}
|
||||
|
||||
name = encode_xattr_name (node->layer, name_buf, name);
|
||||
if (!name)
|
||||
{
|
||||
fuse_reply_err (req, EPERM);
|
||||
return;
|
||||
}
|
||||
name = encode_xattr_name (node->layer, name_buf, name);
|
||||
if (! name)
|
||||
{
|
||||
fuse_reply_err (req, EPERM);
|
||||
return;
|
||||
}
|
||||
|
||||
if (! node->hidden)
|
||||
ret = direct_setxattr (node->layer, node->path, name, value, size, flags);
|
||||
@ -3619,12 +3601,12 @@ ovl_removexattr (fuse_req_t req, fuse_ino_t ino, const char *name)
|
||||
return;
|
||||
}
|
||||
|
||||
name = encode_xattr_name (node->layer, name_buf, name);
|
||||
if (!name)
|
||||
{
|
||||
fuse_reply_err (req, EPERM);
|
||||
return;
|
||||
}
|
||||
name = encode_xattr_name (node->layer, name_buf, name);
|
||||
if (! name)
|
||||
{
|
||||
fuse_reply_err (req, EPERM);
|
||||
return;
|
||||
}
|
||||
|
||||
if (! node->hidden)
|
||||
ret = direct_removexattr (node->layer, node->path, name);
|
||||
|
84
utils.c
84
utils.c
@ -224,16 +224,38 @@ open_fd_or_get_path (struct ovl_layer *l, const char *path, char *out, int *fd,
|
||||
return *fd;
|
||||
}
|
||||
|
||||
int
|
||||
read_device (const char *s, dev_t *dev)
|
||||
{
|
||||
unsigned int major, minor;
|
||||
int ret;
|
||||
|
||||
while (*s == '-')
|
||||
s++;
|
||||
|
||||
ret = sscanf (s, "%u-%u", &major, &minor);
|
||||
if (ret != 2)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*dev = makedev (major, minor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
override_mode (struct ovl_layer *l, int fd, const char *abs_path, const char *path, struct stat *st)
|
||||
{
|
||||
int ret;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
mode_t mode;
|
||||
mode_t mode = 0;
|
||||
char buf[64];
|
||||
cleanup_close int cleanup_fd = -1;
|
||||
const char *xattr_name;
|
||||
cleanup_free char *type = NULL;
|
||||
|
||||
switch (st->st_mode & S_IFMT)
|
||||
{
|
||||
@ -296,8 +318,45 @@ override_mode (struct ovl_layer *l, int fd, const char *abs_path, const char *pa
|
||||
|
||||
buf[ret] = '\0';
|
||||
|
||||
ret = sscanf (buf, "%d:%d:%o", &uid, &gid, &mode);
|
||||
if (ret != 3)
|
||||
ret = sscanf (buf, "%d:%d:%o:%ms", &uid, &gid, &mode, &type);
|
||||
if (ret == 4)
|
||||
{
|
||||
if (has_prefix (type, "dir"))
|
||||
mode |= S_IFDIR;
|
||||
else if (has_prefix (type, "file"))
|
||||
mode |= S_IFREG;
|
||||
else if (has_prefix (type, "symlink"))
|
||||
mode |= S_IFLNK;
|
||||
else if (has_prefix (type, "pipe"))
|
||||
mode |= S_IFIFO;
|
||||
else if (has_prefix (type, "socket"))
|
||||
mode |= S_IFSOCK;
|
||||
else if (has_prefix (type, "block"))
|
||||
{
|
||||
mode |= S_IFBLK;
|
||||
ret = read_device (type + strlen ("block"), &st->st_rdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
else if (has_prefix (type, "char"))
|
||||
{
|
||||
mode |= S_IFCHR;
|
||||
ret = read_device (type + strlen ("char"), &st->st_rdev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else if (ret == 3)
|
||||
{
|
||||
/* If a type is not specified, keep the original one. */
|
||||
mode |= (st->st_mode & S_IFMT);
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
@ -305,7 +364,24 @@ override_mode (struct ovl_layer *l, int fd, const char *abs_path, const char *pa
|
||||
|
||||
st->st_uid = uid;
|
||||
st->st_gid = gid;
|
||||
st->st_mode = (st->st_mode & S_IFMT) | mode;
|
||||
st->st_mode = mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
has_prefix (const char *str, const char *pref)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
if (*pref == '\0')
|
||||
return true;
|
||||
if (*str == '\0')
|
||||
return false;
|
||||
if (*pref != *str)
|
||||
return false;
|
||||
str++;
|
||||
pref++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user