From: Ye Bin yebin10@huawei.com
hulk inclusion category: bugfix bugzilla: 50785 CVE: NA
-----------------------------------------------
We got follow bug_on: [130747.323114] kernel BUG at fs/ext4/extents_status.c:762! [130747.323117] Internal error: Oops - BUG: 0 [#1] SMP ...... [130747.334329] Call trace: [130747.334553] ext4_es_cache_extent+0x150/0x168 [ext4] [130747.334975] ext4_cache_extents+0x64/0xe8 [ext4] [130747.335368] ext4_find_extent+0x300/0x330 [ext4] [130747.335759] ext4_ext_map_blocks+0x74/0x1178 [ext4] [130747.336179] ext4_map_blocks+0x2f4/0x5f0 [ext4] [130747.336567] ext4_mpage_readpages+0x4a8/0x7a8 [ext4] [130747.336995] ext4_readpage+0x54/0x100 [ext4] [130747.337359] generic_file_buffered_read+0x410/0xae8 [130747.337767] generic_file_read_iter+0x114/0x190 [130747.338152] ext4_file_read_iter+0x5c/0x140 [ext4] [130747.338556] __vfs_read+0x11c/0x188 [130747.338851] vfs_read+0x94/0x150 [130747.339110] ksys_read+0x74/0xf0
If call ext4_ext_insert_extent failed but new extent already inserted, we just update "ex->ee_len = orig_ex.ee_len", this will lead to extent overlap, then cause bug on when cache extent.
Signed-off-by: Ye Bin yebin10@huawei.com Reviewed-by: zhangyi (F) yi.zhang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/ext4/extents.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index ebf024258e3c2..3bc2cb4cc5cc5 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -3331,7 +3331,7 @@ static int ext4_split_extent_at(handle_t *handle,
goto out; } else if (err) - goto fix_extent_len; + goto err;
out: ext4_ext_show_leaf(inode, path); @@ -3339,6 +3339,7 @@ static int ext4_split_extent_at(handle_t *handle,
fix_extent_len: ex->ee_len = orig_ex.ee_len; +err: ext4_ext_dirty(handle, inode, path + path->p_depth); return err; }
From: Zhao Xuehui zhaoxuehui1@huawei.com
hulk inclusion category: bugfix bugzilla: 50773 CVE: NA
-------------------------------------------------
An error occurred while activating the livepatch. the error message: 1. "livepatch: klp_check_stack: migration/0:11 has an unreliable stack" 2. "insmod: can't insert 'xxxx.ko': invalid paramete"
The stack of all threads will be checked when activing the livepatch in function klp_check_calltrace(). However, there is no way to get the stack of migration thread during this process. Before the error handling changed in __unwind_start(), the stack state of migration thread is not changed and the function save_stack_trace_tsk_reliable() will return normally. After the error handling in __unwind_start() is fixed, the stack state of migration thread is changged to 'untrusted'. It means that the stack check of migration thread will fail, which causing the failure of activating livepatch. So we skip the thread stack check of the migration thread to ensure the success activation of livepatch.
Fixes: 7ce42682f925 ("x86/unwind/orc: Fix error handling in __unwind_start()")
Signed-off-by: Zhao Xuehui zhaoxuehui1@huawei.com Reviewed-by: Dong Kai dongkai11@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/x86/kernel/livepatch.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/x86/kernel/livepatch.c b/arch/x86/kernel/livepatch.c index c853ac57492dc..e927624d5016f 100644 --- a/arch/x86/kernel/livepatch.c +++ b/arch/x86/kernel/livepatch.c @@ -240,6 +240,9 @@ int klp_check_calltrace(struct klp_patch *patch, int enable) int ret = 0;
for_each_process_thread(g, t) { + /* the stack of migration thread cannot be obtained, skip it here*/ + if (strncmp(t->comm, "migration/", 10) == 0) + continue; ret = klp_check_stack(t, patch, enable); if (ret) goto out;
From: Zhang Ming 154842638@qq.com
openEuler inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I3BPPX CVE: NA
----------------------------------------------------------- The default branch in switch will not run at present, but there may be related extensions in the future, which may lead to memory leakage.
Signed-off-by: Zhang Ming 154842638@qq.com Reported-by: Wang ShaoBo bobo.shaobowang@huawei.com Suggested-by: Jian Cheng cj.chengjian@huawei.com Reviewed-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/arm64/kernel/mpam/mpam_ctrlmon.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm64/kernel/mpam/mpam_ctrlmon.c b/arch/arm64/kernel/mpam/mpam_ctrlmon.c index 4acf9234c3a56..b1d32d432556c 100644 --- a/arch/arm64/kernel/mpam/mpam_ctrlmon.c +++ b/arch/arm64/kernel/mpam/mpam_ctrlmon.c @@ -74,6 +74,7 @@ static int add_schema(enum resctrl_conf_type t, struct resctrl_resource *r) suffix = ""; break; default: + kfree(s); return -EINVAL; }
From: Lu Wei luwei32@huawei.com
hulk inclusion category: bugfix bugzilla: NA CVE: NA
--------------------------------
Commit 07f4c90062f8 ("tcp/dccp: try to not exhaust ip_local_port_range in connect()") allocates even ports for connect() first while leaving odd ports for bind() and this works well in busy servers.
But this strategy causes severe performance degradation in busy clients. when a client has used more than half of the local ports setted in proc/sys/net/ipv4/ip_local_port_range, if this client trys to connect to a server again, the connect time increases rapidly since it will traverse all the even ports though they are exhausted.
So this path provides another strategy by introducing a system option: local_port_allocation. If it is a busy client, users should set it to 1 to use sequential allocation while it should be set to 0 in other situations. Its default value is 0.
See: https://gitee.com/src-openeuler/kernel/issues/I2CT3R?from=project-issue
Signed-off-by: Lu Wei luwei32@huawei.com Reviewed-by: Yue Haibing yuehaibing@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- Documentation/networking/ip-sysctl.txt | 9 +++++++++ include/net/netns/ipv4.h | 1 + net/ipv4/inet_hashtables.c | 11 ++++++++--- net/ipv4/sysctl_net_ipv4.c | 7 +++++++ net/ipv4/tcp_ipv4.c | 1 + 5 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index c99a4423ffba7..60a0309ce1609 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -885,6 +885,15 @@ ip_local_reserved_ports - list of comma separated ranges
Default: Empty
+local_port_allocation - INTEGER + This is a per-namespace sysctl. It defines whether to use + sequential allocation of local ports. If it is set to zero, + even ports will be allocated to connect() while leaving odd + ports for bind(); If it is set to non-zero, sequential allocation + will be applied. + + default: 0 + ip_unprivileged_port_start - INTEGER This is a per-namespace sysctl. It defines the first unprivileged port in the network namespace. Privileged ports diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index 623cfbb7b8dcb..73d5a32d4118e 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -92,6 +92,7 @@ struct netns_ipv4 { int sysctl_icmp_errors_use_inbound_ifaddr;
struct local_ports ip_local_ports; + int sysctl_local_port_allocation;
int sysctl_tcp_ecn; int sysctl_tcp_ecn_fallback; diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 941477baa8d22..421fda1c1b138 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -678,7 +678,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, struct net *net = sock_net(sk); struct inet_bind_bucket *tb; u32 remaining, offset; - int ret, i, low, high; + int ret, i, low, high, span_size; static u32 hint; int l3mdev;
@@ -699,6 +699,11 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, return ret; }
+ /* local_port_allocation 0 means even and odd port allocation strategy + * will be applied, so span size is 2; otherwise sequential allocation + * will be used and span size is 1. Default value is 0. + */ + span_size = (int)net->ipv4.sysctl_local_port_allocation ? 1 : 2; l3mdev = inet_sk_bound_l3mdev(sk);
inet_get_local_port_range(net, &low, &high); @@ -714,7 +719,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, offset &= ~1U; other_parity_scan: port = low + offset; - for (i = 0; i < remaining; i += 2, port += 2) { + for (i = 0; i < remaining; i += span_size, port += span_size) { if (unlikely(port >= high)) port -= remaining; if (inet_is_local_reserved_port(net, port)) @@ -755,7 +760,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, }
offset++; - if ((offset & 1) && remaining > 1) + if ((offset & 1) && remaining > 1 && span_size == 2) goto other_parity_scan;
return -EADDRNOTAVAIL; diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index d427114bd8bab..fdd166ee80f34 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -682,6 +682,13 @@ static struct ctl_table ipv4_net_table[] = { .mode = 0644, .proc_handler = ipv4_local_port_range, }, + { + .procname = "local_port_allocation", + .data = &init_net.ipv4.sysctl_local_port_allocation, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, { .procname = "ip_local_reserved_ports", .data = &init_net.ipv4.sysctl_local_reserved_ports, diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 393c032e82a75..229ae272b2400 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2689,6 +2689,7 @@ static int __net_init tcp_sk_init(struct net *net) spin_lock_init(&net->ipv4.tcp_fastopen_ctx_lock); net->ipv4.sysctl_tcp_fastopen_blackhole_timeout = 60 * 60; atomic_set(&net->ipv4.tfo_active_disable_times, 0); + net->ipv4.sysctl_local_port_allocation = 0;
/* Reno is always built in */ if (!net_eq(net, &init_net) &&