diff options
author | Chao Yu <chao2.yu@samsung.com> | 2015-04-18 06:03:58 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2015-05-07 14:38:31 -0400 |
commit | 272e083f7a968bc81dd01e4f16860a1e9617d454 (patch) | |
tree | 64cff853b2789f18fed41884641d0c0770ac1978 /fs/f2fs/acl.c | |
parent | 5d799881391277e52787df06bafe865e91ae8296 (diff) |
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>
Diffstat (limited to 'fs/f2fs/acl.c')
-rw-r--r-- | fs/f2fs/acl.c | 46 |
1 files changed, 20 insertions, 26 deletions
diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index 4320ffab3495..c8f25f7241f0 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c | |||
@@ -334,51 +334,45 @@ static int f2fs_acl_create(struct inode *dir, umode_t *mode, | |||
334 | struct page *dpage) | 334 | struct page *dpage) |
335 | { | 335 | { |
336 | struct posix_acl *p; | 336 | struct posix_acl *p; |
337 | struct posix_acl *clone; | ||
337 | int ret; | 338 | int ret; |
338 | 339 | ||
340 | *acl = NULL; | ||
341 | *default_acl = NULL; | ||
342 | |||
339 | if (S_ISLNK(*mode) || !IS_POSIXACL(dir)) | 343 | if (S_ISLNK(*mode) || !IS_POSIXACL(dir)) |
340 | goto no_acl; | 344 | return 0; |
341 | 345 | ||
342 | p = __f2fs_get_acl(dir, ACL_TYPE_DEFAULT, dpage); | 346 | p = __f2fs_get_acl(dir, ACL_TYPE_DEFAULT, dpage); |
343 | if (IS_ERR(p)) { | 347 | if (!p || p == ERR_PTR(-EOPNOTSUPP)) { |
344 | if (p == ERR_PTR(-EOPNOTSUPP)) | 348 | *mode &= ~current_umask(); |
345 | goto apply_umask; | 349 | return 0; |
346 | return PTR_ERR(p); | ||
347 | } | 350 | } |
351 | if (IS_ERR(p)) | ||
352 | return PTR_ERR(p); | ||
348 | 353 | ||
349 | if (!p) | 354 | clone = f2fs_acl_clone(p, GFP_NOFS); |
350 | goto apply_umask; | 355 | if (!clone) |
351 | |||
352 | *acl = f2fs_acl_clone(p, GFP_NOFS); | ||
353 | if (!*acl) | ||
354 | goto no_mem; | 356 | goto no_mem; |
355 | 357 | ||
356 | ret = f2fs_acl_create_masq(*acl, mode); | 358 | ret = f2fs_acl_create_masq(clone, mode); |
357 | if (ret < 0) | 359 | if (ret < 0) |
358 | goto no_mem_clone; | 360 | goto no_mem_clone; |
359 | 361 | ||
360 | if (ret == 0) { | 362 | if (ret == 0) |
361 | posix_acl_release(*acl); | 363 | posix_acl_release(clone); |
362 | *acl = NULL; | 364 | else |
363 | } | 365 | *acl = clone; |
364 | 366 | ||
365 | if (!S_ISDIR(*mode)) { | 367 | if (!S_ISDIR(*mode)) |
366 | posix_acl_release(p); | 368 | posix_acl_release(p); |
367 | *default_acl = NULL; | 369 | else |
368 | } else { | ||
369 | *default_acl = p; | 370 | *default_acl = p; |
370 | } | ||
371 | return 0; | ||
372 | 371 | ||
373 | apply_umask: | ||
374 | *mode &= ~current_umask(); | ||
375 | no_acl: | ||
376 | *default_acl = NULL; | ||
377 | *acl = NULL; | ||
378 | return 0; | 372 | return 0; |
379 | 373 | ||
380 | no_mem_clone: | 374 | no_mem_clone: |
381 | posix_acl_release(*acl); | 375 | posix_acl_release(clone); |
382 | no_mem: | 376 | no_mem: |
383 | posix_acl_release(p); | 377 | posix_acl_release(p); |
384 | return -ENOMEM; | 378 | return -ENOMEM; |