f2fs: make posix_acl_create() safer and cleaner
Our f2fs_acl_create is copied from posix_acl_create in ./fs/posix_acl.c and
modified to avoid deadlock bug when inline_dentry feature is enabled.
Dan Carpenter rewrites posix_acl_create in commit 2799563b281f
("fs/posix_acl.c: make posix_acl_create() safer and cleaner") to make this
function more safer, so that we can avoid potential bug in its caller,
especially for ocfs2.
Let's back port the patch to f2fs.
Signed-off-by: Chao Yu <chao2.yu@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
@@ -334,51 +334,45 @@ static int f2fs_acl_create(struct inode *dir, umode_t *mode,
|
|||||||
struct page *dpage)
|
struct page *dpage)
|
||||||
{
|
{
|
||||||
struct posix_acl *p;
|
struct posix_acl *p;
|
||||||
|
struct posix_acl *clone;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
*acl = NULL;
|
||||||
|
*default_acl = NULL;
|
||||||
|
|
||||||
if (S_ISLNK(*mode) || !IS_POSIXACL(dir))
|
if (S_ISLNK(*mode) || !IS_POSIXACL(dir))
|
||||||
goto no_acl;
|
return 0;
|
||||||
|
|
||||||
p = __f2fs_get_acl(dir, ACL_TYPE_DEFAULT, dpage);
|
p = __f2fs_get_acl(dir, ACL_TYPE_DEFAULT, dpage);
|
||||||
if (IS_ERR(p)) {
|
if (!p || p == ERR_PTR(-EOPNOTSUPP)) {
|
||||||
if (p == ERR_PTR(-EOPNOTSUPP))
|
*mode &= ~current_umask();
|
||||||
goto apply_umask;
|
return 0;
|
||||||
return PTR_ERR(p);
|
|
||||||
}
|
}
|
||||||
|
if (IS_ERR(p))
|
||||||
|
return PTR_ERR(p);
|
||||||
|
|
||||||
if (!p)
|
clone = f2fs_acl_clone(p, GFP_NOFS);
|
||||||
goto apply_umask;
|
if (!clone)
|
||||||
|
|
||||||
*acl = f2fs_acl_clone(p, GFP_NOFS);
|
|
||||||
if (!*acl)
|
|
||||||
goto no_mem;
|
goto no_mem;
|
||||||
|
|
||||||
ret = f2fs_acl_create_masq(*acl, mode);
|
ret = f2fs_acl_create_masq(clone, mode);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto no_mem_clone;
|
goto no_mem_clone;
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0)
|
||||||
posix_acl_release(*acl);
|
posix_acl_release(clone);
|
||||||
*acl = NULL;
|
else
|
||||||
}
|
*acl = clone;
|
||||||
|
|
||||||
if (!S_ISDIR(*mode)) {
|
if (!S_ISDIR(*mode))
|
||||||
posix_acl_release(p);
|
posix_acl_release(p);
|
||||||
*default_acl = NULL;
|
else
|
||||||
} else {
|
|
||||||
*default_acl = p;
|
*default_acl = p;
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
apply_umask:
|
|
||||||
*mode &= ~current_umask();
|
|
||||||
no_acl:
|
|
||||||
*default_acl = NULL;
|
|
||||||
*acl = NULL;
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
no_mem_clone:
|
no_mem_clone:
|
||||||
posix_acl_release(*acl);
|
posix_acl_release(clone);
|
||||||
no_mem:
|
no_mem:
|
||||||
posix_acl_release(p);
|
posix_acl_release(p);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|||||||
Reference in New Issue
Block a user