summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-04-09 10:33:58 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2016-04-09 10:33:58 -0700
commit6759212640fda202d0da5ce2f75dd261f1b879cc (patch)
tree8bdb336a048bfb83b22bf87f32533483ace127fd
parent1a59c53920eed3b2718c07286f1afe8674a7d9e6 (diff)
parente56f49814250f4ca4b66ec7d3a71152846761d1b (diff)
downloadlinux-sh-6759212640fda202d0da5ce2f75dd261f1b879cc.tar.gz
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)
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;
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)
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;
}
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:
void orangefs_debugfs_cleanup(void)
{
- if (debug_dir)
- debugfs_remove_recursive(debug_dir);
+ debugfs_remove_recursive(debug_dir);
}
/* 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)
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;
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 @@
+#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__)
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,
"%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);