ext4: release leaked posix acl in ext4_acl_chmod

Submitted by Stanislav Kinsburskiy on Feb. 7, 2018, 3:29 p.m.

Details

Message ID 20180207152908.22615.66664.stgit@localhost.localdomain
State New
Series "ext4: release leaked posix acl in ext4_acl_chmod"
Headers show

Commit Message

Stanislav Kinsburskiy Feb. 7, 2018, 3:29 p.m.
Note: only rh7-3.10.0-693.17.1.el7-based kernels are affected.
I.e. starting from rh7-3.10.0-693.17.1.vz7.43.1.

Posix acl is used to convert of an extended attribute, provided by user to
ext4 attributes. In particular to i_mode in case of ACL_TYPE_ACCESS
request.
IOW, this object is allocated, used for convertion, not stored anywhere
and
must be freed.
However posix_acl_update_mode() can zerofy the pointer to support
ext4_set_acl() logic, but then the object is leaked.
So, fix it by releasing new temporary pointer with the same value instead
of
acl pointer.

In scope of https://jira.sw.ru/browse/PSBM-81384

RHEL bug URL: https://bugzilla.redhat.com/show_bug.cgi?id=1543020

Signed-off-by: Stanislav Kinsburskiy <skinsbursky@virtuozzo.com>
---
 fs/ext4/acl.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index f8a38a2..046b338 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -297,7 +297,7 @@  ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
 int
 ext4_acl_chmod(struct inode *inode)
 {
-	struct posix_acl *acl;
+	struct posix_acl *acl, *real_acl;
 	handle_t *handle;
 	int retries = 0;
 	int error;
@@ -315,6 +315,8 @@  ext4_acl_chmod(struct inode *inode)
 	error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
 	if (error)
 		return error;
+
+	real_acl = acl;
 retry:
 	handle = ext4_journal_start(inode, EXT4_HT_XATTR,
 				    ext4_jbd2_credits_xattr(inode));
@@ -341,7 +343,7 @@  ext4_acl_chmod(struct inode *inode)
 	    ext4_should_retry_alloc(inode->i_sb, &retries))
 		goto retry;
 out:
-	posix_acl_release(acl);
+	posix_acl_release(real_acl);
 	return error;
 }
 

Comments

Dmitry Monakhov Feb. 7, 2018, 3:34 p.m.
Stanislav Kinsburskiy <skinsbursky@virtuozzo.com> writes:

> Note: only rh7-3.10.0-693.17.1.el7-based kernels are affected.
> I.e. starting from rh7-3.10.0-693.17.1.vz7.43.1.
>
> Posix acl is used to convert of an extended attribute, provided by user to
> ext4 attributes. In particular to i_mode in case of ACL_TYPE_ACCESS
> request.
> IOW, this object is allocated, used for convertion, not stored anywhere
> and
> must be freed.
> However posix_acl_update_mode() can zerofy the pointer to support
> ext4_set_acl() logic, but then the object is leaked.
> So, fix it by releasing new temporary pointer with the same value instead
> of
> acl pointer.
>
> In scope of https://jira.sw.ru/browse/PSBM-81384
>
> RHEL bug URL: https://bugzilla.redhat.com/show_bug.cgi?id=1543020
ACK.
>
> Signed-off-by: Stanislav Kinsburskiy <skinsbursky@virtuozzo.com>
> ---
>  fs/ext4/acl.c |    6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
> index f8a38a2..046b338 100644
> --- a/fs/ext4/acl.c
> +++ b/fs/ext4/acl.c
> @@ -297,7 +297,7 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir)
>  int
>  ext4_acl_chmod(struct inode *inode)
>  {
> -	struct posix_acl *acl;
> +	struct posix_acl *acl, *real_acl;
>  	handle_t *handle;
>  	int retries = 0;
>  	int error;
> @@ -315,6 +315,8 @@ ext4_acl_chmod(struct inode *inode)
>  	error = posix_acl_chmod(&acl, GFP_KERNEL, inode->i_mode);
>  	if (error)
>  		return error;
> +
> +	real_acl = acl;
>  retry:
>  	handle = ext4_journal_start(inode, EXT4_HT_XATTR,
>  				    ext4_jbd2_credits_xattr(inode));
> @@ -341,7 +343,7 @@ ext4_acl_chmod(struct inode *inode)
>  	    ext4_should_retry_alloc(inode->i_sb, &retries))
>  		goto retry;
>  out:
> -	posix_acl_release(acl);
> +	posix_acl_release(real_acl);
>  	return error;
>  }
>