bpf: Invoke cgroup/connect{4,6} programs for unprivileged ICMP ping
Bugzilla: https://bugzilla.redhat.com/2166911
Upstream Status: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Conflicts:
- net/ipv6/ping.c: context difference due to already applied af4a12dd88
("inet6: Remove inet6_destroy_sock() in sk->sk_prot->destroy()."), which
removes pingv6_prot.destroy
commit 0ffe2412531e95a309d7f0bfe985fc4ca4d39de8
Author: YiFei Zhu <zhuyifei@google.com>
Date: Fri Sep 9 00:49:39 2022 +0000
bpf: Invoke cgroup/connect{4,6} programs for unprivileged ICMP ping
Usually when a TCP/UDP connection is initiated, we can bind the socket
to a specific IP attached to an interface in a cgroup/connect hook.
But for pings, this is impossible, as the hook is not being called.
This adds the hook invocation to unprivileged ICMP ping (i.e. ping
sockets created with SOCK_DGRAM IPPROTO_ICMP(V6) as opposed to
SOCK_RAW. Logic is mirrored from UDP sockets where the hook is invoked
during pre_connect, after a check for suficiently sized addr_len.
Signed-off-by: YiFei Zhu <zhuyifei@google.com>
Link: https://lore.kernel.org/r/5764914c252fad4cd134fb6664c6ede95f409412.1662682323.git.zhuyifei@google.com
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Signed-off-by: Artem Savkov <asavkov@redhat.com>
This commit is contained in:
parent
fee78f87aa
commit
26e61afb0f
|
@ -33,6 +33,7 @@
|
|||
#include <linux/skbuff.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/bpf-cgroup.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/ping.h>
|
||||
#include <net/udp.h>
|
||||
|
@ -300,6 +301,19 @@ void ping_close(struct sock *sk, long timeout)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(ping_close);
|
||||
|
||||
static int ping_pre_connect(struct sock *sk, struct sockaddr *uaddr,
|
||||
int addr_len)
|
||||
{
|
||||
/* This check is replicated from __ip4_datagram_connect() and
|
||||
* intended to prevent BPF program called below from accessing bytes
|
||||
* that are out of the bound specified by user in addr_len.
|
||||
*/
|
||||
if (addr_len < sizeof(struct sockaddr_in))
|
||||
return -EINVAL;
|
||||
|
||||
return BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr);
|
||||
}
|
||||
|
||||
/* Checks the bind address and possibly modifies sk->sk_bound_dev_if. */
|
||||
static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk,
|
||||
struct sockaddr *uaddr, int addr_len)
|
||||
|
@ -1005,6 +1019,7 @@ struct proto ping_prot = {
|
|||
.owner = THIS_MODULE,
|
||||
.init = ping_init_sock,
|
||||
.close = ping_close,
|
||||
.pre_connect = ping_pre_connect,
|
||||
.connect = ip4_datagram_connect,
|
||||
.disconnect = __udp_disconnect,
|
||||
.setsockopt = ip_setsockopt,
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <net/udp.h>
|
||||
#include <net/transp_v6.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/bpf-cgroup.h>
|
||||
#include <net/ping.h>
|
||||
|
||||
/* Compatibility glue so we can support IPv6 when it's compiled as a module */
|
||||
|
@ -44,6 +45,20 @@ static int dummy_ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ping_v6_pre_connect(struct sock *sk, struct sockaddr *uaddr,
|
||||
int addr_len)
|
||||
{
|
||||
/* This check is replicated from __ip6_datagram_connect() and
|
||||
* intended to prevent BPF program called below from accessing
|
||||
* bytes that are out of the bound specified by user in addr_len.
|
||||
*/
|
||||
|
||||
if (addr_len < SIN6_LEN_RFC2133)
|
||||
return -EINVAL;
|
||||
|
||||
return BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr);
|
||||
}
|
||||
|
||||
static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
|
||||
{
|
||||
struct inet_sock *inet = inet_sk(sk);
|
||||
|
@ -166,6 +181,7 @@ struct proto pingv6_prot = {
|
|||
.owner = THIS_MODULE,
|
||||
.init = ping_init_sock,
|
||||
.close = ping_close,
|
||||
.pre_connect = ping_v6_pre_connect,
|
||||
.connect = ip6_datagram_connect_v6_only,
|
||||
.disconnect = __udp_disconnect,
|
||||
.setsockopt = ipv6_setsockopt,
|
||||
|
|
Loading…
Reference in New Issue