Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/include/linux/sched.h b/include/linux/sched.h
- index 52c4847..b0f3bc3 100644
- --- a/include/linux/sched.h
- +++ b/include/linux/sched.h
- @@ -1586,6 +1586,8 @@ struct task_struct {
- struct files_struct *files;
- /* namespaces */
- struct nsproxy *nsproxy;
- +/* network */
- + int sk_bind_dev_if;
- /* signal handlers */
- struct signal_struct *signal;
- struct sighand_struct *sighand;
- diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
- index a8d0759..f681672 100644
- --- a/include/uapi/linux/prctl.h
- +++ b/include/uapi/linux/prctl.h
- @@ -197,4 +197,8 @@ struct prctl_mm_map {
- # define PR_CAP_AMBIENT_LOWER 3
- # define PR_CAP_AMBIENT_CLEAR_ALL 4
- +/* get/set network interface sockets are bound to by default */
- +#define PR_SET_SK_BIND_DEV_IF 48
- +#define PR_GET_SK_BIND_DEV_IF 49
- +
- #endif /* _LINUX_PRCTL_H */
- diff --git a/kernel/fork.c b/kernel/fork.c
- index d277e83..9171aa4 100644
- --- a/kernel/fork.c
- +++ b/kernel/fork.c
- @@ -390,6 +390,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
- tsk->splice_pipe = NULL;
- tsk->task_frag.page = NULL;
- tsk->wake_q.next = NULL;
- + tsk->sk_bind_dev_if = orig->sk_bind_dev_if;
- account_kernel_stack(ti, 1);
- diff --git a/kernel/sys.c b/kernel/sys.c
- index cf8ba54..6a28ead 100644
- --- a/kernel/sys.c
- +++ b/kernel/sys.c
- @@ -52,6 +52,7 @@
- #include <linux/rcupdate.h>
- #include <linux/uidgid.h>
- #include <linux/cred.h>
- +#include <linux/netdevice.h>
- #include <linux/kmsg_dump.h>
- /* Move somewhere else to avoid recompiling? */
- @@ -2269,6 +2270,40 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
- case PR_GET_FP_MODE:
- error = GET_FP_MODE(me);
- break;
- +#ifdef CONFIG_NET
- + case PR_SET_SK_BIND_DEV_IF:
- + {
- + struct net_device *dev;
- + int idx = (int) arg2;
- +
- + if (!capable(CAP_NET_ADMIN))
- + return -EPERM;
- +
- + if (idx) {
- + dev = dev_get_by_index(me->nsproxy->net_ns, idx);
- + if (!dev)
- + return -EINVAL;
- + dev_put(dev);
- + }
- + me->sk_bind_dev_if = idx;
- + break;
- + }
- + case PR_GET_SK_BIND_DEV_IF:
- + {
- + struct task_struct *tsk;
- + int sk_bind_dev_if = -EINVAL;
- +
- + rcu_read_lock();
- + tsk = find_task_by_vpid(arg2);
- + if (tsk)
- + sk_bind_dev_if = tsk->sk_bind_dev_if;
- + rcu_read_unlock();
- + if (tsk != me && !capable(CAP_NET_ADMIN))
- + return -EPERM;
- + error = sk_bind_dev_if;
- + break;
- + }
- +#endif
- default:
- error = -EINVAL;
- break;
- diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
- index 9e48199..68c86e2 100644
- --- a/net/ipv4/af_inet.c
- +++ b/net/ipv4/af_inet.c
- @@ -351,6 +351,7 @@ lookup_protocol:
- sk->sk_destruct = inet_sock_destruct;
- sk->sk_protocol = protocol;
- sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
- + sk->sk_bound_dev_if = current->sk_bind_dev_if;
- inet->uc_ttl = -1;
- inet->mc_loop = 1;
- diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
- index b11c37c..b895ad0 100644
- --- a/net/ipv6/af_inet6.c
- +++ b/net/ipv6/af_inet6.c
- @@ -192,6 +192,7 @@ lookup_protocol:
- sk->sk_destruct = inet_sock_destruct;
- sk->sk_family = PF_INET6;
- sk->sk_protocol = protocol;
- + sk->sk_bound_dev_if = current->sk_bind_dev_if;
- sk->sk_backlog_rcv = answer->prot->backlog_rcv;
- (END)
Add Comment
Please, Sign In to add comment