Commit e84962e3 authored by Tristan Lelong's avatar Tristan Lelong Committed by Greg Kroah-Hartman
Browse files

staging: lustre: fix sparse warning on LPROC_SEQ_FOPS macros



This patch fix a sparse warning in lustre sources

warning: incorrect type in argument 1 (different address spaces)
    expected void [noderef] <asn:1>*to
    got char *<noident>

This is done by adding the missing __user attribute on userland pointers inside the LPROC_SEQ_FOPS like macros:
- LPROC_SEQ_FOPS
- LPROC_SEQ_FOPS_RW_TYPE
- LPROC_SEQ_FOPS_WR_ONLY
- LDLM_POOL_PROC_WRITER

The patch also updates all the functions that are used by this macro:
- lprocfs_wr_*
- *_seq_write

as well as some helpers used by the previously modified functions (otherwise fixing the sparse warning add some new ones):
- lprocfs_write_frac_helper
- lprocfs_write_helper
- lprocfs_write_u64_helper

The patch also fixes one __user pointer direct dereference by strncmp in function fld_proc_hash_seq_write.

Signed-off-by: default avatarTristan Lelong <tristan@lelong.xyz>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 41f53d57
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -87,13 +87,25 @@ fld_proc_hash_seq_show(struct seq_file *m, void *unused)
}

static ssize_t
fld_proc_hash_seq_write(struct file *file, const char *buffer,
fld_proc_hash_seq_write(struct file *file,
				const char __user *buffer,
				size_t count, loff_t *off)
{
	struct lu_client_fld *fld;
	struct lu_fld_hash *hash = NULL;
	char *name;
	int i;

	if (count > 80)
		return -ENAMETOOLONG;

	name = kmalloc(count, GFP_KERNEL);
	if (!name)
		return -ENOMEM;

	if (copy_from_user(name, buffer, count) != 0)
		return -EFAULT;

	fld = ((struct seq_file *)file->private_data)->private;
	LASSERT(fld != NULL);

@@ -101,7 +113,7 @@ fld_proc_hash_seq_write(struct file *file, const char *buffer,
		if (count != strlen(fld_hash[i].fh_name))
			continue;

		if (!strncmp(fld_hash[i].fh_name, buffer, count)) {
		if (!strncmp(fld_hash[i].fh_name, name, count)) {
			hash = &fld_hash[i];
			break;
		}
@@ -116,6 +128,7 @@ fld_proc_hash_seq_write(struct file *file, const char *buffer,
		       fld->lcf_name, hash->fh_name);
	}

	kfree(name);
	return count;
}

+25 −19
Original line number Diff line number Diff line
@@ -627,16 +627,16 @@ struct adaptive_timeout;
extern int lprocfs_at_hist_helper(struct seq_file *m,
				  struct adaptive_timeout *at);
extern int lprocfs_rd_timeouts(struct seq_file *m, void *data);
extern int lprocfs_wr_timeouts(struct file *file, const char *buffer,
extern int lprocfs_wr_timeouts(struct file *file, const char __user *buffer,
			       unsigned long count, void *data);
extern int lprocfs_wr_evict_client(struct file *file, const char *buffer,
extern int lprocfs_wr_evict_client(struct file *file, const char __user *buffer,
			    size_t count, loff_t *off);
extern int lprocfs_wr_ping(struct file *file, const char *buffer,
extern int lprocfs_wr_ping(struct file *file, const char __user *buffer,
			   size_t count, loff_t *off);
extern int lprocfs_wr_import(struct file *file, const char *buffer,
extern int lprocfs_wr_import(struct file *file, const char __user *buffer,
		      size_t count, loff_t *off);
extern int lprocfs_rd_pinger_recov(struct seq_file *m, void *n);
extern int lprocfs_wr_pinger_recov(struct file *file, const char *buffer,
extern int lprocfs_wr_pinger_recov(struct file *file, const char __user *buffer,
				   size_t count, loff_t *off);

/* Statfs helpers */
@@ -650,8 +650,8 @@ extern int lprocfs_rd_filesfree(struct seq_file *m, void *data);
extern int lprocfs_write_helper(const char __user *buffer, unsigned long count,
				int *val);
extern int lprocfs_seq_read_frac_helper(struct seq_file *m, long val, int mult);
extern int lprocfs_write_u64_helper(const char *buffer, unsigned long count,
				    __u64 *val);
extern int lprocfs_write_u64_helper(const char __user *buffer,
				unsigned long count, __u64 *val);
extern int lprocfs_write_frac_u64_helper(const char *buffer,
					 unsigned long count,
					 __u64 *val, int mult);
@@ -716,7 +716,8 @@ static struct file_operations name##_fops = { \
		return lprocfs_rd_##type(m, m->private);		\
	}								\
	static ssize_t name##_##type##_seq_write(struct file *file,	\
			const char *buffer, size_t count, loff_t *off)	\
			const char __user *buffer, size_t count,	\
						loff_t *off)		\
	{								\
		struct seq_file *seq = file->private_data;		\
		return lprocfs_wr_##type(file, buffer,			\
@@ -726,7 +727,8 @@ static struct file_operations name##_fops = { \

#define LPROC_SEQ_FOPS_WR_ONLY(name, type)				\
	static ssize_t name##_##type##_write(struct file *file,		\
			const char *buffer, size_t count, loff_t *off)	\
			const char __user *buffer, size_t count,	\
						loff_t *off)		\
	{								\
		return lprocfs_wr_##type(file, buffer, count, off);	\
	}								\
@@ -939,19 +941,23 @@ static inline int lprocfs_at_hist_helper(struct seq_file *m,
static inline int lprocfs_rd_timeouts(struct seq_file *m, void *data)
{ return 0; }
static inline int lprocfs_wr_timeouts(struct file *file,
				      const char *buffer,
				const char __user *buffer,
				unsigned long count, void *data)
{ return 0; }
static inline int lprocfs_wr_evict_client(struct file *file, const char *buffer,
static inline int lprocfs_wr_evict_client(struct file *file,
				const char __user *buffer,
				size_t count, loff_t *off)
{ return 0; }
static inline int lprocfs_wr_ping(struct file *file, const char *buffer,
static inline int lprocfs_wr_ping(struct file *file,
				const char __user *buffer,
				size_t count, loff_t *off)
{ return 0; }
static inline int lprocfs_wr_import(struct file *file, const char *buffer,
static inline int lprocfs_wr_import(struct file *file,
				const char __user *buffer,
				size_t count, loff_t *off)
{ return 0; }
static inline int lprocfs_wr_pinger_recov(struct file *file, const char *buffer,
static inline int lprocfs_wr_pinger_recov(struct file *file,
				const char __user *buffer,
				size_t count, loff_t *off)
{ return 0; }

+3 −2
Original line number Diff line number Diff line
@@ -249,7 +249,8 @@ typedef enum ldlm_policy_res ldlm_policy_res_t;
	struct __##var##__dummy_read {; } /* semicolon catcher */

#define LDLM_POOL_PROC_WRITER(var, type)				    \
	static int lprocfs_wr_##var(struct file *file, const char *buffer,  \
	static int lprocfs_wr_##var(struct file *file,			    \
				const char __user *buffer,		    \
				unsigned long count, void *data)	    \
	{								    \
		struct ldlm_pool *pl = data;				    \
+2 −2
Original line number Diff line number Diff line
@@ -697,8 +697,8 @@ LPROC_SEQ_FOPS_RO(lprocfs_grant_plan);
LDLM_POOL_PROC_READER_SEQ_SHOW(recalc_period, int);
LDLM_POOL_PROC_WRITER(recalc_period, int);
static ssize_t lprocfs_recalc_period_seq_write(struct file *file,
					       const char *buf, size_t len,
					       loff_t *off)
					       const char __user *buf,
					       size_t len, loff_t *off)
{
	struct seq_file *seq = file->private_data;

+4 −3
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ extern unsigned int ldlm_cancel_unused_locks_before_replay;
unsigned int ldlm_dump_granted_max = 256;

#if defined(CONFIG_PROC_FS)
static ssize_t lprocfs_wr_dump_ns(struct file *file, const char *buffer,
static ssize_t lprocfs_wr_dump_ns(struct file *file, const char __user *buffer,
				  size_t count, loff_t *off)
{
	ldlm_dump_all_namespaces(LDLM_NAMESPACE_SERVER, D_DLMTRACE);
@@ -287,7 +287,8 @@ static int lprocfs_elc_seq_show(struct seq_file *m, void *v)
	return lprocfs_rd_uint(m, &supp);
}

static ssize_t lprocfs_elc_seq_write(struct file *file, const char *buffer,
static ssize_t lprocfs_elc_seq_write(struct file *file,
				const char __user *buffer,
				size_t count, loff_t *off)
{
	struct ldlm_namespace *ns = ((struct seq_file *)file->private_data)->private;
Loading