mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
ovl: skip copy up of empty security.capability
ovl_copy_xattr() gives up if it can't read an attribute that
listxattr() has named. An empty security.capability, which anybody has
been able to store on any file for a long time, is such a case: it is
listed, and getxattr() has nothing to return for it. A file in a lower
layer that carries one can't be copied up: it can't be written to,
renamed or have its mode changed.
There is nothing to copy if there are no data. Go on with the next
one.
Fixes: 8db6c34f1d ("Introduce v3 namespaced file capabilities")
Cc: stable@vger.kernel.org
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
[amir: treat -EINVAL as no capability too, and do the same in
ovl_copy_up_meta_inode_data()]
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
This commit is contained in:
parent
2001cd7ca5
commit
50912a1715
|
|
@ -75,6 +75,15 @@ static int ovl_copy_acl(struct ovl_fs *ofs, const struct path *path,
|
|||
static ssize_t ovl_getxattr_value(const struct path *path, char *name,
|
||||
char **value, ssize_t *value_size);
|
||||
|
||||
/*
|
||||
* Any user can store an empty security.capability, which fails to read with
|
||||
* -EINVAL. It grants no capability, so treat it as none, like no xattr.
|
||||
*/
|
||||
static bool ovl_no_fscap(ssize_t err)
|
||||
{
|
||||
return err == -ENODATA || err == -EOPNOTSUPP || err == -EINVAL;
|
||||
}
|
||||
|
||||
int ovl_copy_xattr(struct super_block *sb, const struct path *oldpath, struct dentry *new)
|
||||
{
|
||||
struct dentry *old = oldpath->dentry;
|
||||
|
|
@ -134,6 +143,10 @@ int ovl_copy_xattr(struct super_block *sb, const struct path *oldpath, struct de
|
|||
|
||||
size = ovl_getxattr_value(oldpath, name, &value, &value_size);
|
||||
if (size < 0) {
|
||||
if (!strcmp(name, XATTR_NAME_CAPS) && ovl_no_fscap(size)) {
|
||||
error = 0;
|
||||
continue;
|
||||
}
|
||||
error = size;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1099,9 +1112,9 @@ static int ovl_copy_up_meta_inode_data(struct ovl_copy_up_ctx *c)
|
|||
if (c->stat.size) {
|
||||
err = cap_size = ovl_getxattr_value(&upperpath, XATTR_NAME_CAPS,
|
||||
&capability, &cap_size);
|
||||
if (cap_size == -ENODATA || cap_size == -EOPNOTSUPP)
|
||||
if (ovl_no_fscap(cap_size))
|
||||
cap_size = 0;
|
||||
if (cap_size < 0)
|
||||
else if (cap_size < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user