* Re: [PATCH v3 06/18] tcp: authopt: Hook into tcp core @ 2021-12-08 21:09 kernel test robot 0 siblings, 0 replies; 6+ messages in thread From: kernel test robot @ 2021-12-08 21:09 UTC (permalink / raw) To: kbuild [-- Attachment #1: Type: text/plain, Size: 5062 bytes --] CC: kbuild-all(a)lists.01.org In-Reply-To: <c6a0af64b6e41aa74d70dc0f7321a5f2293ee53e.1638962992.git.cdleonard@gmail.com> References: <c6a0af64b6e41aa74d70dc0f7321a5f2293ee53e.1638962992.git.cdleonard@gmail.com> TO: Leonard Crestez <cdleonard@gmail.com> TO: David Ahern <dsahern@kernel.org> TO: Dmitry Safonov <0x7f454c46@gmail.com> TO: Eric Dumazet <edumazet@google.com> CC: Francesco Ruggeri <fruggeri@arista.com> CC: Shuah Khan <skhan@linuxfoundation.org> CC: Herbert Xu <herbert@gondor.apana.org.au> CC: Kuniyuki Iwashima <kuniyu@amazon.co.jp> CC: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> CC: Jakub Kicinski <kuba@kernel.org> CC: Yuchung Cheng <ycheng@google.com> Hi Leonard, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on 1fe5b01262844be03de98afdd56d1d393df04d7e] url: https://github.com/0day-ci/linux/commits/Leonard-Crestez/tcp-Initial-support-for-RFC5925-auth-option/20211208-194125 base: 1fe5b01262844be03de98afdd56d1d393df04d7e :::::: branch date: 9 hours ago :::::: commit date: 9 hours ago config: x86_64-randconfig-m001-20211207 (https://download.01.org/0day-ci/archive/20211209/202112090428.Dm5nhj1N-lkp(a)intel.com/config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> Reported-by: Dan Carpenter <dan.carpenter@oracle.com> smatch warnings: net/ipv6/tcp_ipv6.c:1635 tcp_v6_sig_check() error: uninitialized symbol 'ao'. net/ipv6/tcp_ipv6.c:1640 tcp_v6_sig_check() error: uninitialized symbol 'md5'. net/ipv6/tcp_ipv6.c:1655 tcp_v6_sig_check_req() error: uninitialized symbol 'ao'. net/ipv6/tcp_ipv6.c:1660 tcp_v6_sig_check_req() error: uninitialized symbol 'md5'. net/ipv4/tcp_ipv4.c:1967 tcp_v4_sig_check() error: uninitialized symbol 'ao'. net/ipv4/tcp_ipv4.c:1972 tcp_v4_sig_check() error: uninitialized symbol 'md5'. net/ipv4/tcp_ipv4.c:1987 tcp_v4_sig_check_req() error: uninitialized symbol 'ao'. net/ipv4/tcp_ipv4.c:1992 tcp_v4_sig_check_req() error: uninitialized symbol 'md5'. vim +/ao +1635 net/ipv6/tcp_ipv6.c 2dc49d1680b534 Nicolas Dichtel 2014-12-22 1623 5935c41094c73e Leonard Crestez 2021-12-08 1624 static int tcp_v6_sig_check(struct sock *sk, 5935c41094c73e Leonard Crestez 2021-12-08 1625 struct sk_buff *skb, 5935c41094c73e Leonard Crestez 2021-12-08 1626 int dif, 5935c41094c73e Leonard Crestez 2021-12-08 1627 int sdif) 5935c41094c73e Leonard Crestez 2021-12-08 1628 { 5935c41094c73e Leonard Crestez 2021-12-08 1629 const u8 *md5, *ao; 5935c41094c73e Leonard Crestez 2021-12-08 1630 int ret; 5935c41094c73e Leonard Crestez 2021-12-08 1631 5935c41094c73e Leonard Crestez 2021-12-08 1632 ret = tcp_parse_sig_options(tcp_hdr(skb), &md5, &ao); 5935c41094c73e Leonard Crestez 2021-12-08 1633 if (ret) 5935c41094c73e Leonard Crestez 2021-12-08 1634 return ret; 5935c41094c73e Leonard Crestez 2021-12-08 @1635 ret = tcp_authopt_inbound_check(sk, skb, ao); 5935c41094c73e Leonard Crestez 2021-12-08 1636 if (ret < 0) 5935c41094c73e Leonard Crestez 2021-12-08 1637 return ret; 5935c41094c73e Leonard Crestez 2021-12-08 1638 if (ret == 1) 5935c41094c73e Leonard Crestez 2021-12-08 1639 return 0; 5935c41094c73e Leonard Crestez 2021-12-08 @1640 return tcp_v6_inbound_md5_hash(sk, skb, dif, sdif, md5); 5935c41094c73e Leonard Crestez 2021-12-08 1641 } 5935c41094c73e Leonard Crestez 2021-12-08 1642 5935c41094c73e Leonard Crestez 2021-12-08 1643 static int tcp_v6_sig_check_req(struct request_sock *req, 5935c41094c73e Leonard Crestez 2021-12-08 1644 struct sk_buff *skb, 5935c41094c73e Leonard Crestez 2021-12-08 1645 int dif, 5935c41094c73e Leonard Crestez 2021-12-08 1646 int sdif) 5935c41094c73e Leonard Crestez 2021-12-08 1647 { 5935c41094c73e Leonard Crestez 2021-12-08 1648 struct sock *lsk = req->rsk_listener; 5935c41094c73e Leonard Crestez 2021-12-08 1649 const u8 *md5, *ao; 5935c41094c73e Leonard Crestez 2021-12-08 1650 int ret; 5935c41094c73e Leonard Crestez 2021-12-08 1651 5935c41094c73e Leonard Crestez 2021-12-08 1652 ret = tcp_parse_sig_options(tcp_hdr(skb), &md5, &ao); 5935c41094c73e Leonard Crestez 2021-12-08 1653 if (ret) 5935c41094c73e Leonard Crestez 2021-12-08 1654 return ret; 5935c41094c73e Leonard Crestez 2021-12-08 @1655 ret = tcp_authopt_inbound_check_req(req, skb, ao); 5935c41094c73e Leonard Crestez 2021-12-08 1656 if (ret < 0) 5935c41094c73e Leonard Crestez 2021-12-08 1657 return ret; 5935c41094c73e Leonard Crestez 2021-12-08 1658 if (ret == 1) 5935c41094c73e Leonard Crestez 2021-12-08 1659 return 0; 5935c41094c73e Leonard Crestez 2021-12-08 @1660 return tcp_v6_inbound_md5_hash(lsk, skb, dif, sdif, md5); 5935c41094c73e Leonard Crestez 2021-12-08 1661 } 5935c41094c73e Leonard Crestez 2021-12-08 1662 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 00/18] tcp: Initial support for RFC5925 auth option @ 2021-12-08 11:37 Leonard Crestez 2021-12-08 11:37 ` [PATCH v3 06/18] tcp: authopt: Hook into tcp core Leonard Crestez 0 siblings, 1 reply; 6+ messages in thread From: Leonard Crestez @ 2021-12-08 11:37 UTC (permalink / raw) To: David Ahern, Dmitry Safonov, Eric Dumazet Cc: Francesco Ruggeri, Shuah Khan, David S. Miller, Herbert Xu, Kuniyuki Iwashima, Hideaki YOSHIFUJI, Jakub Kicinski, Yuchung Cheng, Mat Martineau, Christoph Paasch, Ivan Delalande, Priyaranjan Jha, netdev, linux-crypto, linux-kselftest, linux-kernel This is similar to TCP MD5 in functionality but it's sufficiently different that wire formats are incompatible. Compared to TCP-MD5 more algorithms are supported and multiple keys can be used on the same connection but there is still no negotiation mechanism. Expected use-case is protecting long-duration BGP/LDP connections between routers using pre-shared keys. The goal of this series is to allow routers using the linux TCP stack to interoperate with vendors such as Cisco and Juniper. Both algorithms described in RFC5926 are implemented but the code is not very easily extensible beyond that. In particular there are several code paths making stack allocations based on RFC5926 maximum, those would have to be increased. Support for arbitrary algorithms was requested in reply to previous posts but I believe there is no real use case for that. The current implementation is somewhat loose regarding configuration: * Overlaping MKTs can be configured despite what RFC5925 says * Current key can be deleted * If multiple keys are valid for a destination the kernel picks one in an unpredictable manner (this can be overridden). These conditions could be tightened but it is not clear the kernel should prevent misconfiguration from userspace. This version implements prefixlen and incorporates comments from v2 as well as some unrelated fixes. Here are some known flaws and limitations: * Crypto API is used with buffers on the stack and inside struct sock, this might not work on all arches. I'm currently only testing x64 VMs * Interaction with TCP-MD5 not tested in all corners. * Interaction with FASTOPEN not tested and unlikely to work because sequence number assumptions for syn/ack. * Not clear if crypto_ahash_setkey might sleep. If some implementation do that then maybe they could be excluded through alloc flags. * Traffic key is not cached (reducing performance) * There is no useful way to list keys, making userspace debug difficult. Some testing support is included in nettest and fcnal-test.sh, similar to the current level of tcp-md5 testing. A more elaborate test suite using pytest and scapy is available out of tree: https://github.com/cdleonard/tcp-authopt-test That test suite is much larger that the kernel code and did not receive many comments so I will attempt to push it separately (if at all). Changes for frr (old): https://github.com/FRRouting/frr/pull/9442 That PR was made early for ABI feedback, it has many issues. Changes for yabgp (old): https://github.com/cdleonard/yabgp/commits/tcp_authopt This can be use for easy interoperability testing with cisco/juniper/etc. Changes since PATCH v2: * Protect tcp_authopt_alg_get/put_tfm with local_bh_disable instead of preempt_disable. This caused signature corruption when send path executing with BH enabled was interrupted by recv. * Fix accepted keyids not configured locally as "unexpected". If any key is configured that matches the peer then traffic MUST be signed. * Fix issues related to sne rollover during handshake itself. (Francesco) * Implement and test prefixlen (David) * Replace shash with ahash and reuse some of the MD5 code (Dmitry) * Parse md5+ao options only once in the same function (Dmitry) * Pass tcp_authopt_info into inbound check path, this avoids second rcu dereference for same packet. * Pass tcp_request_socket into inbound check path instead of just listen socket. This is required for SNE rollover during handshake and clearifies ISN handling. * Do not allow disabling via sysctl after enabling once, this is difficult to support well (David) * Verbose check for sysctl_tcp_authopt (Dmitry) * Use netif_index_is_l3_master (David) * Cleanup ipvx_addr_match (David) * Add a #define tcp_authopt_needed to wrap static key usage because it looks nicer. * Replace rcu_read_lock with rcu_dereference_protected in SNE updates (Eric) Link: https://lore.kernel.org/netdev/cover.1635784253.git.cdleonard@gmail.com/ Changes since PATCH v1: * Implement Sequence Number Extension * Implement l3index for vrf: TCP_AUTHOPT_KEY_IFINDEX as equivalent of TCP_MD5SIG_FLAG_IFINDEX * Expand TCP-AO tests in fcnal-test.sh to near-parity with md5. * Show addr/port on failure similar to md5 * Remove tox dependency from test suite (create venv directly) * Switch default pytest output format to TAP (kselftest standard) * Fix _copy_from_sockptr_tolerant stack corruption on short sockopts. This was covered in test but error was invisible without STACKPROTECTOR=y * Fix sysctl_tcp_authopt check in tcp_get_authopt_val before memset. This was harmless because error code is checked in getsockopt anyway. * Fix dropping md5 packets on all sockets with AO enabled * Fix checking (key->recv_id & TCP_AUTHOPT_KEY_ADDR_BIND) instead of key->flags in tcp_authopt_key_match_exact * Fix PATCH 1/19 not compiling due to missing "int err" declaration * Add ratelimited message for AO and MD5 both present * Export all symbols required by CONFIG_IPV6=m (again) * Fix compilation with CONFIG_TCP_AUTHOPT=y CONFIG_TCP_MD5SIG=n * Fix checkpatch issues * Pass -rrequirements.txt to tox to avoid dependency variation. Link: https://lore.kernel.org/netdev/cover.1632240523.git.cdleonard@gmail.com/ Changes since RFCv3: * Implement TCP_AUTHOPT handling for timewait and reset replies. Write tests to execute these paths by injecting packets with scapy * Handle combining md5 and authopt: if both are configured use authopt. * Fix locking issues around send_key, introduced in on of the later patches. * Handle IPv4-mapped-IPv6 addresses: it used to be that an ipv4 SYN sent to an ipv6 socket with TCP-AO triggered WARN * Implement un-namespaced sysctl disabled this feature by default * Allocate new key before removing any old one in setsockopt (Dmitry) * Remove tcp_authopt_key_info.local_id because it's no longer used (Dmitry) * Propagate errors from TCP_AUTHOPT getsockopt (Dmitry) * Fix no-longer-correct TCP_AUTHOPT_KEY_DEL docs (Dmitry) * Simplify crypto allocation (Eric) * Use kzmalloc instead of __GFP_ZERO (Eric) * Add static_key_false tcp_authopt_needed (Eric) * Clear authopt_info copied from oldsk in __tcp_authopt_openreq (Eric) * Replace memcmp in ipv4 and ipv6 addr comparisons (Eric) * Export symbols for CONFIG_IPV6=m (kernel test robot) * Mark more functions static (kernel test robot) * Fix build with CONFIG_PROVE_RCU_LIST=y (kernel test robot) Link: https://lore.kernel.org/netdev/cover.1629840814.git.cdleonard@gmail.com/ Changes since RFCv2: * Removed local_id from ABI and match on send_id/recv_id/addr * Add all relevant out-of-tree tests to tools/testing/selftests * Return an error instead of ignoring unknown flags, hopefully this makes it easier to extend. * Check sk_family before __tcp_authopt_info_get_or_create in tcp_set_authopt_key * Use sock_owned_by_me instead of WARN_ON(!lockdep_sock_is_held(sk)) * Fix some intermediate build failures reported by kbuild robot * Improve documentation Link: https://lore.kernel.org/netdev/cover.1628544649.git.cdleonard@gmail.com/ Changes since RFC: * Split into per-topic commits for ease of review. The intermediate commits compile with a few "unused function" warnings and don't do anything useful by themselves. * Add ABI documention including kernel-doc on uapi * Fix lockdep warnings from crypto by creating pools with one shash for each cpu * Accept short options to setsockopt by padding with zeros; this approach allows increasing the size of the structs in the future. * Support for aes-128-cmac-96 * Support for binding addresses to keys in a way similar to old tcp_md5 * Add support for retrieving received keyid/rnextkeyid and controling the keyid/rnextkeyid being sent. Link: https://lore.kernel.org/netdev/01383a8751e97ef826ef2adf93bfde3a08195a43.1626693859.git.cdleonard@gmail.com/ ``` Leonard Crestez (18): tcp: authopt: Initial support and key management docs: Add user documentation for tcp_authopt tcp: authopt: Add crypto initialization tcp: md5: Refactor tcp_sig_hash_skb_data for AO tcp: authopt: Compute packet signatures tcp: authopt: Hook into tcp core tcp: authopt: Disable via sysctl by default tcp: authopt: Implement Sequence Number Extension tcp: ipv6: Add AO signing for tcp_v6_send_response tcp: authopt: Add support for signing skb-less replies tcp: ipv4: Add AO signing for skb-less replies tcp: authopt: Add key selection controls tcp: authopt: Add initial l3index support tcp: authopt: Add NOSEND/NORECV flags tcp: authopt: Add prefixlen support selftests: nettest: Rename md5_prefix to key_addr_prefix selftests: nettest: Initial tcp_authopt support selftests: net/fcnal: Initial tcp_authopt support Documentation/networking/index.rst | 1 + Documentation/networking/ip-sysctl.rst | 6 + Documentation/networking/tcp_authopt.rst | 69 + include/linux/tcp.h | 9 + include/net/tcp.h | 27 +- include/net/tcp_authopt.h | 316 ++++ include/uapi/linux/snmp.h | 1 + include/uapi/linux/tcp.h | 137 ++ net/ipv4/Kconfig | 14 + net/ipv4/Makefile | 1 + net/ipv4/proc.c | 1 + net/ipv4/sysctl_net_ipv4.c | 39 + net/ipv4/tcp.c | 68 +- net/ipv4/tcp_authopt.c | 1671 +++++++++++++++++++++ net/ipv4/tcp_input.c | 41 +- net/ipv4/tcp_ipv4.c | 136 +- net/ipv4/tcp_minisocks.c | 12 + net/ipv4/tcp_output.c | 86 +- net/ipv6/tcp_ipv6.c | 108 +- tools/testing/selftests/net/fcnal-test.sh | 298 ++++ tools/testing/selftests/net/nettest.c | 123 +- 21 files changed, 3085 insertions(+), 79 deletions(-) create mode 100644 Documentation/networking/tcp_authopt.rst create mode 100644 include/net/tcp_authopt.h create mode 100644 net/ipv4/tcp_authopt.c base-commit: 1fe5b01262844be03de98afdd56d1d393df04d7e -- 2.25.1 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 06/18] tcp: authopt: Hook into tcp core 2021-12-08 11:37 [PATCH v3 00/18] tcp: Initial support for RFC5925 auth option Leonard Crestez @ 2021-12-08 11:37 ` Leonard Crestez 2021-12-08 16:45 ` kernel test robot ` (2 more replies) 0 siblings, 3 replies; 6+ messages in thread From: Leonard Crestez @ 2021-12-08 11:37 UTC (permalink / raw) To: David Ahern, Dmitry Safonov, Eric Dumazet Cc: Francesco Ruggeri, Shuah Khan, David S. Miller, Herbert Xu, Kuniyuki Iwashima, Hideaki YOSHIFUJI, Jakub Kicinski, Yuchung Cheng, Mat Martineau, Christoph Paasch, Ivan Delalande, Priyaranjan Jha, netdev, linux-crypto, linux-kselftest, linux-kernel The tcp_authopt features exposes a minimal interface to the rest of the TCP stack. Only a few functions are exposed and if the feature is disabled they return neutral values, avoiding ifdefs in the rest of the code. This approach is different from MD5. There very few interactions with MD5 but tcp_parse_md5sig_option was modifed to parse AO and MD5 simultaneously. If both are present the packet is droppped as required by RFC5925. Add calls into tcp authopt from send, receive and accept code. Signed-off-by: Leonard Crestez <cdleonard@gmail.com> --- include/net/tcp.h | 24 +++- include/net/tcp_authopt.h | 135 ++++++++++++++++++ include/uapi/linux/snmp.h | 1 + net/ipv4/proc.c | 1 + net/ipv4/tcp_authopt.c | 293 ++++++++++++++++++++++++++++++++++++++ net/ipv4/tcp_input.c | 40 ++++-- net/ipv4/tcp_ipv4.c | 50 ++++++- net/ipv4/tcp_minisocks.c | 12 ++ net/ipv4/tcp_output.c | 85 ++++++++++- net/ipv6/tcp_ipv6.c | 49 ++++++- 10 files changed, 665 insertions(+), 25 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 1a0513b0ead0..eed4bbfdca78 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -422,11 +422,33 @@ int tcp_mmap(struct file *file, struct socket *sock, struct vm_area_struct *vma); #endif void tcp_parse_options(const struct net *net, const struct sk_buff *skb, struct tcp_options_received *opt_rx, int estab, struct tcp_fastopen_cookie *foc); -const u8 *tcp_parse_md5sig_option(const struct tcphdr *th); +#if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AUTHOPT) +int tcp_parse_sig_options(const struct tcphdr *th, + const u8 **md5ptr, + const u8 **aoptr); +#else +static inline int tcp_parse_sig_options(const struct tcphdr *th, + const u8 **md5ptr, + const u8 **aoptr) +{ + aoptr = NULL; + md5ptr = NULL; + return 0; +} +#endif +static inline const u8 *tcp_parse_md5sig_option(const struct tcphdr *th) +{ + const u8 *md5, *ao; + int ret; + + ret = tcp_parse_sig_options(th, &md5, &ao); + + return (md5 && !ao && !ret) ? md5 : NULL; +} /* * BPF SKB-less helpers */ u16 tcp_v4_get_syncookie(struct sock *sk, struct iphdr *iph, diff --git a/include/net/tcp_authopt.h b/include/net/tcp_authopt.h index ce005f7ce797..fb07394de261 100644 --- a/include/net/tcp_authopt.h +++ b/include/net/tcp_authopt.h @@ -74,28 +74,163 @@ struct tcphdr_authopt { u8 rnextkeyid; u8 mac[0]; }; #ifdef CONFIG_TCP_AUTHOPT +DECLARE_STATIC_KEY_FALSE(tcp_authopt_needed_key); +#define tcp_authopt_needed (static_branch_unlikely(&tcp_authopt_needed_key)) + +void tcp_authopt_free(struct sock *sk, struct tcp_authopt_info *info); void tcp_authopt_clear(struct sock *sk); int tcp_set_authopt(struct sock *sk, sockptr_t optval, unsigned int optlen); int tcp_get_authopt_val(struct sock *sk, struct tcp_authopt *key); int tcp_set_authopt_key(struct sock *sk, sockptr_t optval, unsigned int optlen); +struct tcp_authopt_key_info *__tcp_authopt_select_key( + const struct sock *sk, + struct tcp_authopt_info *info, + const struct sock *addr_sk, + u8 *rnextkeyid); +static inline struct tcp_authopt_key_info *tcp_authopt_select_key( + const struct sock *sk, + const struct sock *addr_sk, + struct tcp_authopt_info **info, + u8 *rnextkeyid) +{ + if (tcp_authopt_needed) { + *info = rcu_dereference(tcp_sk(sk)->authopt_info); + + if (*info) + return __tcp_authopt_select_key(sk, *info, addr_sk, rnextkeyid); + } + return NULL; +} +int tcp_authopt_hash( + char *hash_location, + struct tcp_authopt_key_info *key, + struct tcp_authopt_info *info, + struct sock *sk, struct sk_buff *skb); +int __tcp_authopt_openreq(struct sock *newsk, const struct sock *oldsk, struct request_sock *req); +static inline int tcp_authopt_openreq( + struct sock *newsk, + const struct sock *oldsk, + struct request_sock *req) +{ + if (!rcu_dereference(tcp_sk(oldsk)->authopt_info)) + return 0; + else + return __tcp_authopt_openreq(newsk, oldsk, req); +} +void __tcp_authopt_finish_connect(struct sock *sk, struct sk_buff *skb, + struct tcp_authopt_info *info); +static inline void tcp_authopt_finish_connect(struct sock *sk, struct sk_buff *skb) +{ + struct tcp_authopt_info *info; + + if (tcp_authopt_needed) { + info = rcu_dereference_protected(tcp_sk(sk)->authopt_info, + lockdep_sock_is_held(sk)); + + if (info) + __tcp_authopt_finish_connect(sk, skb, info); + } +} +static inline void tcp_authopt_time_wait( + struct tcp_timewait_sock *tcptw, + struct tcp_sock *tp) +{ + if (tcp_authopt_needed) { + /* Transfer ownership of authopt_info to the twsk + * This requires no other users of the origin sock. + */ + sock_owned_by_me((struct sock *)tp); + tcptw->tw_authopt_info = tp->authopt_info; + tp->authopt_info = NULL; + } else { + tcptw->tw_authopt_info = NULL; + } +} +/** tcp_authopt_inbound_check - check for valid TCP-AO signature. + * + * Return negative ERRNO on error, 0 if not present and 1 if present and valid. + * + * If the AO signature is present and valid then caller skips MD5 check. + */ +int __tcp_authopt_inbound_check( + struct sock *sk, + struct sk_buff *skb, + struct tcp_authopt_info *info, + const u8 *opt); +static inline int tcp_authopt_inbound_check(struct sock *sk, struct sk_buff *skb, const u8 *opt) +{ + if (tcp_authopt_needed) { + struct tcp_authopt_info *info = rcu_dereference(tcp_sk(sk)->authopt_info); + + if (info) + return __tcp_authopt_inbound_check(sk, skb, info, opt); + } + return 0; +} +static inline int tcp_authopt_inbound_check_req(struct request_sock *req, struct sk_buff *skb, + const u8 *opt) +{ + if (tcp_authopt_needed) { + struct sock *lsk = req->rsk_listener; + struct tcp_authopt_info *info = rcu_dereference(tcp_sk(lsk)->authopt_info); + + if (info) + return __tcp_authopt_inbound_check((struct sock *)req, skb, info, opt); + } + return 0; +} #else static inline int tcp_set_authopt(struct sock *sk, sockptr_t optval, unsigned int optlen) { return -ENOPROTOOPT; } static inline int tcp_get_authopt_val(struct sock *sk, struct tcp_authopt *key) { return -ENOPROTOOPT; } +static inline void tcp_authopt_free(struct sock *sk, struct tcp_authopt_info *info) +{ +} static inline void tcp_authopt_clear(struct sock *sk) { } static inline int tcp_set_authopt_key(struct sock *sk, sockptr_t optval, unsigned int optlen) { return -ENOPROTOOPT; } +static inline int tcp_authopt_hash( + char *hash_location, + struct tcp_authopt_key_info *key, + struct tcp_authopt_key *info, + struct sock *sk, struct sk_buff *skb) +{ + return -EINVAL; +} +static inline int tcp_authopt_openreq(struct sock *newsk, + const struct sock *oldsk, + struct request_sock *req) +{ + return 0; +} +static inline void tcp_authopt_finish_connect(struct sock *sk, struct sk_buff *skb) +{ +} +static inline void tcp_authopt_time_wait( + struct tcp_timewait_sock *tcptw, + struct tcp_sock *tp) +{ +} +static inline int tcp_authopt_inbound_check(struct sock *sk, struct sk_buff *skb, const u8 *opt) +{ + return 0; +} +static inline int tcp_authopt_inbound_check_req(struct request_sock *sk, struct sk_buff *skb, + const u8 *opt) +{ + return 0; +} #endif #endif /* _LINUX_TCP_AUTHOPT_H */ diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h index 904909d020e2..1d96030889a1 100644 --- a/include/uapi/linux/snmp.h +++ b/include/uapi/linux/snmp.h @@ -290,10 +290,11 @@ enum LINUX_MIB_TCPDUPLICATEDATAREHASH, /* TCPDuplicateDataRehash */ LINUX_MIB_TCPDSACKRECVSEGS, /* TCPDSACKRecvSegs */ LINUX_MIB_TCPDSACKIGNOREDDUBIOUS, /* TCPDSACKIgnoredDubious */ LINUX_MIB_TCPMIGRATEREQSUCCESS, /* TCPMigrateReqSuccess */ LINUX_MIB_TCPMIGRATEREQFAILURE, /* TCPMigrateReqFailure */ + LINUX_MIB_TCPAUTHOPTFAILURE, /* TCPAuthOptFailure */ __LINUX_MIB_MAX }; /* linux Xfrm mib definitions */ enum diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index f30273afb539..70f7a8a47045 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -295,10 +295,11 @@ static const struct snmp_mib snmp4_net_list[] = { SNMP_MIB_ITEM("TcpDuplicateDataRehash", LINUX_MIB_TCPDUPLICATEDATAREHASH), SNMP_MIB_ITEM("TCPDSACKRecvSegs", LINUX_MIB_TCPDSACKRECVSEGS), SNMP_MIB_ITEM("TCPDSACKIgnoredDubious", LINUX_MIB_TCPDSACKIGNOREDDUBIOUS), SNMP_MIB_ITEM("TCPMigrateReqSuccess", LINUX_MIB_TCPMIGRATEREQSUCCESS), SNMP_MIB_ITEM("TCPMigrateReqFailure", LINUX_MIB_TCPMIGRATEREQFAILURE), + SNMP_MIB_ITEM("TCPAuthOptFailure", LINUX_MIB_TCPAUTHOPTFAILURE), SNMP_MIB_SENTINEL }; static void icmpmsg_put_line(struct seq_file *seq, unsigned long *vals, unsigned short *type, int count) diff --git a/net/ipv4/tcp_authopt.c b/net/ipv4/tcp_authopt.c index 29524ed56733..dd9b89b1f137 100644 --- a/net/ipv4/tcp_authopt.c +++ b/net/ipv4/tcp_authopt.c @@ -3,10 +3,14 @@ #include <linux/kernel.h> #include <net/tcp.h> #include <net/tcp_authopt.h> #include <crypto/hash.h> +/* This is enabled when first struct tcp_authopt_info is allocated and never released */ +DEFINE_STATIC_KEY_FALSE(tcp_authopt_needed_key); +EXPORT_SYMBOL(tcp_authopt_needed_key); + /* All current algorithms have a mac length of 12 but crypto API digestsize can be larger */ #define TCP_AUTHOPT_MAXMACBUF 20 #define TCP_AUTHOPT_MAX_TRAFFIC_KEY_LEN 20 #define TCP_AUTHOPT_MACLEN 12 @@ -214,10 +218,55 @@ static bool tcp_authopt_key_match_exact(struct tcp_authopt_key_info *info, return false; return true; } +static bool tcp_authopt_key_match_skb_addr(struct tcp_authopt_key_info *key, + struct sk_buff *skb) +{ + u16 keyaf = key->addr.ss_family; + struct iphdr *iph = (struct iphdr *)skb_network_header(skb); + + if (keyaf == AF_INET && iph->version == 4) { + struct sockaddr_in *key_addr = (struct sockaddr_in *)&key->addr; + + return iph->saddr == key_addr->sin_addr.s_addr; + } else if (keyaf == AF_INET6 && iph->version == 6) { + struct ipv6hdr *ip6h = (struct ipv6hdr *)skb_network_header(skb); + struct sockaddr_in6 *key_addr = (struct sockaddr_in6 *)&key->addr; + + return ipv6_addr_equal(&ip6h->saddr, &key_addr->sin6_addr); + } + + /* This actually happens with ipv6-mapped-ipv4-addresses + * IPv6 listen sockets will be asked to validate ipv4 packets. + */ + return false; +} + +static bool tcp_authopt_key_match_sk_addr(struct tcp_authopt_key_info *key, + const struct sock *addr_sk) +{ + u16 keyaf = key->addr.ss_family; + + /* This probably can't happen even with ipv4-mapped-ipv6 */ + if (keyaf != addr_sk->sk_family) + return false; + + if (keyaf == AF_INET) { + struct sockaddr_in *key_addr = (struct sockaddr_in *)&key->addr; + + return addr_sk->sk_daddr == key_addr->sin_addr.s_addr; + } else if (keyaf == AF_INET6) { + struct sockaddr_in6 *key_addr = (struct sockaddr_in6 *)&key->addr; + + return ipv6_addr_equal(&addr_sk->sk_v6_daddr, &key_addr->sin6_addr); + } + + return false; +} + static struct tcp_authopt_key_info *tcp_authopt_key_lookup_exact(const struct sock *sk, struct tcp_authopt_info *info, struct tcp_authopt_key *ukey) { struct tcp_authopt_key_info *key_info; @@ -227,10 +276,50 @@ static struct tcp_authopt_key_info *tcp_authopt_key_lookup_exact(const struct so return key_info; return NULL; } +static struct tcp_authopt_key_info *tcp_authopt_lookup_send(struct tcp_authopt_info *info, + const struct sock *addr_sk, + int send_id) +{ + struct tcp_authopt_key_info *result = NULL; + struct tcp_authopt_key_info *key; + + hlist_for_each_entry_rcu(key, &info->head, node, 0) { + if (send_id >= 0 && key->send_id != send_id) + continue; + if (key->flags & TCP_AUTHOPT_KEY_ADDR_BIND) + if (!tcp_authopt_key_match_sk_addr(key, addr_sk)) + continue; + if (result && net_ratelimit()) + pr_warn("ambiguous tcp authentication keys configured for send\n"); + result = key; + } + + return result; +} + +/** + * __tcp_authopt_select_key - select key for sending + * + * @sk: socket + * @info: socket's tcp_authopt_info + * @addr_sk: socket used for address lookup. Same as sk except for synack case + * @rnextkeyid: value of rnextkeyid caller should write in packet + * + * Result is protected by RCU and can't be stored, it may only be passed to + * tcp_authopt_hash and only under a single rcu_read_lock. + */ +struct tcp_authopt_key_info *__tcp_authopt_select_key(const struct sock *sk, + struct tcp_authopt_info *info, + const struct sock *addr_sk, + u8 *rnextkeyid) +{ + return tcp_authopt_lookup_send(info, addr_sk, -1); +} + static struct tcp_authopt_info *__tcp_authopt_info_get_or_create(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); struct tcp_authopt_info *info; @@ -240,10 +329,12 @@ static struct tcp_authopt_info *__tcp_authopt_info_get_or_create(struct sock *sk info = kzalloc(sizeof(*info), GFP_KERNEL); if (!info) return ERR_PTR(-ENOMEM); + /* Never released: */ + static_branch_inc(&tcp_authopt_needed_key); sk_gso_disable(sk); INIT_HLIST_HEAD(&info->head); rcu_assign_pointer(tp->authopt_info, info); return info; @@ -528,10 +619,71 @@ static int crypto_ahash_buf(struct ahash_request *req, u8 *buf, uint len) ahash_request_set_crypt(req, &sg, NULL, len); return crypto_ahash_update(req); } +static int tcp_authopt_clone_keys(struct sock *newsk, + const struct sock *oldsk, + struct tcp_authopt_info *new_info, + struct tcp_authopt_info *old_info) +{ + struct tcp_authopt_key_info *old_key; + struct tcp_authopt_key_info *new_key; + + hlist_for_each_entry_rcu(old_key, &old_info->head, node, lockdep_sock_is_held(oldsk)) { + new_key = sock_kmalloc(newsk, sizeof(*new_key), GFP_ATOMIC); + if (!new_key) + return -ENOMEM; + memcpy(new_key, old_key, sizeof(*new_key)); + hlist_add_head_rcu(&new_key->node, &new_info->head); + } + + return 0; +} + +/** Called to create accepted sockets. + * + * Need to copy authopt info from listen socket. + */ +int __tcp_authopt_openreq(struct sock *newsk, const struct sock *oldsk, struct request_sock *req) +{ + struct tcp_authopt_info *old_info; + struct tcp_authopt_info *new_info; + int err; + + old_info = rcu_dereference(tcp_sk(oldsk)->authopt_info); + if (!old_info) + return 0; + + /* Clear value copies from oldsk: */ + rcu_assign_pointer(tcp_sk(newsk)->authopt_info, NULL); + + new_info = kzalloc(sizeof(*new_info), GFP_ATOMIC); + if (!new_info) + return -ENOMEM; + + new_info->src_isn = tcp_rsk(req)->snt_isn; + new_info->dst_isn = tcp_rsk(req)->rcv_isn; + INIT_HLIST_HEAD(&new_info->head); + err = tcp_authopt_clone_keys(newsk, oldsk, new_info, old_info); + if (err) { + tcp_authopt_free(newsk, new_info); + return err; + } + sk_gso_disable(newsk); + rcu_assign_pointer(tcp_sk(newsk)->authopt_info, new_info); + + return 0; +} + +void __tcp_authopt_finish_connect(struct sock *sk, struct sk_buff *skb, + struct tcp_authopt_info *info) +{ + info->src_isn = ntohl(tcp_hdr(skb)->ack_seq) - 1; + info->dst_isn = ntohl(tcp_hdr(skb)->seq); +} + /* feed traffic key into ahash */ static int tcp_authopt_ahash_traffic_key(struct tcp_authopt_alg_pool *pool, struct sock *sk, struct sk_buff *skb, struct tcp_authopt_info *info, @@ -768,10 +920,11 @@ static int tcp_authopt_hash_opts(struct tcp_authopt_alg_pool *pool, static int tcp_authopt_hash_packet(struct tcp_authopt_alg_pool *pool, struct sock *sk, struct sk_buff *skb, struct tcphdr_authopt *aoptr, + struct tcp_authopt_info *info, bool input, bool ipv6, bool include_options, u8 *macbuf) { @@ -881,14 +1034,154 @@ static int __tcp_authopt_calc_mac(struct sock *sk, err = tcp_authopt_hash_packet(mac_pool, sk, skb, aoptr, + info, input, ipv6, !(key->flags & TCP_AUTHOPT_KEY_EXCLUDE_OPTS), macbuf); out: tcp_authopt_put_mac_pool(key, mac_pool); return err; } + +/* tcp_authopt_hash - fill in the mac + * + * The key must come from tcp_authopt_select_key. + */ +int tcp_authopt_hash(char *hash_location, + struct tcp_authopt_key_info *key, + struct tcp_authopt_info *info, + struct sock *sk, + struct sk_buff *skb) +{ + /* MAC inside option is truncated to 12 bytes but crypto API needs output + * buffer to be large enough so we use a buffer on the stack. + */ + u8 macbuf[TCP_AUTHOPT_MAXMACBUF]; + int err; + struct tcphdr_authopt *aoptr = (struct tcphdr_authopt *)(hash_location - 4); + + err = __tcp_authopt_calc_mac(sk, skb, aoptr, key, info, false, macbuf); + if (err) + goto fail; + memcpy(hash_location, macbuf, TCP_AUTHOPT_MACLEN); + + return 0; + +fail: + /* If mac calculation fails and caller doesn't handle the error + * try to make it obvious inside the packet. + */ + memset(hash_location, 0, TCP_AUTHOPT_MACLEN); + return err; +} + +static struct tcp_authopt_key_info *tcp_authopt_lookup_recv(struct sock *sk, + struct sk_buff *skb, + struct tcp_authopt_info *info, + int recv_id, + bool *anykey) +{ + struct tcp_authopt_key_info *result = NULL; + struct tcp_authopt_key_info *key; + + *anykey = false; + /* multiple matches will cause occasional failures */ + hlist_for_each_entry_rcu(key, &info->head, node, 0) { + if (key->flags & TCP_AUTHOPT_KEY_ADDR_BIND && + !tcp_authopt_key_match_skb_addr(key, skb)) + continue; + *anykey = true; + if (recv_id >= 0 && key->recv_id != recv_id) + continue; + if (!result) + result = key; + else if (result) + net_warn_ratelimited("ambiguous tcp authentication keys configured for recv\n"); + } + + return result; +} + +/* Show a rate-limited message for authentication fail */ +static void print_tcpao_notice(const char *msg, struct sk_buff *skb) +{ + struct iphdr *iph = (struct iphdr *)skb_network_header(skb); + struct tcphdr *th = (struct tcphdr *)skb_transport_header(skb); + + if (iph->version == 4) { + net_info_ratelimited("%s (%pI4, %d)->(%pI4, %d)\n", msg, + &iph->saddr, ntohs(th->source), + &iph->daddr, ntohs(th->dest)); + } else if (iph->version == 6) { + struct ipv6hdr *ip6h = (struct ipv6hdr *)skb_network_header(skb); + + net_info_ratelimited("%s (%pI6, %d)->(%pI6, %d)\n", msg, + &ip6h->saddr, ntohs(th->source), + &ip6h->daddr, ntohs(th->dest)); + } else { + WARN_ONCE(1, "%s unknown IP version\n", msg); + } +} + +int __tcp_authopt_inbound_check(struct sock *sk, struct sk_buff *skb, + struct tcp_authopt_info *info, const u8 *_opt) +{ + struct tcphdr_authopt *opt = (struct tcphdr_authopt *)_opt; + struct tcp_authopt_key_info *key; + bool anykey; + u8 macbuf[TCP_AUTHOPT_MAXMACBUF]; + int err; + + key = tcp_authopt_lookup_recv(sk, skb, info, opt ? opt->keyid : -1, &anykey); + + /* nothing found or expected */ + if (!opt && !key) + return 0; + if (!opt && key) { + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAUTHOPTFAILURE); + print_tcpao_notice("TCP Authentication Missing", skb); + return -EINVAL; + } + if (opt && !anykey) { + /* RFC5925 Section 7.3: + * A TCP-AO implementation MUST allow for configuration of the behavior + * of segments with TCP-AO but that do not match an MKT. The initial + * default of this configuration SHOULD be to silently accept such + * connections. + */ + if (info->flags & TCP_AUTHOPT_FLAG_REJECT_UNEXPECTED) { + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAUTHOPTFAILURE); + print_tcpao_notice("TCP Authentication Unexpected: Rejected", skb); + return -EINVAL; + } + print_tcpao_notice("TCP Authentication Unexpected: Accepted", skb); + return 0; + } + if (opt && !key) { + /* Keys are configured for peer but with different keyid than packet */ + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAUTHOPTFAILURE); + print_tcpao_notice("TCP Authentication Failed", skb); + return -EINVAL; + } + + /* bad inbound key len */ + if (opt->len != TCPOLEN_AUTHOPT_OUTPUT) + return -EINVAL; + + err = __tcp_authopt_calc_mac(sk, skb, opt, key, info, true, macbuf); + if (err) + return err; + + if (memcmp(macbuf, opt->mac, TCP_AUTHOPT_MACLEN)) { + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAUTHOPTFAILURE); + print_tcpao_notice("TCP Authentication Failed", skb); + return -EINVAL; + } + + return 1; +} +EXPORT_SYMBOL(__tcp_authopt_inbound_check); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 3658b9c3dd2b..4c9e403971fb 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -70,10 +70,11 @@ #include <linux/sysctl.h> #include <linux/kernel.h> #include <linux/prefetch.h> #include <net/dst.h> #include <net/tcp.h> +#include <net/tcp_authopt.h> #include <net/inet_common.h> #include <linux/ipsec.h> #include <asm/unaligned.h> #include <linux/errqueue.h> #include <trace/events/tcp.h> @@ -4173,43 +4174,60 @@ static bool tcp_fast_parse_options(const struct net *net, tp->rx_opt.rcv_tsecr -= tp->tsoffset; return true; } -#ifdef CONFIG_TCP_MD5SIG +#if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AUTHOPT) /* - * Parse MD5 Signature option + * Parse MD5 and AO options + * + * md5ptr: pointer to content of MD5 option (16-byte hash) + * aoptr: pointer to start of AO option (variable length) */ -const u8 *tcp_parse_md5sig_option(const struct tcphdr *th) +int tcp_parse_sig_options(const struct tcphdr *th, const u8 **md5ptr, const u8 **aoptr) { int length = (th->doff << 2) - sizeof(*th); const u8 *ptr = (const u8 *)(th + 1); + *md5ptr = NULL; + *aoptr = NULL; + /* If not enough data remaining, we can short cut */ - while (length >= TCPOLEN_MD5SIG) { + while (length >= 4) { int opcode = *ptr++; int opsize; switch (opcode) { case TCPOPT_EOL: - return NULL; + goto out; case TCPOPT_NOP: length--; continue; default: opsize = *ptr++; if (opsize < 2 || opsize > length) - return NULL; - if (opcode == TCPOPT_MD5SIG) - return opsize == TCPOLEN_MD5SIG ? ptr : NULL; + goto out; + if (opcode == TCPOPT_MD5SIG && opsize == TCPOLEN_MD5SIG) + *md5ptr = ptr; + if (opcode == TCPOPT_AUTHOPT) + *aoptr = ptr - 2; } ptr += opsize - 2; length -= opsize; } - return NULL; + +out: + /* RFC5925 2.2: An endpoint MUST NOT use TCP-AO for the same connection + * in which TCP MD5 is used. When both options appear, TCP MUST silently + * discard the segment. + */ + if (*md5ptr && *aoptr) + return -EINVAL; + + return 0; } -EXPORT_SYMBOL(tcp_parse_md5sig_option); +EXPORT_SYMBOL(tcp_parse_sig_options); #endif /* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM * * It is not fatal. If this ACK does _not_ change critical state (seqs, window) @@ -5992,10 +6010,12 @@ void tcp_finish_connect(struct sock *sk, struct sk_buff *skb) struct inet_connection_sock *icsk = inet_csk(sk); tcp_set_state(sk, TCP_ESTABLISHED); icsk->icsk_ack.lrcvtime = tcp_jiffies32; + tcp_authopt_finish_connect(sk, skb); + if (skb) { icsk->icsk_af_ops->sk_rx_dst_set(sk, skb); security_inet_conn_established(sk, skb); sk_mark_napi_id(sk, skb); } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 91cad11db32e..b16f263c3121 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1405,22 +1405,20 @@ EXPORT_SYMBOL(tcp_v4_md5_hash_skb); #endif /* Called with rcu_read_lock() */ static bool tcp_v4_inbound_md5_hash(const struct sock *sk, const struct sk_buff *skb, - int dif, int sdif) + int dif, int sdif, + const u8 *hash_location) { #ifdef CONFIG_TCP_MD5SIG /* - * This gets called for each TCP segment that arrives - * so we want to be efficient. * We have 3 drop cases: * o No MD5 hash and one expected. * o MD5 hash and we're not expecting one. * o MD5 hash and its wrong. */ - const __u8 *hash_location = NULL; struct tcp_md5sig_key *hash_expected; const struct iphdr *iph = ip_hdr(skb); const struct tcphdr *th = tcp_hdr(skb); const union tcp_md5_addr *addr; unsigned char newhash[16]; @@ -1431,11 +1429,10 @@ static bool tcp_v4_inbound_md5_hash(const struct sock *sk, */ l3index = sdif ? dif : 0; addr = (union tcp_md5_addr *)&iph->saddr; hash_expected = tcp_md5_do_lookup(sk, l3index, addr, AF_INET); - hash_location = tcp_parse_md5sig_option(th); /* We've parsed the options - do we have a hash? */ if (!hash_expected && !hash_location) return false; @@ -1954,10 +1951,49 @@ static void tcp_v4_fill_cb(struct sk_buff *skb, const struct iphdr *iph, TCP_SKB_CB(skb)->sacked = 0; TCP_SKB_CB(skb)->has_rxtstamp = skb->tstamp || skb_hwtstamps(skb)->hwtstamp; } +static int tcp_v4_sig_check(struct sock *sk, + struct sk_buff *skb, + int dif, + int sdif) +{ + const u8 *md5, *ao; + int ret; + + ret = tcp_parse_sig_options(tcp_hdr(skb), &md5, &ao); + if (ret) + return ret; + ret = tcp_authopt_inbound_check(sk, skb, ao); + if (ret < 0) + return ret; + if (ret == 1) + return 0; + return tcp_v4_inbound_md5_hash(sk, skb, dif, sdif, md5); +} + +static int tcp_v4_sig_check_req(struct request_sock *req, + struct sk_buff *skb, + int dif, + int sdif) +{ + struct sock *lsk = req->rsk_listener; + const u8 *md5, *ao; + int ret; + + ret = tcp_parse_sig_options(tcp_hdr(skb), &md5, &ao); + if (ret) + return ret; + ret = tcp_authopt_inbound_check_req(req, skb, ao); + if (ret < 0) + return ret; + if (ret == 1) + return 0; + return tcp_v4_inbound_md5_hash(lsk, skb, dif, sdif, md5); +} + /* * From tcp_input.c */ int tcp_v4_rcv(struct sk_buff *skb) @@ -2011,11 +2047,11 @@ int tcp_v4_rcv(struct sk_buff *skb) struct request_sock *req = inet_reqsk(sk); bool req_stolen = false; struct sock *nsk; sk = req->rsk_listener; - if (unlikely(tcp_v4_inbound_md5_hash(sk, skb, dif, sdif))) { + if (unlikely(tcp_v4_sig_check_req(req, skb, dif, sdif))) { sk_drops_add(sk, skb); reqsk_put(req); goto discard_it; } if (tcp_checksum_complete(skb)) { @@ -2081,11 +2117,11 @@ int tcp_v4_rcv(struct sk_buff *skb) } if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) goto discard_and_relse; - if (tcp_v4_inbound_md5_hash(sk, skb, dif, sdif)) + if (tcp_v4_sig_check(sk, skb, dif, sdif)) goto discard_and_relse; nf_reset_ct(skb); if (tcp_filter(sk, skb)) diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index cf913a66df17..19f749b60231 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -18,10 +18,11 @@ * Arnt Gulbrandsen, <agulbra@nvg.unit.no> * Jorge Cwik, <jorge@laser.satlink.net> */ #include <net/tcp.h> +#include <net/tcp_authopt.h> #include <net/xfrm.h> #include <net/busy_poll.h> static bool tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win) { @@ -300,10 +301,11 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) BUG_ON(tcptw->tw_md5_key && !tcp_alloc_md5sig_pool()); } } } while (0); #endif + tcp_authopt_time_wait(tcptw, tcp_sk(sk)); /* Get the TIME_WAIT timeout firing. */ if (timeo < rto) timeo = rto; @@ -342,10 +344,19 @@ void tcp_twsk_destructor(struct sock *sk) if (twsk->tw_md5_key) kfree_rcu(twsk->tw_md5_key, rcu); } #endif +#ifdef CONFIG_TCP_AUTHOPT + if (tcp_authopt_needed) { + struct tcp_timewait_sock *twsk = tcp_twsk(sk); + + /* twsk only contains sock_common so pass NULL as sk. */ + if (twsk->tw_authopt_info) + tcp_authopt_free(NULL, twsk->tw_authopt_info); + } +#endif } EXPORT_SYMBOL_GPL(tcp_twsk_destructor); /* Warning : This function is called without sk_listener being locked. * Be sure to read socket fields once, as their value could change under us. @@ -532,10 +543,11 @@ struct sock *tcp_create_openreq_child(const struct sock *sk, #ifdef CONFIG_TCP_MD5SIG newtp->md5sig_info = NULL; /*XXX*/ if (newtp->af_specific->md5_lookup(sk, newsk)) newtp->tcp_header_len += TCPOLEN_MD5SIG_ALIGNED; #endif + tcp_authopt_openreq(newsk, sk, req); if (skb->len >= TCP_MSS_DEFAULT + newtp->tcp_header_len) newicsk->icsk_ack.last_seg_size = skb->len - newtp->tcp_header_len; newtp->rx_opt.mss_clamp = req->mss; tcp_ecn_openreq_child(newtp, req); newtp->fastopen_req = NULL; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 5079832af5c1..b959e8b949b6 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -37,10 +37,11 @@ #define pr_fmt(fmt) "TCP: " fmt #include <net/tcp.h> #include <net/mptcp.h> +#include <net/tcp_authopt.h> #include <linux/compiler.h> #include <linux/gfp.h> #include <linux/module.h> #include <linux/static_key.h> @@ -410,10 +411,11 @@ static inline bool tcp_urg_mode(const struct tcp_sock *tp) #define OPTION_SACK_ADVERTISE BIT(0) #define OPTION_TS BIT(1) #define OPTION_MD5 BIT(2) #define OPTION_WSCALE BIT(3) +#define OPTION_AUTHOPT BIT(4) #define OPTION_FAST_OPEN_COOKIE BIT(8) #define OPTION_SMC BIT(9) #define OPTION_MPTCP BIT(10) static void smc_options_write(__be32 *ptr, u16 *options) @@ -434,16 +436,22 @@ static void smc_options_write(__be32 *ptr, u16 *options) struct tcp_out_options { u16 options; /* bit field of OPTION_* */ u16 mss; /* 0 to disable */ u8 ws; /* window scale, 0 to disable */ u8 num_sack_blocks; /* number of SACK blocks to include */ - u8 hash_size; /* bytes in hash_location */ u8 bpf_opt_len; /* length of BPF hdr option */ +#ifdef CONFIG_TCP_AUTHOPT + u8 authopt_rnextkeyid; /* rnextkey */ +#endif __u8 *hash_location; /* temporary pointer, overloaded */ __u32 tsval, tsecr; /* need to include OPTION_TS */ struct tcp_fastopen_cookie *fastopen_cookie; /* Fast open cookie */ struct mptcp_out_options mptcp; +#ifdef CONFIG_TCP_AUTHOPT + struct tcp_authopt_info *authopt_info; + struct tcp_authopt_key_info *authopt_key; +#endif }; static void mptcp_options_write(__be32 *ptr, const struct tcp_sock *tp, struct tcp_out_options *opts) { @@ -616,10 +624,25 @@ static void tcp_options_write(__be32 *ptr, struct tcp_sock *tp, /* overload cookie hash location */ opts->hash_location = (__u8 *)ptr; ptr += 4; } +#ifdef CONFIG_TCP_AUTHOPT + if (unlikely(OPTION_AUTHOPT & options)) { + struct tcp_authopt_key_info *key = opts->authopt_key; + + WARN_ON(!key); + *ptr = htonl((TCPOPT_AUTHOPT << 24) | + (TCPOLEN_AUTHOPT_OUTPUT << 16) | + (key->send_id << 8) | + opts->authopt_rnextkeyid); + /* overload cookie hash location */ + opts->hash_location = (__u8 *)(ptr + 1); + ptr += TCPOLEN_AUTHOPT_OUTPUT / 4; + } +#endif + if (unlikely(opts->mss)) { *ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | opts->mss); } @@ -751,10 +774,28 @@ static void mptcp_set_option_cond(const struct request_sock *req, } } } } +static int tcp_authopt_init_options(const struct sock *sk, + const struct sock *addr_sk, + struct tcp_out_options *opts) +{ +#ifdef CONFIG_TCP_AUTHOPT + struct tcp_authopt_key_info *key; + + key = tcp_authopt_select_key(sk, addr_sk, &opts->authopt_info, &opts->authopt_rnextkeyid); + if (key) { + opts->options |= OPTION_AUTHOPT; + opts->authopt_key = key; + return TCPOLEN_AUTHOPT_OUTPUT; + } +#endif + + return 0; +} + /* Compute TCP options for SYN packets. This is not the final * network wire format yet. */ static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb, struct tcp_out_options *opts, @@ -763,12 +804,15 @@ static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb, struct tcp_sock *tp = tcp_sk(sk); unsigned int remaining = MAX_TCP_OPTION_SPACE; struct tcp_fastopen_request *fastopen = tp->fastopen_req; *md5 = NULL; + + remaining -= tcp_authopt_init_options(sk, sk, opts); #ifdef CONFIG_TCP_MD5SIG if (static_branch_unlikely(&tcp_md5_needed) && + !(opts->options & OPTION_AUTHOPT) && rcu_access_pointer(tp->md5sig_info)) { *md5 = tp->af_specific->md5_lookup(sk, sk); if (*md5) { opts->options |= OPTION_MD5; remaining -= TCPOLEN_MD5SIG_ALIGNED; @@ -847,12 +891,13 @@ static unsigned int tcp_synack_options(const struct sock *sk, struct sk_buff *syn_skb) { struct inet_request_sock *ireq = inet_rsk(req); unsigned int remaining = MAX_TCP_OPTION_SPACE; + remaining -= tcp_authopt_init_options(sk, req_to_sk(req), opts); #ifdef CONFIG_TCP_MD5SIG - if (md5) { + if (md5 && !(opts->options & OPTION_AUTHOPT)) { opts->options |= OPTION_MD5; remaining -= TCPOLEN_MD5SIG_ALIGNED; /* We can't fit any SACK blocks in a packet with MD5 + TS * options. There was discussion about disabling SACK @@ -918,13 +963,15 @@ static unsigned int tcp_established_options(struct sock *sk, struct sk_buff *skb unsigned int size = 0; unsigned int eff_sacks; opts->options = 0; + size += tcp_authopt_init_options(sk, sk, opts); *md5 = NULL; #ifdef CONFIG_TCP_MD5SIG if (static_branch_unlikely(&tcp_md5_needed) && + !(opts->options & OPTION_AUTHOPT) && rcu_access_pointer(tp->md5sig_info)) { *md5 = tp->af_specific->md5_lookup(sk, sk); if (*md5) { opts->options |= OPTION_MD5; size += TCPOLEN_MD5SIG_ALIGNED; @@ -1274,10 +1321,14 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, inet = inet_sk(sk); tcb = TCP_SKB_CB(skb); memset(&opts, 0, sizeof(opts)); +#ifdef CONFIG_TCP_AUTHOPT + /* for tcp_authopt_init_options inside tcp_syn_options or tcp_established_options */ + rcu_read_lock(); +#endif if (unlikely(tcb->tcp_flags & TCPHDR_SYN)) { tcp_options_size = tcp_syn_options(sk, skb, &opts, &md5); } else { tcp_options_size = tcp_established_options(sk, skb, &opts, &md5); @@ -1362,10 +1413,17 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, sk_gso_disable(sk); tp->af_specific->calc_md5_hash(opts.hash_location, md5, sk, skb); } #endif +#ifdef CONFIG_TCP_AUTHOPT + if (opts.authopt_key) { + sk_gso_disable(sk); + tcp_authopt_hash(opts.hash_location, opts.authopt_key, opts.authopt_info, sk, skb); + } + rcu_read_unlock(); +#endif /* BPF prog is the last one writing header option */ bpf_skops_write_hdr_opt(sk, skb, NULL, NULL, 0, &opts); INDIRECT_CALL_INET(icsk->icsk_af_ops->send_check, @@ -1831,12 +1889,21 @@ unsigned int tcp_current_mss(struct sock *sk) u32 mtu = dst_mtu(dst); if (mtu != inet_csk(sk)->icsk_pmtu_cookie) mss_now = tcp_sync_mss(sk, mtu); } +#ifdef CONFIG_TCP_AUTHOPT + /* Even if the result is not used rcu_read_lock is required when scanning for + * tcp authentication keys. Otherwise lockdep will complain. + */ + rcu_read_lock(); +#endif header_len = tcp_established_options(sk, NULL, &opts, &md5) + sizeof(struct tcphdr); +#ifdef CONFIG_TCP_AUTHOPT + rcu_read_unlock(); +#endif /* The mss_cache is sized based on tp->tcp_header_len, which assumes * some common options. If this is an odd packet (because we have SACK * blocks etc) then our calculated header_len will be different, and * we have to adjust mss_now correspondingly */ if (header_len != tp->tcp_header_len) { @@ -3551,10 +3618,14 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst, } #ifdef CONFIG_TCP_MD5SIG rcu_read_lock(); md5 = tcp_rsk(req)->af_specific->req_md5_lookup(sk, req_to_sk(req)); +#endif +#ifdef CONFIG_TCP_AUTHOPT + /* for tcp_authopt_init_options inside tcp_synack_options */ + rcu_read_lock(); #endif skb_set_hash(skb, tcp_rsk(req)->txhash, PKT_HASH_TYPE_L4); /* bpf program will be interested in the tcp_flags */ TCP_SKB_CB(skb)->tcp_flags = TCPHDR_SYN | TCPHDR_ACK; tcp_header_size = tcp_synack_options(sk, req, mss, skb, &opts, md5, @@ -3588,10 +3659,20 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst, if (md5) tcp_rsk(req)->af_specific->calc_md5_hash(opts.hash_location, md5, req_to_sk(req), skb); rcu_read_unlock(); #endif +#ifdef CONFIG_TCP_AUTHOPT + /* If signature fails we do nothing */ + if (opts.authopt_key) + tcp_authopt_hash(opts.hash_location, + opts.authopt_key, + opts.authopt_info, + req_to_sk(req), + skb); + rcu_read_unlock(); +#endif bpf_skops_write_hdr_opt((struct sock *)sk, skb, req, syn_skb, synack_type, &opts); skb->skb_mstamp_ns = now; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index e98fc6f12c61..3105a367d6b5 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -40,10 +40,11 @@ #include <linux/icmpv6.h> #include <linux/random.h> #include <linux/indirect_call_wrapper.h> #include <net/tcp.h> +#include <net/tcp_authopt.h> #include <net/ndisc.h> #include <net/inet6_hashtables.h> #include <net/inet6_connection_sock.h> #include <net/ipv6.h> #include <net/transp_v6.h> @@ -772,14 +773,14 @@ static int tcp_v6_md5_hash_skb(char *md5_hash, #endif static bool tcp_v6_inbound_md5_hash(const struct sock *sk, const struct sk_buff *skb, - int dif, int sdif) + int dif, int sdif, + const u8 *hash_location) { #ifdef CONFIG_TCP_MD5SIG - const __u8 *hash_location = NULL; struct tcp_md5sig_key *hash_expected; const struct ipv6hdr *ip6h = ipv6_hdr(skb); const struct tcphdr *th = tcp_hdr(skb); int genhash, l3index; u8 newhash[16]; @@ -788,11 +789,10 @@ static bool tcp_v6_inbound_md5_hash(const struct sock *sk, * in an L3 domain and dif is set to the l3mdev */ l3index = sdif ? dif : 0; hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr, l3index); - hash_location = tcp_parse_md5sig_option(th); /* We've parsed the options - do we have a hash? */ if (!hash_expected && !hash_location) return false; @@ -1619,10 +1619,49 @@ static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr, TCP_SKB_CB(skb)->sacked = 0; TCP_SKB_CB(skb)->has_rxtstamp = skb->tstamp || skb_hwtstamps(skb)->hwtstamp; } +static int tcp_v6_sig_check(struct sock *sk, + struct sk_buff *skb, + int dif, + int sdif) +{ + const u8 *md5, *ao; + int ret; + + ret = tcp_parse_sig_options(tcp_hdr(skb), &md5, &ao); + if (ret) + return ret; + ret = tcp_authopt_inbound_check(sk, skb, ao); + if (ret < 0) + return ret; + if (ret == 1) + return 0; + return tcp_v6_inbound_md5_hash(sk, skb, dif, sdif, md5); +} + +static int tcp_v6_sig_check_req(struct request_sock *req, + struct sk_buff *skb, + int dif, + int sdif) +{ + struct sock *lsk = req->rsk_listener; + const u8 *md5, *ao; + int ret; + + ret = tcp_parse_sig_options(tcp_hdr(skb), &md5, &ao); + if (ret) + return ret; + ret = tcp_authopt_inbound_check_req(req, skb, ao); + if (ret < 0) + return ret; + if (ret == 1) + return 0; + return tcp_v6_inbound_md5_hash(lsk, skb, dif, sdif, md5); +} + INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb) { int sdif = inet6_sdif(skb); int dif = inet6_iif(skb); const struct tcphdr *th; @@ -1671,11 +1710,11 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb) struct request_sock *req = inet_reqsk(sk); bool req_stolen = false; struct sock *nsk; sk = req->rsk_listener; - if (tcp_v6_inbound_md5_hash(sk, skb, dif, sdif)) { + if (tcp_v6_sig_check_req(req, skb, dif, sdif)) { sk_drops_add(sk, skb); reqsk_put(req); goto discard_it; } if (tcp_checksum_complete(skb)) { @@ -1738,11 +1777,11 @@ INDIRECT_CALLABLE_SCOPE int tcp_v6_rcv(struct sk_buff *skb) } if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) goto discard_and_relse; - if (tcp_v6_inbound_md5_hash(sk, skb, dif, sdif)) + if (tcp_v6_sig_check(sk, skb, dif, sdif)) goto discard_and_relse; if (tcp_filter(sk, skb)) goto discard_and_relse; th = (const struct tcphdr *)skb->data; -- 2.25.1 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3 06/18] tcp: authopt: Hook into tcp core 2021-12-08 11:37 ` [PATCH v3 06/18] tcp: authopt: Hook into tcp core Leonard Crestez @ 2021-12-08 16:45 ` kernel test robot 2021-12-08 20:39 ` kernel test robot 2021-12-09 12:58 ` kernel test robot 2 siblings, 0 replies; 6+ messages in thread From: kernel test robot @ 2021-12-08 16:45 UTC (permalink / raw) To: kbuild-all [-- Attachment #1: Type: text/plain, Size: 5040 bytes --] Hi Leonard, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on 1fe5b01262844be03de98afdd56d1d393df04d7e] url: https://github.com/0day-ci/linux/commits/Leonard-Crestez/tcp-Initial-support-for-RFC5925-auth-option/20211208-194125 base: 1fe5b01262844be03de98afdd56d1d393df04d7e config: um-i386_defconfig (https://download.01.org/0day-ci/archive/20211209/202112090014.hZOqnSC4-lkp(a)intel.com/config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 reproduce (this is a W=1 build): # https://github.com/0day-ci/linux/commit/5935c41094c73eec0e3c39119d7bfb22de066c3b git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Leonard-Crestez/tcp-Initial-support-for-RFC5925-auth-option/20211208-194125 git checkout 5935c41094c73eec0e3c39119d7bfb22de066c3b # save the config file to linux build tree mkdir build_dir make W=1 O=build_dir ARCH=um SUBARCH=i386 SHELL=/bin/bash net/core/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): In file included from net/core/sock.c:139: include/net/tcp.h: In function 'tcp_parse_sig_options': >> include/net/tcp.h:433:17: warning: parameter 'md5ptr' set but not used [-Wunused-but-set-parameter] 433 | const u8 **md5ptr, | ~~~~~~~~~~~^~~~~~ >> include/net/tcp.h:434:17: warning: parameter 'aoptr' set but not used [-Wunused-but-set-parameter] 434 | const u8 **aoptr) | ~~~~~~~~~~~^~~~~ vim +/md5ptr +433 include/net/tcp.h 381 382 383 enum tcp_tw_status tcp_timewait_state_process(struct inet_timewait_sock *tw, 384 struct sk_buff *skb, 385 const struct tcphdr *th); 386 struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, 387 struct request_sock *req, bool fastopen, 388 bool *lost_race); 389 int tcp_child_process(struct sock *parent, struct sock *child, 390 struct sk_buff *skb); 391 void tcp_enter_loss(struct sock *sk); 392 void tcp_cwnd_reduction(struct sock *sk, int newly_acked_sacked, int newly_lost, int flag); 393 void tcp_clear_retrans(struct tcp_sock *tp); 394 void tcp_update_metrics(struct sock *sk); 395 void tcp_init_metrics(struct sock *sk); 396 void tcp_metrics_init(void); 397 bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst); 398 void __tcp_close(struct sock *sk, long timeout); 399 void tcp_close(struct sock *sk, long timeout); 400 void tcp_init_sock(struct sock *sk); 401 void tcp_init_transfer(struct sock *sk, int bpf_op, struct sk_buff *skb); 402 __poll_t tcp_poll(struct file *file, struct socket *sock, 403 struct poll_table_struct *wait); 404 int tcp_getsockopt(struct sock *sk, int level, int optname, 405 char __user *optval, int __user *optlen); 406 bool tcp_bpf_bypass_getsockopt(int level, int optname); 407 int tcp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, 408 unsigned int optlen); 409 void tcp_set_keepalive(struct sock *sk, int val); 410 void tcp_syn_ack_timeout(const struct request_sock *req); 411 int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, 412 int flags, int *addr_len); 413 int tcp_set_rcvlowat(struct sock *sk, int val); 414 int tcp_set_window_clamp(struct sock *sk, int val); 415 void tcp_update_recv_tstamps(struct sk_buff *skb, 416 struct scm_timestamping_internal *tss); 417 void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk, 418 struct scm_timestamping_internal *tss); 419 void tcp_data_ready(struct sock *sk); 420 #ifdef CONFIG_MMU 421 int tcp_mmap(struct file *file, struct socket *sock, 422 struct vm_area_struct *vma); 423 #endif 424 void tcp_parse_options(const struct net *net, const struct sk_buff *skb, 425 struct tcp_options_received *opt_rx, 426 int estab, struct tcp_fastopen_cookie *foc); 427 #if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AUTHOPT) 428 int tcp_parse_sig_options(const struct tcphdr *th, 429 const u8 **md5ptr, 430 const u8 **aoptr); 431 #else 432 static inline int tcp_parse_sig_options(const struct tcphdr *th, > 433 const u8 **md5ptr, > 434 const u8 **aoptr) 435 { 436 aoptr = NULL; 437 md5ptr = NULL; 438 return 0; 439 } 440 #endif 441 static inline const u8 *tcp_parse_md5sig_option(const struct tcphdr *th) 442 { 443 const u8 *md5, *ao; 444 int ret; 445 446 ret = tcp_parse_sig_options(th, &md5, &ao); 447 448 return (md5 && !ao && !ret) ? md5 : NULL; 449 } 450 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 06/18] tcp: authopt: Hook into tcp core 2021-12-08 11:37 ` [PATCH v3 06/18] tcp: authopt: Hook into tcp core Leonard Crestez @ 2021-12-08 20:39 ` kernel test robot 2021-12-08 20:39 ` kernel test robot 2021-12-09 12:58 ` kernel test robot 2 siblings, 0 replies; 6+ messages in thread From: kernel test robot @ 2021-12-08 20:39 UTC (permalink / raw) To: Leonard Crestez, David Ahern, Dmitry Safonov, Eric Dumazet Cc: llvm, kbuild-all, Francesco Ruggeri, Shuah Khan, Herbert Xu, Kuniyuki Iwashima, Hideaki YOSHIFUJI, Jakub Kicinski, Yuchung Cheng Hi Leonard, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on 1fe5b01262844be03de98afdd56d1d393df04d7e] url: https://github.com/0day-ci/linux/commits/Leonard-Crestez/tcp-Initial-support-for-RFC5925-auth-option/20211208-194125 base: 1fe5b01262844be03de98afdd56d1d393df04d7e config: i386-randconfig-a013-20211207 (https://download.01.org/0day-ci/archive/20211209/202112090452.jW34oJZF-lkp@intel.com/config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 097a1cb1d5ebb3a0ec4bcaed8ba3ff6a8e33c00a) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/5935c41094c73eec0e3c39119d7bfb22de066c3b git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Leonard-Crestez/tcp-Initial-support-for-RFC5925-auth-option/20211208-194125 git checkout 5935c41094c73eec0e3c39119d7bfb22de066c3b # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): In file included from net/bpf/test_run.c:15: >> include/net/tcp.h:433:17: warning: parameter 'md5ptr' set but not used [-Wunused-but-set-parameter] const u8 **md5ptr, ^ >> include/net/tcp.h:434:17: warning: parameter 'aoptr' set but not used [-Wunused-but-set-parameter] const u8 **aoptr) ^ net/bpf/test_run.c:170:14: warning: no previous prototype for function 'bpf_fentry_test1' [-Wmissing-prototypes] int noinline bpf_fentry_test1(int a) ^ net/bpf/test_run.c:170:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_fentry_test1(int a) ^ static net/bpf/test_run.c:175:14: warning: no previous prototype for function 'bpf_fentry_test2' [-Wmissing-prototypes] int noinline bpf_fentry_test2(int a, u64 b) ^ net/bpf/test_run.c:175:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_fentry_test2(int a, u64 b) ^ static net/bpf/test_run.c:180:14: warning: no previous prototype for function 'bpf_fentry_test3' [-Wmissing-prototypes] int noinline bpf_fentry_test3(char a, int b, u64 c) ^ net/bpf/test_run.c:180:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_fentry_test3(char a, int b, u64 c) ^ static net/bpf/test_run.c:185:14: warning: no previous prototype for function 'bpf_fentry_test4' [-Wmissing-prototypes] int noinline bpf_fentry_test4(void *a, char b, int c, u64 d) ^ net/bpf/test_run.c:185:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_fentry_test4(void *a, char b, int c, u64 d) ^ static net/bpf/test_run.c:190:14: warning: no previous prototype for function 'bpf_fentry_test5' [-Wmissing-prototypes] int noinline bpf_fentry_test5(u64 a, void *b, short c, int d, u64 e) ^ net/bpf/test_run.c:190:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_fentry_test5(u64 a, void *b, short c, int d, u64 e) ^ static net/bpf/test_run.c:195:14: warning: no previous prototype for function 'bpf_fentry_test6' [-Wmissing-prototypes] int noinline bpf_fentry_test6(u64 a, void *b, short c, int d, void *e, u64 f) ^ net/bpf/test_run.c:195:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_fentry_test6(u64 a, void *b, short c, int d, void *e, u64 f) ^ static net/bpf/test_run.c:204:14: warning: no previous prototype for function 'bpf_fentry_test7' [-Wmissing-prototypes] int noinline bpf_fentry_test7(struct bpf_fentry_test_t *arg) ^ net/bpf/test_run.c:204:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_fentry_test7(struct bpf_fentry_test_t *arg) ^ static net/bpf/test_run.c:209:14: warning: no previous prototype for function 'bpf_fentry_test8' [-Wmissing-prototypes] int noinline bpf_fentry_test8(struct bpf_fentry_test_t *arg) ^ net/bpf/test_run.c:209:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_fentry_test8(struct bpf_fentry_test_t *arg) ^ static net/bpf/test_run.c:214:14: warning: no previous prototype for function 'bpf_modify_return_test' [-Wmissing-prototypes] int noinline bpf_modify_return_test(int a, int *b) ^ net/bpf/test_run.c:214:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_modify_return_test(int a, int *b) ^ static net/bpf/test_run.c:220:14: warning: no previous prototype for function 'bpf_kfunc_call_test1' [-Wmissing-prototypes] u64 noinline bpf_kfunc_call_test1(struct sock *sk, u32 a, u64 b, u32 c, u64 d) ^ net/bpf/test_run.c:220:1: note: declare 'static' if the function is not intended to be used outside of this translation unit u64 noinline bpf_kfunc_call_test1(struct sock *sk, u32 a, u64 b, u32 c, u64 d) ^ static net/bpf/test_run.c:225:14: warning: no previous prototype for function 'bpf_kfunc_call_test2' [-Wmissing-prototypes] int noinline bpf_kfunc_call_test2(struct sock *sk, u32 a, u32 b) ^ net/bpf/test_run.c:225:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_kfunc_call_test2(struct sock *sk, u32 a, u32 b) ^ static net/bpf/test_run.c:230:24: warning: no previous prototype for function 'bpf_kfunc_call_test3' [-Wmissing-prototypes] struct sock * noinline bpf_kfunc_call_test3(struct sock *sk) ^ net/bpf/test_run.c:230:1: note: declare 'static' if the function is not intended to be used outside of this translation unit struct sock * noinline bpf_kfunc_call_test3(struct sock *sk) ^ static 14 warnings generated. -- In file included from net/core/skmsg.c:4: In file included from include/linux/skmsg.h:13: >> include/net/tcp.h:433:17: warning: parameter 'md5ptr' set but not used [-Wunused-but-set-parameter] const u8 **md5ptr, ^ >> include/net/tcp.h:434:17: warning: parameter 'aoptr' set but not used [-Wunused-but-set-parameter] const u8 **aoptr) ^ 2 warnings generated. -- In file included from net/core/sock_map.c:11: In file included from include/linux/skmsg.h:13: >> include/net/tcp.h:434:17: warning: parameter 'aoptr' set but not used [-Wunused-but-set-parameter] const u8 **aoptr) ^ >> include/net/tcp.h:433:17: warning: parameter 'md5ptr' set but not used [-Wunused-but-set-parameter] const u8 **md5ptr, ^ 2 warnings generated. -- In file included from net/ipv4/route.c:94: >> include/net/tcp.h:433:17: warning: parameter 'md5ptr' set but not used [-Wunused-but-set-parameter] const u8 **md5ptr, ^ >> include/net/tcp.h:434:17: warning: parameter 'aoptr' set but not used [-Wunused-but-set-parameter] const u8 **aoptr) ^ net/ipv4/route.c:869:6: warning: variable 'log_martians' set but not used [-Wunused-but-set-variable] int log_martians; ^ 3 warnings generated. -- In file included from net/ipv4/tcp_output.c:40: >> include/net/tcp.h:434:17: warning: parameter 'aoptr' set but not used [-Wunused-but-set-parameter] const u8 **aoptr) ^ >> include/net/tcp.h:433:17: warning: parameter 'md5ptr' set but not used [-Wunused-but-set-parameter] const u8 **md5ptr, ^ net/ipv4/tcp_output.c:189:3: warning: result of comparison of constant -1 with expression of type 'u8' (aka 'unsigned char') is always false [-Wtautological-constant-out-of-range-compare] NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPACKCOMPRESSED, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/net/ip.h:292:41: note: expanded from macro 'NET_ADD_STATS' #define NET_ADD_STATS(net, field, adnd) SNMP_ADD_STATS((net)->mib.net_statistics, field, adnd) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/net/snmp.h:143:4: note: expanded from macro 'SNMP_ADD_STATS' this_cpu_add(mib->mibs[field], addend) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/percpu-defs.h:509:33: note: expanded from macro 'this_cpu_add' #define this_cpu_add(pcp, val) __pcpu_size_call(this_cpu_add_, pcp, val) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all) <scratch space>:113:1: note: expanded from here this_cpu_add_4 ^ arch/x86/include/asm/percpu.h:268:34: note: expanded from macro 'this_cpu_add_4' #define this_cpu_add_4(pcp, val) percpu_add_op(4, volatile, (pcp), val) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/include/asm/percpu.h:127:31: note: expanded from macro 'percpu_add_op' ((val) == 1 || (val) == -1)) ? \ ~~~~~ ^ ~~ 3 warnings generated. -- In file included from net/mptcp/options.c:11: >> include/net/tcp.h:434:17: warning: parameter 'aoptr' set but not used [-Wunused-but-set-parameter] const u8 **aoptr) ^ >> include/net/tcp.h:433:17: warning: parameter 'md5ptr' set but not used [-Wunused-but-set-parameter] const u8 **md5ptr, ^ net/mptcp/options.c:552:21: warning: parameter 'remaining' set but not used [-Wunused-but-set-parameter] unsigned int remaining, ^ 3 warnings generated. vim +/md5ptr +433 include/net/tcp.h 381 382 383 enum tcp_tw_status tcp_timewait_state_process(struct inet_timewait_sock *tw, 384 struct sk_buff *skb, 385 const struct tcphdr *th); 386 struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, 387 struct request_sock *req, bool fastopen, 388 bool *lost_race); 389 int tcp_child_process(struct sock *parent, struct sock *child, 390 struct sk_buff *skb); 391 void tcp_enter_loss(struct sock *sk); 392 void tcp_cwnd_reduction(struct sock *sk, int newly_acked_sacked, int newly_lost, int flag); 393 void tcp_clear_retrans(struct tcp_sock *tp); 394 void tcp_update_metrics(struct sock *sk); 395 void tcp_init_metrics(struct sock *sk); 396 void tcp_metrics_init(void); 397 bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst); 398 void __tcp_close(struct sock *sk, long timeout); 399 void tcp_close(struct sock *sk, long timeout); 400 void tcp_init_sock(struct sock *sk); 401 void tcp_init_transfer(struct sock *sk, int bpf_op, struct sk_buff *skb); 402 __poll_t tcp_poll(struct file *file, struct socket *sock, 403 struct poll_table_struct *wait); 404 int tcp_getsockopt(struct sock *sk, int level, int optname, 405 char __user *optval, int __user *optlen); 406 bool tcp_bpf_bypass_getsockopt(int level, int optname); 407 int tcp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, 408 unsigned int optlen); 409 void tcp_set_keepalive(struct sock *sk, int val); 410 void tcp_syn_ack_timeout(const struct request_sock *req); 411 int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, 412 int flags, int *addr_len); 413 int tcp_set_rcvlowat(struct sock *sk, int val); 414 int tcp_set_window_clamp(struct sock *sk, int val); 415 void tcp_update_recv_tstamps(struct sk_buff *skb, 416 struct scm_timestamping_internal *tss); 417 void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk, 418 struct scm_timestamping_internal *tss); 419 void tcp_data_ready(struct sock *sk); 420 #ifdef CONFIG_MMU 421 int tcp_mmap(struct file *file, struct socket *sock, 422 struct vm_area_struct *vma); 423 #endif 424 void tcp_parse_options(const struct net *net, const struct sk_buff *skb, 425 struct tcp_options_received *opt_rx, 426 int estab, struct tcp_fastopen_cookie *foc); 427 #if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AUTHOPT) 428 int tcp_parse_sig_options(const struct tcphdr *th, 429 const u8 **md5ptr, 430 const u8 **aoptr); 431 #else 432 static inline int tcp_parse_sig_options(const struct tcphdr *th, > 433 const u8 **md5ptr, > 434 const u8 **aoptr) 435 { 436 aoptr = NULL; 437 md5ptr = NULL; 438 return 0; 439 } 440 #endif 441 static inline const u8 *tcp_parse_md5sig_option(const struct tcphdr *th) 442 { 443 const u8 *md5, *ao; 444 int ret; 445 446 ret = tcp_parse_sig_options(th, &md5, &ao); 447 448 return (md5 && !ao && !ret) ? md5 : NULL; 449 } 450 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 06/18] tcp: authopt: Hook into tcp core @ 2021-12-08 20:39 ` kernel test robot 0 siblings, 0 replies; 6+ messages in thread From: kernel test robot @ 2021-12-08 20:39 UTC (permalink / raw) To: kbuild-all [-- Attachment #1: Type: text/plain, Size: 14824 bytes --] Hi Leonard, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on 1fe5b01262844be03de98afdd56d1d393df04d7e] url: https://github.com/0day-ci/linux/commits/Leonard-Crestez/tcp-Initial-support-for-RFC5925-auth-option/20211208-194125 base: 1fe5b01262844be03de98afdd56d1d393df04d7e config: i386-randconfig-a013-20211207 (https://download.01.org/0day-ci/archive/20211209/202112090452.jW34oJZF-lkp(a)intel.com/config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 097a1cb1d5ebb3a0ec4bcaed8ba3ff6a8e33c00a) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/5935c41094c73eec0e3c39119d7bfb22de066c3b git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Leonard-Crestez/tcp-Initial-support-for-RFC5925-auth-option/20211208-194125 git checkout 5935c41094c73eec0e3c39119d7bfb22de066c3b # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): In file included from net/bpf/test_run.c:15: >> include/net/tcp.h:433:17: warning: parameter 'md5ptr' set but not used [-Wunused-but-set-parameter] const u8 **md5ptr, ^ >> include/net/tcp.h:434:17: warning: parameter 'aoptr' set but not used [-Wunused-but-set-parameter] const u8 **aoptr) ^ net/bpf/test_run.c:170:14: warning: no previous prototype for function 'bpf_fentry_test1' [-Wmissing-prototypes] int noinline bpf_fentry_test1(int a) ^ net/bpf/test_run.c:170:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_fentry_test1(int a) ^ static net/bpf/test_run.c:175:14: warning: no previous prototype for function 'bpf_fentry_test2' [-Wmissing-prototypes] int noinline bpf_fentry_test2(int a, u64 b) ^ net/bpf/test_run.c:175:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_fentry_test2(int a, u64 b) ^ static net/bpf/test_run.c:180:14: warning: no previous prototype for function 'bpf_fentry_test3' [-Wmissing-prototypes] int noinline bpf_fentry_test3(char a, int b, u64 c) ^ net/bpf/test_run.c:180:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_fentry_test3(char a, int b, u64 c) ^ static net/bpf/test_run.c:185:14: warning: no previous prototype for function 'bpf_fentry_test4' [-Wmissing-prototypes] int noinline bpf_fentry_test4(void *a, char b, int c, u64 d) ^ net/bpf/test_run.c:185:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_fentry_test4(void *a, char b, int c, u64 d) ^ static net/bpf/test_run.c:190:14: warning: no previous prototype for function 'bpf_fentry_test5' [-Wmissing-prototypes] int noinline bpf_fentry_test5(u64 a, void *b, short c, int d, u64 e) ^ net/bpf/test_run.c:190:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_fentry_test5(u64 a, void *b, short c, int d, u64 e) ^ static net/bpf/test_run.c:195:14: warning: no previous prototype for function 'bpf_fentry_test6' [-Wmissing-prototypes] int noinline bpf_fentry_test6(u64 a, void *b, short c, int d, void *e, u64 f) ^ net/bpf/test_run.c:195:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_fentry_test6(u64 a, void *b, short c, int d, void *e, u64 f) ^ static net/bpf/test_run.c:204:14: warning: no previous prototype for function 'bpf_fentry_test7' [-Wmissing-prototypes] int noinline bpf_fentry_test7(struct bpf_fentry_test_t *arg) ^ net/bpf/test_run.c:204:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_fentry_test7(struct bpf_fentry_test_t *arg) ^ static net/bpf/test_run.c:209:14: warning: no previous prototype for function 'bpf_fentry_test8' [-Wmissing-prototypes] int noinline bpf_fentry_test8(struct bpf_fentry_test_t *arg) ^ net/bpf/test_run.c:209:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_fentry_test8(struct bpf_fentry_test_t *arg) ^ static net/bpf/test_run.c:214:14: warning: no previous prototype for function 'bpf_modify_return_test' [-Wmissing-prototypes] int noinline bpf_modify_return_test(int a, int *b) ^ net/bpf/test_run.c:214:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_modify_return_test(int a, int *b) ^ static net/bpf/test_run.c:220:14: warning: no previous prototype for function 'bpf_kfunc_call_test1' [-Wmissing-prototypes] u64 noinline bpf_kfunc_call_test1(struct sock *sk, u32 a, u64 b, u32 c, u64 d) ^ net/bpf/test_run.c:220:1: note: declare 'static' if the function is not intended to be used outside of this translation unit u64 noinline bpf_kfunc_call_test1(struct sock *sk, u32 a, u64 b, u32 c, u64 d) ^ static net/bpf/test_run.c:225:14: warning: no previous prototype for function 'bpf_kfunc_call_test2' [-Wmissing-prototypes] int noinline bpf_kfunc_call_test2(struct sock *sk, u32 a, u32 b) ^ net/bpf/test_run.c:225:1: note: declare 'static' if the function is not intended to be used outside of this translation unit int noinline bpf_kfunc_call_test2(struct sock *sk, u32 a, u32 b) ^ static net/bpf/test_run.c:230:24: warning: no previous prototype for function 'bpf_kfunc_call_test3' [-Wmissing-prototypes] struct sock * noinline bpf_kfunc_call_test3(struct sock *sk) ^ net/bpf/test_run.c:230:1: note: declare 'static' if the function is not intended to be used outside of this translation unit struct sock * noinline bpf_kfunc_call_test3(struct sock *sk) ^ static 14 warnings generated. -- In file included from net/core/skmsg.c:4: In file included from include/linux/skmsg.h:13: >> include/net/tcp.h:433:17: warning: parameter 'md5ptr' set but not used [-Wunused-but-set-parameter] const u8 **md5ptr, ^ >> include/net/tcp.h:434:17: warning: parameter 'aoptr' set but not used [-Wunused-but-set-parameter] const u8 **aoptr) ^ 2 warnings generated. -- In file included from net/core/sock_map.c:11: In file included from include/linux/skmsg.h:13: >> include/net/tcp.h:434:17: warning: parameter 'aoptr' set but not used [-Wunused-but-set-parameter] const u8 **aoptr) ^ >> include/net/tcp.h:433:17: warning: parameter 'md5ptr' set but not used [-Wunused-but-set-parameter] const u8 **md5ptr, ^ 2 warnings generated. -- In file included from net/ipv4/route.c:94: >> include/net/tcp.h:433:17: warning: parameter 'md5ptr' set but not used [-Wunused-but-set-parameter] const u8 **md5ptr, ^ >> include/net/tcp.h:434:17: warning: parameter 'aoptr' set but not used [-Wunused-but-set-parameter] const u8 **aoptr) ^ net/ipv4/route.c:869:6: warning: variable 'log_martians' set but not used [-Wunused-but-set-variable] int log_martians; ^ 3 warnings generated. -- In file included from net/ipv4/tcp_output.c:40: >> include/net/tcp.h:434:17: warning: parameter 'aoptr' set but not used [-Wunused-but-set-parameter] const u8 **aoptr) ^ >> include/net/tcp.h:433:17: warning: parameter 'md5ptr' set but not used [-Wunused-but-set-parameter] const u8 **md5ptr, ^ net/ipv4/tcp_output.c:189:3: warning: result of comparison of constant -1 with expression of type 'u8' (aka 'unsigned char') is always false [-Wtautological-constant-out-of-range-compare] NET_ADD_STATS(sock_net(sk), LINUX_MIB_TCPACKCOMPRESSED, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/net/ip.h:292:41: note: expanded from macro 'NET_ADD_STATS' #define NET_ADD_STATS(net, field, adnd) SNMP_ADD_STATS((net)->mib.net_statistics, field, adnd) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/net/snmp.h:143:4: note: expanded from macro 'SNMP_ADD_STATS' this_cpu_add(mib->mibs[field], addend) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/percpu-defs.h:509:33: note: expanded from macro 'this_cpu_add' #define this_cpu_add(pcp, val) __pcpu_size_call(this_cpu_add_, pcp, val) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ note: (skipping 1 expansions in backtrace; use -fmacro-backtrace-limit=0 to see all) <scratch space>:113:1: note: expanded from here this_cpu_add_4 ^ arch/x86/include/asm/percpu.h:268:34: note: expanded from macro 'this_cpu_add_4' #define this_cpu_add_4(pcp, val) percpu_add_op(4, volatile, (pcp), val) ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ arch/x86/include/asm/percpu.h:127:31: note: expanded from macro 'percpu_add_op' ((val) == 1 || (val) == -1)) ? \ ~~~~~ ^ ~~ 3 warnings generated. -- In file included from net/mptcp/options.c:11: >> include/net/tcp.h:434:17: warning: parameter 'aoptr' set but not used [-Wunused-but-set-parameter] const u8 **aoptr) ^ >> include/net/tcp.h:433:17: warning: parameter 'md5ptr' set but not used [-Wunused-but-set-parameter] const u8 **md5ptr, ^ net/mptcp/options.c:552:21: warning: parameter 'remaining' set but not used [-Wunused-but-set-parameter] unsigned int remaining, ^ 3 warnings generated. vim +/md5ptr +433 include/net/tcp.h 381 382 383 enum tcp_tw_status tcp_timewait_state_process(struct inet_timewait_sock *tw, 384 struct sk_buff *skb, 385 const struct tcphdr *th); 386 struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, 387 struct request_sock *req, bool fastopen, 388 bool *lost_race); 389 int tcp_child_process(struct sock *parent, struct sock *child, 390 struct sk_buff *skb); 391 void tcp_enter_loss(struct sock *sk); 392 void tcp_cwnd_reduction(struct sock *sk, int newly_acked_sacked, int newly_lost, int flag); 393 void tcp_clear_retrans(struct tcp_sock *tp); 394 void tcp_update_metrics(struct sock *sk); 395 void tcp_init_metrics(struct sock *sk); 396 void tcp_metrics_init(void); 397 bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst); 398 void __tcp_close(struct sock *sk, long timeout); 399 void tcp_close(struct sock *sk, long timeout); 400 void tcp_init_sock(struct sock *sk); 401 void tcp_init_transfer(struct sock *sk, int bpf_op, struct sk_buff *skb); 402 __poll_t tcp_poll(struct file *file, struct socket *sock, 403 struct poll_table_struct *wait); 404 int tcp_getsockopt(struct sock *sk, int level, int optname, 405 char __user *optval, int __user *optlen); 406 bool tcp_bpf_bypass_getsockopt(int level, int optname); 407 int tcp_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, 408 unsigned int optlen); 409 void tcp_set_keepalive(struct sock *sk, int val); 410 void tcp_syn_ack_timeout(const struct request_sock *req); 411 int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, 412 int flags, int *addr_len); 413 int tcp_set_rcvlowat(struct sock *sk, int val); 414 int tcp_set_window_clamp(struct sock *sk, int val); 415 void tcp_update_recv_tstamps(struct sk_buff *skb, 416 struct scm_timestamping_internal *tss); 417 void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk, 418 struct scm_timestamping_internal *tss); 419 void tcp_data_ready(struct sock *sk); 420 #ifdef CONFIG_MMU 421 int tcp_mmap(struct file *file, struct socket *sock, 422 struct vm_area_struct *vma); 423 #endif 424 void tcp_parse_options(const struct net *net, const struct sk_buff *skb, 425 struct tcp_options_received *opt_rx, 426 int estab, struct tcp_fastopen_cookie *foc); 427 #if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AUTHOPT) 428 int tcp_parse_sig_options(const struct tcphdr *th, 429 const u8 **md5ptr, 430 const u8 **aoptr); 431 #else 432 static inline int tcp_parse_sig_options(const struct tcphdr *th, > 433 const u8 **md5ptr, > 434 const u8 **aoptr) 435 { 436 aoptr = NULL; 437 md5ptr = NULL; 438 return 0; 439 } 440 #endif 441 static inline const u8 *tcp_parse_md5sig_option(const struct tcphdr *th) 442 { 443 const u8 *md5, *ao; 444 int ret; 445 446 ret = tcp_parse_sig_options(th, &md5, &ao); 447 448 return (md5 && !ao && !ret) ? md5 : NULL; 449 } 450 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 06/18] tcp: authopt: Hook into tcp core 2021-12-08 11:37 ` [PATCH v3 06/18] tcp: authopt: Hook into tcp core Leonard Crestez 2021-12-08 16:45 ` kernel test robot 2021-12-08 20:39 ` kernel test robot @ 2021-12-09 12:58 ` kernel test robot 2 siblings, 0 replies; 6+ messages in thread From: kernel test robot @ 2021-12-09 12:58 UTC (permalink / raw) To: kbuild-all [-- Attachment #1: Type: text/plain, Size: 7821 bytes --] Hi Leonard, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on 1fe5b01262844be03de98afdd56d1d393df04d7e] url: https://github.com/0day-ci/linux/commits/Leonard-Crestez/tcp-Initial-support-for-RFC5925-auth-option/20211208-194125 base: 1fe5b01262844be03de98afdd56d1d393df04d7e config: m68k-randconfig-s031-20211209 (https://download.01.org/0day-ci/archive/20211209/202112092027.W9QemnAk-lkp(a)intel.com/config) compiler: m68k-linux-gcc (GCC) 11.2.0 reproduce: wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # apt-get install sparse # sparse version: v0.6.4-dirty # https://github.com/0day-ci/linux/commit/5935c41094c73eec0e3c39119d7bfb22de066c3b git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Leonard-Crestez/tcp-Initial-support-for-RFC5925-auth-option/20211208-194125 git checkout 5935c41094c73eec0e3c39119d7bfb22de066c3b # save the config file to linux build tree mkdir build_dir COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=m68k SHELL=/bin/bash net/ipv4/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> sparse warnings: (new ones prefixed by >>) net/ipv4/tcp_minisocks.c: note: in included file: >> include/net/tcp_authopt.h:145:40: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected struct tcp_authopt_info *tw_authopt_info @@ got struct tcp_authopt_info [noderef] __rcu *authopt_info @@ include/net/tcp_authopt.h:145:40: sparse: expected struct tcp_authopt_info *tw_authopt_info include/net/tcp_authopt.h:145:40: sparse: got struct tcp_authopt_info [noderef] __rcu *authopt_info vim +145 include/net/tcp_authopt.h 81 82 void tcp_authopt_free(struct sock *sk, struct tcp_authopt_info *info); 83 void tcp_authopt_clear(struct sock *sk); 84 int tcp_set_authopt(struct sock *sk, sockptr_t optval, unsigned int optlen); 85 int tcp_get_authopt_val(struct sock *sk, struct tcp_authopt *key); 86 int tcp_set_authopt_key(struct sock *sk, sockptr_t optval, unsigned int optlen); 87 struct tcp_authopt_key_info *__tcp_authopt_select_key( 88 const struct sock *sk, 89 struct tcp_authopt_info *info, 90 const struct sock *addr_sk, 91 u8 *rnextkeyid); 92 static inline struct tcp_authopt_key_info *tcp_authopt_select_key( 93 const struct sock *sk, 94 const struct sock *addr_sk, 95 struct tcp_authopt_info **info, 96 u8 *rnextkeyid) 97 { 98 if (tcp_authopt_needed) { 99 *info = rcu_dereference(tcp_sk(sk)->authopt_info); 100 101 if (*info) 102 return __tcp_authopt_select_key(sk, *info, addr_sk, rnextkeyid); 103 } 104 return NULL; 105 } 106 int tcp_authopt_hash( 107 char *hash_location, 108 struct tcp_authopt_key_info *key, 109 struct tcp_authopt_info *info, 110 struct sock *sk, struct sk_buff *skb); 111 int __tcp_authopt_openreq(struct sock *newsk, const struct sock *oldsk, struct request_sock *req); 112 static inline int tcp_authopt_openreq( 113 struct sock *newsk, 114 const struct sock *oldsk, 115 struct request_sock *req) 116 { 117 if (!rcu_dereference(tcp_sk(oldsk)->authopt_info)) 118 return 0; 119 else 120 return __tcp_authopt_openreq(newsk, oldsk, req); 121 } 122 void __tcp_authopt_finish_connect(struct sock *sk, struct sk_buff *skb, 123 struct tcp_authopt_info *info); 124 static inline void tcp_authopt_finish_connect(struct sock *sk, struct sk_buff *skb) 125 { 126 struct tcp_authopt_info *info; 127 128 if (tcp_authopt_needed) { 129 info = rcu_dereference_protected(tcp_sk(sk)->authopt_info, 130 lockdep_sock_is_held(sk)); 131 132 if (info) 133 __tcp_authopt_finish_connect(sk, skb, info); 134 } 135 } 136 static inline void tcp_authopt_time_wait( 137 struct tcp_timewait_sock *tcptw, 138 struct tcp_sock *tp) 139 { 140 if (tcp_authopt_needed) { 141 /* Transfer ownership of authopt_info to the twsk 142 * This requires no other users of the origin sock. 143 */ 144 sock_owned_by_me((struct sock *)tp); > 145 tcptw->tw_authopt_info = tp->authopt_info; 146 tp->authopt_info = NULL; 147 } else { 148 tcptw->tw_authopt_info = NULL; 149 } 150 } 151 /** tcp_authopt_inbound_check - check for valid TCP-AO signature. 152 * 153 * Return negative ERRNO on error, 0 if not present and 1 if present and valid. 154 * 155 * If the AO signature is present and valid then caller skips MD5 check. 156 */ 157 int __tcp_authopt_inbound_check( 158 struct sock *sk, 159 struct sk_buff *skb, 160 struct tcp_authopt_info *info, 161 const u8 *opt); 162 static inline int tcp_authopt_inbound_check(struct sock *sk, struct sk_buff *skb, const u8 *opt) 163 { 164 if (tcp_authopt_needed) { 165 struct tcp_authopt_info *info = rcu_dereference(tcp_sk(sk)->authopt_info); 166 167 if (info) 168 return __tcp_authopt_inbound_check(sk, skb, info, opt); 169 } 170 return 0; 171 } 172 static inline int tcp_authopt_inbound_check_req(struct request_sock *req, struct sk_buff *skb, 173 const u8 *opt) 174 { 175 if (tcp_authopt_needed) { 176 struct sock *lsk = req->rsk_listener; 177 struct tcp_authopt_info *info = rcu_dereference(tcp_sk(lsk)->authopt_info); 178 179 if (info) 180 return __tcp_authopt_inbound_check((struct sock *)req, skb, info, opt); 181 } 182 return 0; 183 } 184 #else 185 static inline int tcp_set_authopt(struct sock *sk, sockptr_t optval, unsigned int optlen) 186 { 187 return -ENOPROTOOPT; 188 } 189 static inline int tcp_get_authopt_val(struct sock *sk, struct tcp_authopt *key) 190 { 191 return -ENOPROTOOPT; 192 } 193 static inline void tcp_authopt_free(struct sock *sk, struct tcp_authopt_info *info) 194 { 195 } 196 static inline void tcp_authopt_clear(struct sock *sk) 197 { 198 } 199 static inline int tcp_set_authopt_key(struct sock *sk, sockptr_t optval, unsigned int optlen) 200 { 201 return -ENOPROTOOPT; 202 } 203 static inline int tcp_authopt_hash( 204 char *hash_location, 205 struct tcp_authopt_key_info *key, 206 struct tcp_authopt_key *info, 207 struct sock *sk, struct sk_buff *skb) 208 { 209 return -EINVAL; 210 } 211 static inline int tcp_authopt_openreq(struct sock *newsk, 212 const struct sock *oldsk, 213 struct request_sock *req) 214 { 215 return 0; 216 } 217 static inline void tcp_authopt_finish_connect(struct sock *sk, struct sk_buff *skb) 218 { 219 } 220 static inline void tcp_authopt_time_wait( 221 struct tcp_timewait_sock *tcptw, 222 struct tcp_sock *tp) 223 { 224 } 225 static inline int tcp_authopt_inbound_check(struct sock *sk, struct sk_buff *skb, const u8 *opt) 226 { 227 return 0; 228 } 229 static inline int tcp_authopt_inbound_check_req(struct request_sock *sk, struct sk_buff *skb, 230 const u8 *opt) 231 { 232 return 0; 233 } 234 #endif 235 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2021-12-09 12:58 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-12-08 21:09 [PATCH v3 06/18] tcp: authopt: Hook into tcp core kernel test robot -- strict thread matches above, loose matches on Subject: below -- 2021-12-08 11:37 [PATCH v3 00/18] tcp: Initial support for RFC5925 auth option Leonard Crestez 2021-12-08 11:37 ` [PATCH v3 06/18] tcp: authopt: Hook into tcp core Leonard Crestez 2021-12-08 16:45 ` kernel test robot 2021-12-08 20:39 ` kernel test robot 2021-12-08 20:39 ` kernel test robot 2021-12-09 12:58 ` kernel test robot
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.