Commit 5a10b5bd authored by Seth Forshee's avatar Seth Forshee Committed by Luis Henriques

UBUNTU: SAUCE: (namespace) posix_acl: Export posix_acl_fix_xattr_userns() to modules

BugLink: http://bugs.launchpad.net/bugs/1634964

Fuse will make use of this function to provide backwards-
compatible acl support when proper posix acl support is added.
Add a check to return immediately if the to and from namespaces
are the same, and remove equivalent checks from its callers.

Also return an error code to indicate to callers whether or not
the conversion of the id between the user namespaces was
successful. For a valid xattr the id will continue to be changed
regardless to maintain the current behaviour for existing
callers, so they do not require updates to handle failed
conversions.
Signed-off-by: default avatarSeth Forshee <seth.forshee@canonical.com>
Acked-by: default avatarTim Gardner <tim.gardner@canonical.com>
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
parent 392767a8
......@@ -626,58 +626,68 @@ EXPORT_SYMBOL(posix_acl_update_mode);
/*
* Fix up the uids and gids in posix acl extended attributes in place.
*/
static void posix_acl_fix_xattr_userns(
int posix_acl_fix_xattr_userns(
struct user_namespace *to, struct user_namespace *from,
void *value, size_t size)
{
posix_acl_xattr_header *header = (posix_acl_xattr_header *)value;
posix_acl_xattr_entry *entry = (posix_acl_xattr_entry *)(header+1), *end;
int count;
kuid_t uid;
kgid_t gid;
kuid_t kuid;
kgid_t kgid;
uid_t uid;
gid_t gid;
int ret = 0;
if (to == from)
return 0;
if (!value)
return;
return 0;
if (size < sizeof(posix_acl_xattr_header))
return;
return -EINVAL;
if (header->a_version != cpu_to_le32(POSIX_ACL_XATTR_VERSION))
return;
return -EINVAL;
count = posix_acl_xattr_count(size);
if (count < 0)
return;
return -EINVAL;
if (count == 0)
return;
return 0;
for (end = entry + count; entry != end; entry++) {
switch(le16_to_cpu(entry->e_tag)) {
case ACL_USER:
uid = make_kuid(from, le32_to_cpu(entry->e_id));
entry->e_id = cpu_to_le32(from_kuid(to, uid));
kuid = make_kuid(from, le32_to_cpu(entry->e_id));
uid = from_kuid(to, kuid);
entry->e_id = cpu_to_le32(uid);
if (uid == (uid_t)-1)
ret = -EOVERFLOW;
break;
case ACL_GROUP:
gid = make_kgid(from, le32_to_cpu(entry->e_id));
entry->e_id = cpu_to_le32(from_kgid(to, gid));
kgid = make_kgid(from, le32_to_cpu(entry->e_id));
gid = from_kgid(to, kgid);
entry->e_id = cpu_to_le32(gid);
if (gid == (gid_t)-1)
ret = -EOVERFLOW;
break;
default:
break;
}
}
return ret;
}
EXPORT_SYMBOL(posix_acl_fix_xattr_userns);
void posix_acl_fix_xattr_from_user(void *value, size_t size)
{
struct user_namespace *user_ns = current_user_ns();
if (user_ns == &init_user_ns)
return;
posix_acl_fix_xattr_userns(&init_user_ns, user_ns, value, size);
}
void posix_acl_fix_xattr_to_user(void *value, size_t size)
{
struct user_namespace *user_ns = current_user_ns();
if (user_ns == &init_user_ns)
return;
posix_acl_fix_xattr_userns(user_ns, &init_user_ns, value, size);
}
......
......@@ -53,9 +53,18 @@ posix_acl_xattr_count(size_t size)
}
#ifdef CONFIG_FS_POSIX_ACL
int posix_acl_fix_xattr_userns(struct user_namespace *to,
struct user_namespace *from,
void *value, size_t size);
void posix_acl_fix_xattr_from_user(void *value, size_t size);
void posix_acl_fix_xattr_to_user(void *value, size_t size);
#else
static inline int posix_acl_fix_xattr_userns(struct user_namespace *to,
struct user_namespace *from,
void *value, size_t size)
{
return 0;
}
static inline void posix_acl_fix_xattr_from_user(void *value, size_t size)
{
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment