Message ID | b0abf2b789220708011a862a892c37b0fd76dc25.1632240523.git.cdleonard@gmail.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | tcp: Initial support for RFC5925 auth option | expand |
Context | Check | Description |
---|---|---|
netdev/cover_letter | success | Link |
netdev/fixes_present | success | Link |
netdev/patch_count | fail | Series longer than 15 patches |
netdev/tree_selection | success | Guessed tree name to be net-next |
netdev/subject_prefix | success | Link |
netdev/cc_maintainers | warning | 2 maintainers not CCed: corbet@lwn.net linux-doc@vger.kernel.org |
netdev/source_inline | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Link |
netdev/module_param | success | Was 0 now: 0 |
netdev/build_32bit | success | Errors and warnings before: 37 this patch: 37 |
netdev/kdoc | success | Errors and warnings before: 27 this patch: 27 |
netdev/verify_fixes | success | Link |
netdev/checkpatch | warning | WARNING: line length of 81 exceeds 80 columns |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 37 this patch: 37 |
netdev/header_inline | success | Link |
On 9/21/21 10:14 AM, Leonard Crestez wrote: > This is mainly intended to protect against local privilege escalations > through a rarely used feature so it is deliberately not namespaced. > > Enforcement is only at the setsockopt level, this should be enough to > ensure that the tcp_authopt_needed static key never turns on. > > No effort is made to handle disabling when the feature is already in > use. > MD5 does not require a sysctl to use it, so why should this auth mechanism?
On 9/25/21 4:57 AM, David Ahern wrote: > On 9/21/21 10:14 AM, Leonard Crestez wrote: >> This is mainly intended to protect against local privilege escalations >> through a rarely used feature so it is deliberately not namespaced. >> >> Enforcement is only at the setsockopt level, this should be enough to >> ensure that the tcp_authopt_needed static key never turns on. >> >> No effort is made to handle disabling when the feature is already in >> use. >> > > MD5 does not require a sysctl to use it, so why should this auth mechanism? I think it would make sense for both these features to be off by default. They interact with TCP in complex ways and are available to all unprivileged users but their real usecases are actually very limited. Having to flip a few sysctls is very reasonable in the context of setting up a router. My concern is that this feature ends up in distro kernels and somebody finds a way to use it for privilege escalation. It also seems reasonable for "experimental" features to be off by default. -- Regards, Leonard
diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst index d91ab28718d4..16e34268ecb4 100644 --- a/Documentation/networking/ip-sysctl.rst +++ b/Documentation/networking/ip-sysctl.rst @@ -995,10 +995,16 @@ tcp_rx_skb_cache - BOOLEAN on systems with a lot of TCP sockets, since it increases memory usage. Default: 0 (disabled) +tcp_authopt - BOOLEAN + Enable the TCP Authentication Option (RFC5925), a replacement for TCP + MD5 Signatures (RFC2835). + + Default: 0 + UDP variables ============= udp_l3mdev_accept - BOOLEAN Enabling this option allows a "global" bound socket to work diff --git a/include/net/tcp_authopt.h b/include/net/tcp_authopt.h index 263f98c3a1a8..422f0034d32b 100644 --- a/include/net/tcp_authopt.h +++ b/include/net/tcp_authopt.h @@ -51,10 +51,11 @@ struct tcp_authopt_info { u32 src_isn; u32 dst_isn; }; #ifdef CONFIG_TCP_AUTHOPT +extern int sysctl_tcp_authopt; DECLARE_STATIC_KEY_FALSE(tcp_authopt_needed); 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); diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 4680268f2e59..365466fbca8b 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -17,10 +17,11 @@ #include <net/udp.h> #include <net/cipso_ipv4.h> #include <net/ping.h> #include <net/protocol.h> #include <net/netevent.h> +#include <net/tcp_authopt.h> static int two = 2; static int three __maybe_unused = 3; static int four = 4; static int thousand = 1000; @@ -595,10 +596,19 @@ static struct ctl_table ipv4_table[] = { .procname = "tcp_tx_skb_cache", .data = &tcp_tx_skb_cache_key.key, .mode = 0644, .proc_handler = proc_do_static_key, }, +#ifdef CONFIG_TCP_AUTHOPT + { + .procname = "tcp_authopt", + .data = &sysctl_tcp_authopt, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, +#endif { } }; static struct ctl_table ipv4_net_table[] = { { diff --git a/net/ipv4/tcp_authopt.c b/net/ipv4/tcp_authopt.c index 0c32b8fb1d41..41f844d5d49a 100644 --- a/net/ipv4/tcp_authopt.c +++ b/net/ipv4/tcp_authopt.c @@ -3,10 +3,15 @@ #include <linux/kernel.h> #include <net/tcp.h> #include <net/tcp_authopt.h> #include <crypto/hash.h> +/* This is mainly intended to protect against local privilege escalations through + * a rarely used feature so it is deliberately not namespaced. + */ +int sysctl_tcp_authopt; + /* This is enabled when first struct tcp_authopt_info is allocated and never released */ DEFINE_STATIC_KEY_FALSE(tcp_authopt_needed); /* only for CONFIG_IPV6=m */ EXPORT_SYMBOL(tcp_authopt_needed); @@ -361,10 +366,12 @@ int tcp_set_authopt(struct sock *sk, sockptr_t optval, unsigned int optlen) struct tcp_authopt opt; struct tcp_authopt_info *info; int err; sock_owned_by_me(sk); + if (!sysctl_tcp_authopt) + return -EPERM; err = _copy_from_sockptr_tolerant((u8*)&opt, sizeof(opt), optval, optlen); if (err) return err; @@ -384,10 +391,12 @@ int tcp_get_authopt_val(struct sock *sk, struct tcp_authopt *opt) { struct tcp_sock *tp = tcp_sk(sk); struct tcp_authopt_info *info; sock_owned_by_me(sk); + if (!sysctl_tcp_authopt) + return -EPERM; memset(opt, 0, sizeof(*opt)); info = rcu_dereference_check(tp->authopt_info, lockdep_sock_is_held(sk)); if (!info) return -ENOENT; @@ -452,10 +461,12 @@ int tcp_set_authopt_key(struct sock *sk, sockptr_t optval, unsigned int optlen) struct tcp_authopt_key_info *key_info, *old_key_info; struct tcp_authopt_alg_imp *alg; int err; sock_owned_by_me(sk); + if (!sysctl_tcp_authopt) + return -EPERM; err = _copy_from_sockptr_tolerant((u8*)&opt, sizeof(opt), optval, optlen); if (err) return err;
This is mainly intended to protect against local privilege escalations through a rarely used feature so it is deliberately not namespaced. Enforcement is only at the setsockopt level, this should be enough to ensure that the tcp_authopt_needed static key never turns on. No effort is made to handle disabling when the feature is already in use. Signed-off-by: Leonard Crestez <cdleonard@gmail.com> --- Documentation/networking/ip-sysctl.rst | 6 ++++++ include/net/tcp_authopt.h | 1 + net/ipv4/sysctl_net_ipv4.c | 10 ++++++++++ net/ipv4/tcp_authopt.c | 11 +++++++++++ 4 files changed, 28 insertions(+)