aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2011-03-04 13:14:21 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2011-03-04 13:14:21 -0500
commit1858efd471624ecb37e6b5462cab8076f47d1cee (patch)
tree29d1e5d2aad63b798e880011fc527bb4bab63e40 /fs
parentb65a0e0c84cf489bfa00d6aa6c48abc5a237100f (diff)
minimal fix for do_filp_open() race
failure exits on the no-O_CREAT side of do_filp_open() merge with those of O_CREAT one; unfortunately, if do_path_lookup() returns -ESTALE, we'll get out_filp:, notice that we are about to return -ESTALE without having trying to create the sucker with LOOKUP_REVAL and jump right into the O_CREAT side of code. And proceed to try and create a file. Usually that'll fail with -ESTALE again, but we can race and get that attempt of pathname resolution to succeed. open() without O_CREAT really shouldn't end up creating files, races or not. The real fix is to rearchitect the whole do_filp_open(), but for now splitting the failure exits will do. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/namei.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 0087cf9c2c6..a5e844fe4b2 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2455,22 +2455,29 @@ struct file *do_filp_open(int dfd, const char *pathname,
2455 /* !O_CREAT, simple open */ 2455 /* !O_CREAT, simple open */
2456 error = do_path_lookup(dfd, pathname, flags, &nd); 2456 error = do_path_lookup(dfd, pathname, flags, &nd);
2457 if (unlikely(error)) 2457 if (unlikely(error))
2458 goto out_filp; 2458 goto out_filp2;
2459 error = -ELOOP; 2459 error = -ELOOP;
2460 if (!(nd.flags & LOOKUP_FOLLOW)) { 2460 if (!(nd.flags & LOOKUP_FOLLOW)) {
2461 if (nd.inode->i_op->follow_link) 2461 if (nd.inode->i_op->follow_link)
2462 goto out_path; 2462 goto out_path2;
2463 } 2463 }
2464 error = -ENOTDIR; 2464 error = -ENOTDIR;
2465 if (nd.flags & LOOKUP_DIRECTORY) { 2465 if (nd.flags & LOOKUP_DIRECTORY) {
2466 if (!nd.inode->i_op->lookup) 2466 if (!nd.inode->i_op->lookup)
2467 goto out_path; 2467 goto out_path2;
2468 } 2468 }
2469 audit_inode(pathname, nd.path.dentry); 2469 audit_inode(pathname, nd.path.dentry);
2470 filp = finish_open(&nd, open_flag, acc_mode); 2470 filp = finish_open(&nd, open_flag, acc_mode);
2471out2:
2471 release_open_intent(&nd); 2472 release_open_intent(&nd);
2472 return filp; 2473 return filp;
2473 2474
2475out_path2:
2476 path_put(&nd.path);
2477out_filp2:
2478 filp = ERR_PTR(error);
2479 goto out2;
2480
2474creat: 2481creat:
2475 /* OK, have to create the file. Find the parent. */ 2482 /* OK, have to create the file. Find the parent. */
2476 error = path_init_rcu(dfd, pathname, 2483 error = path_init_rcu(dfd, pathname,