aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-04-09 13:33:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-04-09 13:33:58 -0400
commit6759212640fda202d0da5ce2f75dd261f1b879cc (patch)
tree8bdb336a048bfb83b22bf87f32533483ace127fd
parent1a59c53920eed3b2718c07286f1afe8674a7d9e6 (diff)
parente56f49814250f4ca4b66ec7d3a71152846761d1b (diff)
Merge tag 'for-linus-4.6-ofs1' of git://git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux
Pull orangefs fixes from Mike Marshall: "Orangefs cleanups and a strncpy vulnerability fix. Cleanups: - remove an unused variable from orangefs_readdir. - clean up printk wrapper used for ofs "gossip" debugging. - clean up truncate ctime and mtime setting in inode.c - remove a useless null check found by coccinelle. - optimize some memcpy/memset boilerplate code. - remove some useless sanity checks from xattr.c Fix: - fix a potential strncpy vulnerability" * tag 'for-linus-4.6-ofs1' of git://git.kernel.org/pub/scm/linux/kernel/git/hubcap/linux: orangefs: remove unused variable orangefs: Add KERN_<LEVEL> to gossip_<level> macros orangefs: strncpy -> strscpy orangefs: clean up truncate ctime and mtime setting Orangefs: fix ifnullfree.cocci warnings Orangefs: optimize boilerplate code. Orangefs: xattr.c cleanup
-rw-r--r--fs/orangefs/dir.c4
-rw-r--r--fs/orangefs/inode.c16
-rw-r--r--fs/orangefs/orangefs-debugfs.c3
-rw-r--r--fs/orangefs/orangefs-utils.c6
-rw-r--r--fs/orangefs/protocol.h33
-rw-r--r--fs/orangefs/xattr.c19
6 files changed, 28 insertions, 53 deletions
diff --git a/fs/orangefs/dir.c b/fs/orangefs/dir.c
index ba7dec40771e..324f0af40d7b 100644
--- a/fs/orangefs/dir.c
+++ b/fs/orangefs/dir.c
@@ -153,7 +153,6 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx)
153 struct dentry *dentry = file->f_path.dentry; 153 struct dentry *dentry = file->f_path.dentry;
154 struct orangefs_kernel_op_s *new_op = NULL; 154 struct orangefs_kernel_op_s *new_op = NULL;
155 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(dentry->d_inode); 155 struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(dentry->d_inode);
156 int buffer_full = 0;
157 struct orangefs_readdir_response_s readdir_response; 156 struct orangefs_readdir_response_s readdir_response;
158 void *dents_buf; 157 void *dents_buf;
159 int i = 0; 158 int i = 0;
@@ -350,8 +349,7 @@ get_new_buffer_index:
350 /* 349 /*
351 * Did we hit the end of the directory? 350 * Did we hit the end of the directory?
352 */ 351 */
353 if (readdir_response.token == ORANGEFS_READDIR_END && 352 if (readdir_response.token == ORANGEFS_READDIR_END) {
354 !buffer_full) {
355 gossip_debug(GOSSIP_DIR_DEBUG, 353 gossip_debug(GOSSIP_DIR_DEBUG,
356 "End of dir detected; setting ctx->pos to ORANGEFS_READDIR_END.\n"); 354 "End of dir detected; setting ctx->pos to ORANGEFS_READDIR_END.\n");
357 ctx->pos = ORANGEFS_READDIR_END; 355 ctx->pos = ORANGEFS_READDIR_END;
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index 0166faabf8f2..85640e955cde 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -204,22 +204,8 @@ static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr)
204 if (ret != 0) 204 if (ret != 0)
205 return ret; 205 return ret;
206 206
207 /* 207 if (orig_size != i_size_read(inode))
208 * Only change the c/mtime if we are changing the size or we are
209 * explicitly asked to change it. This handles the semantic difference
210 * between truncate() and ftruncate() as implemented in the VFS.
211 *
212 * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a
213 * special case where we need to update the times despite not having
214 * these flags set. For all other operations the VFS set these flags
215 * explicitly if it wants a timestamp update.
216 */
217 if (orig_size != i_size_read(inode) &&
218 !(iattr->ia_valid & (ATTR_CTIME | ATTR_MTIME))) {
219 iattr->ia_ctime = iattr->ia_mtime =
220 current_fs_time(inode->i_sb);
221 iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME; 208 iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME;
222 }
223 209
224 return ret; 210 return ret;
225} 211}
diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c
index 19670b8b4053..1714a737d556 100644
--- a/fs/orangefs/orangefs-debugfs.c
+++ b/fs/orangefs/orangefs-debugfs.c
@@ -126,8 +126,7 @@ out:
126 126
127void orangefs_debugfs_cleanup(void) 127void orangefs_debugfs_cleanup(void)
128{ 128{
129 if (debug_dir) 129 debugfs_remove_recursive(debug_dir);
130 debugfs_remove_recursive(debug_dir);
131} 130}
132 131
133/* open ORANGEFS_KMOD_DEBUG_HELP_FILE */ 132/* open ORANGEFS_KMOD_DEBUG_HELP_FILE */
diff --git a/fs/orangefs/orangefs-utils.c b/fs/orangefs/orangefs-utils.c
index 8277aba65e87..2d129b5886ee 100644
--- a/fs/orangefs/orangefs-utils.c
+++ b/fs/orangefs/orangefs-utils.c
@@ -315,9 +315,13 @@ int orangefs_inode_getattr(struct inode *inode, int new, int size)
315 inode->i_size = (loff_t)strlen(new_op-> 315 inode->i_size = (loff_t)strlen(new_op->
316 downcall.resp.getattr.link_target); 316 downcall.resp.getattr.link_target);
317 orangefs_inode->blksize = (1 << inode->i_blkbits); 317 orangefs_inode->blksize = (1 << inode->i_blkbits);
318 strlcpy(orangefs_inode->link_target, 318 ret = strscpy(orangefs_inode->link_target,
319 new_op->downcall.resp.getattr.link_target, 319 new_op->downcall.resp.getattr.link_target,
320 ORANGEFS_NAME_MAX); 320 ORANGEFS_NAME_MAX);
321 if (ret == -E2BIG) {
322 ret = -EIO;
323 goto out;
324 }
321 inode->i_link = orangefs_inode->link_target; 325 inode->i_link = orangefs_inode->link_target;
322 } 326 }
323 break; 327 break;
diff --git a/fs/orangefs/protocol.h b/fs/orangefs/protocol.h
index 50578a28bd9e..1efc6f8a5224 100644
--- a/fs/orangefs/protocol.h
+++ b/fs/orangefs/protocol.h
@@ -1,3 +1,4 @@
1#include <linux/kernel.h>
1#include <linux/types.h> 2#include <linux/types.h>
2#include <linux/spinlock_types.h> 3#include <linux/spinlock_types.h>
3#include <linux/slab.h> 4#include <linux/slab.h>
@@ -74,8 +75,8 @@ static inline void ORANGEFS_khandle_to(const struct orangefs_khandle *kh,
74 void *p, int size) 75 void *p, int size)
75{ 76{
76 77
77 memset(p, 0, size);
78 memcpy(p, kh->u, 16); 78 memcpy(p, kh->u, 16);
79 memset(p + 16, 0, size - 16);
79 80
80} 81}
81 82
@@ -427,26 +428,28 @@ struct ORANGEFS_dev_map_desc {
427/* gossip.h *****************************************************************/ 428/* gossip.h *****************************************************************/
428 429
429#ifdef GOSSIP_DISABLE_DEBUG 430#ifdef GOSSIP_DISABLE_DEBUG
430#define gossip_debug(mask, format, f...) do {} while (0) 431#define gossip_debug(mask, fmt, ...) \
432do { \
433 if (0) \
434 printk(KERN_DEBUG fmt, ##__VA_ARGS__); \
435} while (0)
431#else 436#else
432extern __u64 gossip_debug_mask; 437extern __u64 gossip_debug_mask;
433extern struct client_debug_mask client_debug_mask; 438extern struct client_debug_mask client_debug_mask;
434 439
435/* try to avoid function call overhead by checking masks in macro */ 440/* try to avoid function call overhead by checking masks in macro */
436#define gossip_debug(mask, format, f...) \ 441#define gossip_debug(mask, fmt, ...) \
437do { \ 442do { \
438 if (gossip_debug_mask & mask) \ 443 if (gossip_debug_mask & (mask)) \
439 printk(format, ##f); \ 444 printk(KERN_DEBUG fmt, ##__VA_ARGS__); \
440} while (0) 445} while (0)
441#endif /* GOSSIP_DISABLE_DEBUG */ 446#endif /* GOSSIP_DISABLE_DEBUG */
442 447
443/* do file and line number printouts w/ the GNU preprocessor */ 448/* do file and line number printouts w/ the GNU preprocessor */
444#define gossip_ldebug(mask, format, f...) \ 449#define gossip_ldebug(mask, fmt, ...) \
445 gossip_debug(mask, "%s: " format, __func__, ##f) 450 gossip_debug(mask, "%s: " fmt, __func__, ##__VA_ARGS__)
446 451
447#define gossip_err printk 452#define gossip_err pr_err
448#define gossip_lerr(format, f...) \ 453#define gossip_lerr(fmt, ...) \
449 gossip_err("%s line %d: " format, \ 454 gossip_err("%s line %d: " fmt, \
450 __FILE__, \ 455 __FILE__, __LINE__, ##__VA_ARGS__)
451 __LINE__, \
452 ##f)
diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c
index ef5da7538cd5..63a6280d8c3a 100644
--- a/fs/orangefs/xattr.c
+++ b/fs/orangefs/xattr.c
@@ -73,10 +73,6 @@ ssize_t orangefs_inode_getxattr(struct inode *inode, const char *prefix,
73 "%s: prefix %s name %s, buffer_size %zd\n", 73 "%s: prefix %s name %s, buffer_size %zd\n",
74 __func__, prefix, name, size); 74 __func__, prefix, name, size);
75 75
76 if (name == NULL || (size > 0 && buffer == NULL)) {
77 gossip_err("orangefs_inode_getxattr: bogus NULL pointers\n");
78 return -EINVAL;
79 }
80 if ((strlen(name) + strlen(prefix)) >= ORANGEFS_MAX_XATTR_NAMELEN) { 76 if ((strlen(name) + strlen(prefix)) >= ORANGEFS_MAX_XATTR_NAMELEN) {
81 gossip_err("Invalid key length (%d)\n", 77 gossip_err("Invalid key length (%d)\n",
82 (int)(strlen(name) + strlen(prefix))); 78 (int)(strlen(name) + strlen(prefix)));
@@ -146,8 +142,8 @@ ssize_t orangefs_inode_getxattr(struct inode *inode, const char *prefix,
146 goto out_release_op; 142 goto out_release_op;
147 } 143 }
148 144
149 memset(buffer, 0, size);
150 memcpy(buffer, new_op->downcall.resp.getxattr.val, length); 145 memcpy(buffer, new_op->downcall.resp.getxattr.val, length);
146 memset(buffer + length, 0, size - length);
151 gossip_debug(GOSSIP_XATTR_DEBUG, 147 gossip_debug(GOSSIP_XATTR_DEBUG,
152 "orangefs_inode_getxattr: inode %pU " 148 "orangefs_inode_getxattr: inode %pU "
153 "key %s key_sz %d, val_len %d\n", 149 "key %s key_sz %d, val_len %d\n",
@@ -239,8 +235,7 @@ int orangefs_inode_setxattr(struct inode *inode, const char *prefix,
239 "%s: prefix %s, name %s, buffer_size %zd\n", 235 "%s: prefix %s, name %s, buffer_size %zd\n",
240 __func__, prefix, name, size); 236 __func__, prefix, name, size);
241 237
242 if (size < 0 || 238 if (size >= ORANGEFS_MAX_XATTR_VALUELEN ||
243 size >= ORANGEFS_MAX_XATTR_VALUELEN ||
244 flags < 0) { 239 flags < 0) {
245 gossip_err("orangefs_inode_setxattr: bogus values of size(%d), flags(%d)\n", 240 gossip_err("orangefs_inode_setxattr: bogus values of size(%d), flags(%d)\n",
246 (int)size, 241 (int)size,
@@ -248,12 +243,6 @@ int orangefs_inode_setxattr(struct inode *inode, const char *prefix,
248 return -EINVAL; 243 return -EINVAL;
249 } 244 }
250 245
251 if (name == NULL ||
252 (size > 0 && value == NULL)) {
253 gossip_err("orangefs_inode_setxattr: bogus NULL pointers!\n");
254 return -EINVAL;
255 }
256
257 internal_flag = convert_to_internal_xattr_flags(flags); 246 internal_flag = convert_to_internal_xattr_flags(flags);
258 247
259 if (prefix) { 248 if (prefix) {
@@ -353,10 +342,6 @@ ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size)
353 gossip_err("%s: bogus NULL pointers\n", __func__); 342 gossip_err("%s: bogus NULL pointers\n", __func__);
354 return -EINVAL; 343 return -EINVAL;
355 } 344 }
356 if (size < 0) {
357 gossip_err("Invalid size (%d)\n", (int)size);
358 return -EINVAL;
359 }
360 345
361 down_read(&orangefs_inode->xattr_sem); 346 down_read(&orangefs_inode->xattr_sem);
362 new_op = op_alloc(ORANGEFS_VFS_OP_LISTXATTR); 347 new_op = op_alloc(ORANGEFS_VFS_OP_LISTXATTR);