浏览代码

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
Linus Torvalds 9 年之前
父节点
当前提交
6759212640
共有 6 个文件被更改,包括 28 次插入53 次删除
  1. 1 3
      fs/orangefs/dir.c
  2. 1 15
      fs/orangefs/inode.c
  3. 1 2
      fs/orangefs/orangefs-debugfs.c
  4. 5 1
      fs/orangefs/orangefs-utils.c
  5. 18 15
      fs/orangefs/protocol.h
  6. 2 17
      fs/orangefs/xattr.c

+ 1 - 3
fs/orangefs/dir.c

@@ -153,7 +153,6 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx)
 	struct dentry *dentry = file->f_path.dentry;
 	struct orangefs_kernel_op_s *new_op = NULL;
 	struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(dentry->d_inode);
-	int buffer_full = 0;
 	struct orangefs_readdir_response_s readdir_response;
 	void *dents_buf;
 	int i = 0;
@@ -350,8 +349,7 @@ get_new_buffer_index:
 	/*
 	 * Did we hit the end of the directory?
 	 */
-	if (readdir_response.token == ORANGEFS_READDIR_END &&
-	    !buffer_full) {
+	if (readdir_response.token == ORANGEFS_READDIR_END) {
 		gossip_debug(GOSSIP_DIR_DEBUG,
 		"End of dir detected; setting ctx->pos to ORANGEFS_READDIR_END.\n");
 		ctx->pos = ORANGEFS_READDIR_END;

+ 1 - 15
fs/orangefs/inode.c

@@ -204,22 +204,8 @@ static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr)
 	if (ret != 0)
 		return ret;
 
-	/*
-	 * Only change the c/mtime if we are changing the size or we are
-	 * explicitly asked to change it.  This handles the semantic difference
-	 * between truncate() and ftruncate() as implemented in the VFS.
-	 *
-	 * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a
-	 * special case where we need to update the times despite not having
-	 * these flags set.  For all other operations the VFS set these flags
-	 * explicitly if it wants a timestamp update.
-	 */
-	if (orig_size != i_size_read(inode) &&
-	    !(iattr->ia_valid & (ATTR_CTIME | ATTR_MTIME))) {
-		iattr->ia_ctime = iattr->ia_mtime =
-			current_fs_time(inode->i_sb);
+	if (orig_size != i_size_read(inode))
 		iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME;
-	}
 
 	return ret;
 }

+ 1 - 2
fs/orangefs/orangefs-debugfs.c

@@ -126,8 +126,7 @@ out:
 
 void orangefs_debugfs_cleanup(void)
 {
-	if (debug_dir)
-		debugfs_remove_recursive(debug_dir);
+	debugfs_remove_recursive(debug_dir);
 }
 
 /* open ORANGEFS_KMOD_DEBUG_HELP_FILE */

+ 5 - 1
fs/orangefs/orangefs-utils.c

@@ -315,9 +315,13 @@ int orangefs_inode_getattr(struct inode *inode, int new, int size)
 			inode->i_size = (loff_t)strlen(new_op->
 			    downcall.resp.getattr.link_target);
 			orangefs_inode->blksize = (1 << inode->i_blkbits);
-			strlcpy(orangefs_inode->link_target,
+			ret = strscpy(orangefs_inode->link_target,
 			    new_op->downcall.resp.getattr.link_target,
 			    ORANGEFS_NAME_MAX);
+			if (ret == -E2BIG) {
+				ret = -EIO;
+				goto out;
+			}
 			inode->i_link = orangefs_inode->link_target;
 		}
 		break;

+ 18 - 15
fs/orangefs/protocol.h

@@ -1,3 +1,4 @@
+#include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/spinlock_types.h>
 #include <linux/slab.h>
@@ -74,8 +75,8 @@ static inline void ORANGEFS_khandle_to(const struct orangefs_khandle *kh,
 				   void *p, int size)
 {
 
-	memset(p, 0, size);
 	memcpy(p, kh->u, 16);
+	memset(p + 16, 0, size - 16);
 
 }
 
@@ -427,26 +428,28 @@ struct ORANGEFS_dev_map_desc {
 /* gossip.h *****************************************************************/
 
 #ifdef GOSSIP_DISABLE_DEBUG
-#define gossip_debug(mask, format, f...) do {} while (0)
+#define gossip_debug(mask, fmt, ...)					\
+do {									\
+	if (0)								\
+		printk(KERN_DEBUG fmt, ##__VA_ARGS__);			\
+} while (0)
 #else
 extern __u64 gossip_debug_mask;
 extern struct client_debug_mask client_debug_mask;
 
 /* try to avoid function call overhead by checking masks in macro */
-#define gossip_debug(mask, format, f...)			\
-do {								\
-	if (gossip_debug_mask & mask)				\
-		printk(format, ##f);				\
+#define gossip_debug(mask, fmt, ...)					\
+do {									\
+	if (gossip_debug_mask & (mask))					\
+		printk(KERN_DEBUG fmt, ##__VA_ARGS__);			\
 } while (0)
 #endif /* GOSSIP_DISABLE_DEBUG */
 
 /* do file and line number printouts w/ the GNU preprocessor */
-#define gossip_ldebug(mask, format, f...)				\
-		gossip_debug(mask, "%s: " format, __func__, ##f)
-
-#define gossip_err printk
-#define gossip_lerr(format, f...)					\
-		gossip_err("%s line %d: " format,			\
-			   __FILE__,					\
-			   __LINE__,					\
-			   ##f)
+#define gossip_ldebug(mask, fmt, ...)					\
+	gossip_debug(mask, "%s: " fmt, __func__, ##__VA_ARGS__)
+
+#define gossip_err pr_err
+#define gossip_lerr(fmt, ...)						\
+	gossip_err("%s line %d: " fmt,					\
+		   __FILE__, __LINE__, ##__VA_ARGS__)

+ 2 - 17
fs/orangefs/xattr.c

@@ -73,10 +73,6 @@ ssize_t orangefs_inode_getxattr(struct inode *inode, const char *prefix,
 		     "%s: prefix %s name %s, buffer_size %zd\n",
 		     __func__, prefix, name, size);
 
-	if (name == NULL || (size > 0 && buffer == NULL)) {
-		gossip_err("orangefs_inode_getxattr: bogus NULL pointers\n");
-		return -EINVAL;
-	}
 	if ((strlen(name) + strlen(prefix)) >= ORANGEFS_MAX_XATTR_NAMELEN) {
 		gossip_err("Invalid key length (%d)\n",
 			   (int)(strlen(name) + strlen(prefix)));
@@ -146,8 +142,8 @@ ssize_t orangefs_inode_getxattr(struct inode *inode, const char *prefix,
 		goto out_release_op;
 	}
 
-	memset(buffer, 0, size);
 	memcpy(buffer, new_op->downcall.resp.getxattr.val, length);
+	memset(buffer + length, 0, size - length);
 	gossip_debug(GOSSIP_XATTR_DEBUG,
 	     "orangefs_inode_getxattr: inode %pU "
 	     "key %s key_sz %d, val_len %d\n",
@@ -239,8 +235,7 @@ int orangefs_inode_setxattr(struct inode *inode, const char *prefix,
 		     "%s: prefix %s, name %s, buffer_size %zd\n",
 		     __func__, prefix, name, size);
 
-	if (size < 0 ||
-	    size >= ORANGEFS_MAX_XATTR_VALUELEN ||
+	if (size >= ORANGEFS_MAX_XATTR_VALUELEN ||
 	    flags < 0) {
 		gossip_err("orangefs_inode_setxattr: bogus values of size(%d), flags(%d)\n",
 			   (int)size,
@@ -248,12 +243,6 @@ int orangefs_inode_setxattr(struct inode *inode, const char *prefix,
 		return -EINVAL;
 	}
 
-	if (name == NULL ||
-	    (size > 0 && value == NULL)) {
-		gossip_err("orangefs_inode_setxattr: bogus NULL pointers!\n");
-		return -EINVAL;
-	}
-
 	internal_flag = convert_to_internal_xattr_flags(flags);
 
 	if (prefix) {
@@ -353,10 +342,6 @@ ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size)
 		gossip_err("%s: bogus NULL pointers\n", __func__);
 		return -EINVAL;
 	}
-	if (size < 0) {
-		gossip_err("Invalid size (%d)\n", (int)size);
-		return -EINVAL;
-	}
 
 	down_read(&orangefs_inode->xattr_sem);
 	new_op = op_alloc(ORANGEFS_VFS_OP_LISTXATTR);