Commit 16e5c1fc authored by Al Viro's avatar Al Viro

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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 7e935c7c
...@@ -227,16 +227,12 @@ static ssize_t proc_read_simdisk(struct file *file, char __user *buf, ...@@ -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, static ssize_t proc_write_simdisk(struct file *file, const char __user *buf,
size_t count, loff_t *ppos) 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)); struct simdisk *dev = PDE_DATA(file_inode(file));
int err; int err;
if (tmp == NULL) if (IS_ERR(tmp))
return -ENOMEM; return PTR_ERR(tmp);
if (copy_from_user(tmp, buf, count)) {
err = -EFAULT;
goto out_free;
}
err = simdisk_detach(dev); err = simdisk_detach(dev);
if (err != 0) if (err != 0)
...@@ -244,8 +240,6 @@ static ssize_t proc_write_simdisk(struct file *file, const char __user *buf, ...@@ -244,8 +240,6 @@ static ssize_t proc_write_simdisk(struct file *file, const char __user *buf,
if (count > 0 && tmp[count - 1] == '\n') if (count > 0 && tmp[count - 1] == '\n')
tmp[count - 1] = 0; tmp[count - 1] = 0;
else
tmp[count] = 0;
if (tmp[0]) if (tmp[0])
err = simdisk_attach(dev, tmp); err = simdisk_attach(dev, tmp);
......
...@@ -580,16 +580,10 @@ static ssize_t wil_write_file_rxon(struct file *file, const char __user *buf, ...@@ -580,16 +580,10 @@ static ssize_t wil_write_file_rxon(struct file *file, const char __user *buf,
long channel; long channel;
bool on; 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); rc = kstrtol(kbuf, 0, &channel);
kfree(kbuf); kfree(kbuf);
if (rc) if (rc)
......
...@@ -88,14 +88,9 @@ vmcp_write(struct file *file, const char __user *buff, size_t count, ...@@ -88,14 +88,9 @@ vmcp_write(struct file *file, const char __user *buff, size_t count,
if (count > 240) if (count > 240)
return -EINVAL; return -EINVAL;
cmd = kmalloc(count + 1, GFP_KERNEL); cmd = memdup_user_nul(buff, count);
if (!cmd) if (IS_ERR(cmd))
return -ENOMEM; return PTR_ERR(cmd);
if (copy_from_user(cmd, buff, count)) {
kfree(cmd);
return -EFAULT;
}
cmd[count] = '\0';
session = file->private_data; session = file->private_data;
if (mutex_lock_interruptible(&session->mutex)) { if (mutex_lock_interruptible(&session->mutex)) {
kfree(cmd); kfree(cmd);
......
...@@ -390,16 +390,9 @@ static int copyin_string(char __user *user, size_t len, char **ptr) ...@@ -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) if ((ssize_t)len < 0 || (ssize_t)(len + 1) < 0)
return -EINVAL; return -EINVAL;
tmp = kmalloc(len + 1, GFP_KERNEL); tmp = memdup_user_nul(user, len);
if (!tmp) if (IS_ERR(tmp))
return -ENOMEM; return PTR_ERR(tmp);
if (copy_from_user(tmp, user, len)) {
kfree(tmp);
return -EFAULT;
}
tmp[len] = '\0';
*ptr = tmp; *ptr = tmp;
......
...@@ -230,14 +230,9 @@ static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf, ...@@ -230,14 +230,9 @@ static ssize_t afs_proc_cells_write(struct file *file, const char __user *buf,
if (size <= 1 || size >= PAGE_SIZE) if (size <= 1 || size >= PAGE_SIZE)
return -EINVAL; return -EINVAL;
kbuf = kmalloc(size + 1, GFP_KERNEL); kbuf = memdup_user_nul(buf, size);
if (!kbuf) if (IS_ERR(kbuf))
return -ENOMEM; return PTR_ERR(kbuf);
ret = -EFAULT;
if (copy_from_user(kbuf, buf, size) != 0)
goto done;
kbuf[size] = 0;
/* trim to first NL */ /* trim to first NL */
name = memchr(kbuf, '\n', size); name = memchr(kbuf, '\n', size);
...@@ -315,15 +310,9 @@ static ssize_t afs_proc_rootcell_write(struct file *file, ...@@ -315,15 +310,9 @@ static ssize_t afs_proc_rootcell_write(struct file *file,
if (size <= 1 || size >= PAGE_SIZE) if (size <= 1 || size >= PAGE_SIZE)
return -EINVAL; return -EINVAL;
ret = -ENOMEM; kbuf = memdup_user_nul(buf, size);
kbuf = kmalloc(size + 1, GFP_KERNEL); if (IS_ERR(kbuf))
if (!kbuf) return PTR_ERR(kbuf);
goto nomem;
ret = -EFAULT;
if (copy_from_user(kbuf, buf, size) != 0)
goto infault;
kbuf[size] = 0;
/* trim to first NL */ /* trim to first NL */
s = memchr(kbuf, '\n', size); s = memchr(kbuf, '\n', size);
...@@ -337,9 +326,7 @@ static ssize_t afs_proc_rootcell_write(struct file *file, ...@@ -337,9 +326,7 @@ static ssize_t afs_proc_rootcell_write(struct file *file,
if (ret >= 0) if (ret >= 0)
ret = size; /* consume everything, always */ ret = size; /* consume everything, always */
infault:
kfree(kbuf); kfree(kbuf);
nomem:
_leave(" = %d", ret); _leave(" = %d", ret);
return ret; return ret;
} }
......
...@@ -226,15 +226,9 @@ static ssize_t cachefiles_daemon_write(struct file *file, ...@@ -226,15 +226,9 @@ static ssize_t cachefiles_daemon_write(struct file *file,
return -EOPNOTSUPP; return -EOPNOTSUPP;
/* drag the command string into the kernel so we can parse it */ /* drag the command string into the kernel so we can parse it */
data = kmalloc(datalen + 1, GFP_KERNEL); data = memdup_user_nul(_data, datalen);
if (!data) if (IS_ERR(data))
return -ENOMEM; return PTR_ERR(data);
ret = -EFAULT;
if (copy_from_user(data, _data, datalen) != 0)
goto error;
data[datalen] = '\0';
ret = -EINVAL; ret = -EINVAL;
if (memchr(data, '\0', datalen)) if (memchr(data, '\0', datalen))
......
...@@ -515,14 +515,9 @@ static ssize_t device_write(struct file *file, const char __user *buf, ...@@ -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) if (count > sizeof(struct dlm_write_request) + DLM_RESNAME_MAXLEN)
return -EINVAL; return -EINVAL;
kbuf = kzalloc(count + 1, GFP_NOFS); kbuf = memdup_user_nul(buf, count);
if (!kbuf) if (!IS_ERR(kbuf))
return -ENOMEM; return PTR_ERR(kbuf);
if (copy_from_user(kbuf, buf, count)) {
error = -EFAULT;
goto out_free;
}
if (check_version(kbuf)) { if (check_version(kbuf)) {
error = -EBADE; error = -EBADE;
......
...@@ -349,16 +349,10 @@ static ssize_t blk_msg_write(struct file *filp, const char __user *buffer, ...@@ -349,16 +349,10 @@ static ssize_t blk_msg_write(struct file *filp, const char __user *buffer,
if (count >= BLK_TN_MAX_MSG) if (count >= BLK_TN_MAX_MSG)
return -EINVAL; return -EINVAL;
msg = kmalloc(count + 1, GFP_KERNEL); msg = memdup_user_nul(buffer, count);
if (msg == NULL) if (IS_ERR(msg))
return -ENOMEM; return PTR_ERR(msg);
if (copy_from_user(msg, buffer, count)) {
kfree(msg);
return -EFAULT;
}
msg[count] = '\0';
bt = filp->private_data; bt = filp->private_data;
__trace_note_message(bt, "%s", msg); __trace_note_message(bt, "%s", msg);
kfree(msg); kfree(msg);
......
...@@ -657,14 +657,9 @@ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf, ...@@ -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); pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
return -E2BIG; return -E2BIG;
} }
tmpbuf = kmalloc(len + 1, GFP_KERNEL); tmpbuf = memdup_user_nul(ubuf, len);
if (!tmpbuf) if (IS_ERR(tmpbuf))
return -ENOMEM; return PTR_ERR(tmpbuf);
if (copy_from_user(tmpbuf, ubuf, len)) {
kfree(tmpbuf);
return -EFAULT;
}
tmpbuf[len] = '\0';
vpr_info("read %d bytes from userspace\n", (int)len); vpr_info("read %d bytes from userspace\n", (int)len);
ret = ddebug_exec_queries(tmpbuf, NULL); ret = ddebug_exec_queries(tmpbuf, NULL);
......
...@@ -896,15 +896,9 @@ int rxrpc_request_key(struct rxrpc_sock *rx, char __user *optval, int optlen) ...@@ -896,15 +896,9 @@ int rxrpc_request_key(struct rxrpc_sock *rx, char __user *optval, int optlen)
if (optlen <= 0 || optlen > PAGE_SIZE - 1) if (optlen <= 0 || optlen > PAGE_SIZE - 1)
return -EINVAL; return -EINVAL;
description = kmalloc(optlen + 1, GFP_KERNEL); description = memdup_user_nul(optval, optlen);
if (!description) if (IS_ERR(description))
return -ENOMEM; return PTR_ERR(description);
if (copy_from_user(description, optval, optlen)) {
kfree(description);
return -EFAULT;
}
description[optlen] = 0;
key = request_key(&key_type_rxrpc, description, NULL); key = request_key(&key_type_rxrpc, description, NULL);
if (IS_ERR(key)) { if (IS_ERR(key)) {
...@@ -933,15 +927,9 @@ int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval, ...@@ -933,15 +927,9 @@ int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval,
if (optlen <= 0 || optlen > PAGE_SIZE - 1) if (optlen <= 0 || optlen > PAGE_SIZE - 1)
return -EINVAL; return -EINVAL;
description = kmalloc(optlen + 1, GFP_KERNEL); description = memdup_user_nul(optval, optlen);
if (!description) if (IS_ERR(description))
return -ENOMEM; return PTR_ERR(description);
if (copy_from_user(description, optval, optlen)) {
kfree(description);
return -EFAULT;
}
description[optlen] = 0;
key = request_key(&key_type_keyring, description, NULL); key = request_key(&key_type_keyring, description, NULL);
if (IS_ERR(key)) { if (IS_ERR(key)) {
......
...@@ -497,14 +497,9 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf, ...@@ -497,14 +497,9 @@ static ssize_t smk_write_rules_list(struct file *file, const char __user *buf,
} }
} }
data = kmalloc(count + 1, GFP_KERNEL); data = memdup_user_nul(buf, count);
if (data == NULL) if (IS_ERR(data))
return -ENOMEM; return PTR_ERR(data);
if (copy_from_user(data, buf, count) != 0) {
rc = -EFAULT;
goto out;
}
/* /*
* In case of parsing only part of user buf, * 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, ...@@ -884,16 +879,10 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
(count < SMK_CIPSOMIN || count > SMK_CIPSOMAX)) (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX))
return -EINVAL; return -EINVAL;
data = kzalloc(count + 1, GFP_KERNEL); data = memdup_user_nul(buf, count);
if (data == NULL) if (IS_ERR(data))
return -ENOMEM; return PTR_ERR(data);
if (copy_from_user(data, buf, count) != 0) {
rc = -EFAULT;
goto unlockedout;
}
data[count] = '\0';
rule = data; rule = data;
/* /*
* Only allow one writer at a time. Writes should be * 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, ...@@ -946,7 +935,6 @@ static ssize_t smk_set_cipso(struct file *file, const char __user *buf,
out: out:
mutex_unlock(&smack_cipso_lock); mutex_unlock(&smack_cipso_lock);
unlockedout:
kfree(data); kfree(data);
return rc; return rc;
} }
...@@ -1187,14 +1175,9 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, ...@@ -1187,14 +1175,9 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf,
if (count < SMK_NETLBLADDRMIN) if (count < SMK_NETLBLADDRMIN)
return -EINVAL; return -EINVAL;
data = kzalloc(count + 1, GFP_KERNEL); data = memdup_user_nul(buf, count);
if (data == NULL) if (IS_ERR(data))
return -ENOMEM; return PTR_ERR(data);
if (copy_from_user(data, buf, count) != 0) {
rc = -EFAULT;
goto free_data_out;
}
smack = kzalloc(count + 1, GFP_KERNEL); smack = kzalloc(count + 1, GFP_KERNEL);
if (smack == NULL) { if (smack == NULL) {
...@@ -1202,8 +1185,6 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, ...@@ -1202,8 +1185,6 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf,
goto free_data_out; goto free_data_out;
} }
data[count] = '\0';
rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%u %s", rc = sscanf(data, "%hhd.%hhd.%hhd.%hhd/%u %s",
&host[0], &host[1], &host[2], &host[3], &masks, smack); &host[0], &host[1], &host[2], &host[3], &masks, smack);
if (rc != 6) { if (rc != 6) {
...@@ -1454,14 +1435,9 @@ static ssize_t smk_write_net6addr(struct file *file, const char __user *buf, ...@@ -1454,14 +1435,9 @@ static ssize_t smk_write_net6addr(struct file *file, const char __user *buf,
if (count < SMK_NETLBLADDRMIN) if (count < SMK_NETLBLADDRMIN)
return -EINVAL; return -EINVAL;
data = kzalloc(count + 1, GFP_KERNEL); data = memdup_user_nul(buf, count);
if (data == NULL) if (IS_ERR(data))
return -ENOMEM; return PTR_ERR(data);
if (copy_from_user(data, buf, count) != 0) {
rc = -EFAULT;
goto free_data_out;
}
smack = kzalloc(count + 1, GFP_KERNEL); smack = kzalloc(count + 1, GFP_KERNEL);
if (smack == NULL) { if (smack == NULL) {
...@@ -1469,8 +1445,6 @@ static ssize_t smk_write_net6addr(struct file *file, const char __user *buf, ...@@ -1469,8 +1445,6 @@ static ssize_t smk_write_net6addr(struct file *file, const char __user *buf,
goto free_data_out; goto free_data_out;
} }
data[count] = '\0';
i = sscanf(data, "%x:%x:%x:%x:%x:%x:%x:%x/%u %s", i = sscanf(data, "%x:%x:%x:%x:%x:%x:%x:%x/%u %s",
&scanned[0], &scanned[1], &scanned[2], &scanned[3], &scanned[0], &scanned[1], &scanned[2], &scanned[3],
&scanned[4], &scanned[5], &scanned[6], &scanned[7], &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, ...@@ -1865,14 +1839,9 @@ static ssize_t smk_write_ambient(struct file *file, const char __user *buf,
if (!smack_privileged(CAP_MAC_ADMIN)) if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM; return -EPERM;
data = kzalloc(count + 1, GFP_KERNEL); data = memdup_user_nul(buf, count);
if (data == NULL) if (IS_ERR(data))
return -ENOMEM; return PTR_ERR(data);
if (copy_from_user(data, buf, count) != 0) {
rc = -EFAULT;
goto out;
}
skp = smk_import_entry(data, count); skp = smk_import_entry(data, count);
if (IS_ERR(skp)) { if (IS_ERR(skp)) {
...@@ -2041,14 +2010,9 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, ...@@ -2041,14 +2010,9 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf,
if (!smack_privileged(CAP_MAC_ADMIN)) if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM; return -EPERM;
data = kzalloc(count + 1, GFP_KERNEL); data = memdup_user_nul(buf, count);
if (data == NULL) if (IS_ERR(data))
return -ENOMEM; return PTR_ERR(data);
if (copy_from_user(data, buf, count) != 0) {
kfree(data);
return -EFAULT;
}
rc = smk_parse_label_list(data, &list_tmp); rc = smk_parse_label_list(data, &list_tmp);
kfree(data); kfree(data);
...@@ -2133,14 +2097,9 @@ static ssize_t smk_write_unconfined(struct file *file, const char __user *buf, ...@@ -2133,14 +2097,9 @@ static ssize_t smk_write_unconfined(struct file *file, const char __user *buf,
if (!smack_privileged(CAP_MAC_ADMIN)) if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM; return -EPERM;
data = kzalloc(count + 1, GFP_KERNEL); data = memdup_user_nul(buf, count);
if (data == NULL) if (IS_ERR(data))
return -ENOMEM; return PTR_ERR(data);
if (copy_from_user(data, buf, count) != 0) {
rc = -EFAULT;
goto freeout;
}
/* /*
* Clear the smack_unconfined on invalid label errors. This means * 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, ...@@ -2696,19 +2655,15 @@ static ssize_t smk_write_syslog(struct file *file, const char __user *buf,
if (!smack_privileged(CAP_MAC_ADMIN)) if (!smack_privileged(CAP_MAC_ADMIN))
return -EPERM; return -EPERM;
data = kzalloc(count + 1, GFP_KERNEL); data = memdup_user_nul(buf, count);
if (data == NULL) if (IS_ERR(data))
return -ENOMEM; return PTR_ERR(data);
if (copy_from_user(data, buf, count) != 0) skp = smk_import_entry(data, count);
rc = -EFAULT; if (IS_ERR(skp))
else { rc = PTR_ERR(skp);
skp = smk_import_entry(data, count); else
if (IS_ERR(skp)) smack_syslog_label = skp;
rc = PTR_ERR(skp);
else
smack_syslog_label = skp;
}
kfree(data); kfree(data);
return rc; return rc;
...@@ -2798,14 +2753,9 @@ static ssize_t smk_write_relabel_self(struct file *file, const char __user *buf, ...@@ -2798,14 +2753,9 @@ static ssize_t smk_write_relabel_self(struct file *file, const char __user *buf,
if (*ppos != 0) if (*ppos != 0)
return -EINVAL; return -EINVAL;
data = kzalloc(count + 1, GFP_KERNEL); data = memdup_user_nul(buf, count);
if (data == NULL) if (IS_ERR(data))
return -ENOMEM; return PTR_ERR(data);
if (copy_from_user(data, buf, count) != 0) {
kfree(data);
return -EFAULT;
}
rc = smk_parse_label_list(data, &list_tmp); rc = smk_parse_label_list(data, &list_tmp);
kfree(data); kfree(data);
......
...@@ -43,13 +43,9 @@ static ssize_t tomoyo_write_self(struct file *file, const char __user *buf, ...@@ -43,13 +43,9 @@ static ssize_t tomoyo_write_self(struct file *file, const char __user *buf,
int error; int error;
if (!count || count >= TOMOYO_EXEC_TMPSIZE - 10) if (!count || count >= TOMOYO_EXEC_TMPSIZE - 10)
return -ENOMEM; return -ENOMEM;
data = kzalloc(count + 1, GFP_NOFS); data = memdup_user_nul(buf, count);
if (!data) if (IS_ERR(data))
return -ENOMEM; return PTR_ERR(data);
if (copy_from_user(data, buf, count)) {
error = -EFAULT;
goto out;
}
tomoyo_normalize_line(data); tomoyo_normalize_line(data);
if (tomoyo_correct_domain(data)) { if (tomoyo_correct_domain(data)) {
const int idx = tomoyo_read_lock(); const int idx = tomoyo_read_lock();
...@@ -87,7 +83,6 @@ static ssize_t tomoyo_write_self(struct file *file, const char __user *buf, ...@@ -87,7 +83,6 @@ static ssize_t tomoyo_write_self(struct file *file, const char __user *buf,
tomoyo_read_unlock(idx); tomoyo_read_unlock(idx);
} else } else
error = -EINVAL; error = -EINVAL;
out:
kfree(data); kfree(data);
return error ? error : count; return error ? error : count;
} }
......
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