Commit f0fc8696 authored by Al Viro's avatar Al Viro

switch wireless debugfs ->write() instances to memdup_user_nul()

again, it only parses the contents of the copied buffer, so
get_zeroed_page() might as well had been kmalloc(), which makes
it open-coded memdup_user_nul()
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 8365a719
...@@ -56,19 +56,15 @@ static ssize_t lbs_sleepparams_write(struct file *file, ...@@ -56,19 +56,15 @@ static ssize_t lbs_sleepparams_write(struct file *file,
loff_t *ppos) loff_t *ppos)
{ {
struct lbs_private *priv = file->private_data; struct lbs_private *priv = file->private_data;
ssize_t buf_size, ret; ssize_t ret;
struct sleep_params sp; struct sleep_params sp;
int p1, p2, p3, p4, p5, p6; int p1, p2, p3, p4, p5, p6;
unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf;
char *buf = (char *)addr;
if (!buf) buf = memdup_user_nul(user_buf, min(count, len - 1));
return -ENOMEM; if (IS_ERR(buf))
return PTR_ERR(buf);
buf_size = min(count, len - 1);
if (copy_from_user(buf, user_buf, buf_size)) {
ret = -EFAULT;
goto out_unlock;
}
ret = sscanf(buf, "%d %d %d %d %d %d", &p1, &p2, &p3, &p4, &p5, &p6); ret = sscanf(buf, "%d %d %d %d %d %d", &p1, &p2, &p3, &p4, &p5, &p6);
if (ret != 6) { if (ret != 6) {
ret = -EINVAL; ret = -EINVAL;
...@@ -88,7 +84,7 @@ static ssize_t lbs_sleepparams_write(struct file *file, ...@@ -88,7 +84,7 @@ static ssize_t lbs_sleepparams_write(struct file *file,
ret = -EINVAL; ret = -EINVAL;
out_unlock: out_unlock:
free_page(addr); kfree(buf);
return ret; return ret;
} }
...@@ -125,18 +121,14 @@ static ssize_t lbs_host_sleep_write(struct file *file, ...@@ -125,18 +121,14 @@ static ssize_t lbs_host_sleep_write(struct file *file,
loff_t *ppos) loff_t *ppos)
{ {
struct lbs_private *priv = file->private_data; struct lbs_private *priv = file->private_data;
ssize_t buf_size, ret; ssize_t ret;
int host_sleep; int host_sleep;
unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf;
char *buf = (char *)addr;
if (!buf) buf = memdup_user_nul(user_buf, min(count, len - 1));
return -ENOMEM; if (IS_ERR(buf))
return PTR_ERR(buf);
buf_size = min(count, len - 1);
if (copy_from_user(buf, user_buf, buf_size)) {
ret = -EFAULT;
goto out_unlock;
}
ret = sscanf(buf, "%d", &host_sleep); ret = sscanf(buf, "%d", &host_sleep);
if (ret != 1) { if (ret != 1) {
ret = -EINVAL; ret = -EINVAL;
...@@ -162,7 +154,7 @@ static ssize_t lbs_host_sleep_write(struct file *file, ...@@ -162,7 +154,7 @@ static ssize_t lbs_host_sleep_write(struct file *file,
ret = count; ret = count;
out_unlock: out_unlock:
free_page(addr); kfree(buf);
return ret; return ret;
} }
...@@ -281,21 +273,15 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask, ...@@ -281,21 +273,15 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask,
struct cmd_ds_802_11_subscribe_event *events; struct cmd_ds_802_11_subscribe_event *events;
struct mrvl_ie_thresholds *tlv; struct mrvl_ie_thresholds *tlv;
struct lbs_private *priv = file->private_data; struct lbs_private *priv = file->private_data;
ssize_t buf_size;
int value, freq, new_mask; int value, freq, new_mask;
uint16_t curr_mask; uint16_t curr_mask;
char *buf; char *buf;
int ret; int ret;
buf = (char *)get_zeroed_page(GFP_KERNEL); buf = memdup_user_nul(userbuf, min(count, len - 1));
if (!buf) if (IS_ERR(buf))
return -ENOMEM; return PTR_ERR(buf);
buf_size = min(count, len - 1);
if (copy_from_user(buf, userbuf, buf_size)) {
ret = -EFAULT;
goto out_page;
}
ret = sscanf(buf, "%d %d %d", &value, &freq, &new_mask); ret = sscanf(buf, "%d %d %d", &value, &freq, &new_mask);
if (ret != 3) { if (ret != 3) {
ret = -EINVAL; ret = -EINVAL;
...@@ -343,7 +329,7 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask, ...@@ -343,7 +329,7 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask,
out_events: out_events:
kfree(events); kfree(events);
out_page: out_page:
free_page((unsigned long)buf); kfree(buf);
return ret; return ret;
} }
...@@ -472,22 +458,15 @@ static ssize_t lbs_rdmac_write(struct file *file, ...@@ -472,22 +458,15 @@ static ssize_t lbs_rdmac_write(struct file *file,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct lbs_private *priv = file->private_data; struct lbs_private *priv = file->private_data;
ssize_t res, buf_size; char *buf;
unsigned long addr = get_zeroed_page(GFP_KERNEL);
char *buf = (char *)addr; buf = memdup_user_nul(userbuf, min(count, len - 1));
if (!buf) if (IS_ERR(buf))
return -ENOMEM; return PTR_ERR(buf);
buf_size = min(count, len - 1);
if (copy_from_user(buf, userbuf, buf_size)) {
res = -EFAULT;
goto out_unlock;
}
priv->mac_offset = simple_strtoul(buf, NULL, 16); priv->mac_offset = simple_strtoul(buf, NULL, 16);
res = count; kfree(buf);
out_unlock: return count;
free_page(addr);
return res;
} }
static ssize_t lbs_wrmac_write(struct file *file, static ssize_t lbs_wrmac_write(struct file *file,
...@@ -496,18 +475,14 @@ static ssize_t lbs_wrmac_write(struct file *file, ...@@ -496,18 +475,14 @@ static ssize_t lbs_wrmac_write(struct file *file,
{ {
struct lbs_private *priv = file->private_data; struct lbs_private *priv = file->private_data;
ssize_t res, buf_size; ssize_t res;
u32 offset, value; u32 offset, value;
unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf;
char *buf = (char *)addr;
if (!buf) buf = memdup_user_nul(userbuf, min(count, len - 1));
return -ENOMEM; if (IS_ERR(buf))
return PTR_ERR(buf);
buf_size = min(count, len - 1);
if (copy_from_user(buf, userbuf, buf_size)) {
res = -EFAULT;
goto out_unlock;
}
res = sscanf(buf, "%x %x", &offset, &value); res = sscanf(buf, "%x %x", &offset, &value);
if (res != 2) { if (res != 2) {
res = -EFAULT; res = -EFAULT;
...@@ -520,7 +495,7 @@ static ssize_t lbs_wrmac_write(struct file *file, ...@@ -520,7 +495,7 @@ static ssize_t lbs_wrmac_write(struct file *file,
if (!res) if (!res)
res = count; res = count;
out_unlock: out_unlock:
free_page(addr); kfree(buf);
return res; return res;
} }
...@@ -554,22 +529,16 @@ static ssize_t lbs_rdbbp_write(struct file *file, ...@@ -554,22 +529,16 @@ static ssize_t lbs_rdbbp_write(struct file *file,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct lbs_private *priv = file->private_data; struct lbs_private *priv = file->private_data;
ssize_t res, buf_size; char *buf;
unsigned long addr = get_zeroed_page(GFP_KERNEL);
char *buf = (char *)addr; buf = memdup_user_nul(userbuf, min(count, len - 1));
if (!buf) if (IS_ERR(buf))
return -ENOMEM; return PTR_ERR(buf);
buf_size = min(count, len - 1);
if (copy_from_user(buf, userbuf, buf_size)) {
res = -EFAULT;
goto out_unlock;
}
priv->bbp_offset = simple_strtoul(buf, NULL, 16); priv->bbp_offset = simple_strtoul(buf, NULL, 16);
res = count; kfree(buf);
out_unlock:
free_page(addr); return count;
return res;
} }
static ssize_t lbs_wrbbp_write(struct file *file, static ssize_t lbs_wrbbp_write(struct file *file,
...@@ -578,18 +547,14 @@ static ssize_t lbs_wrbbp_write(struct file *file, ...@@ -578,18 +547,14 @@ static ssize_t lbs_wrbbp_write(struct file *file,
{ {
struct lbs_private *priv = file->private_data; struct lbs_private *priv = file->private_data;
ssize_t res, buf_size; ssize_t res;
u32 offset, value; u32 offset, value;
unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf;
char *buf = (char *)addr;
if (!buf) buf = memdup_user_nul(userbuf, min(count, len - 1));
return -ENOMEM; if (IS_ERR(buf))
return PTR_ERR(buf);
buf_size = min(count, len - 1);
if (copy_from_user(buf, userbuf, buf_size)) {
res = -EFAULT;
goto out_unlock;
}
res = sscanf(buf, "%x %x", &offset, &value); res = sscanf(buf, "%x %x", &offset, &value);
if (res != 2) { if (res != 2) {
res = -EFAULT; res = -EFAULT;
...@@ -602,7 +567,7 @@ static ssize_t lbs_wrbbp_write(struct file *file, ...@@ -602,7 +567,7 @@ static ssize_t lbs_wrbbp_write(struct file *file,
if (!res) if (!res)
res = count; res = count;
out_unlock: out_unlock:
free_page(addr); kfree(buf);
return res; return res;
} }
...@@ -636,22 +601,15 @@ static ssize_t lbs_rdrf_write(struct file *file, ...@@ -636,22 +601,15 @@ static ssize_t lbs_rdrf_write(struct file *file,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct lbs_private *priv = file->private_data; struct lbs_private *priv = file->private_data;
ssize_t res, buf_size; char *buf;
unsigned long addr = get_zeroed_page(GFP_KERNEL);
char *buf = (char *)addr; buf = memdup_user_nul(userbuf, min(count, len - 1));
if (!buf) if (IS_ERR(buf))
return -ENOMEM; return PTR_ERR(buf);
buf_size = min(count, len - 1);
if (copy_from_user(buf, userbuf, buf_size)) {
res = -EFAULT;
goto out_unlock;
}
priv->rf_offset = simple_strtoul(buf, NULL, 16); priv->rf_offset = simple_strtoul(buf, NULL, 16);
res = count; kfree(buf);
out_unlock: return count;
free_page(addr);
return res;
} }
static ssize_t lbs_wrrf_write(struct file *file, static ssize_t lbs_wrrf_write(struct file *file,
...@@ -660,18 +618,14 @@ static ssize_t lbs_wrrf_write(struct file *file, ...@@ -660,18 +618,14 @@ static ssize_t lbs_wrrf_write(struct file *file,
{ {
struct lbs_private *priv = file->private_data; struct lbs_private *priv = file->private_data;
ssize_t res, buf_size; ssize_t res;
u32 offset, value; u32 offset, value;
unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf;
char *buf = (char *)addr;
if (!buf) buf = memdup_user_nul(userbuf, min(count, len - 1));
return -ENOMEM; if (IS_ERR(buf))
return PTR_ERR(buf);
buf_size = min(count, len - 1);
if (copy_from_user(buf, userbuf, buf_size)) {
res = -EFAULT;
goto out_unlock;
}
res = sscanf(buf, "%x %x", &offset, &value); res = sscanf(buf, "%x %x", &offset, &value);
if (res != 2) { if (res != 2) {
res = -EFAULT; res = -EFAULT;
...@@ -684,7 +638,7 @@ static ssize_t lbs_wrrf_write(struct file *file, ...@@ -684,7 +638,7 @@ static ssize_t lbs_wrrf_write(struct file *file,
if (!res) if (!res)
res = count; res = count;
out_unlock: out_unlock:
free_page(addr); kfree(buf);
return res; return res;
} }
...@@ -915,16 +869,9 @@ static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf, ...@@ -915,16 +869,9 @@ static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf,
if (cnt == 0) if (cnt == 0)
return 0; return 0;
pdata = kmalloc(cnt + 1, GFP_KERNEL); pdata = memdup_user_nul(buf, cnt);
if (pdata == NULL) if (IS_ERR(pdata))
return 0; return PTR_ERR(pdata);
if (copy_from_user(pdata, buf, cnt)) {
lbs_deb_debugfs("Copy from user failed\n");
kfree(pdata);
return 0;
}
pdata[cnt] = '\0';
p0 = pdata; p0 = pdata;
for (i = 0; i < num_of_items; i++) { for (i = 0; i < num_of_items; i++) {
......
...@@ -447,20 +447,13 @@ static ssize_t ...@@ -447,20 +447,13 @@ static ssize_t
mwifiex_regrdwr_write(struct file *file, mwifiex_regrdwr_write(struct file *file,
const char __user *ubuf, size_t count, loff_t *ppos) const char __user *ubuf, size_t count, loff_t *ppos)
{ {
unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf;
char *buf = (char *) addr;
size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
int ret; int ret;
u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX; u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX;
if (!buf) buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
return -ENOMEM; if (IS_ERR(buf))
return PTR_ERR(buf);
if (copy_from_user(buf, ubuf, buf_size)) {
ret = -EFAULT;
goto done;
}
sscanf(buf, "%u %x %x", &reg_type, &reg_offset, &reg_value); sscanf(buf, "%u %x %x", &reg_type, &reg_offset, &reg_value);
...@@ -474,7 +467,7 @@ mwifiex_regrdwr_write(struct file *file, ...@@ -474,7 +467,7 @@ mwifiex_regrdwr_write(struct file *file,
ret = count; ret = count;
} }
done: done:
free_page(addr); kfree(buf);
return ret; return ret;
} }
...@@ -572,17 +565,11 @@ mwifiex_debug_mask_write(struct file *file, const char __user *ubuf, ...@@ -572,17 +565,11 @@ mwifiex_debug_mask_write(struct file *file, const char __user *ubuf,
int ret; int ret;
unsigned long debug_mask; unsigned long debug_mask;
struct mwifiex_private *priv = (void *)file->private_data; struct mwifiex_private *priv = (void *)file->private_data;
unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf;
char *buf = (void *)addr;
size_t buf_size = min(count, (size_t)(PAGE_SIZE - 1));
if (!buf) buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
return -ENOMEM; if (IS_ERR(buf))
return PTR_ERR(buf);
if (copy_from_user(buf, ubuf, buf_size)) {
ret = -EFAULT;
goto done;
}
if (kstrtoul(buf, 0, &debug_mask)) { if (kstrtoul(buf, 0, &debug_mask)) {
ret = -EINVAL; ret = -EINVAL;
...@@ -592,7 +579,7 @@ mwifiex_debug_mask_write(struct file *file, const char __user *ubuf, ...@@ -592,7 +579,7 @@ mwifiex_debug_mask_write(struct file *file, const char __user *ubuf,
priv->adapter->debug_mask = debug_mask; priv->adapter->debug_mask = debug_mask;
ret = count; ret = count;
done: done:
free_page(addr); kfree(buf);
return ret; return ret;
} }
...@@ -609,17 +596,11 @@ mwifiex_memrw_write(struct file *file, const char __user *ubuf, size_t count, ...@@ -609,17 +596,11 @@ mwifiex_memrw_write(struct file *file, const char __user *ubuf, size_t count,
struct mwifiex_ds_mem_rw mem_rw; struct mwifiex_ds_mem_rw mem_rw;
u16 cmd_action; u16 cmd_action;
struct mwifiex_private *priv = (void *)file->private_data; struct mwifiex_private *priv = (void *)file->private_data;
unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf;
char *buf = (void *)addr;
size_t buf_size = min(count, (size_t)(PAGE_SIZE - 1));
if (!buf)
return -ENOMEM;
if (copy_from_user(buf, ubuf, buf_size)) { buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
ret = -EFAULT; if (IS_ERR(buf))
goto done; return PTR_ERR(buf);
}
ret = sscanf(buf, "%c %x %x", &cmd, &mem_rw.addr, &mem_rw.value); ret = sscanf(buf, "%c %x %x", &cmd, &mem_rw.addr, &mem_rw.value);
if (ret != 3) { if (ret != 3) {
...@@ -645,7 +626,7 @@ mwifiex_memrw_write(struct file *file, const char __user *ubuf, size_t count, ...@@ -645,7 +626,7 @@ mwifiex_memrw_write(struct file *file, const char __user *ubuf, size_t count,
ret = count; ret = count;
done: done:
free_page(addr); kfree(buf);
return ret; return ret;
} }
...@@ -686,20 +667,13 @@ static ssize_t ...@@ -686,20 +667,13 @@ static ssize_t
mwifiex_rdeeprom_write(struct file *file, mwifiex_rdeeprom_write(struct file *file,
const char __user *ubuf, size_t count, loff_t *ppos) const char __user *ubuf, size_t count, loff_t *ppos)
{ {
unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf;
char *buf = (char *) addr;
size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
int ret = 0; int ret = 0;
int offset = -1, bytes = -1; int offset = -1, bytes = -1;
if (!buf) buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
return -ENOMEM; if (IS_ERR(buf))
return PTR_ERR(buf);
if (copy_from_user(buf, ubuf, buf_size)) {
ret = -EFAULT;
goto done;
}
sscanf(buf, "%d %d", &offset, &bytes); sscanf(buf, "%d %d", &offset, &bytes);
...@@ -712,7 +686,7 @@ mwifiex_rdeeprom_write(struct file *file, ...@@ -712,7 +686,7 @@ mwifiex_rdeeprom_write(struct file *file,
ret = count; ret = count;
} }
done: done:
free_page(addr); kfree(buf);
return ret; return ret;
} }
...@@ -771,21 +745,15 @@ mwifiex_hscfg_write(struct file *file, const char __user *ubuf, ...@@ -771,21 +745,15 @@ mwifiex_hscfg_write(struct file *file, const char __user *ubuf,
size_t count, loff_t *ppos) size_t count, loff_t *ppos)
{ {
struct mwifiex_private *priv = (void *)file->private_data; struct mwifiex_private *priv = (void *)file->private_data;
unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf;
char *buf = (char *)addr;
size_t buf_size = min_t(size_t, count, PAGE_SIZE - 1);
int ret, arg_num; int ret, arg_num;
struct mwifiex_ds_hs_cfg hscfg; struct mwifiex_ds_hs_cfg hscfg;
int conditions = HS_CFG_COND_DEF; int conditions = HS_CFG_COND_DEF;
u32 gpio = HS_CFG_GPIO_DEF, gap = HS_CFG_GAP_DEF; u32 gpio = HS_CFG_GPIO_DEF, gap = HS_CFG_GAP_DEF;
if (!buf) buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
return -ENOMEM; if (IS_ERR(buf))
return PTR_ERR(buf);
if (copy_from_user(buf, ubuf, buf_size)) {
ret = -EFAULT;
goto done;
}
arg_num = sscanf(buf, "%d %x %x", &conditions, &gpio, &gap); arg_num = sscanf(buf, "%d %x %x", &conditions, &gpio, &gap);
...@@ -823,7 +791,7 @@ mwifiex_hscfg_write(struct file *file, const char __user *ubuf, ...@@ -823,7 +791,7 @@ mwifiex_hscfg_write(struct file *file, const char __user *ubuf,
priv->adapter->hs_enabling = false; priv->adapter->hs_enabling = false;
ret = count; ret = count;
done: done:
free_page(addr); kfree(buf);
return ret; return ret;
} }
......
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