Commit 67592126 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 1a59c539 e56f4981
...@@ -153,7 +153,6 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx) ...@@ -153,7 +153,6 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx)
struct dentry *dentry = file->f_path.dentry; struct dentry *dentry = file->f_path.dentry;
struct orangefs_kernel_op_s *new_op = NULL; struct orangefs_kernel_op_s *new_op = NULL;
struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(dentry->d_inode); struct orangefs_inode_s *orangefs_inode = ORANGEFS_I(dentry->d_inode);
int buffer_full = 0;
struct orangefs_readdir_response_s readdir_response; struct orangefs_readdir_response_s readdir_response;
void *dents_buf; void *dents_buf;
int i = 0; int i = 0;
...@@ -350,8 +349,7 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx) ...@@ -350,8 +349,7 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx)
/* /*
* Did we hit the end of the directory? * Did we hit the end of the directory?
*/ */
if (readdir_response.token == ORANGEFS_READDIR_END && if (readdir_response.token == ORANGEFS_READDIR_END) {
!buffer_full) {
gossip_debug(GOSSIP_DIR_DEBUG, gossip_debug(GOSSIP_DIR_DEBUG,
"End of dir detected; setting ctx->pos to ORANGEFS_READDIR_END.\n"); "End of dir detected; setting ctx->pos to ORANGEFS_READDIR_END.\n");
ctx->pos = ORANGEFS_READDIR_END; ctx->pos = ORANGEFS_READDIR_END;
......
...@@ -204,22 +204,8 @@ static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr) ...@@ -204,22 +204,8 @@ static int orangefs_setattr_size(struct inode *inode, struct iattr *iattr)
if (ret != 0) if (ret != 0)
return ret; return ret;
/* if (orig_size != i_size_read(inode))
* 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);
iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME; iattr->ia_valid |= ATTR_CTIME | ATTR_MTIME;
}
return ret; return ret;
} }
......
...@@ -126,8 +126,7 @@ int orangefs_debugfs_init(void) ...@@ -126,8 +126,7 @@ int orangefs_debugfs_init(void)
void orangefs_debugfs_cleanup(void) void orangefs_debugfs_cleanup(void)
{ {
if (debug_dir) debugfs_remove_recursive(debug_dir);
debugfs_remove_recursive(debug_dir);
} }
/* open ORANGEFS_KMOD_DEBUG_HELP_FILE */ /* open ORANGEFS_KMOD_DEBUG_HELP_FILE */
......
...@@ -315,9 +315,13 @@ int orangefs_inode_getattr(struct inode *inode, int new, int size) ...@@ -315,9 +315,13 @@ int orangefs_inode_getattr(struct inode *inode, int new, int size)
inode->i_size = (loff_t)strlen(new_op-> inode->i_size = (loff_t)strlen(new_op->
downcall.resp.getattr.link_target); downcall.resp.getattr.link_target);
orangefs_inode->blksize = (1 << inode->i_blkbits); 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, new_op->downcall.resp.getattr.link_target,
ORANGEFS_NAME_MAX); ORANGEFS_NAME_MAX);
if (ret == -E2BIG) {
ret = -EIO;
goto out;
}
inode->i_link = orangefs_inode->link_target; inode->i_link = orangefs_inode->link_target;
} }
break; break;
......
#include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/spinlock_types.h> #include <linux/spinlock_types.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -74,8 +75,8 @@ static inline void ORANGEFS_khandle_to(const struct orangefs_khandle *kh, ...@@ -74,8 +75,8 @@ static inline void ORANGEFS_khandle_to(const struct orangefs_khandle *kh,
void *p, int size) void *p, int size)
{ {
memset(p, 0, size);
memcpy(p, kh->u, 16); memcpy(p, kh->u, 16);
memset(p + 16, 0, size - 16);
} }
...@@ -427,26 +428,28 @@ struct ORANGEFS_dev_map_desc { ...@@ -427,26 +428,28 @@ struct ORANGEFS_dev_map_desc {
/* gossip.h *****************************************************************/ /* gossip.h *****************************************************************/
#ifdef GOSSIP_DISABLE_DEBUG #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 #else
extern __u64 gossip_debug_mask; extern __u64 gossip_debug_mask;
extern struct client_debug_mask client_debug_mask; extern struct client_debug_mask client_debug_mask;
/* try to avoid function call overhead by checking masks in macro */ /* try to avoid function call overhead by checking masks in macro */
#define gossip_debug(mask, format, f...) \ #define gossip_debug(mask, fmt, ...) \
do { \ do { \
if (gossip_debug_mask & mask) \ if (gossip_debug_mask & (mask)) \
printk(format, ##f); \ printk(KERN_DEBUG fmt, ##__VA_ARGS__); \
} while (0) } while (0)
#endif /* GOSSIP_DISABLE_DEBUG */ #endif /* GOSSIP_DISABLE_DEBUG */
/* do file and line number printouts w/ the GNU preprocessor */ /* do file and line number printouts w/ the GNU preprocessor */
#define gossip_ldebug(mask, format, f...) \ #define gossip_ldebug(mask, fmt, ...) \
gossip_debug(mask, "%s: " format, __func__, ##f) gossip_debug(mask, "%s: " fmt, __func__, ##__VA_ARGS__)
#define gossip_err printk #define gossip_err pr_err
#define gossip_lerr(format, f...) \ #define gossip_lerr(fmt, ...) \
gossip_err("%s line %d: " format, \ gossip_err("%s line %d: " fmt, \
__FILE__, \ __FILE__, __LINE__, ##__VA_ARGS__)
__LINE__, \
##f)
...@@ -73,10 +73,6 @@ ssize_t orangefs_inode_getxattr(struct inode *inode, const char *prefix, ...@@ -73,10 +73,6 @@ ssize_t orangefs_inode_getxattr(struct inode *inode, const char *prefix,
"%s: prefix %s name %s, buffer_size %zd\n", "%s: prefix %s name %s, buffer_size %zd\n",
__func__, prefix, name, size); __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) { if ((strlen(name) + strlen(prefix)) >= ORANGEFS_MAX_XATTR_NAMELEN) {
gossip_err("Invalid key length (%d)\n", gossip_err("Invalid key length (%d)\n",
(int)(strlen(name) + strlen(prefix))); (int)(strlen(name) + strlen(prefix)));
...@@ -146,8 +142,8 @@ ssize_t orangefs_inode_getxattr(struct inode *inode, const char *prefix, ...@@ -146,8 +142,8 @@ ssize_t orangefs_inode_getxattr(struct inode *inode, const char *prefix,
goto out_release_op; goto out_release_op;
} }
memset(buffer, 0, size);
memcpy(buffer, new_op->downcall.resp.getxattr.val, length); memcpy(buffer, new_op->downcall.resp.getxattr.val, length);
memset(buffer + length, 0, size - length);
gossip_debug(GOSSIP_XATTR_DEBUG, gossip_debug(GOSSIP_XATTR_DEBUG,
"orangefs_inode_getxattr: inode %pU " "orangefs_inode_getxattr: inode %pU "
"key %s key_sz %d, val_len %d\n", "key %s key_sz %d, val_len %d\n",
...@@ -239,8 +235,7 @@ int orangefs_inode_setxattr(struct inode *inode, const char *prefix, ...@@ -239,8 +235,7 @@ int orangefs_inode_setxattr(struct inode *inode, const char *prefix,
"%s: prefix %s, name %s, buffer_size %zd\n", "%s: prefix %s, name %s, buffer_size %zd\n",
__func__, prefix, name, size); __func__, prefix, name, size);
if (size < 0 || if (size >= ORANGEFS_MAX_XATTR_VALUELEN ||
size >= ORANGEFS_MAX_XATTR_VALUELEN ||
flags < 0) { flags < 0) {
gossip_err("orangefs_inode_setxattr: bogus values of size(%d), flags(%d)\n", gossip_err("orangefs_inode_setxattr: bogus values of size(%d), flags(%d)\n",
(int)size, (int)size,
...@@ -248,12 +243,6 @@ int orangefs_inode_setxattr(struct inode *inode, const char *prefix, ...@@ -248,12 +243,6 @@ int orangefs_inode_setxattr(struct inode *inode, const char *prefix,
return -EINVAL; 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); internal_flag = convert_to_internal_xattr_flags(flags);
if (prefix) { if (prefix) {
...@@ -353,10 +342,6 @@ ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size) ...@@ -353,10 +342,6 @@ ssize_t orangefs_listxattr(struct dentry *dentry, char *buffer, size_t size)
gossip_err("%s: bogus NULL pointers\n", __func__); gossip_err("%s: bogus NULL pointers\n", __func__);
return -EINVAL; return -EINVAL;
} }
if (size < 0) {
gossip_err("Invalid size (%d)\n", (int)size);
return -EINVAL;
}
down_read(&orangefs_inode->xattr_sem); down_read(&orangefs_inode->xattr_sem);
new_op = op_alloc(ORANGEFS_VFS_OP_LISTXATTR); new_op = op_alloc(ORANGEFS_VFS_OP_LISTXATTR);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment