diff options
| -rw-r--r-- | fs/cifs/readdir.c | 5 | ||||
| -rw-r--r-- | fs/file.c | 14 | ||||
| -rw-r--r-- | fs/namei.c | 5 | ||||
| -rw-r--r-- | fs/nfs/dir.c | 7 |
4 files changed, 21 insertions, 10 deletions
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index f9b5d3d6cf33..1c576e871366 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
| @@ -86,14 +86,17 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name, | |||
| 86 | 86 | ||
| 87 | dentry = d_lookup(parent, name); | 87 | dentry = d_lookup(parent, name); |
| 88 | if (dentry) { | 88 | if (dentry) { |
| 89 | int err; | ||
| 89 | inode = dentry->d_inode; | 90 | inode = dentry->d_inode; |
| 90 | /* update inode in place if i_ino didn't change */ | 91 | /* update inode in place if i_ino didn't change */ |
| 91 | if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) { | 92 | if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) { |
| 92 | cifs_fattr_to_inode(inode, fattr); | 93 | cifs_fattr_to_inode(inode, fattr); |
| 93 | return dentry; | 94 | return dentry; |
| 94 | } | 95 | } |
| 95 | d_drop(dentry); | 96 | err = d_invalidate(dentry); |
| 96 | dput(dentry); | 97 | dput(dentry); |
| 98 | if (err) | ||
| 99 | return NULL; | ||
| 97 | } | 100 | } |
| 98 | 101 | ||
| 99 | dentry = d_alloc(parent, name); | 102 | dentry = d_alloc(parent, name); |
| @@ -994,16 +994,18 @@ int iterate_fd(struct files_struct *files, unsigned n, | |||
| 994 | const void *p) | 994 | const void *p) |
| 995 | { | 995 | { |
| 996 | struct fdtable *fdt; | 996 | struct fdtable *fdt; |
| 997 | struct file *file; | ||
| 998 | int res = 0; | 997 | int res = 0; |
| 999 | if (!files) | 998 | if (!files) |
| 1000 | return 0; | 999 | return 0; |
| 1001 | spin_lock(&files->file_lock); | 1000 | spin_lock(&files->file_lock); |
| 1002 | fdt = files_fdtable(files); | 1001 | for (fdt = files_fdtable(files); n < fdt->max_fds; n++) { |
| 1003 | while (!res && n < fdt->max_fds) { | 1002 | struct file *file; |
| 1004 | file = rcu_dereference_check_fdtable(files, fdt->fd[n++]); | 1003 | file = rcu_dereference_check_fdtable(files, fdt->fd[n]); |
| 1005 | if (file) | 1004 | if (!file) |
| 1006 | res = f(p, file, n); | 1005 | continue; |
| 1006 | res = f(p, file, n); | ||
| 1007 | if (res) | ||
| 1008 | break; | ||
| 1007 | } | 1009 | } |
| 1008 | spin_unlock(&files->file_lock); | 1010 | spin_unlock(&files->file_lock); |
| 1009 | return res; | 1011 | return res; |
diff --git a/fs/namei.c b/fs/namei.c index 937f9d50c84b..5f4cdf3ad913 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -2131,6 +2131,11 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) | |||
| 2131 | if (!len) | 2131 | if (!len) |
| 2132 | return ERR_PTR(-EACCES); | 2132 | return ERR_PTR(-EACCES); |
| 2133 | 2133 | ||
| 2134 | if (unlikely(name[0] == '.')) { | ||
| 2135 | if (len < 2 || (len == 2 && name[1] == '.')) | ||
| 2136 | return ERR_PTR(-EACCES); | ||
| 2137 | } | ||
| 2138 | |||
| 2134 | while (len--) { | 2139 | while (len--) { |
| 2135 | c = *(const unsigned char *)name++; | 2140 | c = *(const unsigned char *)name++; |
| 2136 | if (c == '/' || c == '\0') | 2141 | if (c == '/' || c == '\0') |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index ce8cb926526b..b9e66b7e0c14 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -450,7 +450,8 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry) | |||
| 450 | nfs_refresh_inode(dentry->d_inode, entry->fattr); | 450 | nfs_refresh_inode(dentry->d_inode, entry->fattr); |
| 451 | goto out; | 451 | goto out; |
| 452 | } else { | 452 | } else { |
| 453 | d_drop(dentry); | 453 | if (d_invalidate(dentry) != 0) |
| 454 | goto out; | ||
| 454 | dput(dentry); | 455 | dput(dentry); |
| 455 | } | 456 | } |
| 456 | } | 457 | } |
| @@ -1100,6 +1101,8 @@ out_set_verifier: | |||
| 1100 | out_zap_parent: | 1101 | out_zap_parent: |
| 1101 | nfs_zap_caches(dir); | 1102 | nfs_zap_caches(dir); |
| 1102 | out_bad: | 1103 | out_bad: |
| 1104 | nfs_free_fattr(fattr); | ||
| 1105 | nfs_free_fhandle(fhandle); | ||
| 1103 | nfs_mark_for_revalidate(dir); | 1106 | nfs_mark_for_revalidate(dir); |
| 1104 | if (inode && S_ISDIR(inode->i_mode)) { | 1107 | if (inode && S_ISDIR(inode->i_mode)) { |
| 1105 | /* Purge readdir caches. */ | 1108 | /* Purge readdir caches. */ |
| @@ -1112,8 +1115,6 @@ out_zap_parent: | |||
| 1112 | shrink_dcache_parent(dentry); | 1115 | shrink_dcache_parent(dentry); |
| 1113 | } | 1116 | } |
| 1114 | d_drop(dentry); | 1117 | d_drop(dentry); |
| 1115 | nfs_free_fattr(fattr); | ||
| 1116 | nfs_free_fhandle(fhandle); | ||
| 1117 | dput(parent); | 1118 | dput(parent); |
| 1118 | dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n", | 1119 | dfprintk(LOOKUPCACHE, "NFS: %s(%s/%s) is invalid\n", |
| 1119 | __func__, dentry->d_parent->d_name.name, | 1120 | __func__, dentry->d_parent->d_name.name, |
