From: Greg Kroah-Hartman Date: Thu, 31 Aug 2023 10:59:10 +0000 (+0200) Subject: 6.5-stable patches X-Git-Tag: v6.5.1~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bde6b238ab550465cc36568e64b1b97926658a6e;p=thirdparty%2Fkernel%2Fstable-queue.git 6.5-stable patches added patches: ipv6-remove-hard-coded-limitation-on-ipv6_pinfo.patch lockdep-fix-static-memory-detection-even-more.patch --- diff --git a/queue-6.5/ipv6-remove-hard-coded-limitation-on-ipv6_pinfo.patch b/queue-6.5/ipv6-remove-hard-coded-limitation-on-ipv6_pinfo.patch new file mode 100644 index 00000000000..985458b7fea --- /dev/null +++ b/queue-6.5/ipv6-remove-hard-coded-limitation-on-ipv6_pinfo.patch @@ -0,0 +1,231 @@ +From f5f80e32de12fad2813d37270e8364a03e6d3ef0 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 20 Jul 2023 11:09:01 +0000 +Subject: ipv6: remove hard coded limitation on ipv6_pinfo + +From: Eric Dumazet + +commit f5f80e32de12fad2813d37270e8364a03e6d3ef0 upstream. + +IPv6 inet sockets are supposed to have a "struct ipv6_pinfo" +field at the end of their definition, so that inet6_sk_generic() +can derive from socket size the offset of the "struct ipv6_pinfo". + +This is very fragile, and prevents adding bigger alignment +in sockets, because inet6_sk_generic() does not work +if the compiler adds padding after the ipv6_pinfo component. + +We are currently working on a patch series to reorganize +TCP structures for better data locality and found issues +similar to the one fixed in commit f5d547676ca0 +("tcp: fix tcp_inet6_sk() for 32bit kernels") + +Alternative would be to force an alignment on "struct ipv6_pinfo", +greater or equal to __alignof__(any ipv6 sock) to ensure there is +no padding. This does not look great. + +v2: fix typo in mptcp_proto_v6_init() (Paolo) + +Signed-off-by: Eric Dumazet +Cc: Chao Wu +Cc: Wei Wang +Cc: Coco Li +Cc: YiFei Zhu +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Cc: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/ipv6.h | 15 ++++----------- + include/net/sock.h | 1 + + net/dccp/ipv6.c | 1 + + net/dccp/ipv6.h | 4 ---- + net/ipv6/af_inet6.c | 4 ++-- + net/ipv6/ping.c | 1 + + net/ipv6/raw.c | 1 + + net/ipv6/tcp_ipv6.c | 1 + + net/ipv6/udp.c | 1 + + net/ipv6/udplite.c | 1 + + net/l2tp/l2tp_ip6.c | 4 +--- + net/mptcp/protocol.c | 1 + + net/sctp/socket.c | 1 + + 13 files changed, 16 insertions(+), 20 deletions(-) + +--- a/include/linux/ipv6.h ++++ b/include/linux/ipv6.h +@@ -199,14 +199,7 @@ struct inet6_cork { + u8 tclass; + }; + +-/** +- * struct ipv6_pinfo - ipv6 private area +- * +- * In the struct sock hierarchy (tcp6_sock, upd6_sock, etc) +- * this _must_ be the last member, so that inet6_sk_generic +- * is able to calculate its offset from the base struct sock +- * by using the struct proto->slab_obj_size member. -acme +- */ ++/* struct ipv6_pinfo - ipv6 private area */ + struct ipv6_pinfo { + struct in6_addr saddr; + struct in6_pktinfo sticky_pktinfo; +@@ -306,19 +299,19 @@ struct raw6_sock { + __u32 offset; /* checksum offset */ + struct icmp6_filter filter; + __u32 ip6mr_table; +- /* ipv6_pinfo has to be the last member of raw6_sock, see inet6_sk_generic */ ++ + struct ipv6_pinfo inet6; + }; + + struct udp6_sock { + struct udp_sock udp; +- /* ipv6_pinfo has to be the last member of udp6_sock, see inet6_sk_generic */ ++ + struct ipv6_pinfo inet6; + }; + + struct tcp6_sock { + struct tcp_sock tcp; +- /* ipv6_pinfo has to be the last member of tcp6_sock, see inet6_sk_generic */ ++ + struct ipv6_pinfo inet6; + }; + +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -1340,6 +1340,7 @@ struct proto { + + struct kmem_cache *slab; + unsigned int obj_size; ++ unsigned int ipv6_pinfo_offset; + slab_flags_t slab_flags; + unsigned int useroffset; /* Usercopy region offset */ + unsigned int usersize; /* Usercopy region size */ +--- a/net/dccp/ipv6.c ++++ b/net/dccp/ipv6.c +@@ -1056,6 +1056,7 @@ static struct proto dccp_v6_prot = { + .orphan_count = &dccp_orphan_count, + .max_header = MAX_DCCP_HEADER, + .obj_size = sizeof(struct dccp6_sock), ++ .ipv6_pinfo_offset = offsetof(struct dccp6_sock, inet6), + .slab_flags = SLAB_TYPESAFE_BY_RCU, + .rsk_prot = &dccp6_request_sock_ops, + .twsk_prot = &dccp6_timewait_sock_ops, +--- a/net/dccp/ipv6.h ++++ b/net/dccp/ipv6.h +@@ -13,10 +13,6 @@ + + struct dccp6_sock { + struct dccp_sock dccp; +- /* +- * ipv6_pinfo has to be the last member of dccp6_sock, +- * see inet6_sk_generic. +- */ + struct ipv6_pinfo inet6; + }; + +--- a/net/ipv6/af_inet6.c ++++ b/net/ipv6/af_inet6.c +@@ -102,9 +102,9 @@ bool ipv6_mod_enabled(void) + } + EXPORT_SYMBOL_GPL(ipv6_mod_enabled); + +-static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk) ++static struct ipv6_pinfo *inet6_sk_generic(struct sock *sk) + { +- const int offset = sk->sk_prot->obj_size - sizeof(struct ipv6_pinfo); ++ const int offset = sk->sk_prot->ipv6_pinfo_offset; + + return (struct ipv6_pinfo *)(((u8 *)sk) + offset); + } +--- a/net/ipv6/ping.c ++++ b/net/ipv6/ping.c +@@ -215,6 +215,7 @@ struct proto pingv6_prot = { + .get_port = ping_get_port, + .put_port = ping_unhash, + .obj_size = sizeof(struct raw6_sock), ++ .ipv6_pinfo_offset = offsetof(struct raw6_sock, inet6), + }; + EXPORT_SYMBOL_GPL(pingv6_prot); + +--- a/net/ipv6/raw.c ++++ b/net/ipv6/raw.c +@@ -1216,6 +1216,7 @@ struct proto rawv6_prot = { + .hash = raw_hash_sk, + .unhash = raw_unhash_sk, + .obj_size = sizeof(struct raw6_sock), ++ .ipv6_pinfo_offset = offsetof(struct raw6_sock, inet6), + .useroffset = offsetof(struct raw6_sock, filter), + .usersize = sizeof_field(struct raw6_sock, filter), + .h.raw_hash = &raw_v6_hashinfo, +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -2176,6 +2176,7 @@ struct proto tcpv6_prot = { + .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_tcp_rmem), + .max_header = MAX_TCP_HEADER, + .obj_size = sizeof(struct tcp6_sock), ++ .ipv6_pinfo_offset = offsetof(struct tcp6_sock, inet6), + .slab_flags = SLAB_TYPESAFE_BY_RCU, + .twsk_prot = &tcp6_timewait_sock_ops, + .rsk_prot = &tcp6_request_sock_ops, +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -1802,6 +1802,7 @@ struct proto udpv6_prot = { + .sysctl_wmem_offset = offsetof(struct net, ipv4.sysctl_udp_wmem_min), + .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_udp_rmem_min), + .obj_size = sizeof(struct udp6_sock), ++ .ipv6_pinfo_offset = offsetof(struct udp6_sock, inet6), + .h.udp_table = NULL, + .diag_destroy = udp_abort, + }; +--- a/net/ipv6/udplite.c ++++ b/net/ipv6/udplite.c +@@ -67,6 +67,7 @@ struct proto udplitev6_prot = { + .sysctl_wmem_offset = offsetof(struct net, ipv4.sysctl_udp_wmem_min), + .sysctl_rmem_offset = offsetof(struct net, ipv4.sysctl_udp_rmem_min), + .obj_size = sizeof(struct udp6_sock), ++ .ipv6_pinfo_offset = offsetof(struct udp6_sock, inet6), + .h.udp_table = &udplite_table, + }; + +--- a/net/l2tp/l2tp_ip6.c ++++ b/net/l2tp/l2tp_ip6.c +@@ -36,9 +36,6 @@ struct l2tp_ip6_sock { + u32 conn_id; + u32 peer_conn_id; + +- /* ipv6_pinfo has to be the last member of l2tp_ip6_sock, see +- * inet6_sk_generic +- */ + struct ipv6_pinfo inet6; + }; + +@@ -730,6 +727,7 @@ static struct proto l2tp_ip6_prot = { + .hash = l2tp_ip6_hash, + .unhash = l2tp_ip6_unhash, + .obj_size = sizeof(struct l2tp_ip6_sock), ++ .ipv6_pinfo_offset = offsetof(struct l2tp_ip6_sock, inet6), + }; + + static const struct proto_ops l2tp_ip6_ops = { +--- a/net/mptcp/protocol.c ++++ b/net/mptcp/protocol.c +@@ -3987,6 +3987,7 @@ int __init mptcp_proto_v6_init(void) + strcpy(mptcp_v6_prot.name, "MPTCPv6"); + mptcp_v6_prot.slab = NULL; + mptcp_v6_prot.obj_size = sizeof(struct mptcp6_sock); ++ mptcp_v6_prot.ipv6_pinfo_offset = offsetof(struct mptcp6_sock, np); + + err = proto_register(&mptcp_v6_prot, 1); + if (err) +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -9732,6 +9732,7 @@ struct proto sctpv6_prot = { + .unhash = sctp_unhash, + .no_autobind = true, + .obj_size = sizeof(struct sctp6_sock), ++ .ipv6_pinfo_offset = offsetof(struct sctp6_sock, inet6), + .useroffset = offsetof(struct sctp6_sock, sctp.subscribe), + .usersize = offsetof(struct sctp6_sock, sctp.initmsg) - + offsetof(struct sctp6_sock, sctp.subscribe) + diff --git a/queue-6.5/lockdep-fix-static-memory-detection-even-more.patch b/queue-6.5/lockdep-fix-static-memory-detection-even-more.patch new file mode 100644 index 00000000000..7a249df7b18 --- /dev/null +++ b/queue-6.5/lockdep-fix-static-memory-detection-even-more.patch @@ -0,0 +1,132 @@ +From 0a6b58c5cd0dfd7961e725212f0fc8dfc5d96195 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Tue, 15 Aug 2023 00:31:09 +0200 +Subject: lockdep: fix static memory detection even more + +From: Helge Deller + +commit 0a6b58c5cd0dfd7961e725212f0fc8dfc5d96195 upstream. + +On the parisc architecture, lockdep reports for all static objects which +are in the __initdata section (e.g. "setup_done" in devtmpfs, +"kthreadd_done" in init/main.c) this warning: + + INFO: trying to register non-static key. + +The warning itself is wrong, because those objects are in the __initdata +section, but the section itself is on parisc outside of range from +_stext to _end, which is why the static_obj() functions returns a wrong +answer. + +While fixing this issue, I noticed that the whole existing check can +be simplified a lot. +Instead of checking against the _stext and _end symbols (which include +code areas too) just check for the .data and .bss segments (since we check a +data object). This can be done with the existing is_kernel_core_data() +macro. + +In addition objects in the __initdata section can be checked with +init_section_contains(), and is_kernel_rodata() allows keys to be in the +_ro_after_init section. + +This partly reverts and simplifies commit bac59d18c701 ("x86/setup: Fix static +memory detection"). + +Link: https://lkml.kernel.org/r/ZNqrLRaOi/3wPAdp@p100 +Fixes: bac59d18c701 ("x86/setup: Fix static memory detection") +Signed-off-by: Helge Deller +Cc: Borislav Petkov +Cc: Greg Kroah-Hartman +Cc: Guenter Roeck +Cc: Peter Zijlstra +Cc: "Rafael J. Wysocki" +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/sections.h | 18 ------------------ + kernel/locking/lockdep.c | 36 ++++++++++++++---------------------- + 2 files changed, 14 insertions(+), 40 deletions(-) + +--- a/arch/x86/include/asm/sections.h ++++ b/arch/x86/include/asm/sections.h +@@ -2,8 +2,6 @@ + #ifndef _ASM_X86_SECTIONS_H + #define _ASM_X86_SECTIONS_H + +-#define arch_is_kernel_initmem_freed arch_is_kernel_initmem_freed +- + #include + #include + +@@ -18,20 +16,4 @@ extern char __end_of_kernel_reserve[]; + + extern unsigned long _brk_start, _brk_end; + +-static inline bool arch_is_kernel_initmem_freed(unsigned long addr) +-{ +- /* +- * If _brk_start has not been cleared, brk allocation is incomplete, +- * and we can not make assumptions about its use. +- */ +- if (_brk_start) +- return 0; +- +- /* +- * After brk allocation is complete, space between _brk_end and _end +- * is available for allocation. +- */ +- return addr >= _brk_end && addr < (unsigned long)&_end; +-} +- + #endif /* _ASM_X86_SECTIONS_H */ +--- a/kernel/locking/lockdep.c ++++ b/kernel/locking/lockdep.c +@@ -819,34 +819,26 @@ static int very_verbose(struct lock_clas + * Is this the address of a static object: + */ + #ifdef __KERNEL__ +-/* +- * Check if an address is part of freed initmem. After initmem is freed, +- * memory can be allocated from it, and such allocations would then have +- * addresses within the range [_stext, _end]. +- */ +-#ifndef arch_is_kernel_initmem_freed +-static int arch_is_kernel_initmem_freed(unsigned long addr) +-{ +- if (system_state < SYSTEM_FREEING_INITMEM) +- return 0; +- +- return init_section_contains((void *)addr, 1); +-} +-#endif +- + static int static_obj(const void *obj) + { +- unsigned long start = (unsigned long) &_stext, +- end = (unsigned long) &_end, +- addr = (unsigned long) obj; ++ unsigned long addr = (unsigned long) obj; + +- if (arch_is_kernel_initmem_freed(addr)) +- return 0; ++ if (is_kernel_core_data(addr)) ++ return 1; ++ ++ /* ++ * keys are allowed in the __ro_after_init section. ++ */ ++ if (is_kernel_rodata(addr)) ++ return 1; + + /* +- * static variable? ++ * in initdata section and used during bootup only? ++ * NOTE: On some platforms the initdata section is ++ * outside of the _stext ... _end range. + */ +- if ((addr >= start) && (addr < end)) ++ if (system_state < SYSTEM_FREEING_INITMEM && ++ init_section_contains((void *)addr, 1)) + return 1; + + /* diff --git a/queue-6.5/series b/queue-6.5/series index 427d571aad4..3700da06caf 100644 --- a/queue-6.5/series +++ b/queue-6.5/series @@ -3,3 +3,5 @@ module-expose-module_init_layout_section.patch arm64-module-use-module_init_layout_section-to-spot-init-sections.patch arm-module-use-module_init_layout_section-to-spot-init-sections.patch module-decompress-use-vmalloc-for-zstd-decompression-workspace.patch +ipv6-remove-hard-coded-limitation-on-ipv6_pinfo.patch +lockdep-fix-static-memory-detection-even-more.patch