Pull vfs fixes from Al Viro: "A couple of fixes for bugs caught while digging in fs/namei.c. The first one is this cycle regression, the second is 3.11 and later" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: path_openat(): fix double fput() namei: d_is_negative() should be checked before ->d_seq validation
Unified · Split
| @@ -1415,6 +1415,7 @@ static int lookup_fast(struct nameidata *nd, · 1414 unmodified lines | |||
| 1415 | */ | 1415 | */ |
| 1416 | if (nd->flags & LOOKUP_RCU) { | 1416 | if (nd->flags & LOOKUP_RCU) { |
| 1417 | unsigned seq; | 1417 | unsigned seq; |
| 1418 | bool negative; | ||
| 1418 | dentry = __d_lookup_rcu(parent, &nd->last, &seq); | 1419 | dentry = __d_lookup_rcu(parent, &nd->last, &seq); |
| 1419 | if (!dentry) | 1420 | if (!dentry) |
| 1420 | goto unlazy; | 1421 | goto unlazy; |
| @@ -1424,8 +1425,11 @@ static int lookup_fast(struct nameidata *nd, · 3 unmodified lines | |||
| 1424 | * the dentry name information from lookup. | 1425 | * the dentry name information from lookup. |
| 1425 | */ | 1426 | */ |
| 1426 | *inode = dentry->d_inode; | 1427 | *inode = dentry->d_inode; |
| 1428 | negative = d_is_negative(dentry); | ||
| 1427 | if (read_seqcount_retry(&dentry->d_seq, seq)) | 1429 | if (read_seqcount_retry(&dentry->d_seq, seq)) |
| 1428 | return -ECHILD; | 1430 | return -ECHILD; |
| 1431 | if (negative) | ||
| 1432 | return -ENOENT; | ||
| 1429 | 1433 | ||
| 1430 | /* | 1434 | /* |
| 1431 | * This sequence count validates that the parent had no | 1435 | * This sequence count validates that the parent had no |
| @@ -1472,6 +1476,10 @@ unlazy: · 40 unmodified lines | |||
| 1472 | goto need_lookup; | 1476 | goto need_lookup; |
| 1473 | } | 1477 | } |
| 1474 | 1478 | ||
| 1479 | if (unlikely(d_is_negative(dentry))) { | ||
| 1480 | dput(dentry); | ||
| 1481 | return -ENOENT; | ||
| 1482 | } | ||
| 1475 | path->mnt = mnt; | 1483 | path->mnt = mnt; |
| 1476 | path->dentry = dentry; | 1484 | path->dentry = dentry; |
| 1477 | err = follow_managed(path, nd->flags); | 1485 | err = follow_managed(path, nd->flags); |
| @@ -1583,10 +1591,10 @@ static inline int walk_component(struct nameidata *nd, struct path *path, · 105 unmodified lines | |||
| 1583 | goto out_err; | 1591 | goto out_err; |
| 1584 | 1592 | ||
| 1585 | inode = path->dentry->d_inode; | 1593 | inode = path->dentry->d_inode; |
| 1594 | err = -ENOENT; | ||
| 1595 | if (d_is_negative(path->dentry)) | ||
| 1596 | goto out_path_put; | ||
| 1586 | } | 1597 | } |
| 1587 | err = -ENOENT; | ||
| 1588 | if (d_is_negative(path->dentry)) | ||
| 1589 | goto out_path_put; | ||
| 1590 | 1598 | ||
| 1591 | if (should_follow_link(path->dentry, follow)) { | 1599 | if (should_follow_link(path->dentry, follow)) { |
| 1592 | if (nd->flags & LOOKUP_RCU) { | 1600 | if (nd->flags & LOOKUP_RCU) { |
| @@ -3036,14 +3044,13 @@ retry_lookup: · 1443 unmodified lines | |||
| 3036 | 3044 | ||
| 3037 | BUG_ON(nd->flags & LOOKUP_RCU); | 3045 | BUG_ON(nd->flags & LOOKUP_RCU); |
| 3038 | inode = path->dentry->d_inode; | 3046 | inode = path->dentry->d_inode; |
| 3039 | finish_lookup: | ||
| 3040 | /* we _can_ be in RCU mode here */ | ||
| 3041 | error = -ENOENT; | 3047 | error = -ENOENT; |
| 3042 | if (d_is_negative(path->dentry)) { | 3048 | if (d_is_negative(path->dentry)) { |
| 3043 | path_to_nameidata(path, nd); | 3049 | path_to_nameidata(path, nd); |
| 3044 | goto out; | 3050 | goto out; |
| 3045 | } | 3051 | } |
| 3046 | 3052 | finish_lookup: | |
| 3053 | /* we _can_ be in RCU mode here */ | ||
| 3047 | if (should_follow_link(path->dentry, !symlink_ok)) { | 3054 | if (should_follow_link(path->dentry, !symlink_ok)) { |
| 3048 | if (nd->flags & LOOKUP_RCU) { | 3055 | if (nd->flags & LOOKUP_RCU) { |
| 3049 | if (unlikely(nd->path.mnt != path->mnt || | 3056 | if (unlikely(nd->path.mnt != path->mnt || |
| @@ -3226,7 +3233,7 @@ static struct file *path_openat(int dfd, struct filename *pathname, · 176 unmodified lines | |||
| 3226 | 3233 | ||
| 3227 | if (unlikely(file->f_flags & __O_TMPFILE)) { | 3234 | if (unlikely(file->f_flags & __O_TMPFILE)) { |
| 3228 | error = do_tmpfile(dfd, pathname, nd, flags, op, file, &opened); | 3235 | error = do_tmpfile(dfd, pathname, nd, flags, op, file, &opened); |
| 3229 | goto out; | 3236 | goto out2; |
| 3230 | } | 3237 | } |
| 3231 | 3238 | ||
| 3232 | error = path_init(dfd, pathname, flags, nd); | 3239 | error = path_init(dfd, pathname, flags, nd); |
| @@ -3256,6 +3263,7 @@ static struct file *path_openat(int dfd, struct filename *pathname, · 23 unmodified lines | |||
| 3256 | } | 3263 | } |
| 3257 | out: | 3264 | out: |
| 3258 | path_cleanup(nd); | 3265 | path_cleanup(nd); |
| 3266 | out2: | ||
| 3259 | if (!(opened & FILE_OPENED)) { | 3267 | if (!(opened & FILE_OPENED)) { |
| 3260 | BUG_ON(!error); | 3268 | BUG_ON(!error); |
| 3261 | put_filp(file); | 3269 | put_filp(file); |