From: Kuniyuki Iwashima <kuniyu@xxxxxxxxxx> Date: Fri, 13 Oct 2023 15:04:28 -0700 > diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c > index 514f1a4abdee..b1dd415863ff 100644 > --- a/net/ipv4/syncookies.c > +++ b/net/ipv4/syncookies.c > @@ -317,6 +317,37 @@ struct request_sock *cookie_tcp_reqsk_alloc(const struct request_sock_ops *ops, > } > EXPORT_SYMBOL_GPL(cookie_tcp_reqsk_alloc); > > +#if IS_ENABLED(CONFIG_CGROUP_BPF) && IS_ENABLED(CONFIG_SYN_COOKIES) > +int bpf_skops_cookie_check(struct sock *sk, struct request_sock *req, struct sk_buff *skb) > +{ > + struct bpf_sock_ops_kern sock_ops; > + > + memset(&sock_ops, 0, offsetof(struct bpf_sock_ops_kern, temp)); > + > + sock_ops.op = BPF_SOCK_OPS_CHECK_SYNCOOKIE_CB; > + sock_ops.sk = req_to_sk(req); > + sock_ops.args[0] = tcp_rsk(req)->snt_isn; > + > + bpf_skops_init_skb(&sock_ops, skb, tcp_hdrlen(skb)); > + > + if (BPF_CGROUP_RUN_PROG_SOCK_OPS_SK(&sock_ops, sk)) > + goto err; > + > + if (!sock_ops.replylong[0]) > + goto err; I noticed this test is insufficient to check valid MSS. I'll use msstab[0] as the minimum valid MSS in v2. ---8<--- diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 22353a9af52d..4af165fd48f9 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -287,6 +287,7 @@ int bpf_skops_cookie_check(struct sock *sk, struct request_sock *req, struct sk_ struct bpf_sock_ops_kern sock_ops; struct net *net = sock_net(sk); u32 options; + u16 min_mss; if (tcp_opt->saw_tstamp) { if (!READ_ONCE(net->ipv4.sysctl_tcp_timestamps)) @@ -307,7 +308,8 @@ int bpf_skops_cookie_check(struct sock *sk, struct request_sock *req, struct sk_ if (BPF_CGROUP_RUN_PROG_SOCK_OPS_SK(&sock_ops, sk)) goto err; - if (!sock_ops.replylong[0]) + min_mss = skb->protocol == htons(ETH_P_IP) ? msstab[0] : IPV6_MIN_MTU - 60; + if (sock_ops.replylong[0] < min_mss) goto err; options = sock_ops.replylong[1]; ---8<--- > + > + __NET_INC_STATS(sock_net(sk), LINUX_MIB_SYNCOOKIESRECV); > + > + return sock_ops.replylong[0]; > + > +err: > + __NET_INC_STATS(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED); > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(bpf_skops_cookie_check); > +#endif > + > /* On input, sk is a listener. > * Output is listener if incoming packet would not create a child > * NULL if memory could not be allocated.