netfilter: nf_log: fix direct userspace memory access in proc handler
Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
@@ -47,7 +47,6 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger)
|
|||||||
mutex_lock(&nf_log_mutex);
|
mutex_lock(&nf_log_mutex);
|
||||||
|
|
||||||
if (pf == NFPROTO_UNSPEC) {
|
if (pf == NFPROTO_UNSPEC) {
|
||||||
int i;
|
|
||||||
for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
|
for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
|
||||||
list_add_tail(&(logger->list[i]), &(nf_loggers_l[i]));
|
list_add_tail(&(logger->list[i]), &(nf_loggers_l[i]));
|
||||||
} else {
|
} else {
|
||||||
@@ -216,7 +215,7 @@ static const struct file_operations nflog_file_ops = {
|
|||||||
#endif /* PROC_FS */
|
#endif /* PROC_FS */
|
||||||
|
|
||||||
#ifdef CONFIG_SYSCTL
|
#ifdef CONFIG_SYSCTL
|
||||||
struct ctl_path nf_log_sysctl_path[] = {
|
static struct ctl_path nf_log_sysctl_path[] = {
|
||||||
{ .procname = "net", .ctl_name = CTL_NET, },
|
{ .procname = "net", .ctl_name = CTL_NET, },
|
||||||
{ .procname = "netfilter", .ctl_name = NET_NETFILTER, },
|
{ .procname = "netfilter", .ctl_name = NET_NETFILTER, },
|
||||||
{ .procname = "nf_log", .ctl_name = CTL_UNNUMBERED, },
|
{ .procname = "nf_log", .ctl_name = CTL_UNNUMBERED, },
|
||||||
@@ -228,19 +227,26 @@ static struct ctl_table nf_log_sysctl_table[NFPROTO_NUMPROTO+1];
|
|||||||
static struct ctl_table_header *nf_log_dir_header;
|
static struct ctl_table_header *nf_log_dir_header;
|
||||||
|
|
||||||
static int nf_log_proc_dostring(ctl_table *table, int write, struct file *filp,
|
static int nf_log_proc_dostring(ctl_table *table, int write, struct file *filp,
|
||||||
void *buffer, size_t *lenp, loff_t *ppos)
|
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||||
{
|
{
|
||||||
const struct nf_logger *logger;
|
const struct nf_logger *logger;
|
||||||
|
char buf[NFLOGGER_NAME_LEN];
|
||||||
|
size_t size = *lenp;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
int tindex = (unsigned long)table->extra1;
|
int tindex = (unsigned long)table->extra1;
|
||||||
|
|
||||||
if (write) {
|
if (write) {
|
||||||
if (!strcmp(buffer, "NONE")) {
|
if (size > sizeof(buf))
|
||||||
|
size = sizeof(buf);
|
||||||
|
if (copy_from_user(buf, buffer, size))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
if (!strcmp(buf, "NONE")) {
|
||||||
nf_log_unbind_pf(tindex);
|
nf_log_unbind_pf(tindex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
mutex_lock(&nf_log_mutex);
|
mutex_lock(&nf_log_mutex);
|
||||||
logger = __find_logger(tindex, buffer);
|
logger = __find_logger(tindex, buf);
|
||||||
if (logger == NULL) {
|
if (logger == NULL) {
|
||||||
mutex_unlock(&nf_log_mutex);
|
mutex_unlock(&nf_log_mutex);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
Reference in New Issue
Block a user