diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/filter.c | 59 | ||||
-rw-r--r-- | net/core/gen_estimator.c | 2 | ||||
-rw-r--r-- | net/core/neighbour.c | 75 | ||||
-rw-r--r-- | net/core/pktgen.c | 6 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 8 | ||||
-rw-r--r-- | net/core/scm.c | 4 | ||||
-rw-r--r-- | net/core/sock.c | 16 |
7 files changed, 100 insertions, 70 deletions
diff --git a/net/core/filter.c b/net/core/filter.c index bd903aa..e0a0694 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -387,6 +387,25 @@ int sk_chk_filter(struct sock_filter *filter, int flen) } /** + * sk_filter_rcu_release: Release a socket filter by rcu_head + * @rcu: rcu_head that contains the sk_filter to free + */ +static void sk_filter_rcu_release(struct rcu_head *rcu) +{ + struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); + + sk_filter_release(fp); +} + +static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp) +{ + unsigned int size = sk_filter_len(fp); + + atomic_sub(size, &sk->sk_omem_alloc); + call_rcu_bh(&fp->rcu, sk_filter_rcu_release); +} + +/** * sk_attach_filter - attach a socket filter * @fprog: the filter program * @sk: the socket to use @@ -398,7 +417,7 @@ int sk_chk_filter(struct sock_filter *filter, int flen) */ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) { - struct sk_filter *fp; + struct sk_filter *fp, *old_fp; unsigned int fsize = sizeof(struct sock_filter) * fprog->len; int err; @@ -418,19 +437,35 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) fp->len = fprog->len; err = sk_chk_filter(fp->insns, fp->len); - if (!err) { - struct sk_filter *old_fp; - - rcu_read_lock_bh(); - old_fp = rcu_dereference(sk->sk_filter); - rcu_assign_pointer(sk->sk_filter, fp); - rcu_read_unlock_bh(); - fp = old_fp; + if (err) { + sk_filter_uncharge(sk, fp); + return err; } - if (fp) - sk_filter_release(sk, fp); - return err; + rcu_read_lock_bh(); + old_fp = rcu_dereference(sk->sk_filter); + rcu_assign_pointer(sk->sk_filter, fp); + rcu_read_unlock_bh(); + + if (old_fp) + sk_filter_delayed_uncharge(sk, old_fp); + return 0; +} + +int sk_detach_filter(struct sock *sk) +{ + int ret = -ENOENT; + struct sk_filter *filter; + + rcu_read_lock_bh(); + filter = rcu_dereference(sk->sk_filter); + if (filter) { + rcu_assign_pointer(sk->sk_filter, NULL); + sk_filter_delayed_uncharge(sk, filter); + ret = 0; + } + rcu_read_unlock_bh(); + return ret; } EXPORT_SYMBOL(sk_chk_filter); diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index 590a767..daadbcc 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c @@ -15,7 +15,7 @@ #include <asm/uaccess.h> #include <asm/system.h> -#include <asm/bitops.h> +#include <linux/bitops.h> #include <linux/module.h> #include <linux/types.h> #include <linux/kernel.h> diff --git a/net/core/neighbour.c b/net/core/neighbour.c index cd3af59..67ba991 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -2496,7 +2496,6 @@ static struct neigh_sysctl_table { .proc_handler = &proc_dointvec, }, { - .ctl_name = NET_NEIGH_RETRANS_TIME, .procname = "retrans_time", .maxlen = sizeof(int), .mode = 0644, @@ -2541,27 +2540,40 @@ static struct neigh_sysctl_table { .proc_handler = &proc_dointvec, }, { - .ctl_name = NET_NEIGH_ANYCAST_DELAY, .procname = "anycast_delay", .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_userhz_jiffies, }, { - .ctl_name = NET_NEIGH_PROXY_DELAY, .procname = "proxy_delay", .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_userhz_jiffies, }, { - .ctl_name = NET_NEIGH_LOCKTIME, .procname = "locktime", .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_userhz_jiffies, }, { + .ctl_name = NET_NEIGH_RETRANS_TIME_MS, + .procname = "retrans_time_ms", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_ms_jiffies, + .strategy = &sysctl_ms_jiffies, + }, + { + .ctl_name = NET_NEIGH_REACHABLE_TIME_MS, + .procname = "base_reachable_time_ms", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_ms_jiffies, + .strategy = &sysctl_ms_jiffies, + }, + { .ctl_name = NET_NEIGH_GC_INTERVAL, .procname = "gc_interval", .maxlen = sizeof(int), @@ -2590,22 +2602,7 @@ static struct neigh_sysctl_table { .mode = 0644, .proc_handler = &proc_dointvec, }, - { - .ctl_name = NET_NEIGH_RETRANS_TIME_MS, - .procname = "retrans_time_ms", - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec_ms_jiffies, - .strategy = &sysctl_ms_jiffies, - }, - { - .ctl_name = NET_NEIGH_REACHABLE_TIME_MS, - .procname = "base_reachable_time_ms", - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec_ms_jiffies, - .strategy = &sysctl_ms_jiffies, - }, + {} }, .neigh_dev = { { @@ -2658,42 +2655,48 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, t->neigh_vars[9].data = &p->anycast_delay; t->neigh_vars[10].data = &p->proxy_delay; t->neigh_vars[11].data = &p->locktime; + t->neigh_vars[12].data = &p->retrans_time; + t->neigh_vars[13].data = &p->base_reachable_time; if (dev) { dev_name_source = dev->name; t->neigh_dev[0].ctl_name = dev->ifindex; - t->neigh_vars[12].procname = NULL; - t->neigh_vars[13].procname = NULL; - t->neigh_vars[14].procname = NULL; - t->neigh_vars[15].procname = NULL; + /* Terminate the table early */ + memset(&t->neigh_vars[14], 0, sizeof(t->neigh_vars[14])); } else { dev_name_source = t->neigh_dev[0].procname; - t->neigh_vars[12].data = (int *)(p + 1); - t->neigh_vars[13].data = (int *)(p + 1) + 1; - t->neigh_vars[14].data = (int *)(p + 1) + 2; - t->neigh_vars[15].data = (int *)(p + 1) + 3; + t->neigh_vars[14].data = (int *)(p + 1); + t->neigh_vars[15].data = (int *)(p + 1) + 1; + t->neigh_vars[16].data = (int *)(p + 1) + 2; + t->neigh_vars[17].data = (int *)(p + 1) + 3; } - t->neigh_vars[16].data = &p->retrans_time; - t->neigh_vars[17].data = &p->base_reachable_time; if (handler || strategy) { /* RetransTime */ t->neigh_vars[3].proc_handler = handler; t->neigh_vars[3].strategy = strategy; t->neigh_vars[3].extra1 = dev; + if (!strategy) + t->neigh_vars[3].ctl_name = CTL_UNNUMBERED; /* ReachableTime */ t->neigh_vars[4].proc_handler = handler; t->neigh_vars[4].strategy = strategy; t->neigh_vars[4].extra1 = dev; + if (!strategy) + t->neigh_vars[4].ctl_name = CTL_UNNUMBERED; /* RetransTime (in milliseconds)*/ - t->neigh_vars[16].proc_handler = handler; - t->neigh_vars[16].strategy = strategy; - t->neigh_vars[16].extra1 = dev; + t->neigh_vars[12].proc_handler = handler; + t->neigh_vars[12].strategy = strategy; + t->neigh_vars[12].extra1 = dev; + if (!strategy) + t->neigh_vars[12].ctl_name = CTL_UNNUMBERED; /* ReachableTime (in milliseconds) */ - t->neigh_vars[17].proc_handler = handler; - t->neigh_vars[17].strategy = strategy; - t->neigh_vars[17].extra1 = dev; + t->neigh_vars[13].proc_handler = handler; + t->neigh_vars[13].strategy = strategy; + t->neigh_vars[13].extra1 = dev; + if (!strategy) + t->neigh_vars[13].ctl_name = CTL_UNNUMBERED; } dev_name = kstrdup(dev_name_source, GFP_KERNEL); diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 2100c73..7ac7031 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -161,7 +161,7 @@ #endif #include <asm/byteorder.h> #include <linux/rcupdate.h> -#include <asm/bitops.h> +#include <linux/bitops.h> #include <asm/io.h> #include <asm/dma.h> #include <asm/uaccess.h> @@ -2454,7 +2454,7 @@ static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev) spin_lock(&x->lock); iph = ip_hdr(skb); - err = x->mode->output(x, skb); + err = x->outer_mode->output(x, skb); if (err) goto error; err = x->type->output(x, skb); @@ -3514,7 +3514,7 @@ static int pktgen_thread_worker(void *arg) init_waitqueue_head(&t->queue); - pr_debug("pktgen: starting pktgen/%d: pid=%d\n", cpu, current->pid); + pr_debug("pktgen: starting pktgen/%d: pid=%d\n", cpu, task_pid_nr(current)); set_current_state(TASK_INTERRUPTIBLE); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 1072d16..4a2640d 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -744,10 +744,10 @@ static struct net *get_net_ns_by_pid(pid_t pid) rcu_read_lock(); tsk = find_task_by_pid(pid); if (tsk) { - task_lock(tsk); - if (tsk->nsproxy) - net = get_net(tsk->nsproxy->net_ns); - task_unlock(tsk); + struct nsproxy *nsproxy; + nsproxy = task_nsproxy(tsk); + if (nsproxy) + net = get_net(nsproxy->net_ns); } rcu_read_unlock(); return net; diff --git a/net/core/scm.c b/net/core/scm.c index 530bee8..100ba6d 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -24,6 +24,8 @@ #include <linux/interrupt.h> #include <linux/netdevice.h> #include <linux/security.h> +#include <linux/pid.h> +#include <linux/nsproxy.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -42,7 +44,7 @@ static __inline__ int scm_check_creds(struct ucred *creds) { - if ((creds->pid == current->tgid || capable(CAP_SYS_ADMIN)) && + if ((creds->pid == task_tgid_vnr(current) || capable(CAP_SYS_ADMIN)) && ((creds->uid == current->uid || creds->uid == current->euid || creds->uid == current->suid) || capable(CAP_SETUID)) && ((creds->gid == current->gid || creds->gid == current->egid || diff --git a/net/core/sock.c b/net/core/sock.c index d45ecdc..febbcbc 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -232,7 +232,7 @@ static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen) warned++; printk(KERN_INFO "sock_set_timeout: `%s' (pid %d) " "tries to set negative timeout\n", - current->comm, current->pid); + current->comm, task_pid_nr(current)); return 0; } *timeo_p = MAX_SCHEDULE_TIMEOUT; @@ -428,7 +428,6 @@ int sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) { struct sock *sk=sock->sk; - struct sk_filter *filter; int val; int valbool; struct linger ling; @@ -652,16 +651,7 @@ set_rcvbuf: break; case SO_DETACH_FILTER: - rcu_read_lock_bh(); - filter = rcu_dereference(sk->sk_filter); - if (filter) { - rcu_assign_pointer(sk->sk_filter, NULL); - sk_filter_release(sk, filter); - rcu_read_unlock_bh(); - break; - } - rcu_read_unlock_bh(); - ret = -ENONET; + ret = sk_detach_filter(sk); break; case SO_PASSSEC: @@ -925,7 +915,7 @@ void sk_free(struct sock *sk) filter = rcu_dereference(sk->sk_filter); if (filter) { - sk_filter_release(sk, filter); + sk_filter_uncharge(sk, filter); rcu_assign_pointer(sk->sk_filter, NULL); } |