convert a bunch of open-coded instances of memdup_user_nul()

A _lot_ of ->write() instances were open-coding it; some are
converted to memdup_user_nul(), a lot more remain...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2015-12-24 00:06:05 -05:00
parent 7e935c7ca1
commit 16e5c1fc36
12 changed files with 71 additions and 197 deletions

View file

@ -227,16 +227,12 @@ static ssize_t proc_read_simdisk(struct file *file, char __user *buf,
static ssize_t proc_write_simdisk(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
char *tmp = kmalloc(count + 1, GFP_KERNEL);
char *tmp = memdup_user_nul(buf, count);
struct simdisk *dev = PDE_DATA(file_inode(file));
int err;
if (tmp == NULL)
return -ENOMEM;
if (copy_from_user(tmp, buf, count)) {
err = -EFAULT;
goto out_free;
}
if (IS_ERR(tmp))
return PTR_ERR(tmp);
err = simdisk_detach(dev);
if (err != 0)
@ -244,8 +240,6 @@ static ssize_t proc_write_simdisk(struct file *file, const char __user *buf,
if (count > 0 && tmp[count - 1] == '\n')
tmp[count - 1] = 0;
else
tmp[count] = 0;
if (tmp[0])
err = simdisk_attach(dev, tmp);

View file

@ -580,16 +580,10 @@ static ssize_t wil_write_file_rxon(struct file *file, const char __user *buf,
long channel;
bool on;
char *kbuf = kmalloc(len + 1, GFP_KERNEL);
char *kbuf = memdup_user_nul(buf, len);
if (!kbuf)
return -ENOMEM;
if (copy_from_user(kbuf, buf, len)) {
kfree(kbuf);
return -EIO;
}
kbuf[len] = '\0';
if (IS_ERR(kbuf))
return PTR_ERR(kbuf);
rc = kstrtol(kbuf, 0, &channel);
kfree(kbuf);
if (rc)

View file

@ -88,14 +88,9 @@ vmcp_write(struct file *file, const char __user *buff, size_t count,
if (count > 240)
return -EINVAL;
cmd = kmalloc(count + 1, GFP_KERNEL);
if (!cmd)
return -ENOMEM;
if (copy_from_user(cmd, buff, count)) {
kfree(cmd);
return -EFAULT;
}
cmd[count] = '\0';
cmd = memdup_user_nul(buff, count);
if (IS_ERR(cmd))
return PTR_ERR(cmd);
session = file->private_data;
if (mutex_lock_interruptible(&session->mutex)) {
kfree(cmd);

View file

@ -390,16 +390,9 @@ static int copyin_string(char __user *user, size_t len, char **ptr)
if ((ssize_t)len < 0 || (ssize_t)(len + 1) < 0)
return -EINVAL;
tmp = kmalloc(len + 1, GFP_KERNEL);
if (!tmp)
return -ENOMEM;
if (copy_from_user(tmp, user, len)) {
kfree(tmp);
return -EFAULT;
}
tmp[len] = '\0';
tmp = memdup_user_nul(user, len);
if (IS_ERR(tmp))
return PTR_ERR(tmp);
*ptr = tmp;

View file

@ -230,14 +230,9 @@ static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf,
if (size <= 1 || size >= PAGE_SIZE)
return -EINVAL;
kbuf = kmalloc(size + 1, GFP_KERNEL);
if (!kbuf)
return -ENOMEM;
ret = -EFAULT;
if (copy_from_user(kbuf, buf, size) != 0)
goto done;
kbuf[size] = 0;
kbuf = memdup_user_nul(buf, size);
if (IS_ERR(kbuf))
return PTR_ERR(kbuf);
/* trim to first NL */
name = memchr(kbuf, '\n', size);
@ -315,15 +310,9 @@ static ssize_t afs_proc_rootcell_write(struct file *file,
if (size <= 1 || size >= PAGE_SIZE)
return -EINVAL;
ret = -ENOMEM;
kbuf = kmalloc(size + 1, GFP_KERNEL);
if (!kbuf)
goto nomem;
ret = -EFAULT;
if (copy_from_user(kbuf, buf, size) != 0)
goto infault;
kbuf[size] = 0;
kbuf = memdup_user_nul(buf, size);
if (IS_ERR(kbuf))
return PTR_ERR(kbuf);
/* trim to first NL */
s = memchr(kbuf, '\n', size);
@ -337,9 +326,7 @@ static ssize_t afs_proc_rootcell_write(struct file *file,
if (ret >= 0)
ret = size; /* consume everything, always */
infault:
kfree(kbuf);
nomem:
_leave(" = %d", ret);
return ret;
}

View file

@ -226,15 +226,9 @@ static ssize_t cachefiles_daemon_write(struct file *file,
return -EOPNOTSUPP;
/* drag the command string into the kernel so we can parse it */
data = kmalloc(datalen + 1, GFP_KERNEL);
if (!data)
return -ENOMEM;
ret = -EFAULT;
if (copy_from_user(data, _data, datalen) != 0)
goto error;
data[datalen] = '\0';
data = memdup_user_nul(_data, datalen);
if (IS_ERR(data))
return PTR_ERR(data);
ret = -EINVAL;
if (memchr(data, '\0', datalen))

View file

@ -515,14 +515,9 @@ static ssize_t device_write(struct file *file, const char __user *buf,
if (count > sizeof(struct dlm_write_request) + DLM_RESNAME_MAXLEN)
return -EINVAL;
kbuf = kzalloc(count + 1, GFP_NOFS);
if (!kbuf)
return -ENOMEM;
if (copy_from_user(kbuf, buf, count)) {
error = -EFAULT;
goto out_free;
}
kbuf = memdup_user_nul(buf, count);
if (!IS_ERR(kbuf))
return PTR_ERR(kbuf);
if (check_version(kbuf)) {
error = -EBADE;

View file

@ -349,16 +349,10 @@ static ssize_t blk_msg_write(struct file *filp, const char __user *buffer,
if (count >= BLK_TN_MAX_MSG)
return -EINVAL;
msg = kmalloc(count + 1, GFP_KERNEL);
if (msg == NULL)
return -ENOMEM;
msg = memdup_user_nul(buffer, count);
if (IS_ERR(msg))
return PTR_ERR(msg);
if (copy_from_user(msg, buffer, count)) {
kfree(msg);
return -EFAULT;
}
msg[count] = '\0';
bt = filp->private_data;
__trace_note_message(bt, "%s", msg);
kfree(msg);

View file

@ -657,14 +657,9 @@ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
return -E2BIG;
}
tmpbuf = kmalloc(len + 1, GFP_KERNEL);
if (!tmpbuf)
return -ENOMEM;
if (copy_from_user(tmpbuf, ubuf, len)) {
kfree(tmpbuf);
return -EFAULT;
}
tmpbuf[len] = '\0';
tmpbuf = memdup_user_nul(ubuf, len);
if (IS_ERR(tmpbuf))
return PTR_ERR(tmpbuf);
vpr_info("read %d bytes from userspace\n", (int)len);
ret = ddebug_exec_queries(tmpbuf, NULL);

View file

@ -896,15 +896,9 @@ int rxrpc_request_key(struct rxrpc_sock *rx, char __user *optval, int optlen)
if (optlen <= 0 || optlen > PAGE_SIZE - 1)
return -EINVAL;
description = kmalloc(optlen + 1, GFP_KERNEL);
if (!description)
return -ENOMEM;
if (copy_from_user(description, optval, optlen)) {
kfree(description);
return -EFAULT;
}
description[optlen] = 0;
description = memdup_user_nul(optval, optlen);
if (IS_ERR(description))
return PTR_ERR(description);
key = request_key(&key_type_rxrpc, description, NULL);
if (IS_ERR(key)) {
@ -933,15 +927,9 @@ int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval,
if (optlen <= 0 || optlen > PAGE_SIZE - 1)
return -EINVAL;
description = kmalloc(optlen + 1, GFP_KERNEL);
if (!description)
return -ENOMEM;
if (copy_from_user(description, optval, optlen)) {
kfree(description);
return -EFAULT;
}
description[optlen] = 0;
description = memdup_user_nul(optval, optlen);
if (IS_ERR(description))
return PTR_ERR(description);
key = request_key(&key_type_keyring, description, NULL);
if (IS_ERR(key)) {

View file

@ -497,14 +497,9 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
}
}
data = kmalloc(count + 1, GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
if (copy_from_user(data, buf, count) != 0) {
rc = -EFAULT;
goto out;
}
data = memdup_user_nul(buf, count);
if (IS_ERR(data))
return PTR_ERR(data);
/*
* In case of parsing only part of user buf,
@ -884,16 +879,10 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
(count < SMK_CIPSOMIN || count > SMK_CIPSOMAX))
return -EINVAL;
data = kzalloc(count + 1, GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
data = memdup_user_nul(buf, count);
if (IS_ERR(data))
return PTR_ERR(data);
if (copy_from_user(data, buf, count) != 0) {
rc = -EFAULT;
goto unlockedout;
}
data[count] = '\0';
rule = data;
/*
* Only allow one writer at a time. Writes should be
@ -946,7 +935,6 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
out:
mutex_unlock(&smack_cipso_lock);
unlockedout:
kfree(data);
return rc;
}
@ -1187,14 +1175,9 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf,
if (count < SMK_NETLBLADDRMIN)
return -EINVAL;
data = kzalloc(count + 1, GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
if (copy_from_user(data, buf, count) != 0) {
rc = -EFAULT;
goto free_data_out;
}
data = memdup_user_nul(buf, count);
if (IS_ERR(data))
return PTR_ERR(data);
smack = kzalloc(count + 1, GFP_KERNEL);
if (smack == NULL) {
@ -1202,8 +1185,6 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf,
goto free_data_out;
}
data[count] = '\0';
rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%u %s",
&host[0], &host[1], &host[2], &host[3], &masks, smack);
if (rc != 6) {
@ -1454,14 +1435,9 @@ static ssize_t smk_write_net6addr(struct file *file, const char __user *buf,
if (count < SMK_NETLBLADDRMIN)
return -EINVAL;
data = kzalloc(count + 1, GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
if (copy_from_user(data, buf, count) != 0) {
rc = -EFAULT;
goto free_data_out;
}
data = memdup_user_nul(buf, count);
if (IS_ERR(data))
return PTR_ERR(data);
smack = kzalloc(count + 1, GFP_KERNEL);
if (smack == NULL) {
@ -1469,8 +1445,6 @@ static ssize_t smk_write_net6addr(struct file *file, const char __user *buf,
goto free_data_out;
}
data[count] = '\0';
i = sscanf(data, "%x:%x:%x:%x:%x:%x:%x:%x/%u %s",
&scanned[0], &scanned[1], &scanned[2], &scanned[3],
&scanned[4], &scanned[5], &scanned[6], &scanned[7],
@ -1865,14 +1839,9 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM;
data = kzalloc(count + 1, GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
if (copy_from_user(data, buf, count) != 0) {
rc = -EFAULT;
goto out;
}
data = memdup_user_nul(buf, count);
if (IS_ERR(data))
return PTR_ERR(data);
skp = smk_import_entry(data, count);
if (IS_ERR(skp)) {
@ -2041,14 +2010,9 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM;
data = kzalloc(count + 1, GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
if (copy_from_user(data, buf, count) != 0) {
kfree(data);
return -EFAULT;
}
data = memdup_user_nul(buf, count);
if (IS_ERR(data))
return PTR_ERR(data);
rc = smk_parse_label_list(data, &list_tmp);
kfree(data);
@ -2133,14 +2097,9 @@ static ssize_t smk_write_unconfined(struct file *file, const char __user *buf,
if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM;
data = kzalloc(count + 1, GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
if (copy_from_user(data, buf, count) != 0) {
rc = -EFAULT;
goto freeout;
}
data = memdup_user_nul(buf, count);
if (IS_ERR(data))
return PTR_ERR(data);
/*
* Clear the smack_unconfined on invalid label errors. This means
@ -2696,19 +2655,15 @@ static ssize_t smk_write_syslog(struct file *file, const char __user *buf,
if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM;
data = kzalloc(count + 1, GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
data = memdup_user_nul(buf, count);
if (IS_ERR(data))
return PTR_ERR(data);
if (copy_from_user(data, buf, count) != 0)
rc = -EFAULT;
else {
skp = smk_import_entry(data, count);
if (IS_ERR(skp))
rc = PTR_ERR(skp);
else
smack_syslog_label = skp;
}
skp = smk_import_entry(data, count);
if (IS_ERR(skp))
rc = PTR_ERR(skp);
else
smack_syslog_label = skp;
kfree(data);
return rc;
@ -2798,14 +2753,9 @@ static ssize_t smk_write_relabel_self(struct file *file, const char __user *buf,
if (*ppos != 0)
return -EINVAL;
data = kzalloc(count + 1, GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
if (copy_from_user(data, buf, count) != 0) {
kfree(data);
return -EFAULT;
}
data = memdup_user_nul(buf, count);
if (IS_ERR(data))
return PTR_ERR(data);
rc = smk_parse_label_list(data, &list_tmp);
kfree(data);

View file

@ -43,13 +43,9 @@ static ssize_t tomoyo_write_self(struct file *file, const char __user *buf,
int error;
if (!count || count >= TOMOYO_EXEC_TMPSIZE - 10)
return -ENOMEM;
data = kzalloc(count + 1, GFP_NOFS);
if (!data)
return -ENOMEM;
if (copy_from_user(data, buf, count)) {
error = -EFAULT;
goto out;
}
data = memdup_user_nul(buf, count);
if (IS_ERR(data))
return PTR_ERR(data);
tomoyo_normalize_line(data);
if (tomoyo_correct_domain(data)) {
const int idx = tomoyo_read_lock();
@ -87,7 +83,6 @@ static ssize_t tomoyo_write_self(struct file *file, const char __user *buf,
tomoyo_read_unlock(idx);
} else
error = -EINVAL;
out:
kfree(data);
return error ? error : count;
}