* [PATCH] netfilter: nft_socket: socket expressions for GID & UID @ 2022-04-20 18:54 Topi Miettinen 2022-04-20 21:15 ` Jan Engelhardt 2022-04-25 18:45 ` Topi Miettinen 0 siblings, 2 replies; 17+ messages in thread From: Topi Miettinen @ 2022-04-20 18:54 UTC (permalink / raw) To: netfilter-devel; +Cc: Topi Miettinen Add socket expressions for checking GID or UID of the originating socket. These work also on input side, unlike meta skuid/skgid. Signed-off-by: Topi Miettinen <toiwoton@gmail.com> --- include/uapi/linux/netfilter/nf_tables.h | 4 ++++ net/netfilter/nft_socket.c | 28 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index 466fd3f4447c..b3c09c67d13a 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -1040,12 +1040,16 @@ enum nft_socket_attributes { * @NFT_SOCKET_MARK: Value of the socket mark * @NFT_SOCKET_WILDCARD: Whether the socket is zero-bound (e.g. 0.0.0.0 or ::0) * @NFT_SOCKET_CGROUPV2: Match on cgroups version 2 + * @NFT_SOCKET_GID: Match on GID of socket owner + * @NFT_SOCKET_GID: Match on UID of socket owner */ enum nft_socket_keys { NFT_SOCKET_TRANSPARENT, NFT_SOCKET_MARK, NFT_SOCKET_WILDCARD, NFT_SOCKET_CGROUPV2, + NFT_SOCKET_GID, + NFT_SOCKET_UID, __NFT_SOCKET_MAX }; #define NFT_SOCKET_MAX (__NFT_SOCKET_MAX - 1) diff --git a/net/netfilter/nft_socket.c b/net/netfilter/nft_socket.c index b8f011145765..2f0fe9d886f3 100644 --- a/net/netfilter/nft_socket.c +++ b/net/netfilter/nft_socket.c @@ -113,6 +113,32 @@ static void nft_socket_eval(const struct nft_expr *expr, } break; #endif + case NFT_SOCKET_GID: + if (sk_fullsock(sk)) { + struct socket *sock; + + sock = sk->sk_socket; + if (sock && sock->file) + *dest = from_kgid_munged(sock_net(sk)->user_ns, + sock->file->f_cred->fsgid); + } else { + regs->verdict.code = NFT_BREAK; + return; + } + break; + case NFT_SOCKET_UID: + if (sk_fullsock(sk)) { + struct socket *sock; + + sock = sk->sk_socket; + if (sock && sock->file) + *dest = from_kuid_munged(sock_net(sk)->user_ns, + sock->file->f_cred->fsuid); + } else { + regs->verdict.code = NFT_BREAK; + return; + } + break; default: WARN_ON(1); regs->verdict.code = NFT_BREAK; @@ -156,6 +182,8 @@ static int nft_socket_init(const struct nft_ctx *ctx, len = sizeof(u8); break; case NFT_SOCKET_MARK: + case NFT_SOCKET_GID: + case NFT_SOCKET_UID: len = sizeof(u32); break; #ifdef CONFIG_CGROUPS -- 2.35.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH] netfilter: nft_socket: socket expressions for GID & UID 2022-04-20 18:54 [PATCH] netfilter: nft_socket: socket expressions for GID & UID Topi Miettinen @ 2022-04-20 21:15 ` Jan Engelhardt 2022-04-21 16:35 ` Topi Miettinen 2022-04-25 18:45 ` Topi Miettinen 1 sibling, 1 reply; 17+ messages in thread From: Jan Engelhardt @ 2022-04-20 21:15 UTC (permalink / raw) To: Topi Miettinen; +Cc: netfilter-devel On Wednesday 2022-04-20 20:54, Topi Miettinen wrote: >Add socket expressions for checking GID or UID of the originating >socket. These work also on input side, unlike meta skuid/skgid. Why exactly is it that meta skuid does not work? Because of the skb_to_full_sk() call in nft_meta_get_eval_skugid()? >+ case NFT_SOCKET_GID: >+ if (sk_fullsock(sk)) { >+ struct socket *sock; >+ >+ sock = sk->sk_socket; >+ if (sock && sock->file) >+ *dest = from_kgid_munged(sock_net(sk)->user_ns, >+ sock->file->f_cred->fsgid); The code is quite the same as nft_meta_get_eval_skugid's, save for the BH locking and skb_to_full_sk. Perhaps nft_socket.c could still call into a suitably augmented nft_meta_get_eval_skugid function to share code. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] netfilter: nft_socket: socket expressions for GID & UID 2022-04-20 21:15 ` Jan Engelhardt @ 2022-04-21 16:35 ` Topi Miettinen 2022-04-26 21:05 ` Pablo Neira Ayuso 0 siblings, 1 reply; 17+ messages in thread From: Topi Miettinen @ 2022-04-21 16:35 UTC (permalink / raw) To: Jan Engelhardt; +Cc: netfilter-devel On 21.4.2022 0.15, Jan Engelhardt wrote: > > On Wednesday 2022-04-20 20:54, Topi Miettinen wrote: > >> Add socket expressions for checking GID or UID of the originating >> socket. These work also on input side, unlike meta skuid/skgid. > > Why exactly is it that meta skuid does not work? > Because of the skb_to_full_sk() call in nft_meta_get_eval_skugid()? I don't know the details, but early demux isn't reliable and filters aren't run after final demux. In my case, something like "ct state new meta skuid < 1000 drop" as part of input filter doesn't do anything. Making "meta skuid" 100% reliable would be of course preferable to adding a new expression. > >> + case NFT_SOCKET_GID: >> + if (sk_fullsock(sk)) { >> + struct socket *sock; >> + >> + sock = sk->sk_socket; >> + if (sock && sock->file) >> + *dest = from_kgid_munged(sock_net(sk)->user_ns, >> + sock->file->f_cred->fsgid); > > The code is quite the same as nft_meta_get_eval_skugid's, save for the BH > locking and skb_to_full_sk. Perhaps nft_socket.c could still call into a > suitably augmented nft_meta_get_eval_skugid function to share code. Makes sense. -Topi ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] netfilter: nft_socket: socket expressions for GID & UID 2022-04-21 16:35 ` Topi Miettinen @ 2022-04-26 21:05 ` Pablo Neira Ayuso 2022-04-26 21:07 ` Pablo Neira Ayuso 0 siblings, 1 reply; 17+ messages in thread From: Pablo Neira Ayuso @ 2022-04-26 21:05 UTC (permalink / raw) To: Topi Miettinen; +Cc: Jan Engelhardt, netfilter-devel [-- Attachment #1: Type: text/plain, Size: 1011 bytes --] On Thu, Apr 21, 2022 at 07:35:06PM +0300, Topi Miettinen wrote: > On 21.4.2022 0.15, Jan Engelhardt wrote: > > > > On Wednesday 2022-04-20 20:54, Topi Miettinen wrote: > > > > > Add socket expressions for checking GID or UID of the originating > > > socket. These work also on input side, unlike meta skuid/skgid. > > > > Why exactly is it that meta skuid does not work? > > Because of the skb_to_full_sk() call in nft_meta_get_eval_skugid()? > > I don't know the details, but early demux isn't reliable and filters aren't > run after final demux. In my case, something like "ct state new meta skuid < > 1000 drop" as part of input filter doesn't do anything. Making "meta skuid" > 100% reliable would be of course preferable to adding a new expression. Could you give a try to this kernel patch? This patch adds a new socket hook for inet layer 4 protocols, it is coming after the NF_LOCAL_IN hook, where the socket information is available for all cases. You also need a small patch for userspace nft. [-- Attachment #2: kernel-socket-hook.patch --] [-- Type: text/x-diff, Size: 9321 bytes --] diff --git a/include/linux/netfilter_socket.h b/include/linux/netfilter_socket.h new file mode 100644 index 000000000000..7acdb5463e14 --- /dev/null +++ b/include/linux/netfilter_socket.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _NETFILTER_SOCKET_H_ +#define _NETFILTER_SOCKET_H_ + +#include <linux/netfilter.h> + +static inline bool nf_hook_socket_active(struct net *net, const struct sk_buff *skb) +{ +#ifdef CONFIG_JUMP_LABEL + if (!static_key_false(&nf_hooks_needed[NFPROTO_INET][NF_INET_SOCKET])) + return false; +#endif + return rcu_access_pointer(net->nf.hooks_socket[0]); +} + +/* caller must hold rcu_read_lock */ +static inline int nf_hook_socket(struct net *net, struct sk_buff *skb) +{ + struct nf_hook_entries *e = rcu_dereference(net->nf.hooks_socket[0]); + struct nf_hook_state state; + int ret; + + if (unlikely(!e)) + return 0; + + nf_hook_state_init(&state, NF_INET_SOCKET, + NFPROTO_INET, skb->dev, NULL, NULL, + dev_net(skb->dev), NULL); + ret = nf_hook_slow(skb, &state, e, 0); + if (ret == 0) + return -1; + + return ret; +} + +#else /* CONFIG_NETFILTER_SOCKET */ +static inline int nf_hook_socket_active(struct sk_buff *skb) +{ + return 0; +} + +static inline int nf_hook_socket(struct sk_buff *skb) +{ + return 0; +} +#endif /* _NETFILTER_SOCKET_H_ */ diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 20af9d3557b9..790c073629e8 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -15,7 +15,7 @@ #include <net/flow_offload.h> #include <net/netns/generic.h> -#define NFT_MAX_HOOKS (NF_INET_INGRESS + 1) +#define NFT_MAX_HOOKS (NF_INET_SOCKET + 1) struct module; diff --git a/include/net/netns/netfilter.h b/include/net/netns/netfilter.h index b593f95e9991..d65922f0d65a 100644 --- a/include/net/netns/netfilter.h +++ b/include/net/netns/netfilter.h @@ -18,6 +18,7 @@ struct netns_nf { #endif struct nf_hook_entries __rcu *hooks_ipv4[NF_INET_NUMHOOKS]; struct nf_hook_entries __rcu *hooks_ipv6[NF_INET_NUMHOOKS]; + struct nf_hook_entries __rcu *hooks_socket[1]; #ifdef CONFIG_NETFILTER_FAMILY_ARP struct nf_hook_entries __rcu *hooks_arp[NF_ARP_NUMHOOKS]; #endif diff --git a/include/net/sock.h b/include/net/sock.h index c4b91fc19b9c..4e40823d2a43 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2907,4 +2907,7 @@ static inline bool sk_is_readable(struct sock *sk) return sk->sk_prot->sock_is_readable(sk); return false; } + +int sk_inet_filter(struct sock *sk, struct sk_buff *skb, unsigned int cap); + #endif /* _SOCK_H */ diff --git a/include/uapi/linux/netfilter.h b/include/uapi/linux/netfilter.h index 53411ccc69db..65c6691249e6 100644 --- a/include/uapi/linux/netfilter.h +++ b/include/uapi/linux/netfilter.h @@ -45,8 +45,9 @@ enum nf_inet_hooks { NF_INET_FORWARD, NF_INET_LOCAL_OUT, NF_INET_POST_ROUTING, + NF_INET_INGRESS, NF_INET_NUMHOOKS, - NF_INET_INGRESS = NF_INET_NUMHOOKS, + NF_INET_SOCKET = NF_INET_NUMHOOKS, }; enum nf_dev_hooks { diff --git a/net/core/sock.c b/net/core/sock.c index 1180a0cb0110..19e7906f8955 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -129,6 +129,7 @@ #include <net/cls_cgroup.h> #include <net/netprio_cgroup.h> #include <linux/sock_diag.h> +#include <linux/netfilter_socket.h> #include <linux/filter.h> #include <net/sock_reuseport.h> @@ -520,7 +521,7 @@ int __sk_receive_skb(struct sock *sk, struct sk_buff *skb, { int rc = NET_RX_SUCCESS; - if (sk_filter_trim_cap(sk, skb, trim_cap)) + if (sk_inet_filter(sk, skb, trim_cap)) goto discard_and_relse; skb->dev = NULL; @@ -3222,6 +3223,25 @@ void sk_stop_timer_sync(struct sock *sk, struct timer_list *timer) } EXPORT_SYMBOL(sk_stop_timer_sync); +int sk_inet_filter(struct sock *sk, struct sk_buff *skb, unsigned int cap) +{ + struct net *net = sock_net(sk); + int ret; + + ret = sk_filter_trim_cap(sk, skb, cap); + if (ret < 0) + return ret; + + if (nf_hook_socket_active(net, skb)) { + ret = nf_hook_socket(net, skb); + if (ret == 0) + return -EPERM; + } + + return 0; +} +EXPORT_SYMBOL_GPL(sk_inet_filter); + void sock_init_data(struct socket *sock, struct sock *sk) { sk_init_common(sk); diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index eab3bd1ee9a0..0f7bffde01ae 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -593,7 +593,7 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) if (skb->protocol == htons(ETH_P_IP)) return dccp_v4_do_rcv(sk, skb); - if (sk_filter(sk, skb)) + if (sk_inet_filter(sk, skb, 1)) goto discard; /* diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index f9cec624068d..0aa5af583f71 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1872,7 +1872,7 @@ int tcp_filter(struct sock *sk, struct sk_buff *skb) { struct tcphdr *th = (struct tcphdr *)skb->data; - return sk_filter_trim_cap(sk, skb, th->doff * 4); + return sk_inet_filter(sk, skb, th->doff * 4); } EXPORT_SYMBOL(tcp_filter); diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 6b4d8361560f..ac4a64071ac7 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -2211,7 +2211,7 @@ static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) udp_lib_checksum_complete(skb)) goto csum_error; - if (sk_filter_trim_cap(sk, skb, sizeof(struct udphdr))) { + if (sk_inet_filter(sk, skb, sizeof(struct udphdr))) { drop_reason = SKB_DROP_REASON_SOCKET_FILTER; goto drop; } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 7f0fa9bd9ffe..374bc818c94f 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -734,7 +734,7 @@ static int udpv6_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb) udp_lib_checksum_complete(skb)) goto csum_error; - if (sk_filter_trim_cap(sk, skb, sizeof(struct udphdr))) + if (sk_inet_filter(sk, skb, sizeof(struct udphdr))) goto drop; udp_csum_pull_header(skb); diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index ddc54b6d18ee..3eb7d54225f5 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -18,6 +18,13 @@ config NETFILTER_EGRESS This allows you to classify packets before transmission using the Netfilter infrastructure. +config NETFILTER_SOCKET + bool "Netfilter socket support" + default y + help + This allows you to classify packets for local sockets using the + Netfilter infrastructure. + config NETFILTER_SKIP_EGRESS def_bool NETFILTER_EGRESS && (NET_CLS_ACT || IFB) diff --git a/net/netfilter/core.c b/net/netfilter/core.c index dcf752b55a52..0dfdf69e389a 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c @@ -284,13 +284,17 @@ nf_hook_entry_head(struct net *net, int pf, unsigned int hooknum, #endif #ifdef CONFIG_NETFILTER_INGRESS case NFPROTO_INET: - if (WARN_ON_ONCE(hooknum != NF_INET_INGRESS)) - return NULL; - if (!dev || dev_net(dev) != net) { - WARN_ON_ONCE(1); - return NULL; + if (hooknum == NF_INET_INGRESS) { + if (!dev || dev_net(dev) != net) { + WARN_ON_ONCE(1); + return NULL; + } + return &dev->nf_hooks_ingress; + } else if (hooknum == NF_INET_SOCKET) { + return net->nf.hooks_socket; } - return &dev->nf_hooks_ingress; + WARN_ON_ONCE(1); + return NULL; #endif case NFPROTO_IPV4: if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv4) <= hooknum)) @@ -523,7 +527,8 @@ static void __nf_unregister_net_hook(struct net *net, int pf, void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg) { if (reg->pf == NFPROTO_INET) { - if (reg->hooknum == NF_INET_INGRESS) { + if (reg->hooknum == NF_INET_INGRESS || + reg->hooknum == NF_INET_SOCKET) { __nf_unregister_net_hook(net, NFPROTO_INET, reg); } else { __nf_unregister_net_hook(net, NFPROTO_IPV4, reg); @@ -553,7 +558,8 @@ int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg) int err; if (reg->pf == NFPROTO_INET) { - if (reg->hooknum == NF_INET_INGRESS) { + if (reg->hooknum == NF_INET_INGRESS || + reg->hooknum == NF_INET_SOCKET) { err = __nf_register_net_hook(net, NFPROTO_INET, reg); if (err < 0) return err; diff --git a/net/netfilter/nft_chain_filter.c b/net/netfilter/nft_chain_filter.c index c3563f0be269..eceeebfd0ab2 100644 --- a/net/netfilter/nft_chain_filter.c +++ b/net/netfilter/nft_chain_filter.c @@ -201,7 +201,8 @@ static const struct nft_chain_type nft_chain_filter_inet = { (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD) | (1 << NF_INET_PRE_ROUTING) | - (1 << NF_INET_POST_ROUTING), + (1 << NF_INET_POST_ROUTING) | + (1 << NF_INET_SOCKET), .hooks = { [NF_INET_INGRESS] = nft_do_chain_inet_ingress, [NF_INET_LOCAL_IN] = nft_do_chain_inet, @@ -209,6 +210,7 @@ static const struct nft_chain_type nft_chain_filter_inet = { [NF_INET_FORWARD] = nft_do_chain_inet, [NF_INET_PRE_ROUTING] = nft_do_chain_inet, [NF_INET_POST_ROUTING] = nft_do_chain_inet, + [NF_INET_SOCKET] = nft_do_chain_inet, }, }; diff --git a/net/sctp/input.c b/net/sctp/input.c index 90e12bafdd48..2ea84d1f607f 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -203,7 +203,7 @@ int sctp_rcv(struct sk_buff *skb) goto discard_release; nf_reset_ct(skb); - if (sk_filter(sk, skb)) + if (sk_inet_filter(sk, skb, 1)) goto discard_release; /* Create an SCTP packet structure. */ [-- Attachment #3: nft.patch --] [-- Type: text/x-diff, Size: 2249 bytes --] diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 9e07888013e8..5fd054c42212 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -49,6 +49,7 @@ enum nf_inet_hooks { NF_INET_LOCAL_OUT, NF_INET_POST_ROUTING, NF_INET_INGRESS, + NF_INET_SOCKET, NF_INET_NUMHOOKS }; diff --git a/src/evaluate.c b/src/evaluate.c index b5f74d2f5051..03c18f413b09 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -4465,6 +4465,8 @@ static uint32_t str2hooknum(uint32_t family, const char *hook) case NFPROTO_INET: if (!strcmp(hook, "ingress")) return NF_INET_INGRESS; + if (!strcmp(hook, "socket")) + return NF_INET_SOCKET; /* fall through */ case NFPROTO_IPV4: case NFPROTO_BRIDGE: diff --git a/src/parser_bison.y b/src/parser_bison.y index ca5c488cd5ff..046ce92c0ab6 100644 --- a/src/parser_bison.y +++ b/src/parser_bison.y @@ -618,8 +618,8 @@ int nft_lex(void *, void *, void *); %type <limit_rate> limit_rate_pkts %type <limit_rate> limit_rate_bytes -%type <string> identifier type_identifier string comment_spec -%destructor { xfree($$); } identifier type_identifier string comment_spec +%type <string> identifier type_identifier string comment_spec hook_str +%destructor { xfree($$); } identifier type_identifier string comment_spec hook_str %type <val> time_spec quota_used @@ -2390,7 +2390,11 @@ type_identifier : STRING { $$ = $1; } | CLASSID { $$ = xstrdup("classid"); } ; -hook_spec : TYPE close_scope_type STRING HOOK STRING dev_spec prio_spec +hook_str : STRING { $$ = $1; } + | SOCKET { $$ = xstrdup("socket"); } + ; + +hook_spec : TYPE close_scope_type STRING HOOK hook_str dev_spec prio_spec { const char *chain_type = chain_type_name_lookup($3); diff --git a/src/rule.c b/src/rule.c index 799092eb15c5..b05351144c62 100644 --- a/src/rule.c +++ b/src/rule.c @@ -677,6 +677,7 @@ static const char * const chain_hookname_str_array[] = { "output", "ingress", "egress", + "socket", NULL, }; @@ -815,6 +816,8 @@ const char *hooknum2str(unsigned int family, unsigned int hooknum) return "output"; case NF_INET_INGRESS: return "ingress"; + case NF_INET_SOCKET: + return "socket"; default: break; }; ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH] netfilter: nft_socket: socket expressions for GID & UID 2022-04-26 21:05 ` Pablo Neira Ayuso @ 2022-04-26 21:07 ` Pablo Neira Ayuso 2022-04-27 18:07 ` Topi Miettinen 0 siblings, 1 reply; 17+ messages in thread From: Pablo Neira Ayuso @ 2022-04-26 21:07 UTC (permalink / raw) To: Topi Miettinen; +Cc: Jan Engelhardt, netfilter-devel On Tue, Apr 26, 2022 at 11:05:09PM +0200, Pablo Neira Ayuso wrote: > On Thu, Apr 21, 2022 at 07:35:06PM +0300, Topi Miettinen wrote: > > On 21.4.2022 0.15, Jan Engelhardt wrote: > > > > > > On Wednesday 2022-04-20 20:54, Topi Miettinen wrote: > > > > > > > Add socket expressions for checking GID or UID of the originating > > > > socket. These work also on input side, unlike meta skuid/skgid. > > > > > > Why exactly is it that meta skuid does not work? > > > Because of the skb_to_full_sk() call in nft_meta_get_eval_skugid()? > > > > I don't know the details, but early demux isn't reliable and filters aren't > > run after final demux. In my case, something like "ct state new meta skuid < > > 1000 drop" as part of input filter doesn't do anything. Making "meta skuid" > > 100% reliable would be of course preferable to adding a new expression. > > Could you give a try to this kernel patch? > > This patch adds a new socket hook for inet layer 4 protocols, it is > coming after the NF_LOCAL_IN hook, where the socket information is > available for all cases. > > You also need a small patch for userspace nft. Quickly tested it with: table inet x { chain y { type filter hook socket priority 0; policy accept; counter } } ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] netfilter: nft_socket: socket expressions for GID & UID 2022-04-26 21:07 ` Pablo Neira Ayuso @ 2022-04-27 18:07 ` Topi Miettinen 2022-05-02 17:02 ` Pablo Neira Ayuso 0 siblings, 1 reply; 17+ messages in thread From: Topi Miettinen @ 2022-04-27 18:07 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: Jan Engelhardt, netfilter-devel On 27.4.2022 0.07, Pablo Neira Ayuso wrote: > On Tue, Apr 26, 2022 at 11:05:09PM +0200, Pablo Neira Ayuso wrote: >> On Thu, Apr 21, 2022 at 07:35:06PM +0300, Topi Miettinen wrote: >>> On 21.4.2022 0.15, Jan Engelhardt wrote: >>>> >>>> On Wednesday 2022-04-20 20:54, Topi Miettinen wrote: >>>> >>>>> Add socket expressions for checking GID or UID of the originating >>>>> socket. These work also on input side, unlike meta skuid/skgid. >>>> >>>> Why exactly is it that meta skuid does not work? >>>> Because of the skb_to_full_sk() call in nft_meta_get_eval_skugid()? >>> >>> I don't know the details, but early demux isn't reliable and filters aren't >>> run after final demux. In my case, something like "ct state new meta skuid < >>> 1000 drop" as part of input filter doesn't do anything. Making "meta skuid" >>> 100% reliable would be of course preferable to adding a new expression. >> >> Could you give a try to this kernel patch? >> >> This patch adds a new socket hook for inet layer 4 protocols, it is >> coming after the NF_LOCAL_IN hook, where the socket information is >> available for all cases. >> >> You also need a small patch for userspace nft. > > Quickly tested it with: > > table inet x { > chain y { > type filter hook socket priority 0; policy accept; > counter > } > } Thanks. Assuming that this makes the 'meta skuid' and 'meta cgroupv2' always usable, I'd prefer this approach to new 'socket uid'. I changed the hook of my input and output filters to 'socket' but then there are lots of errors: /etc/nftables.conf:411:3-67: Error: Could not process rule: Operation not supported ct state new socket cgroupv2 level 1 vmap @dict_cgroup_level_1_in ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /etc/nftables.conf:412:3-79: Error: Could not process rule: Operation not supported ct state new meta skuid < 1000 meta l4proto vmap { tcp : jump tcp_input_sys } ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /etc/nftables.conf:413:3-108: Error: Could not process rule: Operation not supported ct state new meta skuid >= 1000 meta l4proto vmap { tcp : jump tcp_input_user, udp : jump udp_input_user } ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /etc/nftables.conf:417:3-36: Error: Could not process rule: Operation not supported icmpv6 type 144-147 counter accept ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /etc/nftables.conf:418:3-56: Error: Could not process rule: Operation not supported meta l4proto { icmp, icmpv6 } counter jump icmp_common ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /etc/nftables.conf:423:3-51: Error: Could not process rule: Operation not supported counter log prefix "[inet-input] " flags all drop ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /etc/nftables.conf:429:3-53: Error: Could not process rule: Operation not supported counter log prefix "[inet-forward] " flags all drop ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /etc/nftables.conf:435:3-100: Error: Could not process rule: Operation not supported rt type 0 counter log prefix "[inet-output-rt] " flags all reject with icmpx type admin-prohibited ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /etc/nftables.conf:436:3-122: Error: Could not process rule: Operation not supported meta protocol != { ip, ip6 } counter log prefix "[inet-output-proto] " flags all reject with icmpx type admin-prohibited ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /etc/nftables.conf:437:3-78: Error: Could not process rule: Operation not supported meta l4proto != { icmp, icmpv6, tcp, udp } counter jump log_bad_proto_output ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /etc/nftables.conf:438:3-50: Error: Could not process rule: Operation not supported ct state { established, related } counter accept ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /etc/nftables.conf:441:3-68: Error: Could not process rule: Operation not supported ct state new socket cgroupv2 level 1 vmap @dict_cgroup_level_1_out ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /etc/nftables.conf:443:3-56: Error: Could not process rule: Operation not supported meta l4proto { icmp, icmpv6 } counter jump icmp_common ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /etc/nftables.conf:448:3-87: Error: Could not process rule: Operation not supported counter log prefix "[inet-output] " flags all reject with icmpx type admin-prohibited ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Topi ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] netfilter: nft_socket: socket expressions for GID & UID 2022-04-27 18:07 ` Topi Miettinen @ 2022-05-02 17:02 ` Pablo Neira Ayuso 0 siblings, 0 replies; 17+ messages in thread From: Pablo Neira Ayuso @ 2022-05-02 17:02 UTC (permalink / raw) To: Topi Miettinen; +Cc: Jan Engelhardt, netfilter-devel On Wed, Apr 27, 2022 at 09:07:07PM +0300, Topi Miettinen wrote: > On 27.4.2022 0.07, Pablo Neira Ayuso wrote: > > On Tue, Apr 26, 2022 at 11:05:09PM +0200, Pablo Neira Ayuso wrote: > > > On Thu, Apr 21, 2022 at 07:35:06PM +0300, Topi Miettinen wrote: > > > > On 21.4.2022 0.15, Jan Engelhardt wrote: > > > > > > > > > > On Wednesday 2022-04-20 20:54, Topi Miettinen wrote: > > > > > > > > > > > Add socket expressions for checking GID or UID of the originating > > > > > > socket. These work also on input side, unlike meta skuid/skgid. > > > > > > > > > > Why exactly is it that meta skuid does not work? > > > > > Because of the skb_to_full_sk() call in nft_meta_get_eval_skugid()? > > > > > > > > I don't know the details, but early demux isn't reliable and filters aren't > > > > run after final demux. In my case, something like "ct state new meta skuid < > > > > 1000 drop" as part of input filter doesn't do anything. Making "meta skuid" > > > > 100% reliable would be of course preferable to adding a new expression. > > > > > > Could you give a try to this kernel patch? > > > > > > This patch adds a new socket hook for inet layer 4 protocols, it is > > > coming after the NF_LOCAL_IN hook, where the socket information is > > > available for all cases. > > > > > > You also need a small patch for userspace nft. > > > > Quickly tested it with: > > > > table inet x { > > chain y { > > type filter hook socket priority 0; policy accept; > > counter > > } > > } > > Thanks. Assuming that this makes the 'meta skuid' and 'meta cgroupv2' always > usable, I'd prefer this approach to new 'socket uid'. > > I changed the hook of my input and output filters to 'socket' but then there > are lots of errors: > > /etc/nftables.conf:411:3-67: Error: Could not process rule: Operation not > supported > ct state new socket cgroupv2 level 1 vmap > @dict_cgroup_level_1_in My patch is missing an update for nft_socket. Could you send me your ruleset so I can test my next patchset works with it? Private email is fine. Thanks. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] netfilter: nft_socket: socket expressions for GID & UID 2022-04-20 18:54 [PATCH] netfilter: nft_socket: socket expressions for GID & UID Topi Miettinen 2022-04-20 21:15 ` Jan Engelhardt @ 2022-04-25 18:45 ` Topi Miettinen 2022-04-25 22:34 ` Florian Westphal 1 sibling, 1 reply; 17+ messages in thread From: Topi Miettinen @ 2022-04-25 18:45 UTC (permalink / raw) To: netfilter-devel On 20.4.2022 21.54, Topi Miettinen wrote: > Add socket expressions for checking GID or UID of the originating > socket. These work also on input side, unlike meta skuid/skgid. Unfortunately, there's a reproducible kernel BUG when closing a local connection: Apr 25 21:18:13 kernel: ================================================================== Apr 25 21:18:13 kernel: BUG: KASAN: null-ptr-deref in nf_sk_lookup_slow_v6+0x45b/0x590 [nf_socket_ipv6] Apr 25 21:18:13 kernel: Read of size 4 at addr 00000000000000d8 by task ssh/1754 Apr 25 21:18:13 kernel: Apr 25 21:18:13 kernel: CPU: 8 PID: 1754 Comm: ssh Tainted: G E 5.17.0-rc7+ #6 Apr 25 21:18:13 kernel: Hardware name: XXX Apr 25 21:18:13 kernel: Call Trace: Apr 25 21:18:13 kernel: <IRQ> Apr 25 21:18:13 kernel: dump_stack_lvl+0x34/0x44 Apr 25 21:18:13 kernel: ? nf_sk_lookup_slow_v6+0x45b/0x590 [nf_socket_ipv6] Apr 25 21:18:13 kernel: kasan_report.cold+0x66/0xdc Apr 25 21:18:13 kernel: ? nf_sk_lookup_slow_v6+0x45b/0x590 [nf_socket_ipv6] Apr 25 21:18:13 kernel: nf_sk_lookup_slow_v6+0x45b/0x590 [nf_socket_ipv6] Apr 25 21:18:13 kernel: ? 0xffffffffc141c000 Apr 25 21:18:13 kernel: ? preempt_count_sub+0xf/0xb0 Apr 25 21:18:13 kernel: ? unwind_next_frame+0x6c6/0xbf0 Apr 25 21:18:13 kernel: ? entry_SYSCALL_64_after_hwframe+0x44/0xae Apr 25 21:18:13 kernel: ? bpf_ksym_find+0x8f/0xe0 Apr 25 21:18:13 kernel: ? __rcu_read_unlock+0x2a/0x60 Apr 25 21:18:13 kernel: ? is_bpf_text_address+0x1a/0x30 Apr 25 21:18:13 kernel: ? kernel_text_address+0x57/0xb0 Apr 25 21:18:13 kernel: ? __kernel_text_address+0x9/0x30 Apr 25 21:18:13 kernel: ? unwind_get_return_address+0x2a/0x40 Apr 25 21:18:13 kernel: ? create_prof_cpu_mask+0x20/0x20 Apr 25 21:18:13 kernel: ? arch_stack_walk+0x99/0xf0 Apr 25 21:18:13 kernel: ? __orc_find+0x63/0xc0 Apr 25 21:18:13 kernel: ? deref_stack_reg+0x7a/0xb0 Apr 25 21:18:13 kernel: ? get_stack_info_noinstr+0x12/0xf0 Apr 25 21:18:13 kernel: nft_socket_eval+0xea/0x491 [nft_socket] Apr 25 21:18:13 kernel: nft_do_chain+0x240/0x860 [nf_tables] Apr 25 21:18:13 kernel: ? bpf_ksym_find+0x8f/0xe0 Apr 25 21:18:13 kernel: ? __nft_trace_verdict.isra.0+0x20/0x20 [nf_tables] Apr 25 21:18:13 kernel: ? __kernel_text_address+0x9/0x30 Apr 25 21:18:13 kernel: ? unwind_get_return_address+0x2a/0x40 Apr 25 21:18:13 kernel: ? create_prof_cpu_mask+0x20/0x20 Apr 25 21:18:13 kernel: ? _raw_spin_lock_irqsave+0x88/0xe0 Apr 25 21:18:13 kernel: ? __cpuidle_text_end+0x3/0x3 Apr 25 21:18:13 kernel: ? selinux_netlbl_skbuff_setsid+0x215/0x2a0 Apr 25 21:18:13 kernel: ? selinux_netlbl_skbuff_setsid+0x215/0x2a0 Apr 25 21:18:13 kernel: ? stack_trace_save+0x8c/0xc0 Apr 25 21:18:13 kernel: ? _raw_spin_lock_bh+0x82/0xe0 Apr 25 21:18:13 kernel: ? _raw_write_lock_irq+0xd0/0xd0 Apr 25 21:18:13 kernel: ? __nf_ct_refresh_acct+0xa6/0xd0 [nf_conntrack] Apr 25 21:18:13 kernel: ? nf_ct_acct_add+0x32/0x80 [nf_conntrack] Apr 25 21:18:13 kernel: ? nf_conntrack_tcp_packet+0xef7/0x2c20 [nf_conntrack] Apr 25 21:18:13 kernel: ? kasan_record_aux_stack_noalloc+0x5/0x10 Apr 25 21:18:13 kernel: ? selinux_netlbl_skbuff_setsid+0x215/0x2a0 Apr 25 21:18:13 kernel: ? selinux_ip_output+0x7b/0xa0 Apr 25 21:18:13 kernel: ? ipv6_find_hdr+0x102/0x500 Apr 25 21:18:13 kernel: ? ipv6_skip_exthdr+0x240/0x240 Apr 25 21:18:13 kernel: ? ipv6_find_tlv+0xf0/0xf0 Apr 25 21:18:13 kernel: ? tcp_new+0x420/0x420 [nf_conntrack] Apr 25 21:18:13 kernel: ? __nf_conntrack_find_get+0x52e/0x750 [nf_conntrack] Apr 25 21:18:13 kernel: nf_route_table_hook6+0x216/0x400 [nf_tables] Apr 25 21:18:13 kernel: ? nf_route_table_hook4+0x280/0x280 [nf_tables] Apr 25 21:18:13 kernel: ? __kasan_slab_alloc+0x2c/0x80 Apr 25 21:18:13 kernel: ? security_netlbl_sid_to_secattr+0xb6/0x130 Apr 25 21:18:13 kernel: ? nf_conntrack_in+0x768/0xa50 [nf_conntrack] Apr 25 21:18:13 kernel: ? nf_route_table_hook6+0x400/0x400 [nf_tables] Apr 25 21:18:13 kernel: nf_route_table_inet+0xdf/0xf0 [nf_tables] Apr 25 21:18:13 kernel: ? nf_route_table_hook6+0x400/0x400 [nf_tables] Apr 25 21:18:13 kernel: nf_hook_slow+0x57/0xd0 Apr 25 21:18:13 kernel: ip6_xmit+0x6d3/0xaa0 Apr 25 21:18:13 kernel: ? ip6_forward_finish+0x1b0/0x1b0 Apr 25 21:18:13 kernel: ? tcp_v6_send_response+0x19f/0xc00 Apr 25 21:18:13 kernel: ? ip6_output+0x220/0x220 Apr 25 21:18:13 kernel: ? ip6_dst_lookup_tail.constprop.0+0x860/0x860 Apr 25 21:18:13 kernel: ? __build_skb_around+0x109/0x130 Apr 25 21:18:13 kernel: ? selinux_xfrm_skb_sid_ingress+0xe1/0x110 Apr 25 21:18:13 kernel: tcp_v6_send_response+0x7bd/0xc00 Apr 25 21:18:13 kernel: ? tcp_v6_connect+0xbb0/0xbb0 Apr 25 21:18:13 kernel: ? tcp_rcv_state_process+0x1d9c/0x1de0 Apr 25 21:18:13 kernel: tcp_v6_send_reset+0x2b2/0x630 Apr 25 21:18:13 kernel: ? tcp_parse_md5sig_option+0x16/0xa0 Apr 25 21:18:13 kernel: ? reqsk_put+0x150/0x150 Apr 25 21:18:13 kernel: ? tcp_v6_inbound_md5_hash+0xc4/0x260 Apr 25 21:18:13 kernel: ? bpf_skb_vlan_pop+0xa0/0xa0 Apr 25 21:18:13 kernel: tcp_v6_do_rcv+0x394/0x740 Apr 25 21:18:13 kernel: tcp_v6_rcv+0x13e5/0x15d0 Apr 25 21:18:13 kernel: ? tcp_v6_do_rcv+0x740/0x740 Apr 25 21:18:13 kernel: ? ipv6_confirm+0x11f/0x260 [nf_conntrack] Apr 25 21:18:13 kernel: ? ipv4_confirm+0x130/0x130 [nf_conntrack] Apr 25 21:18:13 kernel: ip6_protocol_deliver_rcu+0x182/0x910 Apr 25 21:18:13 kernel: ip6_input+0x156/0x170 Apr 25 21:18:13 kernel: ? ip6_input_finish+0x30/0x30 Apr 25 21:18:13 kernel: ? ip6_protocol_deliver_rcu+0x910/0x910 Apr 25 21:18:13 kernel: ? nf_nat_ipv6_fn+0x1a0/0x1a0 [nf_nat] Apr 25 21:18:13 kernel: ? nf_hook_slow+0x98/0xd0 Apr 25 21:18:13 kernel: ipv6_rcv+0x22f/0x270 Apr 25 21:18:13 kernel: ? ip6_input+0x170/0x170 Apr 25 21:18:13 kernel: ? __bitmap_and+0x6e/0x100 Apr 25 21:18:13 kernel: ? _find_next_bit+0x5a/0x110 Apr 25 21:18:13 kernel: ? ipv6_list_rcv+0x260/0x260 Apr 25 21:18:13 kernel: ? load_balance+0x1181/0x1290 Apr 25 21:18:13 kernel: ? ip6_input+0x170/0x170 Apr 25 21:18:13 kernel: __netif_receive_skb_one_core+0xd4/0x130 Apr 25 21:18:13 kernel: ? __netif_receive_skb_list_core+0x4c0/0x4c0 Apr 25 21:18:13 kernel: ? _raw_spin_lock+0x82/0xe0 Apr 25 21:18:13 kernel: ? _raw_spin_lock_bh+0xe0/0xe0 Apr 25 21:18:13 kernel: process_backlog+0xec/0x270 Apr 25 21:18:13 kernel: __napi_poll+0x57/0x1c0 Apr 25 21:18:13 kernel: net_rx_action+0x1df/0x450 Apr 25 21:18:13 kernel: ? napi_threaded_poll+0x1a0/0x1a0 Apr 25 21:18:13 kernel: ? read_hpet+0x100/0x1d0 Apr 25 21:18:13 kernel: ? native_flush_tlb_global+0xcc/0xe0 Apr 25 21:18:13 kernel: __do_softirq+0x108/0x2b1 Apr 25 21:18:13 kernel: ? sched_clock_cpu+0x113/0x130 Apr 25 21:18:13 kernel: do_softirq+0xa1/0xd0 Apr 25 21:18:13 kernel: </IRQ> Apr 25 21:18:13 kernel: <TASK> Apr 25 21:18:13 kernel: __local_bh_enable_ip+0x60/0x70 Apr 25 21:18:13 kernel: ip6_finish_output2+0x408/0x9e0 Apr 25 21:18:13 kernel: ? ip6_dst_lookup+0x40/0x40 Apr 25 21:18:13 kernel: ? __rcu_read_unlock+0x2a/0x60 Apr 25 21:18:13 kernel: ? ip6_mtu+0x7b/0xc0 Apr 25 21:18:13 kernel: ? __ip6_finish_output+0x18d/0x420 Apr 25 21:18:13 kernel: ip6_output+0x110/0x220 Apr 25 21:18:13 kernel: ? ip6_finish_output+0xc0/0xc0 Apr 25 21:18:13 kernel: ? __ip6_finish_output+0x420/0x420 Apr 25 21:18:13 kernel: ip6_xmit+0x7ea/0xaa0 Apr 25 21:18:13 kernel: ? ip6_forward_finish+0x1b0/0x1b0 Apr 25 21:18:13 kernel: ? cpu_weight_nice_read_s64+0x46/0x90 Apr 25 21:18:13 kernel: ? __rcu_read_unlock+0x43/0x60 Apr 25 21:18:13 kernel: ? ip6_output+0x220/0x220 Apr 25 21:18:13 kernel: ? __sk_dst_check+0x64/0xe0 Apr 25 21:18:13 kernel: ? inet6_csk_route_socket+0x29e/0x3e0 Apr 25 21:18:13 kernel: ? inet6_csk_addr2sockaddr+0xd0/0xd0 Apr 25 21:18:13 kernel: ? unwind_get_return_address+0x2a/0x40 Apr 25 21:18:13 kernel: ? create_prof_cpu_mask+0x20/0x20 Apr 25 21:18:13 kernel: ? arch_stack_walk+0x99/0xf0 Apr 25 21:18:13 kernel: inet6_csk_xmit+0x1b2/0x250 Apr 25 21:18:13 kernel: ? inet6_csk_update_pmtu+0x110/0x110 Apr 25 21:18:13 kernel: ? bpf_skops_hdr_opt_len+0x1e0/0x1e0 Apr 25 21:18:13 kernel: ? __tcp_select_window+0x143/0x470 Apr 25 21:18:13 kernel: ? tcp_options_write+0xc9/0x370 Apr 25 21:18:13 kernel: __tcp_transmit_skb+0xa8a/0x14b0 Apr 25 21:18:13 kernel: ? __tcp_select_window+0x470/0x470 Apr 25 21:18:13 kernel: ? hpet_msi_interrupt_handler+0x30/0x30 Apr 25 21:18:13 kernel: ? tcp_stream_alloc_skb+0x47/0x3d0 Apr 25 21:18:13 kernel: tcp_write_xmit+0x72a/0x2510 Apr 25 21:18:13 kernel: ? skb_page_frag_refill+0x15c/0x190 Apr 25 21:18:13 kernel: ? __virt_addr_valid+0xb9/0x130 Apr 25 21:18:13 kernel: __tcp_push_pending_frames+0x51/0x170 Apr 25 21:18:13 kernel: tcp_sendmsg_locked+0x4a7/0x1460 Apr 25 21:18:13 kernel: ? tcp_sendpage+0x80/0x80 Apr 25 21:18:13 kernel: ? _raw_spin_lock_bh+0x82/0xe0 Apr 25 21:18:13 kernel: ? _raw_write_lock_irq+0xd0/0xd0 Apr 25 21:18:13 kernel: ? inet6_ioctl+0x1b0/0x1b0 Apr 25 21:18:13 kernel: tcp_sendmsg+0x23/0x40 Apr 25 21:18:13 kernel: sock_sendmsg+0x73/0xa0 Apr 25 21:18:13 kernel: sock_write_iter+0x125/0x1d0 Apr 25 21:18:13 kernel: ? sock_sendmsg+0xa0/0xa0 Apr 25 21:18:13 kernel: ? bpf_local_storage_map_alloc_check+0x40/0xc0 Apr 25 21:18:13 kernel: ? new_sync_read+0x33d/0x360 Apr 25 21:18:13 kernel: ? audit_filter_rules.constprop.0+0x1326/0x1ef0 Apr 25 21:18:13 kernel: ? audit_filter_rules.constprop.0+0x1326/0x1ef0 Apr 25 21:18:13 kernel: new_sync_write+0x348/0x360 Apr 25 21:18:13 kernel: ? new_sync_read+0x360/0x360 Apr 25 21:18:13 kernel: ? bpf_local_storage_map_alloc_check+0x40/0xc0 Apr 25 21:18:13 kernel: ? bpf_fd_pass+0xf0/0xf0 Apr 25 21:18:13 kernel: ? selinux_file_permission+0x11c/0x1f0 Apr 25 21:18:13 kernel: vfs_write+0x33e/0x3e0 Apr 25 21:18:13 kernel: ksys_write+0x11b/0x150 Apr 25 21:18:13 kernel: ? __ia32_sys_read+0x40/0x40 Apr 25 21:18:13 kernel: ? __audit_syscall_entry+0x173/0x1f0 Apr 25 21:18:13 kernel: ? ktime_get_coarse_real_ts64+0x45/0x60 Apr 25 21:18:13 kernel: do_syscall_64+0x5c/0x80 Apr 25 21:18:13 kernel: ? syscall_exit_to_user_mode+0x1d/0x40 Apr 25 21:18:13 kernel: ? do_syscall_64+0x69/0x80 Apr 25 21:18:13 kernel: ? do_syscall_64+0x69/0x80 Apr 25 21:18:13 kernel: ? do_syscall_64+0x69/0x80 Apr 25 21:18:13 kernel: entry_SYSCALL_64_after_hwframe+0x44/0xae Apr 25 21:18:13 kernel: RIP: 0033:0x75f2a694c603 Apr 25 21:18:13 kernel: Code: 8b 15 71 38 0e 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b7 0f 1f 00 64 8b 04 25 18 00 00 00 85 c0 75 14 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 55 c3 0f 1f 40 00 48 83 ec 28 48 89 54 24 18 Apr 25 21:18:13 kernel: RSP: 002b:00004a29af4792c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 Apr 25 21:18:13 kernel: RAX: ffffffffffffffda RBX: 000000000000003c RCX: 000075f2a694c603 Apr 25 21:18:13 kernel: RDX: 000000000000003c RSI: 000065287ad9af00 RDI: 0000000000000003 Apr 25 21:18:13 kernel: RBP: 000065287ad8f380 R08: 0000000000000000 R09: 0000000000000000 Apr 25 21:18:13 kernel: R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 Apr 25 21:18:13 kernel: R13: 00000000ffffffe8 R14: 000065287ad939c0 R15: 0000000000000000 Apr 25 21:18:13 kernel: </TASK> Apr 25 21:18:13 kernel: ================================================================== Apr 25 21:18:13 kernel: Disabling lock debugging due to kernel taint Apr 25 21:18:13 kernel: BUG: kernel NULL pointer dereference, address: 00000000000000d8 Apr 25 21:18:13 kernel: #PF: supervisor read access in kernel mode Apr 25 21:18:13 kernel: #PF: error_code(0x0000) - not-present page ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] netfilter: nft_socket: socket expressions for GID & UID 2022-04-25 18:45 ` Topi Miettinen @ 2022-04-25 22:34 ` Florian Westphal 2022-04-26 19:02 ` Topi Miettinen 0 siblings, 1 reply; 17+ messages in thread From: Florian Westphal @ 2022-04-25 22:34 UTC (permalink / raw) To: Topi Miettinen; +Cc: netfilter-devel Topi Miettinen <toiwoton@gmail.com> wrote: > On 20.4.2022 21.54, Topi Miettinen wrote: > > Add socket expressions for checking GID or UID of the originating > > socket. These work also on input side, unlike meta skuid/skgid. > > Unfortunately, there's a reproducible kernel BUG when closing a local > connection: > > Apr 25 21:18:13 kernel: > ================================================================== > Apr 25 21:18:13 kernel: BUG: KASAN: null-ptr-deref in > nf_sk_lookup_slow_v6+0x45b/0x590 [nf_socket_ipv6] You can pass this to scripts/faddr2line to get the location of the null deref. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] netfilter: nft_socket: socket expressions for GID & UID 2022-04-25 22:34 ` Florian Westphal @ 2022-04-26 19:02 ` Topi Miettinen 2022-04-27 5:48 ` Florian Westphal 0 siblings, 1 reply; 17+ messages in thread From: Topi Miettinen @ 2022-04-26 19:02 UTC (permalink / raw) To: Florian Westphal; +Cc: netfilter-devel On 26.4.2022 1.34, Florian Westphal wrote: > Topi Miettinen <toiwoton@gmail.com> wrote: >> On 20.4.2022 21.54, Topi Miettinen wrote: >>> Add socket expressions for checking GID or UID of the originating >>> socket. These work also on input side, unlike meta skuid/skgid. >> >> Unfortunately, there's a reproducible kernel BUG when closing a local >> connection: >> >> Apr 25 21:18:13 kernel: >> ================================================================== >> Apr 25 21:18:13 kernel: BUG: KASAN: null-ptr-deref in >> nf_sk_lookup_slow_v6+0x45b/0x590 [nf_socket_ipv6] > > You can pass this to scripts/faddr2line to get the location of the null deref. Didn't work, but with grep and gdb I think I located the error to net/ipv6/netfilter/nf_socket_ipv6.c: static struct sock * nf_socket_get_sock_v6(struct net *net, struct sk_buff *skb, int doff, const u8 protocol, const struct in6_addr *saddr, const struct in6_addr *daddr, const __be16 sport, const __be16 dport, const struct net_device *in) { switch (protocol) { case IPPROTO_TCP: return inet6_lookup(net, &tcp_hashinfo, skb, doff, saddr, sport, daddr, dport, in->ifindex); ^^^^^^^^^^^ where in->ifindex would be a NULL deref. -Topi ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] netfilter: nft_socket: socket expressions for GID & UID 2022-04-26 19:02 ` Topi Miettinen @ 2022-04-27 5:48 ` Florian Westphal 2022-04-27 7:01 ` Pablo Neira Ayuso 0 siblings, 1 reply; 17+ messages in thread From: Florian Westphal @ 2022-04-27 5:48 UTC (permalink / raw) To: Topi Miettinen; +Cc: Florian Westphal, netfilter-devel Topi Miettinen <toiwoton@gmail.com> wrote: > On 26.4.2022 1.34, Florian Westphal wrote: > > Topi Miettinen <toiwoton@gmail.com> wrote: > > > On 20.4.2022 21.54, Topi Miettinen wrote: > > > > Add socket expressions for checking GID or UID of the originating > > > > socket. These work also on input side, unlike meta skuid/skgid. > > > > > > Unfortunately, there's a reproducible kernel BUG when closing a local > > > connection: > > > > > > Apr 25 21:18:13 kernel: > > > ================================================================== > > > Apr 25 21:18:13 kernel: BUG: KASAN: null-ptr-deref in > > > nf_sk_lookup_slow_v6+0x45b/0x590 [nf_socket_ipv6] > > > > You can pass this to scripts/faddr2line to get the location of the null deref. > > Didn't work, ? You pass the object file and the nf_sk_lookup_slow_v6+0x45b/0x590 info. I can't do it for you because I lack the object file and the exact source code. > net/ipv6/netfilter/nf_socket_ipv6.c: > > static struct sock * > nf_socket_get_sock_v6(struct net *net, struct sk_buff *skb, int doff, > const u8 protocol, > const struct in6_addr *saddr, const struct in6_addr > *daddr, > const __be16 sport, const __be16 dport, > const struct net_device *in) > { > switch (protocol) { > case IPPROTO_TCP: > return inet6_lookup(net, &tcp_hashinfo, skb, doff, > saddr, sport, daddr, dport, > in->ifindex); What does that rule look like? Seems like no input interface is available, seems like a bug in existing code? ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] netfilter: nft_socket: socket expressions for GID & UID 2022-04-27 5:48 ` Florian Westphal @ 2022-04-27 7:01 ` Pablo Neira Ayuso 2022-04-27 15:00 ` Topi Miettinen 0 siblings, 1 reply; 17+ messages in thread From: Pablo Neira Ayuso @ 2022-04-27 7:01 UTC (permalink / raw) To: Florian Westphal; +Cc: Topi Miettinen, netfilter-devel On Wed, Apr 27, 2022 at 07:48:20AM +0200, Florian Westphal wrote: > Topi Miettinen <toiwoton@gmail.com> wrote: > > On 26.4.2022 1.34, Florian Westphal wrote: > > > Topi Miettinen <toiwoton@gmail.com> wrote: > > > > On 20.4.2022 21.54, Topi Miettinen wrote: > > > > > Add socket expressions for checking GID or UID of the originating > > > > > socket. These work also on input side, unlike meta skuid/skgid. > > > > > > > > Unfortunately, there's a reproducible kernel BUG when closing a local > > > > connection: > > > > > > > > Apr 25 21:18:13 kernel: > > > > ================================================================== > > > > Apr 25 21:18:13 kernel: BUG: KASAN: null-ptr-deref in > > > > nf_sk_lookup_slow_v6+0x45b/0x590 [nf_socket_ipv6] > > > > > > You can pass this to scripts/faddr2line to get the location of the null deref. > > > > Didn't work, > > ? > > You pass the object file and the nf_sk_lookup_slow_v6+0x45b/0x590 info. > I can't do it for you because I lack the object file and the exact > source code. > > > net/ipv6/netfilter/nf_socket_ipv6.c: > > > > static struct sock * > > nf_socket_get_sock_v6(struct net *net, struct sk_buff *skb, int doff, > > const u8 protocol, > > const struct in6_addr *saddr, const struct in6_addr > > *daddr, > > const __be16 sport, const __be16 dport, > > const struct net_device *in) > > { > > switch (protocol) { > > case IPPROTO_TCP: > > return inet6_lookup(net, &tcp_hashinfo, skb, doff, > > saddr, sport, daddr, dport, > > in->ifindex); > > What does that rule look like? Seems like no input interface is > available, seems like a bug in existing code? nft_socket_eval() assumes it always run from input path. @Topi: How does you test ruleset look like? ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] netfilter: nft_socket: socket expressions for GID & UID 2022-04-27 7:01 ` Pablo Neira Ayuso @ 2022-04-27 15:00 ` Topi Miettinen 2022-04-27 15:28 ` Florian Westphal 2022-04-27 15:30 ` Pablo Neira Ayuso 0 siblings, 2 replies; 17+ messages in thread From: Topi Miettinen @ 2022-04-27 15:00 UTC (permalink / raw) To: Pablo Neira Ayuso, Florian Westphal; +Cc: netfilter-devel On 27.4.2022 10.01, Pablo Neira Ayuso wrote: > On Wed, Apr 27, 2022 at 07:48:20AM +0200, Florian Westphal wrote: >> Topi Miettinen <toiwoton@gmail.com> wrote: >>> On 26.4.2022 1.34, Florian Westphal wrote: >>>> Topi Miettinen <toiwoton@gmail.com> wrote: >>>>> On 20.4.2022 21.54, Topi Miettinen wrote: >>>>>> Add socket expressions for checking GID or UID of the originating >>>>>> socket. These work also on input side, unlike meta skuid/skgid. >>>>> >>>>> Unfortunately, there's a reproducible kernel BUG when closing a local >>>>> connection: >>>>> >>>>> Apr 25 21:18:13 kernel: >>>>> ================================================================== >>>>> Apr 25 21:18:13 kernel: BUG: KASAN: null-ptr-deref in >>>>> nf_sk_lookup_slow_v6+0x45b/0x590 [nf_socket_ipv6] >>>> >>>> You can pass this to scripts/faddr2line to get the location of the null deref. >>> >>> Didn't work, >> >> ? >> >> You pass the object file and the nf_sk_lookup_slow_v6+0x45b/0x590 info. >> I can't do it for you because I lack the object file and the exact >> source code. >> $ faddr2line nf_socket_ipv6.ko nf_sk_lookup_slow_v6+0x45b/0x590 bad symbol size: base: 0x0000000000000000 end: 0x0000000000000000 $ faddr2line nf_socket_ipv6.o nf_sk_lookup_slow_v6+0x45b/0x590 bad symbol size: base: 0x0000000000000000 end: 0x0000000000000000 $ faddr2line nf_socket_ipv6.mod nf_sk_lookup_slow_v6+0x45b/0x590 readelf: Error: nf_socket_ipv6.mod: Failed to read file header size: nf_socket_ipv6.mod: file format not recognized nm: nf_socket_ipv6.mod: file format not recognized size: nf_socket_ipv6.mod: file format not recognized nm: nf_socket_ipv6.mod: file format not recognized no match for nf_sk_lookup_slow_v6+0x45b/0x590 $ faddr2line nf_socket_ipv6.mod.o nf_sk_lookup_slow_v6+0x45b/0x590 no match for nf_sk_lookup_slow_v6+0x45b/0x590 $ faddr2line vmlinux nf_sk_lookup_slow_v6+0x45b/0x590 no match for nf_sk_lookup_slow_v6+0x45b/0x590 >>> net/ipv6/netfilter/nf_socket_ipv6.c: >>> >>> static struct sock * >>> nf_socket_get_sock_v6(struct net *net, struct sk_buff *skb, int doff, >>> const u8 protocol, >>> const struct in6_addr *saddr, const struct in6_addr >>> *daddr, >>> const __be16 sport, const __be16 dport, >>> const struct net_device *in) >>> { >>> switch (protocol) { >>> case IPPROTO_TCP: >>> return inet6_lookup(net, &tcp_hashinfo, skb, doff, >>> saddr, sport, daddr, dport, >>> in->ifindex); >> >> What does that rule look like? Seems like no input interface is >> available, seems like a bug in existing code? > > nft_socket_eval() assumes it always run from input path. > > @Topi: How does you test ruleset look like? Here's a reproducer: #!/usr/sbin/nft -f table inet mangle { chain output { type route hook output priority mangle; policy accept; socket uid != 0 reject with icmpx type admin-prohibited } } Start nc -6l 1 as root Try 'telnet ::1 1' as root, press enter and close the connection. After 1-3 tries, system hangs and Caps Lock starts blinking. -Topi ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] netfilter: nft_socket: socket expressions for GID & UID 2022-04-27 15:00 ` Topi Miettinen @ 2022-04-27 15:28 ` Florian Westphal 2022-04-27 15:30 ` Pablo Neira Ayuso 1 sibling, 0 replies; 17+ messages in thread From: Florian Westphal @ 2022-04-27 15:28 UTC (permalink / raw) To: Topi Miettinen; +Cc: Pablo Neira Ayuso, Florian Westphal, netfilter-devel Topi Miettinen <toiwoton@gmail.com> wrote: > On 27.4.2022 10.01, Pablo Neira Ayuso wrote: > > On Wed, Apr 27, 2022 at 07:48:20AM +0200, Florian Westphal wrote: > > > Topi Miettinen <toiwoton@gmail.com> wrote: > > > > On 26.4.2022 1.34, Florian Westphal wrote: > > > > > Topi Miettinen <toiwoton@gmail.com> wrote: > > > > > > On 20.4.2022 21.54, Topi Miettinen wrote: > > > > > > > Add socket expressions for checking GID or UID of the originating > > > > > > > socket. These work also on input side, unlike meta skuid/skgid. > > > > > > > > > > > > Unfortunately, there's a reproducible kernel BUG when closing a local > > > > > > connection: > > > > > > > > > > > > Apr 25 21:18:13 kernel: > > > > > > ================================================================== > > > > > > Apr 25 21:18:13 kernel: BUG: KASAN: null-ptr-deref in > > > > > > nf_sk_lookup_slow_v6+0x45b/0x590 [nf_socket_ipv6] > > > > > > > > > > You can pass this to scripts/faddr2line to get the location of the null deref. > > > > > > > > Didn't work, > > > > > > ? > > > > > > You pass the object file and the nf_sk_lookup_slow_v6+0x45b/0x590 info. > > > I can't do it for you because I lack the object file and the exact > > > source code. > > > > > $ faddr2line nf_socket_ipv6.ko nf_sk_lookup_slow_v6+0x45b/0x590 > bad symbol size: base: 0x0000000000000000 end: 0x0000000000000000 > $ faddr2line nf_socket_ipv6.o nf_sk_lookup_slow_v6+0x45b/0x590 > bad symbol size: base: 0x0000000000000000 end: 0x0000000000000000 > $ faddr2line nf_socket_ipv6.mod nf_sk_lookup_slow_v6+0x45b/0x590 > readelf: Error: nf_socket_ipv6.mod: Failed to read file header > size: nf_socket_ipv6.mod: file format not recognized > nm: nf_socket_ipv6.mod: file format not recognized > size: nf_socket_ipv6.mod: file format not recognized > nm: nf_socket_ipv6.mod: file format not recognized > no match for nf_sk_lookup_slow_v6+0x45b/0x590 > $ faddr2line nf_socket_ipv6.mod.o nf_sk_lookup_slow_v6+0x45b/0x590 > no match for nf_sk_lookup_slow_v6+0x45b/0x590 > $ faddr2line vmlinux nf_sk_lookup_slow_v6+0x45b/0x590 > no match for nf_sk_lookup_slow_v6+0x45b/0x590 > > > > > net/ipv6/netfilter/nf_socket_ipv6.c: > > > > > > > > static struct sock * > > > > nf_socket_get_sock_v6(struct net *net, struct sk_buff *skb, int doff, > > > > const u8 protocol, > > > > const struct in6_addr *saddr, const struct in6_addr > > > > *daddr, > > > > const __be16 sport, const __be16 dport, > > > > const struct net_device *in) > > > > { > > > > switch (protocol) { > > > > case IPPROTO_TCP: > > > > return inet6_lookup(net, &tcp_hashinfo, skb, doff, > > > > saddr, sport, daddr, dport, > > > > in->ifindex); > > > > > > What does that rule look like? Seems like no input interface is > > > available, seems like a bug in existing code? > > > > nft_socket_eval() assumes it always run from input path. Oof, there is no restriction. I don't think we can make it illegal now, so probably best to check for indev != NULL first. I'll send a patch. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] netfilter: nft_socket: socket expressions for GID & UID 2022-04-27 15:00 ` Topi Miettinen 2022-04-27 15:28 ` Florian Westphal @ 2022-04-27 15:30 ` Pablo Neira Ayuso 2022-04-27 15:42 ` Florian Westphal 1 sibling, 1 reply; 17+ messages in thread From: Pablo Neira Ayuso @ 2022-04-27 15:30 UTC (permalink / raw) To: Topi Miettinen; +Cc: Florian Westphal, netfilter-devel [-- Attachment #1: Type: text/plain, Size: 3589 bytes --] On Wed, Apr 27, 2022 at 06:00:49PM +0300, Topi Miettinen wrote: > On 27.4.2022 10.01, Pablo Neira Ayuso wrote: > > On Wed, Apr 27, 2022 at 07:48:20AM +0200, Florian Westphal wrote: > > > Topi Miettinen <toiwoton@gmail.com> wrote: > > > > On 26.4.2022 1.34, Florian Westphal wrote: > > > > > Topi Miettinen <toiwoton@gmail.com> wrote: > > > > > > On 20.4.2022 21.54, Topi Miettinen wrote: > > > > > > > Add socket expressions for checking GID or UID of the originating > > > > > > > socket. These work also on input side, unlike meta skuid/skgid. > > > > > > > > > > > > Unfortunately, there's a reproducible kernel BUG when closing a local > > > > > > connection: > > > > > > > > > > > > Apr 25 21:18:13 kernel: > > > > > > ================================================================== > > > > > > Apr 25 21:18:13 kernel: BUG: KASAN: null-ptr-deref in > > > > > > nf_sk_lookup_slow_v6+0x45b/0x590 [nf_socket_ipv6] > > > > > > > > > > You can pass this to scripts/faddr2line to get the location of the null deref. > > > > > > > > Didn't work, > > > > > > ? > > > > > > You pass the object file and the nf_sk_lookup_slow_v6+0x45b/0x590 info. > > > I can't do it for you because I lack the object file and the exact > > > source code. > > > > > $ faddr2line nf_socket_ipv6.ko nf_sk_lookup_slow_v6+0x45b/0x590 > bad symbol size: base: 0x0000000000000000 end: 0x0000000000000000 > $ faddr2line nf_socket_ipv6.o nf_sk_lookup_slow_v6+0x45b/0x590 > bad symbol size: base: 0x0000000000000000 end: 0x0000000000000000 > $ faddr2line nf_socket_ipv6.mod nf_sk_lookup_slow_v6+0x45b/0x590 > readelf: Error: nf_socket_ipv6.mod: Failed to read file header > size: nf_socket_ipv6.mod: file format not recognized > nm: nf_socket_ipv6.mod: file format not recognized > size: nf_socket_ipv6.mod: file format not recognized > nm: nf_socket_ipv6.mod: file format not recognized > no match for nf_sk_lookup_slow_v6+0x45b/0x590 > $ faddr2line nf_socket_ipv6.mod.o nf_sk_lookup_slow_v6+0x45b/0x590 > no match for nf_sk_lookup_slow_v6+0x45b/0x590 > $ faddr2line vmlinux nf_sk_lookup_slow_v6+0x45b/0x590 > no match for nf_sk_lookup_slow_v6+0x45b/0x590 > > > > > net/ipv6/netfilter/nf_socket_ipv6.c: > > > > > > > > static struct sock * > > > > nf_socket_get_sock_v6(struct net *net, struct sk_buff *skb, int doff, > > > > const u8 protocol, > > > > const struct in6_addr *saddr, const struct in6_addr > > > > *daddr, > > > > const __be16 sport, const __be16 dport, > > > > const struct net_device *in) > > > > { > > > > switch (protocol) { > > > > case IPPROTO_TCP: > > > > return inet6_lookup(net, &tcp_hashinfo, skb, doff, > > > > saddr, sport, daddr, dport, > > > > in->ifindex); > > > > > > What does that rule look like? Seems like no input interface is > > > available, seems like a bug in existing code? > > > > nft_socket_eval() assumes it always run from input path. > > > > @Topi: How does you test ruleset look like? > > Here's a reproducer: > #!/usr/sbin/nft -f > > table inet mangle { > chain output { > type route hook output priority mangle; policy accept; > > socket uid != 0 reject with icmpx type admin-prohibited > } > } > > Start nc -6l 1 as root > > Try 'telnet ::1 1' as root, press enter and close the connection. After 1-3 > tries, system hangs and Caps Lock starts blinking. Looks like skb->sk is NULL? Patch attached. [-- Attachment #2: fix-nft-socket.patch --] [-- Type: text/x-diff, Size: 2057 bytes --] diff --git a/net/netfilter/nft_socket.c b/net/netfilter/nft_socket.c index 6d9e8e0a3a7d..d6da68a3b739 100644 --- a/net/netfilter/nft_socket.c +++ b/net/netfilter/nft_socket.c @@ -59,21 +59,27 @@ static void nft_socket_eval(const struct nft_expr *expr, const struct nft_pktinfo *pkt) { const struct nft_socket *priv = nft_expr_priv(expr); + u32 *dest = ®s->data[priv->dreg]; struct sk_buff *skb = pkt->skb; + const struct net_device *dev; struct sock *sk = skb->sk; - u32 *dest = ®s->data[priv->dreg]; if (sk && !net_eq(nft_net(pkt), sock_net(sk))) sk = NULL; - if (!sk) + if (nft_hook(pkt) == NF_INET_LOCAL_OUT) + dev = nft_out(pkt); + else + dev = nft_in(pkt); + + if (!sk) { switch(nft_pf(pkt)) { case NFPROTO_IPV4: - sk = nf_sk_lookup_slow_v4(nft_net(pkt), skb, nft_in(pkt)); + sk = nf_sk_lookup_slow_v4(nft_net(pkt), skb, dev); break; #if IS_ENABLED(CONFIG_NF_TABLES_IPV6) case NFPROTO_IPV6: - sk = nf_sk_lookup_slow_v6(nft_net(pkt), skb, nft_in(pkt)); + sk = nf_sk_lookup_slow_v6(nft_net(pkt), skb, dev); break; #endif default: @@ -81,6 +87,7 @@ static void nft_socket_eval(const struct nft_expr *expr, regs->verdict.code = NFT_BREAK; return; } + } if (!sk) { regs->verdict.code = NFT_BREAK; @@ -184,6 +191,15 @@ static int nft_socket_init(const struct nft_ctx *ctx, NULL, NFT_DATA_VALUE, len); } +static int nft_socket_validate(const struct nft_ctx *ctx, + const struct nft_expr *expr, + const struct nft_data **data) +{ + return nft_chain_validate_hooks(ctx->chain, (1 << NF_INET_PRE_ROUTING) | + (1 << NF_INET_LOCAL_IN) | + (1 << NF_INET_LOCAL_OUT)); +} + static int nft_socket_dump(struct sk_buff *skb, const struct nft_expr *expr) { @@ -230,6 +246,7 @@ static const struct nft_expr_ops nft_socket_ops = { .size = NFT_EXPR_SIZE(sizeof(struct nft_socket)), .eval = nft_socket_eval, .init = nft_socket_init, + .validate = nft_socket_validate, .dump = nft_socket_dump, .reduce = nft_socket_reduce, }; ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH] netfilter: nft_socket: socket expressions for GID & UID 2022-04-27 15:30 ` Pablo Neira Ayuso @ 2022-04-27 15:42 ` Florian Westphal 2022-04-27 15:45 ` Pablo Neira Ayuso 0 siblings, 1 reply; 17+ messages in thread From: Florian Westphal @ 2022-04-27 15:42 UTC (permalink / raw) To: Pablo Neira Ayuso; +Cc: Topi Miettinen, Florian Westphal, netfilter-devel Pablo Neira Ayuso <pablo@netfilter.org> wrote: > Looks like skb->sk is NULL? Patch attached. > diff --git a/net/netfilter/nft_socket.c b/net/netfilter/nft_socket.c > index 6d9e8e0a3a7d..d6da68a3b739 100644 > --- a/net/netfilter/nft_socket.c > +++ b/net/netfilter/nft_socket.c > @@ -59,21 +59,27 @@ static void nft_socket_eval(const struct nft_expr *expr, > const struct nft_pktinfo *pkt) > { > const struct nft_socket *priv = nft_expr_priv(expr); > + u32 *dest = ®s->data[priv->dreg]; > struct sk_buff *skb = pkt->skb; > + const struct net_device *dev; > struct sock *sk = skb->sk; > - u32 *dest = ®s->data[priv->dreg]; > > if (sk && !net_eq(nft_net(pkt), sock_net(sk))) > sk = NULL; > > - if (!sk) > + if (nft_hook(pkt) == NF_INET_LOCAL_OUT) > + dev = nft_out(pkt); > + else > + dev = nft_in(pkt); I think its better to just NFT_BREAK for NF_INET_LOCAL_OUT && skb->sk == NULL, I don't see how nf_sk_lookup_slow_.() could provide meaningful result here, they assume packet header daddr/dport are the local, not the remote addresses. Or, check nft_in(pkt) == NULL || !sk -> BREAK, whatever seems simpler to you. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] netfilter: nft_socket: socket expressions for GID & UID 2022-04-27 15:42 ` Florian Westphal @ 2022-04-27 15:45 ` Pablo Neira Ayuso 0 siblings, 0 replies; 17+ messages in thread From: Pablo Neira Ayuso @ 2022-04-27 15:45 UTC (permalink / raw) To: Florian Westphal; +Cc: Topi Miettinen, netfilter-devel On Wed, Apr 27, 2022 at 05:42:19PM +0200, Florian Westphal wrote: > Pablo Neira Ayuso <pablo@netfilter.org> wrote: > > Looks like skb->sk is NULL? Patch attached. > > > diff --git a/net/netfilter/nft_socket.c b/net/netfilter/nft_socket.c > > index 6d9e8e0a3a7d..d6da68a3b739 100644 > > --- a/net/netfilter/nft_socket.c > > +++ b/net/netfilter/nft_socket.c > > @@ -59,21 +59,27 @@ static void nft_socket_eval(const struct nft_expr *expr, > > const struct nft_pktinfo *pkt) > > { > > const struct nft_socket *priv = nft_expr_priv(expr); > > + u32 *dest = ®s->data[priv->dreg]; > > struct sk_buff *skb = pkt->skb; > > + const struct net_device *dev; > > struct sock *sk = skb->sk; > > - u32 *dest = ®s->data[priv->dreg]; > > > > if (sk && !net_eq(nft_net(pkt), sock_net(sk))) > > sk = NULL; > > > > - if (!sk) > > + if (nft_hook(pkt) == NF_INET_LOCAL_OUT) > > + dev = nft_out(pkt); > > + else > > + dev = nft_in(pkt); > > I think its better to just NFT_BREAK for NF_INET_LOCAL_OUT && skb->sk == NULL, > I don't see how nf_sk_lookup_slow_.() could provide meaningful result > here, they assume packet header daddr/dport are the local, not the > remote addresses. > > Or, check nft_in(pkt) == NULL || !sk -> BREAK, whatever seems simpler to > you. Makes sense. I'll let you follow up on this. I'll tag https://patchwork.ozlabs.org/project/netfilter-devel/patch/20220427153333.18424-1-pablo@netfilter.org/ as changed requested too ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2022-05-02 17:03 UTC | newest] Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-04-20 18:54 [PATCH] netfilter: nft_socket: socket expressions for GID & UID Topi Miettinen 2022-04-20 21:15 ` Jan Engelhardt 2022-04-21 16:35 ` Topi Miettinen 2022-04-26 21:05 ` Pablo Neira Ayuso 2022-04-26 21:07 ` Pablo Neira Ayuso 2022-04-27 18:07 ` Topi Miettinen 2022-05-02 17:02 ` Pablo Neira Ayuso 2022-04-25 18:45 ` Topi Miettinen 2022-04-25 22:34 ` Florian Westphal 2022-04-26 19:02 ` Topi Miettinen 2022-04-27 5:48 ` Florian Westphal 2022-04-27 7:01 ` Pablo Neira Ayuso 2022-04-27 15:00 ` Topi Miettinen 2022-04-27 15:28 ` Florian Westphal 2022-04-27 15:30 ` Pablo Neira Ayuso 2022-04-27 15:42 ` Florian Westphal 2022-04-27 15:45 ` Pablo Neira Ayuso
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.