diff mbox series

[SRU,Xenial] UBUNTU: SAUCE: vfs_setxattr: free converted value if xattr_permission returns error

Message ID 20210415232336.199462-3-cascardo@canonical.com
State New
Headers show
Series [SRU,Xenial] UBUNTU: SAUCE: vfs_setxattr: free converted value if xattr_permission returns error | expand

Commit Message

Thadeu Lima de Souza Cascardo April 15, 2021, 11:23 p.m. UTC
BugLink: https://bugs.launchpad.net/bugs/1924611

The backport of commit 7c03e2cda4a5 ("vfs: move cap_convert_nscap() call
into vfs_setxattr()") did not consider that vfs_setxattr had other exit
paths that would require a converted value to be freed.

If xattr_permission returns a failure, it would cause a memory leak. In the
case of security.capability attribute, which is the only that can allocate
a new value, xattr_permission will return a failure in case of
HAS_UNMAPPED_ID(inode), which would already be caught by cap_convert_nscap,
at !capable_wrt_inode_uidgid(inode, CAP_SETFCAP).

However, if the file IS_IMMUTABLE or IS_APPEND, the failure will be
returned and the leak will happen.

Though setting a file as immutable or append is restricted to
CAP_FILE_IMMUTABLE, the leak was still shown to happen when trying to
setcap on an immutable file after doing a mount unshare.

Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
---
 fs/xattr.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Krzysztof Kozlowski April 16, 2021, 7:19 a.m. UTC | #1
On 16/04/2021 01:23, Thadeu Lima de Souza Cascardo wrote:
> BugLink: https://bugs.launchpad.net/bugs/1924611
> 
> The backport of commit 7c03e2cda4a5 ("vfs: move cap_convert_nscap() call
> into vfs_setxattr()") did not consider that vfs_setxattr had other exit
> paths that would require a converted value to be freed.
> 
> If xattr_permission returns a failure, it would cause a memory leak. In the
> case of security.capability attribute, which is the only that can allocate
> a new value, xattr_permission will return a failure in case of
> HAS_UNMAPPED_ID(inode), which would already be caught by cap_convert_nscap,
> at !capable_wrt_inode_uidgid(inode, CAP_SETFCAP).
> 
> However, if the file IS_IMMUTABLE or IS_APPEND, the failure will be
> returned and the leak will happen.
> 
> Though setting a file as immutable or append is restricted to
> CAP_FILE_IMMUTABLE, the leak was still shown to happen when trying to
> setcap on an immutable file after doing a mount unshare.
> 
> Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
> ---
>  fs/xattr.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

Just in case there  is any other derivative work from this kernel:
Fixes: f9e973d2d1ca ("vfs: move cap_convert_nscap() call into vfs_setxattr()")

Best regards,
Krzysztof
diff mbox series

Patch

diff --git a/fs/xattr.c b/fs/xattr.c
index 6f38106d08dc..53086977db5c 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -142,7 +142,7 @@  vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 
 	error = xattr_permission(inode, name, MAY_WRITE);
 	if (error)
-		return error;
+		goto out_free;
 
 	mutex_lock(&inode->i_mutex);
 	error = security_inode_setxattr(dentry, name, value, size, flags);
@@ -153,6 +153,7 @@  vfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 
 out:
 	mutex_unlock(&inode->i_mutex);
+out_free:
 	if (value != orig_value)
 		kfree(value);