diff --git a/patches.kabi/media-dvb_frontend-kabi-workaround.patch b/patches.kabi/media-dvb_frontend-kabi-workaround.patch new file mode 100644 index 0000000..9e6f69d --- /dev/null +++ b/patches.kabi/media-dvb_frontend-kabi-workaround.patch @@ -0,0 +1,133 @@ +From: Takashi Iwai +Subject: media: dvb_frontend: kABI workaround +Patch-mainline: Never, kABI workaround +References: CVE-2022-45885 bsc#1205758 + +For keeping the kABI workaround, the newly introduced remove_mutex +of dvb_frontend to be a global one. It's not urgent for performance, +so we can live with that. + +Signed-off-by: Takashi Iwai + +--- + drivers/media/dvb-core/dvb_frontend.c | 23 ++++++++++++----------- + include/media/dvb_frontend.h | 4 ---- + 2 files changed, 12 insertions(+), 15 deletions(-) + +--- a/drivers/media/dvb-core/dvb_frontend.c ++++ b/drivers/media/dvb-core/dvb_frontend.c +@@ -90,6 +90,8 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wai + + static DEFINE_MUTEX(frontend_mutex); + ++static DEFINE_MUTEX(remove_mutex); ++ + struct dvb_frontend_private { + /* thread/frontend values */ + struct dvb_device *dvbdev; +@@ -817,20 +819,20 @@ static void dvb_frontend_stop(struct dvb + + dev_dbg(fe->dvb->device, "%s:\n", __func__); + +- mutex_lock(&fe->remove_mutex); ++ mutex_lock(&remove_mutex); + + if (fe->exit != DVB_FE_DEVICE_REMOVED) + fe->exit = DVB_FE_NORMAL_EXIT; + mb(); + + if (!fepriv->thread) { +- mutex_unlock(&fe->remove_mutex); ++ mutex_unlock(&remove_mutex); + return; + } + + kthread_stop(fepriv->thread); + +- mutex_unlock(&fe->remove_mutex); ++ mutex_unlock(&remove_mutex); + + if (fepriv->dvbdev->users < -1) { + wait_event(fepriv->dvbdev->wait_queue, +@@ -2772,7 +2774,7 @@ static int dvb_frontend_open(struct inod + struct dvb_adapter *adapter = fe->dvb; + int ret; + +- mutex_lock(&fe->remove_mutex); ++ mutex_lock(&remove_mutex); + + dev_dbg(fe->dvb->device, "%s:\n", __func__); + if (fe->exit == DVB_FE_DEVICE_REMOVED) { +@@ -2875,7 +2877,7 @@ static int dvb_frontend_open(struct inod + if (adapter->mfe_shared) + mutex_unlock(&adapter->mfe_lock); + +- mutex_unlock(&fe->remove_mutex); ++ mutex_unlock(&remove_mutex); + return ret; + + err3: +@@ -2899,7 +2901,7 @@ err0: + mutex_unlock(&adapter->mfe_lock); + + err_remove_mutex: +- mutex_unlock(&fe->remove_mutex); ++ mutex_unlock(&remove_mutex); + return ret; + } + +@@ -2910,7 +2912,7 @@ static int dvb_frontend_release(struct i + struct dvb_frontend_private *fepriv = fe->frontend_priv; + int ret; + +- mutex_lock(&fe->remove_mutex); ++ mutex_lock(&remove_mutex); + + dev_dbg(fe->dvb->device, "%s:\n", __func__); + +@@ -2937,14 +2939,14 @@ static int dvb_frontend_release(struct i + fe->ops.ts_bus_ctrl(fe, 0); + + if (fe->exit != DVB_FE_NO_EXIT) { +- mutex_unlock(&fe->remove_mutex); ++ mutex_unlock(&remove_mutex); + wake_up(&dvbdev->wait_queue); + } else { +- mutex_unlock(&fe->remove_mutex); ++ mutex_unlock(&remove_mutex); + } + + } else { +- mutex_unlock(&fe->remove_mutex); ++ mutex_unlock(&remove_mutex); + } + + dvb_frontend_put(fe); +@@ -3041,7 +3043,6 @@ int dvb_register_frontend(struct dvb_ada + fepriv = fe->frontend_priv; + + kref_init(&fe->refcount); +- mutex_init(&fe->remove_mutex); + + /* + * After initialization, there need to be two references: one +--- a/include/media/dvb_frontend.h ++++ b/include/media/dvb_frontend.h +@@ -681,9 +681,6 @@ struct dtv_frontend_properties { + * @exit: Used to inform the DVB core that the frontend + * thread should exit (usually, means that the hardware + * got disconnected). +- * @remove_mutex: mutex that avoids a race condition between a callback +- * called when the hardware is disconnected and the +- * file_operations of dvb_frontend. + */ + + struct dvb_frontend { +@@ -701,7 +698,6 @@ struct dvb_frontend { + int (*callback)(void *adapter_priv, int component, int cmd, int arg); + int id; + unsigned int exit; +- struct mutex remove_mutex; + }; + + /** diff --git a/patches.kabi/media-dvb_net-kabi-workaround.patch b/patches.kabi/media-dvb_net-kabi-workaround.patch new file mode 100644 index 0000000..6d2f2a8 --- /dev/null +++ b/patches.kabi/media-dvb_net-kabi-workaround.patch @@ -0,0 +1,107 @@ +From: Takashi Iwai +Subject: media: dvb_net: kABI workaround +Patch-mainline: Never, kABI workaround +References: CVE-2022-45886 bsc#1205760 + +For keeping the kABI workaround, the newly introduced remove_mutex +of dvb_net to be a global one. It's not urgent for performance, +so we can live with that. + +Signed-off-by: Takashi Iwai + +--- + drivers/media/dvb-core/dvb_net.c | 19 ++++++++++--------- + include/media/dvb_net.h | 4 ---- + 2 files changed, 10 insertions(+), 13 deletions(-) + +--- a/drivers/media/dvb-core/dvb_net.c ++++ b/drivers/media/dvb-core/dvb_net.c +@@ -57,6 +57,8 @@ + #include + #include + ++static DEFINE_MUTEX(remove_mutex); ++ + static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt ) + { + unsigned int j; +@@ -1570,17 +1572,17 @@ static int locked_dvb_net_open(struct in + struct dvb_net *dvbnet = dvbdev->priv; + int ret; + +- if (mutex_lock_interruptible(&dvbnet->remove_mutex)) ++ if (mutex_lock_interruptible(&remove_mutex)) + return -ERESTARTSYS; + + if (dvbnet->exit) { +- mutex_unlock(&dvbnet->remove_mutex); ++ mutex_unlock(&remove_mutex); + return -ENODEV; + } + + ret = dvb_generic_open(inode, file); + +- mutex_unlock(&dvbnet->remove_mutex); ++ mutex_unlock(&remove_mutex); + + return ret; + } +@@ -1590,15 +1592,15 @@ static int dvb_net_close(struct inode *i + struct dvb_device *dvbdev = file->private_data; + struct dvb_net *dvbnet = dvbdev->priv; + +- mutex_lock(&dvbnet->remove_mutex); ++ mutex_lock(&remove_mutex); + + dvb_generic_release(inode, file); + + if (dvbdev->users == 1 && dvbnet->exit == 1) { +- mutex_unlock(&dvbnet->remove_mutex); ++ mutex_unlock(&remove_mutex); + wake_up(&dvbdev->wait_queue); + } else { +- mutex_unlock(&dvbnet->remove_mutex); ++ mutex_unlock(&remove_mutex); + } + + return 0; +@@ -1627,9 +1629,9 @@ void dvb_net_release (struct dvb_net *dv + { + int i; + +- mutex_lock(&dvbnet->remove_mutex); ++ mutex_lock(&remove_mutex); + dvbnet->exit = 1; +- mutex_unlock(&dvbnet->remove_mutex); ++ mutex_unlock(&remove_mutex); + + if (dvbnet->dvbdev->users < 1) + wait_event(dvbnet->dvbdev->wait_queue, +@@ -1652,7 +1654,6 @@ int dvb_net_init (struct dvb_adapter *ad + int i; + + mutex_init(&dvbnet->ioctl_mutex); +- mutex_init(&dvbnet->remove_mutex); + dvbnet->demux = dmx; + + for (i=0; i +Date: Thu, 26 Jan 2023 18:32:50 -0800 +Subject: [PATCH] netrom: Fix use-after-free caused by accept on already + connected socket +Git-commit: 611792920925fb088ddccbe2783c7f92fdfb6b64 +Patch-mainline: v6.2-rc7 +References: bsc#1211186 CVE-2023-32269 + +If you call listen() and accept() on an already connect()ed +AF_NETROM socket, accept() can successfully connect. +This is because when the peer socket sends data to sendmsg, +the skb with its own sk stored in the connected socket's +sk->sk_receive_queue is connected, and nr_accept() dequeues +the skb waiting in the sk->sk_receive_queue. + +As a result, nr_accept() allocates and returns a sock with +the sk of the parent AF_NETROM socket. + +And here use-after-free can happen through complex race conditions: +``` + cpu0 cpu1 + 1. socket_2 = socket(AF_NETROM) + . + . + listen(socket_2) + accepted_socket = accept(socket_2) + 2. socket_1 = socket(AF_NETROM) + nr_create() // sk refcount : 1 + connect(socket_1) + 3. write(accepted_socket) + nr_sendmsg() + nr_output() + nr_kick() + nr_send_iframe() + nr_transmit_buffer() + nr_route_frame() + nr_loopback_queue() + nr_loopback_timer() + nr_rx_frame() + nr_process_rx_frame(sk, skb); // sk : socket_1's sk + nr_state3_machine() + nr_queue_rx_frame() + sock_queue_rcv_skb() + sock_queue_rcv_skb_reason() + __sock_queue_rcv_skb() + __skb_queue_tail(list, skb); // list : socket_1's sk->sk_receive_queue + 4. listen(socket_1) + nr_listen() + uaf_socket = accept(socket_1) + nr_accept() + skb_dequeue(&sk->sk_receive_queue); + 5. close(accepted_socket) + nr_release() + nr_write_internal(sk, NR_DISCREQ) + nr_transmit_buffer() // NR_DISCREQ + nr_route_frame() + nr_loopback_queue() + nr_loopback_timer() + nr_rx_frame() // sk : socket_1's sk + nr_process_rx_frame() // NR_STATE_3 + nr_state3_machine() // NR_DISCREQ + nr_disconnect() + nr_sk(sk)->state = NR_STATE_0; + 6. close(socket_1) // sk refcount : 3 + nr_release() // NR_STATE_0 + sock_put(sk); // sk refcount : 0 + sk_free(sk); + close(uaf_socket) + nr_release() + sock_hold(sk); // UAF +``` + +KASAN report by syzbot: +``` +Bug: KASAN: use-after-free in nr_release+0x66/0x460 net/netrom/af_netrom.c:520 +Write of size 4 at addr ffff8880235d8080 by task syz-executor564/5128 + +Call Trace: + + __dump_stack lib/dump_stack.c:88 [inline] + dump_stack_lvl+0xd1/0x138 lib/dump_stack.c:106 + print_address_description mm/kasan/report.c:306 [inline] + print_report+0x15e/0x461 mm/kasan/report.c:417 + kasan_report+0xbf/0x1f0 mm/kasan/report.c:517 + check_region_inline mm/kasan/generic.c:183 [inline] + kasan_check_range+0x141/0x190 mm/kasan/generic.c:189 + instrument_atomic_read_write include/linux/instrumented.h:102 [inline] + atomic_fetch_add_relaxed include/linux/atomic/atomic-instrumented.h:116 [inline] + __refcount_add include/linux/refcount.h:193 [inline] + __refcount_inc include/linux/refcount.h:250 [inline] + refcount_inc include/linux/refcount.h:267 [inline] + sock_hold include/net/sock.h:775 [inline] + nr_release+0x66/0x460 net/netrom/af_netrom.c:520 + __sock_release+0xcd/0x280 net/socket.c:650 + sock_close+0x1c/0x20 net/socket.c:1365 + __fput+0x27c/0xa90 fs/file_table.c:320 + task_work_run+0x16f/0x270 kernel/task_work.c:179 + exit_task_work include/linux/task_work.h:38 [inline] + do_exit+0xaa8/0x2950 kernel/exit.c:867 + do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 + get_signal+0x21c3/0x2450 kernel/signal.c:2859 + arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 + exit_to_user_mode_loop kernel/entry/common.c:168 [inline] + exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 + __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] + syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 + do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 + entry_SYSCALL_64_after_hwframe+0x63/0xcd +Rip: 0033:0x7f6c19e3c9b9 +Code: Unable to access opcode bytes at 0x7f6c19e3c98f. +Rsp: 002b:00007fffd4ba2ce8 EFLAGS: 00000246 ORIG_RAX: 0000000000000133 +Rax: 0000000000000116 RBX: 0000000000000003 RCX: 00007f6c19e3c9b9 +Rdx: 0000000000000318 RSI: 00000000200bd000 RDI: 0000000000000006 +Rbp: 0000000000000003 R08: 000000000000000d R09: 000000000000000d +R10: 0000000000000000 R11: 0000000000000246 R12: 000055555566a2c0 +R13: 0000000000000011 R14: 0000000000000000 R15: 0000000000000000 + + +Allocated by task 5128: + kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 + kasan_set_track+0x25/0x30 mm/kasan/common.c:52 + ____kasan_kmalloc mm/kasan/common.c:371 [inline] + ____kasan_kmalloc mm/kasan/common.c:330 [inline] + __kasan_kmalloc+0xa3/0xb0 mm/kasan/common.c:380 + kasan_kmalloc include/linux/kasan.h:211 [inline] + __do_kmalloc_node mm/slab_common.c:968 [inline] + __kmalloc+0x5a/0xd0 mm/slab_common.c:981 + kmalloc include/linux/slab.h:584 [inline] + sk_prot_alloc+0x140/0x290 net/core/sock.c:2038 + sk_alloc+0x3a/0x7a0 net/core/sock.c:2091 + nr_create+0xb6/0x5f0 net/netrom/af_netrom.c:433 + __sock_create+0x359/0x790 net/socket.c:1515 + sock_create net/socket.c:1566 [inline] + __sys_socket_create net/socket.c:1603 [inline] + __sys_socket_create net/socket.c:1588 [inline] + __sys_socket+0x133/0x250 net/socket.c:1636 + __do_sys_socket net/socket.c:1649 [inline] + __se_sys_socket net/socket.c:1647 [inline] + __x64_sys_socket+0x73/0xb0 net/socket.c:1647 + do_syscall_x64 arch/x86/entry/common.c:50 [inline] + do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + +Freed by task 5128: + kasan_save_stack+0x22/0x40 mm/kasan/common.c:45 + kasan_set_track+0x25/0x30 mm/kasan/common.c:52 + kasan_save_free_info+0x2b/0x40 mm/kasan/generic.c:518 + ____kasan_slab_free mm/kasan/common.c:236 [inline] + ____kasan_slab_free+0x13b/0x1a0 mm/kasan/common.c:200 + kasan_slab_free include/linux/kasan.h:177 [inline] + __cache_free mm/slab.c:3394 [inline] + __do_kmem_cache_free mm/slab.c:3580 [inline] + __kmem_cache_free+0xcd/0x3b0 mm/slab.c:3587 + sk_prot_free net/core/sock.c:2074 [inline] + __sk_destruct+0x5df/0x750 net/core/sock.c:2166 + sk_destruct net/core/sock.c:2181 [inline] + __sk_free+0x175/0x460 net/core/sock.c:2192 + sk_free+0x7c/0xa0 net/core/sock.c:2203 + sock_put include/net/sock.h:1991 [inline] + nr_release+0x39e/0x460 net/netrom/af_netrom.c:554 + __sock_release+0xcd/0x280 net/socket.c:650 + sock_close+0x1c/0x20 net/socket.c:1365 + __fput+0x27c/0xa90 fs/file_table.c:320 + task_work_run+0x16f/0x270 kernel/task_work.c:179 + exit_task_work include/linux/task_work.h:38 [inline] + do_exit+0xaa8/0x2950 kernel/exit.c:867 + do_group_exit+0xd4/0x2a0 kernel/exit.c:1012 + get_signal+0x21c3/0x2450 kernel/signal.c:2859 + arch_do_signal_or_restart+0x79/0x5c0 arch/x86/kernel/signal.c:306 + exit_to_user_mode_loop kernel/entry/common.c:168 [inline] + exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 + __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] + syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 + do_syscall_64+0x46/0xb0 arch/x86/entry/common.c:86 + entry_SYSCALL_64_after_hwframe+0x63/0xcd +``` + +To fix this issue, nr_listen() returns -EINVAL for sockets that +successfully nr_connect(). + +Reported-by: syzbot+caa188bdfc1eeafeb418@syzkaller.appspotmail.com +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Hyunwoo Kim +Reviewed-by: Kuniyuki Iwashima +Signed-off-by: David S. Miller +Acked-by: Vasant Karasulli + +--- + net/netrom/af_netrom.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c +index 6f7f4392cffb..5a4cb796150f 100644 +--- a/net/netrom/af_netrom.c ++++ b/net/netrom/af_netrom.c +@@ -400,6 +400,11 @@ static int nr_listen(struct socket *sock, int backlog) + struct sock *sk = sock->sk; + + lock_sock(sk); ++ if (sock->state != SS_UNCONNECTED) { ++ release_sock(sk); ++ return -EINVAL; ++ } ++ + if (sk->sk_state != TCP_LISTEN) { + memset(&nr_sk(sk)->user_addr, 0, AX25_ADDR_LEN); + sk->sk_max_ack_backlog = backlog; +-- +2.34.1 + diff --git a/patches.suse/act_mirred-use-the-backlog-for-nested-calls-to-mirre.patch b/patches.suse/act_mirred-use-the-backlog-for-nested-calls-to-mirre.patch new file mode 100644 index 0000000..c0706c9 --- /dev/null +++ b/patches.suse/act_mirred-use-the-backlog-for-nested-calls-to-mirre.patch @@ -0,0 +1,131 @@ +From: Davide Caratti +Date: Fri, 20 Jan 2023 18:01:40 +0100 +Subject: act_mirred: use the backlog for nested calls to mirred ingress +Patch-mainline: v6.3-rc1 +Git-commit: ca22da2fbd693b54dc8e3b7b54ccc9f7e9ba3640 +References: CVE-2022-4269 bsc#1206024 + +William reports kernel soft-lockups on some OVS topologies when TC mirred +egress->ingress action is hit by local TCP traffic [1]. +The same can also be reproduced with SCTP (thanks Xin for verifying), when +client and server reach themselves through mirred egress to ingress, and +one of the two peers sends a "heartbeat" packet (from within a timer). + +Enqueueing to backlog proved to fix this soft lockup; however, as Cong +noticed [2], we should preserve - when possible - the current mirred +behavior that counts as "overlimits" any eventual packet drop subsequent to +the mirred forwarding action [3]. A compromise solution might use the +backlog only when tcf_mirred_act() has a nest level greater than one: +change tcf_mirred_forward() accordingly. + +Also, add a kselftest that can reproduce the lockup and verifies TC mirred +ability to account for further packet drops after TC mirred egress->ingress +(when the nest level is 1). + + [1] https://lore.kernel.org/netdev/33dc43f587ec1388ba456b4915c75f02a8aae226.1663945716.git.dcaratti@redhat.com/ + [2] https://lore.kernel.org/netdev/Y0w%2FWWY60gqrtGLp@pop-os.localdomain/ + [3] such behavior is not guaranteed: for example, if RPS or skb RX + timestamping is enabled on the mirred target device, the kernel + can defer receiving the skb and return NET_RX_SUCCESS inside + tcf_mirred_forward(). + +Reported-by: William Zhao +CC: Xin Long +Signed-off-by: Davide Caratti +Reviewed-by: Marcelo Ricardo Leitner +Acked-by: Jamal Hadi Salim +Signed-off-by: Paolo Abeni +Acked-by: Michal Kubecek + +--- + net/sched/act_mirred.c | 7 +++ + .../selftests/net/forwarding/tc_actions.sh | 49 ++++++++++++++++++- + 2 files changed, 55 insertions(+), 1 deletion(-) + +--- a/net/sched/act_mirred.c ++++ b/net/sched/act_mirred.c +@@ -207,12 +207,19 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, + return err; + } + ++static bool is_mirred_nested(void) ++{ ++ return unlikely(__this_cpu_read(mirred_nest_level) > 1); ++} ++ + static int tcf_mirred_forward(bool want_ingress, struct sk_buff *skb) + { + int err; + + if (!want_ingress) + err = dev_queue_xmit(skb); ++ else if (is_mirred_nested()) ++ err = netif_rx(skb); + else + err = netif_receive_skb(skb); + +--- a/tools/testing/selftests/net/forwarding/tc_actions.sh ++++ b/tools/testing/selftests/net/forwarding/tc_actions.sh +@@ -2,7 +2,8 @@ + # SPDX-License-Identifier: GPL-2.0 + + ALL_TESTS="gact_drop_and_ok_test mirred_egress_redirect_test \ +- mirred_egress_mirror_test gact_trap_test" ++ mirred_egress_mirror_test gact_trap_test \ ++ mirred_egress_to_ingress_tcp_test" + NUM_NETIFS=4 + source tc_common.sh + source lib.sh +@@ -148,6 +149,52 @@ gact_trap_test() + log_test "trap ($tcflags)" + } + ++mirred_egress_to_ingress_tcp_test() ++{ ++ local tmpfile=$(mktemp) tmpfile1=$(mktemp) ++ ++ RET=0 ++ dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$tmpfile ++ tc filter add dev $h1 protocol ip pref 100 handle 100 egress flower \ ++ $tcflags ip_proto tcp src_ip 192.0.2.1 dst_ip 192.0.2.2 \ ++ action ct commit nat src addr 192.0.2.2 pipe \ ++ action ct clear pipe \ ++ action ct commit nat dst addr 192.0.2.1 pipe \ ++ action ct clear pipe \ ++ action skbedit ptype host pipe \ ++ action mirred ingress redirect dev $h1 ++ tc filter add dev $h1 protocol ip pref 101 handle 101 egress flower \ ++ $tcflags ip_proto icmp \ ++ action mirred ingress redirect dev $h1 ++ tc filter add dev $h1 protocol ip pref 102 handle 102 ingress flower \ ++ ip_proto icmp \ ++ action drop ++ ++ ip vrf exec v$h1 nc --recv-only -w10 -l -p 12345 -o $tmpfile1 & ++ local rpid=$! ++ ip vrf exec v$h1 nc -w1 --send-only 192.0.2.2 12345 <$tmpfile ++ wait -n $rpid ++ cmp -s $tmpfile $tmpfile1 ++ check_err $? "server output check failed" ++ ++ $MZ $h1 -c 10 -p 64 -a $h1mac -b $h1mac -A 192.0.2.1 -B 192.0.2.1 \ ++ -t icmp "ping,id=42,seq=5" -q ++ tc_check_packets "dev $h1 egress" 101 10 ++ check_err $? "didn't mirred redirect ICMP" ++ tc_check_packets "dev $h1 ingress" 102 10 ++ check_err $? "didn't drop mirred ICMP" ++ local overlimits=$(tc_rule_stats_get ${h1} 101 egress .overlimits) ++ test ${overlimits} = 10 ++ check_err $? "wrong overlimits, expected 10 got ${overlimits}" ++ ++ tc filter del dev $h1 egress protocol ip pref 100 handle 100 flower ++ tc filter del dev $h1 egress protocol ip pref 101 handle 101 flower ++ tc filter del dev $h1 ingress protocol ip pref 102 handle 102 flower ++ ++ rm -f $tmpfile $tmpfile1 ++ log_test "mirred_egress_to_ingress_tcp ($tcflags)" ++} ++ + setup_prepare() + { + h1=${NETIFS[p1]} diff --git a/patches.suse/ext4-add-EXT4_INODE_HAS_XATTR_SPACE-macro-in-xattr.h.patch b/patches.suse/ext4-add-EXT4_INODE_HAS_XATTR_SPACE-macro-in-xattr.h.patch new file mode 100644 index 0000000..a774a79 --- /dev/null +++ b/patches.suse/ext4-add-EXT4_INODE_HAS_XATTR_SPACE-macro-in-xattr.h.patch @@ -0,0 +1,50 @@ +From 179b14152dcb6a24c3415200603aebca70ff13af Mon Sep 17 00:00:00 2001 +From: Baokun Li +Date: Thu, 16 Jun 2022 10:13:55 +0800 +Subject: [PATCH] ext4: add EXT4_INODE_HAS_XATTR_SPACE macro in xattr.h +Git-commit: 179b14152dcb6a24c3415200603aebca70ff13af +Patch-mainline: v6.0-rc1 +References: bsc#1206878 + +When adding an xattr to an inode, we must ensure that the inode_size is +not less than EXT4_GOOD_OLD_INODE_SIZE + extra_isize + pad. Otherwise, +the end position may be greater than the start position, resulting in UAF. + +Signed-off-by: Baokun Li +Reviewed-by: Jan Kara +Reviewed-by: Ritesh Harjani (IBM) +Link: https://lore.kernel.org/r/20220616021358.2504451-2-libaokun1@huawei.com +Signed-off-by: Theodore Ts'o +Acked-by: Jan Kara + +--- + fs/ext4/xattr.h | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h +index 77efb9a627ad..f885f362add4 100644 +--- a/fs/ext4/xattr.h ++++ b/fs/ext4/xattr.h +@@ -95,6 +95,19 @@ struct ext4_xattr_entry { + + #define EXT4_ZERO_XATTR_VALUE ((void *)-1) + ++/* ++ * If we want to add an xattr to the inode, we should make sure that ++ * i_extra_isize is not 0 and that the inode size is not less than ++ * EXT4_GOOD_OLD_INODE_SIZE + extra_isize + pad. ++ * EXT4_GOOD_OLD_INODE_SIZE extra_isize header entry pad data ++ * |--------------------------|------------|------|---------|---|-------| ++ */ ++#define EXT4_INODE_HAS_XATTR_SPACE(inode) \ ++ ((EXT4_I(inode)->i_extra_isize != 0) && \ ++ (EXT4_GOOD_OLD_INODE_SIZE + EXT4_I(inode)->i_extra_isize + \ ++ sizeof(struct ext4_xattr_ibody_header) + EXT4_XATTR_PAD <= \ ++ EXT4_INODE_SIZE((inode)->i_sb))) ++ + struct ext4_xattr_info { + const char *name; + const void *value; +-- +2.35.3 + diff --git a/patches.suse/ext4-fix-use-after-free-in-ext4_xattr_set_entry.patch b/patches.suse/ext4-fix-use-after-free-in-ext4_xattr_set_entry.patch new file mode 100644 index 0000000..5a8567b --- /dev/null +++ b/patches.suse/ext4-fix-use-after-free-in-ext4_xattr_set_entry.patch @@ -0,0 +1,129 @@ +From 67d7d8ad99beccd9fe92d585b87f1760dc9018e3 Mon Sep 17 00:00:00 2001 +From: Baokun Li +Date: Thu, 16 Jun 2022 10:13:56 +0800 +Subject: [PATCH] ext4: fix use-after-free in ext4_xattr_set_entry +Git-commit: 67d7d8ad99beccd9fe92d585b87f1760dc9018e3 +Patch-mainline: v6.0-rc1 +References: bsc#1206878 bsc#1211105 CVE-2023-2513 + +Hulk Robot reported a issue: +================================================================== +Bug: KASAN: use-after-free in ext4_xattr_set_entry+0x18ab/0x3500 +Write of size 4105 at addr ffff8881675ef5f4 by task syz-executor.0/7092 + +Cpu: 1 PID: 7092 Comm: syz-executor.0 Not tainted 4.19.90-dirty #17 +Call Trace: +[...] + memcpy+0x34/0x50 mm/kasan/kasan.c:303 + ext4_xattr_set_entry+0x18ab/0x3500 fs/ext4/xattr.c:1747 + ext4_xattr_ibody_inline_set+0x86/0x2a0 fs/ext4/xattr.c:2205 + ext4_xattr_set_handle+0x940/0x1300 fs/ext4/xattr.c:2386 + ext4_xattr_set+0x1da/0x300 fs/ext4/xattr.c:2498 + __vfs_setxattr+0x112/0x170 fs/xattr.c:149 + __vfs_setxattr_noperm+0x11b/0x2a0 fs/xattr.c:180 + __vfs_setxattr_locked+0x17b/0x250 fs/xattr.c:238 + vfs_setxattr+0xed/0x270 fs/xattr.c:255 + setxattr+0x235/0x330 fs/xattr.c:520 + path_setxattr+0x176/0x190 fs/xattr.c:539 + __do_sys_lsetxattr fs/xattr.c:561 [inline] + __se_sys_lsetxattr fs/xattr.c:557 [inline] + __x64_sys_lsetxattr+0xc2/0x160 fs/xattr.c:557 + do_syscall_64+0xdf/0x530 arch/x86/entry/common.c:298 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 +Rip: 0033:0x459fe9 +Rsp: 002b:00007fa5e54b4c08 EFLAGS: 00000246 ORIG_RAX: 00000000000000bd +Rax: ffffffffffffffda RBX: 000000000051bf60 RCX: 0000000000459fe9 +Rdx: 00000000200003c0 RSI: 0000000020000180 RDI: 0000000020000140 +Rbp: 000000000051bf60 R08: 0000000000000001 R09: 0000000000000000 +R10: 0000000000001009 R11: 0000000000000246 R12: 0000000000000000 +R13: 00007ffc73c93fc0 R14: 000000000051bf60 R15: 00007fa5e54b4d80 +[...] +================================================================== + +Above issue may happen as follows: + +Acked-by: Jan Kara + +------------------------------------- +ext4_xattr_set + ext4_xattr_set_handle + ext4_xattr_ibody_find + >> s->end < s->base + >> no EXT4_STATE_XATTR + >> xattr_check_inode is not executed + ext4_xattr_ibody_set + ext4_xattr_set_entry + >> size_t min_offs = s->end - s->base + >> UAF in memcpy + +we can easily reproduce this problem with the following commands: + mkfs.ext4 -F /dev/sda + mount -o debug_want_extra_isize=128 /dev/sda /mnt + touch /mnt/file + setfattr -n user.cat -v `seq -s z 4096|tr -d '[:digit:]'` /mnt/file + +In ext4_xattr_ibody_find, we have the following assignment logic: + header = IHDR(inode, raw_inode) + = raw_inode + EXT4_GOOD_OLD_INODE_SIZE + i_extra_isize + is->s.base = IFIRST(header) + = header + sizeof(struct ext4_xattr_ibody_header) + is->s.end = raw_inode + s_inode_size + +In ext4_xattr_set_entry + min_offs = s->end - s->base + = s_inode_size - EXT4_GOOD_OLD_INODE_SIZE - i_extra_isize - + sizeof(struct ext4_xattr_ibody_header) + last = s->first + free = min_offs - ((void *)last - s->base) - sizeof(__u32) + = s_inode_size - EXT4_GOOD_OLD_INODE_SIZE - i_extra_isize - + sizeof(struct ext4_xattr_ibody_header) - sizeof(__u32) + +In the calculation formula, all values except s_inode_size and +i_extra_size are fixed values. When i_extra_size is the maximum value +s_inode_size - EXT4_GOOD_OLD_INODE_SIZE, min_offs is -4 and free is -8. +The value overflows. As a result, the preceding issue is triggered when +memcpy is executed. + +Therefore, when finding xattr or setting xattr, check whether +there is space for storing xattr in the inode to resolve this issue. + +Cc: stable@kernel.org +Reported-by: Hulk Robot +Signed-off-by: Baokun Li +Reviewed-by: Ritesh Harjani (IBM) +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20220616021358.2504451-3-libaokun1@huawei.com +Signed-off-by: Theodore Ts'o +--- + fs/ext4/xattr.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index 564e28a1aa94..c42b3e0d2d94 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -2175,8 +2175,9 @@ int ext4_xattr_ibody_find(struct inode *inode, struct ext4_xattr_info *i, + struct ext4_inode *raw_inode; + int error; + +- if (EXT4_I(inode)->i_extra_isize == 0) ++ if (!EXT4_INODE_HAS_XATTR_SPACE(inode)) + return 0; ++ + raw_inode = ext4_raw_inode(&is->iloc); + header = IHDR(inode, raw_inode); + is->s.base = is->s.first = IFIRST(header); +@@ -2204,8 +2205,9 @@ int ext4_xattr_ibody_set(handle_t *handle, struct inode *inode, + struct ext4_xattr_search *s = &is->s; + int error; + +- if (EXT4_I(inode)->i_extra_isize == 0) ++ if (!EXT4_INODE_HAS_XATTR_SPACE(inode)) + return -ENOSPC; ++ + error = ext4_xattr_set_entry(i, s, handle, inode, false /* is_block */); + if (error) + return error; +-- +2.35.3 + diff --git a/patches.suse/i2c-xgene-slimpro-Fix-out-of-bounds-bug-in-xgene_sli.patch b/patches.suse/i2c-xgene-slimpro-Fix-out-of-bounds-bug-in-xgene_sli.patch new file mode 100644 index 0000000..294f202 --- /dev/null +++ b/patches.suse/i2c-xgene-slimpro-Fix-out-of-bounds-bug-in-xgene_sli.patch @@ -0,0 +1,40 @@ +From: Wei Chen +Date: Tue, 14 Mar 2023 16:54:21 +0000 +Subject: i2c: xgene-slimpro: Fix out-of-bounds bug in xgene_slimpro_i2c_xfer() +Patch-mainline: v6.3-rc4 +Git-commit: 92fbb6d1296f81f41f65effd7f5f8c0f74943d15 +References: bsc#1210715 CVE-2023-2194 + +The data->block[0] variable comes from user and is a number between +0-255. Without proper check, the variable may be very large to cause +an out-of-bounds when performing memcpy in slimpro_i2c_blkwr. + +Fix this bug by checking the value of writelen. + +Fixes: f6505fbabc42 ("i2c: add SLIMpro I2C device driver on APM X-Gene platform") +Signed-off-by: Wei Chen +Cc: stable@vger.kernel.org +Reviewed-by: Andi Shyti +Signed-off-by: Wolfram Sang +Acked-by: Lee, Chun-Yi +--- + drivers/i2c/busses/i2c-xgene-slimpro.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/i2c/busses/i2c-xgene-slimpro.c b/drivers/i2c/busses/i2c-xgene-slimpro.c +index 63259b3ea5ab..3538d36368a9 100644 +--- a/drivers/i2c/busses/i2c-xgene-slimpro.c ++++ b/drivers/i2c/busses/i2c-xgene-slimpro.c +@@ -308,6 +308,9 @@ static int slimpro_i2c_blkwr(struct slimpro_i2c_dev *ctx, u32 chip, + u32 msg[3]; + int rc; + ++ if (writelen > I2C_SMBUS_BLOCK_MAX) ++ return -EINVAL; ++ + memcpy(ctx->dma_buffer, data, writelen); + paddr = dma_map_single(ctx->dev, ctx->dma_buffer, writelen, + DMA_TO_DEVICE); +-- +2.35.3 + diff --git a/patches.suse/io_uring-prevent-race-on-registering-fixed-files.patch b/patches.suse/io_uring-prevent-race-on-registering-fixed-files.patch index 37908da..0a68484 100644 --- a/patches.suse/io_uring-prevent-race-on-registering-fixed-files.patch +++ b/patches.suse/io_uring-prevent-race-on-registering-fixed-files.patch @@ -3,7 +3,7 @@ From: Gabriel Krisman Bertazi Date: Mon, 1 May 2023 11:49:09 -0400 Subject: [PATCH] io_uring: prevent race on registering fixed files Patch-mainline: Never, specific to 15SP3 -References: 1210414 CVE-2023-1872 +References: bsc#1210414 CVE-2023-1872 in 5.3, io_sqe_files_unregister is called without holding the io_uring ctx lock when in sqpoll,which means it can race with the io_sqe_files_unregister. This diff --git a/patches.suse/ipv6-sr-fix-out-of-bounds-read-when-setting-HMAC-dat.patch b/patches.suse/ipv6-sr-fix-out-of-bounds-read-when-setting-HMAC-dat.patch new file mode 100644 index 0000000..869f8db --- /dev/null +++ b/patches.suse/ipv6-sr-fix-out-of-bounds-read-when-setting-HMAC-dat.patch @@ -0,0 +1,77 @@ +From 4388f1ebeee9ba362b6b94ea587e1006a8721a15 Mon Sep 17 00:00:00 2001 +From: David Lebrun +Date: Fri, 2 Sep 2022 10:45:06 +0100 +Subject: [PATCH] ipv6: sr: fix out-of-bounds read when setting HMAC data. +Git-commit: 84a53580c5d2138c7361c7c3eea5b31827e63b35 +Patch-mainline: v6.0-rc5 +References: bsc#1211592 + +The SRv6 layer allows defining HMAC data that can later be used to sign IPv6 +Segment Routing Headers. This configuration is realised via netlink through +four attributes: SEG6_ATTR_HMACKEYID, SEG6_ATTR_SECRET, SEG6_ATTR_SECRETLEN and +SEG6_ATTR_ALGID. Because the SECRETLEN attribute is decoupled from the actual +length of the SECRET attribute, it is possible to provide invalid combinations +(e.g., secret = "", secretlen = 64). This case is not checked in the code and +with an appropriately crafted netlink message, an out-of-bounds read of up +to 64 bytes (max secret length) can occur past the skb end pointer and into +skb_shared_info: + +Breakpoint 1, seg6_genl_sethmac (skb=, info=) at net/ipv6/seg6.c:208 +208 memcpy(hinfo->secret, secret, slen); +(gdb) bt + #0 seg6_genl_sethmac (skb=, info=) at net/ipv6/seg6.c:208 + #1 0xffffffff81e012e9 in genl_family_rcv_msg_doit (skb=skb@entry=0xffff88800b1f9f00, nlh=nlh@entry=0xffff88800b1b7600, + extack=extack@entry=0xffffc90000ba7af0, ops=ops@entry=0xffffc90000ba7a80, hdrlen=4, net=0xffffffff84237580 , family=, + family=) at net/netlink/genetlink.c:731 + #2 0xffffffff81e01435 in genl_family_rcv_msg (extack=0xffffc90000ba7af0, nlh=0xffff88800b1b7600, skb=0xffff88800b1f9f00, + family=0xffffffff82fef6c0 ) at net/netlink/genetlink.c:775 + #3 genl_rcv_msg (skb=0xffff88800b1f9f00, nlh=0xffff88800b1b7600, extack=0xffffc90000ba7af0) at net/netlink/genetlink.c:792 + #4 0xffffffff81dfffc3 in netlink_rcv_skb (skb=skb@entry=0xffff88800b1f9f00, cb=cb@entry=0xffffffff81e01350 ) + at net/netlink/af_netlink.c:2501 + #5 0xffffffff81e00919 in genl_rcv (skb=0xffff88800b1f9f00) at net/netlink/genetlink.c:803 + #6 0xffffffff81dff6ae in netlink_unicast_kernel (ssk=0xffff888010eec800, skb=0xffff88800b1f9f00, sk=0xffff888004aed000) + at net/netlink/af_netlink.c:1319 + #7 netlink_unicast (ssk=ssk@entry=0xffff888010eec800, skb=skb@entry=0xffff88800b1f9f00, portid=portid@entry=0, nonblock=) + at net/netlink/af_netlink.c:1345 + #8 0xffffffff81dff9a4 in netlink_sendmsg (sock=, msg=0xffffc90000ba7e48, len=) at net/netlink/af_netlink.c:1921 +... +(gdb) p/x ((struct sk_buff *)0xffff88800b1f9f00)->head + ((struct sk_buff *)0xffff88800b1f9f00)->end +$1 = 0xffff88800b1b76c0 +(gdb) p/x secret +$2 = 0xffff88800b1b76c0 +(gdb) p slen +$3 = 64 '@' + +The OOB data can then be read back from userspace by dumping HMAC state. This +commit fixes this by ensuring SECRETLEN cannot exceed the actual length of +SECRET. + +Reported-by: Lucas Leong +Tested: verified that EINVAL is correctly returned when secretlen > len(secret) +Fixes: 4f4853dc1c9c1 ("ipv6: sr: implement API to control SR HMAC structure") +Signed-off-by: David Lebrun +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + net/ipv6/seg6.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c +index 4458e46977fe..c7f5e76d1544 100644 +--- a/net/ipv6/seg6.c ++++ b/net/ipv6/seg6.c +@@ -129,6 +129,11 @@ static int seg6_genl_sethmac(struct sk_buff *skb, struct genl_info *info) + goto out_unlock; + } + ++ if (slen > nla_len(info->attrs[SEG6_ATTR_SECRET])) { ++ err = -EINVAL; ++ goto out_unlock; ++ } ++ + if (hinfo) { + err = seg6_hmac_info_del(net, hmackeyid); + if (err) +-- +2.16.4 + diff --git a/patches.suse/media-dvb-core-Fix-kernel-WARNING-for-blocking-opera.patch b/patches.suse/media-dvb-core-Fix-kernel-WARNING-for-blocking-opera.patch new file mode 100644 index 0000000..6725ab1 --- /dev/null +++ b/patches.suse/media-dvb-core-Fix-kernel-WARNING-for-blocking-opera.patch @@ -0,0 +1,60 @@ +From b8c75e4a1b325ea0a9433fa8834be97b5836b946 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 12 May 2023 16:18:00 +0100 +Subject: [PATCH] media: dvb-core: Fix kernel WARNING for blocking operation in wait_event*() +Git-commit: b8c75e4a1b325ea0a9433fa8834be97b5836b946 +Patch-mainline: v6.4-rc3 +References: CVE-2023-31084 bsc#1210783 + +Using a semaphore in the wait_event*() condition is no good idea. +It hits a kernel WARN_ON() at prepare_to_wait_event() like: + do not call blocking ops when !TASK_RUNNING; state=1 set at + prepare_to_wait_event+0x6d/0x690 + +For avoiding the potential deadlock, rewrite to an open-coded loop +instead. Unlike the loop in wait_event*(), this uses wait_woken() +after the condition check, hence the task state stays consistent. + +CVE-2023-31084 was assigned to this bug. + +Link: https://lore.kernel.org/r/CA+UBctCu7fXn4q41O_3=id1+OdyQ85tZY1x+TkT-6OVBL6KAUw@mail.gmail.com/ + +Link: https://lore.kernel.org/linux-media/20230512151800.1874-1-tiwai@suse.de +Reported-by: Yu Hao +Closes: https://nvd.nist.gov/vuln/detail/CVE-2023-31084 +Signed-off-by: Takashi Iwai +Signed-off-by: Mauro Carvalho Chehab + +--- + drivers/media/dvb-core/dvb_frontend.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +--- a/drivers/media/dvb-core/dvb_frontend.c ++++ b/drivers/media/dvb-core/dvb_frontend.c +@@ -293,14 +293,22 @@ static int dvb_frontend_get_event(struct + } + + if (events->eventw == events->eventr) { +- int ret; ++ struct wait_queue_entry wait; ++ int ret = 0; + + if (flags & O_NONBLOCK) + return -EWOULDBLOCK; + +- ret = wait_event_interruptible(events->wait_queue, +- dvb_frontend_test_event(fepriv, events)); +- ++ init_waitqueue_entry(&wait, current); ++ add_wait_queue(&events->wait_queue, &wait); ++ while (!dvb_frontend_test_event(fepriv, events)) { ++ wait_woken(&wait, TASK_INTERRUPTIBLE, 0); ++ if (signal_pending(current)) { ++ ret = -ERESTARTSYS; ++ break; ++ } ++ } ++ remove_wait_queue(&events->wait_queue, &wait); + if (ret < 0) + return ret; + } diff --git a/patches.suse/media-dvb-core-Fix-use-after-free-due-on-race-condit.patch b/patches.suse/media-dvb-core-Fix-use-after-free-due-on-race-condit.patch new file mode 100644 index 0000000..140516f --- /dev/null +++ b/patches.suse/media-dvb-core-Fix-use-after-free-due-on-race-condit.patch @@ -0,0 +1,138 @@ +From 4172385b0c9ac366dcab78eda48c26814b87ed1a Mon Sep 17 00:00:00 2001 +From: Hyunwoo Kim +Date: Thu, 17 Nov 2022 04:59:23 +0000 +Subject: [PATCH] media: dvb-core: Fix use-after-free due on race condition at dvb_net +Git-commit: 4172385b0c9ac366dcab78eda48c26814b87ed1a +Patch-mainline: v6.4-rc3 +References: CVE-2022-45886 bsc#1205760 + +A race condition may occur between the .disconnect function, which +is called when the device is disconnected, and the dvb_device_open() +function, which is called when the device node is open()ed. +This results in several types of UAFs. + +The root cause of this is that you use the dvb_device_open() function, +which does not implement a conditional statement +that checks 'dvbnet->exit'. + +So, add 'remove_mutex` to protect 'dvbnet->exit' and use +locked_dvb_net_open() function to check 'dvbnet->exit'. + +[mchehab: fix a checkpatch warning] + +Link: https://lore.kernel.org/linux-media/20221117045925.14297-3-imv4bel@gmail.com +Signed-off-by: Hyunwoo Kim +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/media/dvb-core/dvb_net.c | 38 +++++++++++++++++++++++++++++--- + include/media/dvb_net.h | 4 ++++ + 2 files changed, 39 insertions(+), 3 deletions(-) + +diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c +index 8a2febf33ce2..8bb8dd34c223 100644 +--- a/drivers/media/dvb-core/dvb_net.c ++++ b/drivers/media/dvb-core/dvb_net.c +@@ -1564,15 +1564,43 @@ static long dvb_net_ioctl(struct file *file, + return dvb_usercopy(file, cmd, arg, dvb_net_do_ioctl); + } + ++static int locked_dvb_net_open(struct inode *inode, struct file *file) ++{ ++ struct dvb_device *dvbdev = file->private_data; ++ struct dvb_net *dvbnet = dvbdev->priv; ++ int ret; ++ ++ if (mutex_lock_interruptible(&dvbnet->remove_mutex)) ++ return -ERESTARTSYS; ++ ++ if (dvbnet->exit) { ++ mutex_unlock(&dvbnet->remove_mutex); ++ return -ENODEV; ++ } ++ ++ ret = dvb_generic_open(inode, file); ++ ++ mutex_unlock(&dvbnet->remove_mutex); ++ ++ return ret; ++} ++ + static int dvb_net_close(struct inode *inode, struct file *file) + { + struct dvb_device *dvbdev = file->private_data; + struct dvb_net *dvbnet = dvbdev->priv; + ++ mutex_lock(&dvbnet->remove_mutex); ++ + dvb_generic_release(inode, file); + +- if(dvbdev->users == 1 && dvbnet->exit == 1) ++ if (dvbdev->users == 1 && dvbnet->exit == 1) { ++ mutex_unlock(&dvbnet->remove_mutex); + wake_up(&dvbdev->wait_queue); ++ } else { ++ mutex_unlock(&dvbnet->remove_mutex); ++ } ++ + return 0; + } + +@@ -1580,7 +1608,7 @@ static int dvb_net_close(struct inode *inode, struct file *file) + static const struct file_operations dvb_net_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = dvb_net_ioctl, +- .open = dvb_generic_open, ++ .open = locked_dvb_net_open, + .release = dvb_net_close, + .llseek = noop_llseek, + }; +@@ -1599,10 +1627,13 @@ void dvb_net_release (struct dvb_net *dvbnet) + { + int i; + ++ mutex_lock(&dvbnet->remove_mutex); + dvbnet->exit = 1; ++ mutex_unlock(&dvbnet->remove_mutex); ++ + if (dvbnet->dvbdev->users < 1) + wait_event(dvbnet->dvbdev->wait_queue, +- dvbnet->dvbdev->users==1); ++ dvbnet->dvbdev->users == 1); + + dvb_unregister_device(dvbnet->dvbdev); + +@@ -1621,6 +1652,7 @@ int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet, + int i; + + mutex_init(&dvbnet->ioctl_mutex); ++ mutex_init(&dvbnet->remove_mutex); + dvbnet->demux = dmx; + + for (i=0; i +Date: Thu, 17 Nov 2022 04:59:24 +0000 +Subject: [PATCH] media: dvb-core: Fix use-after-free due to race at dvb_register_device() +Git-commit: 627bb528b086b4136315c25d6a447a98ea9448d3 +Patch-mainline: v6.4-rc3 +References: CVE-2022-45884 bsc#1205756 + +dvb_register_device() dynamically allocates fops with kmemdup() +to set the fops->owner. +And these fops are registered in 'file->f_ops' using replace_fops() +in the dvb_device_open() process, and kfree()d in dvb_free_device(). + +However, it is not common to use dynamically allocated fops instead +of 'static const' fops as an argument of replace_fops(), +and UAF may occur. +These UAFs can occur on any dvb type using dvb_register_device(), +such as dvb_dvr, dvb_demux, dvb_frontend, dvb_net, etc. + +So, instead of kfree() the fops dynamically allocated in +dvb_register_device() in dvb_free_device() called during the +.disconnect() process, kfree() it collectively in exit_dvbdev() +called when the dvbdev.c module is removed. + +Link: https://lore.kernel.org/linux-media/20221117045925.14297-4-imv4bel@gmail.com +Signed-off-by: Hyunwoo Kim +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/media/dvb-core/dvbdev.c | 84 ++++++++++++++++++++++++++++++---------- + include/media/dvbdev.h | 15 +++++++ + 2 files changed, 78 insertions(+), 21 deletions(-) + +--- a/drivers/media/dvb-core/dvbdev.c ++++ b/drivers/media/dvb-core/dvbdev.c +@@ -37,6 +37,7 @@ + #include + + static DEFINE_MUTEX(dvbdev_mutex); ++static LIST_HEAD(dvbdevfops_list); + static int dvbdev_debug; + + module_param(dvbdev_debug, int, 0644); +@@ -459,14 +460,15 @@ int dvb_register_device(struct dvb_adapt + enum dvb_device_type type, int demux_sink_pads) + { + struct dvb_device *dvbdev; +- struct file_operations *dvbdevfops; ++ struct file_operations *dvbdevfops = NULL; ++ struct dvbdevfops_node *node = NULL, *new_node = NULL; + struct device *clsdev; + int minor; + int id, ret; + + mutex_lock(&dvbdev_register_lock); + +- if ((id = dvbdev_get_free_id (adap, type)) < 0){ ++ if ((id = dvbdev_get_free_id (adap, type)) < 0) { + mutex_unlock(&dvbdev_register_lock); + *pdvbdev = NULL; + pr_err("%s: couldn't find free device id\n", __func__); +@@ -474,18 +476,45 @@ int dvb_register_device(struct dvb_adapt + } + + *pdvbdev = dvbdev = kzalloc(sizeof(*dvbdev), GFP_KERNEL); +- + if (!dvbdev){ + mutex_unlock(&dvbdev_register_lock); + return -ENOMEM; + } + +- dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL); ++ /* ++ * When a device of the same type is probe()d more than once, ++ * the first allocated fops are used. This prevents memory leaks ++ * that can occur when the same device is probe()d repeatedly. ++ */ ++ list_for_each_entry(node, &dvbdevfops_list, list_head) { ++ if (node->fops->owner == adap->module && ++ node->type == type && ++ node->template == template) { ++ dvbdevfops = node->fops; ++ break; ++ } ++ } + +- if (!dvbdevfops){ +- kfree (dvbdev); +- mutex_unlock(&dvbdev_register_lock); +- return -ENOMEM; ++ if (dvbdevfops == NULL) { ++ dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL); ++ if (!dvbdevfops) { ++ kfree(dvbdev); ++ mutex_unlock(&dvbdev_register_lock); ++ return -ENOMEM; ++ } ++ ++ new_node = kzalloc(sizeof(struct dvbdevfops_node), GFP_KERNEL); ++ if (!new_node) { ++ kfree(dvbdevfops); ++ kfree(dvbdev); ++ mutex_unlock(&dvbdev_register_lock); ++ return -ENOMEM; ++ } ++ ++ new_node->fops = dvbdevfops; ++ new_node->type = type; ++ new_node->template = template; ++ list_add_tail (&new_node->list_head, &dvbdevfops_list); + } + + memcpy(dvbdev, template, sizeof(struct dvb_device)); +@@ -495,20 +524,20 @@ int dvb_register_device(struct dvb_adapt + dvbdev->priv = priv; + dvbdev->fops = dvbdevfops; + init_waitqueue_head (&dvbdev->wait_queue); +- + dvbdevfops->owner = adap->module; +- + list_add_tail (&dvbdev->list_head, &adap->device_list); +- + down_write(&minor_rwsem); + #ifdef CONFIG_DVB_DYNAMIC_MINORS + for (minor = 0; minor < MAX_DVB_MINORS; minor++) + if (dvb_minors[minor] == NULL) + break; +- + if (minor == MAX_DVB_MINORS) { ++ if (new_node) { ++ list_del (&new_node->list_head); ++ kfree(dvbdevfops); ++ kfree(new_node); ++ } + list_del (&dvbdev->list_head); +- kfree(dvbdevfops); + kfree(dvbdev); + up_write(&minor_rwsem); + mutex_unlock(&dvbdev_register_lock); +@@ -517,41 +546,47 @@ int dvb_register_device(struct dvb_adapt + #else + minor = nums2minor(adap->num, type, id); + #endif +- + dvbdev->minor = minor; + dvb_minors[minor] = dvbdev; + up_write(&minor_rwsem); +- + ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads); + if (ret) { + pr_err("%s: dvb_register_media_device failed to create the mediagraph\n", + __func__); +- ++ if (new_node) { ++ list_del (&new_node->list_head); ++ kfree(dvbdevfops); ++ kfree(new_node); ++ } + dvb_media_device_free(dvbdev); + list_del (&dvbdev->list_head); +- kfree(dvbdevfops); + kfree(dvbdev); + mutex_unlock(&dvbdev_register_lock); + return ret; + } + +- mutex_unlock(&dvbdev_register_lock); +- + clsdev = device_create(dvb_class, adap->device, + MKDEV(DVB_MAJOR, minor), + dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id); + if (IS_ERR(clsdev)) { + pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n", + __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); ++ if (new_node) { ++ list_del (&new_node->list_head); ++ kfree(dvbdevfops); ++ kfree(new_node); ++ } + dvb_media_device_free(dvbdev); + list_del (&dvbdev->list_head); +- kfree(dvbdevfops); + kfree(dvbdev); ++ mutex_unlock(&dvbdev_register_lock); + return PTR_ERR(clsdev); + } ++ + dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", + adap->num, dnames[type], id, minor, minor); + ++ mutex_unlock(&dvbdev_register_lock); + return 0; + } + EXPORT_SYMBOL(dvb_register_device); +@@ -580,7 +615,6 @@ void dvb_free_device(struct dvb_device * + if (!dvbdev) + return; + +- kfree (dvbdev->fops); + kfree (dvbdev); + } + EXPORT_SYMBOL(dvb_free_device); +@@ -1072,9 +1106,17 @@ error: + + static void __exit exit_dvbdev(void) + { ++ struct dvbdevfops_node *node, *next; ++ + class_destroy(dvb_class); + cdev_del(&dvb_device_cdev); + unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS); ++ ++ list_for_each_entry_safe(node, next, &dvbdevfops_list, list_head) { ++ list_del (&node->list_head); ++ kfree(node->fops); ++ kfree(node); ++ } + } + + subsys_initcall(init_dvbdev); +--- a/include/media/dvbdev.h ++++ b/include/media/dvbdev.h +@@ -188,6 +188,21 @@ struct dvb_device { + }; + + /** ++ * struct dvbdevfops_node - fops nodes registered in dvbdevfops_list ++ * ++ * @fops: Dynamically allocated fops for ->owner registration ++ * @type: type of dvb_device ++ * @template: dvb_device used for registration ++ * @list_head: list_head for dvbdevfops_list ++ */ ++struct dvbdevfops_node { ++ struct file_operations *fops; ++ enum dvb_device_type type; ++ const struct dvb_device *template; ++ struct list_head list_head; ++}; ++ ++/** + * dvb_register_adapter - Registers a new DVB adapter + * + * @adap: pointer to struct dvb_adapter diff --git a/patches.suse/media-dvb-core-Fix-use-after-free-due-to-race-condit.patch b/patches.suse/media-dvb-core-Fix-use-after-free-due-to-race-condit.patch new file mode 100644 index 0000000..d7a4989 --- /dev/null +++ b/patches.suse/media-dvb-core-Fix-use-after-free-due-to-race-condit.patch @@ -0,0 +1,128 @@ +From 280a8ab81733da8bc442253c700a52c4c0886ffd Mon Sep 17 00:00:00 2001 +From: Hyunwoo Kim +Date: Mon, 21 Nov 2022 06:33:08 +0000 +Subject: [PATCH] media: dvb-core: Fix use-after-free due to race condition at dvb_ca_en50221 +Git-commit: 280a8ab81733da8bc442253c700a52c4c0886ffd +Patch-mainline: v6.4-rc3 +References: CVE-2022-45919 bsc#1205803 + +If the device node of dvb_ca_en50221 is open() and the +device is disconnected, a UAF may occur when calling +close() on the device node. + +The root cause is that wake_up() and wait_event() for +dvbdev->wait_queue are not implemented. + +So implement wait_event() function in dvb_ca_en50221_release() +and add 'remove_mutex' which prevents race condition +for 'ca->exit'. + +[mchehab: fix a checkpatch warning] + +Link: https://lore.kernel.org/linux-media/20221121063308.GA33821@ubuntu +Signed-off-by: Hyunwoo Kim +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/media/dvb-core/dvb_ca_en50221.c | 37 ++++++++++++++++++++++++- + 1 file changed, 36 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c +index b6ca29dfb184..baf64540dc00 100644 +--- a/drivers/media/dvb-core/dvb_ca_en50221.c ++++ b/drivers/media/dvb-core/dvb_ca_en50221.c +@@ -151,6 +151,12 @@ struct dvb_ca_private { + + /* mutex serializing ioctls */ + struct mutex ioctl_mutex; ++ ++ /* A mutex used when a device is disconnected */ ++ struct mutex remove_mutex; ++ ++ /* Whether the device is disconnected */ ++ int exit; + }; + + static void dvb_ca_private_free(struct dvb_ca_private *ca) +@@ -1711,12 +1717,22 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file) + + dprintk("%s\n", __func__); + +- if (!try_module_get(ca->pub->owner)) ++ mutex_lock(&ca->remove_mutex); ++ ++ if (ca->exit) { ++ mutex_unlock(&ca->remove_mutex); ++ return -ENODEV; ++ } ++ ++ if (!try_module_get(ca->pub->owner)) { ++ mutex_unlock(&ca->remove_mutex); + return -EIO; ++ } + + err = dvb_generic_open(inode, file); + if (err < 0) { + module_put(ca->pub->owner); ++ mutex_unlock(&ca->remove_mutex); + return err; + } + +@@ -1741,6 +1757,7 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file) + + dvb_ca_private_get(ca); + ++ mutex_unlock(&ca->remove_mutex); + return 0; + } + +@@ -1760,6 +1777,8 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file) + + dprintk("%s\n", __func__); + ++ mutex_lock(&ca->remove_mutex); ++ + /* mark the CA device as closed */ + ca->open = 0; + dvb_ca_en50221_thread_update_delay(ca); +@@ -1770,6 +1789,13 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file) + + dvb_ca_private_put(ca); + ++ if (dvbdev->users == 1 && ca->exit == 1) { ++ mutex_unlock(&ca->remove_mutex); ++ wake_up(&dvbdev->wait_queue); ++ } else { ++ mutex_unlock(&ca->remove_mutex); ++ } ++ + return err; + } + +@@ -1893,6 +1919,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, + } + + mutex_init(&ca->ioctl_mutex); ++ mutex_init(&ca->remove_mutex); + + if (signal_pending(current)) { + ret = -EINTR; +@@ -1935,6 +1962,14 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca) + + dprintk("%s\n", __func__); + ++ mutex_lock(&ca->remove_mutex); ++ ca->exit = 1; ++ mutex_unlock(&ca->remove_mutex); ++ ++ if (ca->dvbdev->users < 1) ++ wait_event(ca->dvbdev->wait_queue, ++ ca->dvbdev->users == 1); ++ + /* shutdown the thread if there was one */ + kthread_stop(ca->thread); + +-- +2.35.3 + diff --git a/patches.suse/media-dvb-core-Fix-use-after-free-on-race-condition-.patch b/patches.suse/media-dvb-core-Fix-use-after-free-on-race-condition-.patch new file mode 100644 index 0000000..f80d11b --- /dev/null +++ b/patches.suse/media-dvb-core-Fix-use-after-free-on-race-condition-.patch @@ -0,0 +1,179 @@ +From 6769a0b7ee0c3b31e1b22c3fadff2bfb642de23f Mon Sep 17 00:00:00 2001 +From: Hyunwoo Kim +Date: Thu, 17 Nov 2022 04:59:22 +0000 +Subject: [PATCH] media: dvb-core: Fix use-after-free on race condition at dvb_frontend +Git-commit: 6769a0b7ee0c3b31e1b22c3fadff2bfb642de23f +Patch-mainline: v6.4-rc3 +References: CVE-2022-45885 bsc#1205758 + +If the device node of dvb_frontend is open() and the device is +disconnected, many kinds of UAFs may occur when calling close() +on the device node. + +The root cause of this is that wake_up() for dvbdev->wait_queue +is implemented in the dvb_frontend_release() function, but +wait_event() is not implemented in the dvb_frontend_stop() function. + +So, implement wait_event() function in dvb_frontend_stop() and +add 'remove_mutex' which prevents race condition for 'fe->exit'. + +[mchehab: fix a couple of checkpatch warnings and some mistakes at the error handling logic] + +Link: https://lore.kernel.org/linux-media/20221117045925.14297-2-imv4bel@gmail.com +Signed-off-by: Hyunwoo Kim +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/media/dvb-core/dvb_frontend.c | 50 ++++++++++++++++++++++++++++------ + include/media/dvb_frontend.h | 6 +++- + 2 files changed, 47 insertions(+), 9 deletions(-) + +--- a/drivers/media/dvb-core/dvb_frontend.c ++++ b/drivers/media/dvb-core/dvb_frontend.c +@@ -809,15 +809,26 @@ static void dvb_frontend_stop(struct dvb + + dev_dbg(fe->dvb->device, "%s:\n", __func__); + ++ mutex_lock(&fe->remove_mutex); ++ + if (fe->exit != DVB_FE_DEVICE_REMOVED) + fe->exit = DVB_FE_NORMAL_EXIT; + mb(); + +- if (!fepriv->thread) ++ if (!fepriv->thread) { ++ mutex_unlock(&fe->remove_mutex); + return; ++ } + + kthread_stop(fepriv->thread); + ++ mutex_unlock(&fe->remove_mutex); ++ ++ if (fepriv->dvbdev->users < -1) { ++ wait_event(fepriv->dvbdev->wait_queue, ++ fepriv->dvbdev->users == -1); ++ } ++ + sema_init(&fepriv->sem, 1); + fepriv->state = FESTATE_IDLE; + +@@ -2753,9 +2764,13 @@ static int dvb_frontend_open(struct inod + struct dvb_adapter *adapter = fe->dvb; + int ret; + ++ mutex_lock(&fe->remove_mutex); ++ + dev_dbg(fe->dvb->device, "%s:\n", __func__); +- if (fe->exit == DVB_FE_DEVICE_REMOVED) +- return -ENODEV; ++ if (fe->exit == DVB_FE_DEVICE_REMOVED) { ++ ret = -ENODEV; ++ goto err_remove_mutex; ++ } + + if (adapter->mfe_shared) { + mutex_lock(&adapter->mfe_lock); +@@ -2776,8 +2791,10 @@ static int dvb_frontend_open(struct inod + while (mferetry-- && (mfedev->users != -1 || + mfepriv->thread)) { + if (msleep_interruptible(500)) { +- if (signal_pending(current)) +- return -EINTR; ++ if (signal_pending(current)) { ++ ret = -EINTR; ++ goto err_remove_mutex; ++ } + } + } + +@@ -2789,7 +2806,8 @@ static int dvb_frontend_open(struct inod + if (mfedev->users != -1 || + mfepriv->thread) { + mutex_unlock(&adapter->mfe_lock); +- return -EBUSY; ++ ret = -EBUSY; ++ goto err_remove_mutex; + } + adapter->mfe_dvbdev = dvbdev; + } +@@ -2848,6 +2866,8 @@ static int dvb_frontend_open(struct inod + + if (adapter->mfe_shared) + mutex_unlock(&adapter->mfe_lock); ++ ++ mutex_unlock(&fe->remove_mutex); + return ret; + + err3: +@@ -2869,6 +2889,9 @@ err1: + err0: + if (adapter->mfe_shared) + mutex_unlock(&adapter->mfe_lock); ++ ++err_remove_mutex: ++ mutex_unlock(&fe->remove_mutex); + return ret; + } + +@@ -2879,6 +2902,8 @@ static int dvb_frontend_release(struct i + struct dvb_frontend_private *fepriv = fe->frontend_priv; + int ret; + ++ mutex_lock(&fe->remove_mutex); ++ + dev_dbg(fe->dvb->device, "%s:\n", __func__); + + if ((file->f_flags & O_ACCMODE) != O_RDONLY) { +@@ -2900,10 +2925,18 @@ static int dvb_frontend_release(struct i + } + mutex_unlock(&fe->dvb->mdev_lock); + #endif +- if (fe->exit != DVB_FE_NO_EXIT) +- wake_up(&dvbdev->wait_queue); + if (fe->ops.ts_bus_ctrl) + fe->ops.ts_bus_ctrl(fe, 0); ++ ++ if (fe->exit != DVB_FE_NO_EXIT) { ++ mutex_unlock(&fe->remove_mutex); ++ wake_up(&dvbdev->wait_queue); ++ } else { ++ mutex_unlock(&fe->remove_mutex); ++ } ++ ++ } else { ++ mutex_unlock(&fe->remove_mutex); + } + + dvb_frontend_put(fe); +@@ -3000,6 +3033,7 @@ int dvb_register_frontend(struct dvb_ada + fepriv = fe->frontend_priv; + + kref_init(&fe->refcount); ++ mutex_init(&fe->remove_mutex); + + /* + * After initialization, there need to be two references: one +--- a/include/media/dvb_frontend.h ++++ b/include/media/dvb_frontend.h +@@ -680,7 +680,10 @@ struct dtv_frontend_properties { + * @id: Frontend ID + * @exit: Used to inform the DVB core that the frontend + * thread should exit (usually, means that the hardware +- * got disconnected. ++ * got disconnected). ++ * @remove_mutex: mutex that avoids a race condition between a callback ++ * called when the hardware is disconnected and the ++ * file_operations of dvb_frontend. + */ + + struct dvb_frontend { +@@ -698,6 +701,7 @@ struct dvb_frontend { + int (*callback)(void *adapter_priv, int component, int cmd, int arg); + int id; + unsigned int exit; ++ struct mutex remove_mutex; + }; + + /** diff --git a/patches.suse/media-dvbdev-Fix-memleak-in-dvb_register_device.patch b/patches.suse/media-dvbdev-Fix-memleak-in-dvb_register_device.patch new file mode 100644 index 0000000..a6798b5 --- /dev/null +++ b/patches.suse/media-dvbdev-Fix-memleak-in-dvb_register_device.patch @@ -0,0 +1,37 @@ +From 167faadfcf9339088910e9e85a1b711fcbbef8e9 Mon Sep 17 00:00:00 2001 +From: Dinghao Liu +Date: Mon, 24 Aug 2020 14:27:46 +0200 +Subject: [PATCH] media: dvbdev: Fix memleak in dvb_register_device +Git-commit: 167faadfcf9339088910e9e85a1b711fcbbef8e9 +Patch-mainline: v5.11-rc1 +References: CVE-2022-45884 bsc#1205756 + +When device_create() fails, dvbdev and dvbdevfops should +be freed just like when dvb_register_media_device() fails. + +Signed-off-by: Dinghao Liu +Signed-off-by: Sean Young +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/media/dvb-core/dvbdev.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c +index 959fa2820259..5ff7bedee247 100644 +--- a/drivers/media/dvb-core/dvbdev.c ++++ b/drivers/media/dvb-core/dvbdev.c +@@ -539,6 +539,9 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, + if (IS_ERR(clsdev)) { + pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n", + __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); ++ dvb_media_device_free(dvbdev); ++ kfree(dvbdevfops); ++ kfree(dvbdev); + return PTR_ERR(clsdev); + } + dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", +-- +2.35.3 + diff --git a/patches.suse/media-dvbdev-fix-error-logic-at-dvb_register_device.patch b/patches.suse/media-dvbdev-fix-error-logic-at-dvb_register_device.patch new file mode 100644 index 0000000..ee4a8fb --- /dev/null +++ b/patches.suse/media-dvbdev-fix-error-logic-at-dvb_register_device.patch @@ -0,0 +1,55 @@ +From 1fec2ecc252301110e4149e6183fa70460d29674 Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Wed, 9 Jun 2021 14:32:29 +0200 +Subject: [PATCH] media: dvbdev: fix error logic at dvb_register_device() +Git-commit: 1fec2ecc252301110e4149e6183fa70460d29674 +Patch-mainline: v5.14-rc1 +References: CVE-2022-45884 bsc#1205756 + +As reported by smatch: + + drivers/media/dvb-core/dvbdev.c: drivers/media/dvb-core/dvbdev.c:510 dvb_register_device() warn: '&dvbdev->list_head' not removed from list + drivers/media/dvb-core/dvbdev.c: drivers/media/dvb-core/dvbdev.c:530 dvb_register_device() warn: '&dvbdev->list_head' not removed from list + drivers/media/dvb-core/dvbdev.c: drivers/media/dvb-core/dvbdev.c:545 dvb_register_device() warn: '&dvbdev->list_head' not removed from list + +The error logic inside dvb_register_device() doesn't remove +devices from the dvb_adapter_list in case of errors. + +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/media/dvb-core/dvbdev.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c +index 3862ddc86ec4..795d9bfaba5c 100644 +--- a/drivers/media/dvb-core/dvbdev.c ++++ b/drivers/media/dvb-core/dvbdev.c +@@ -506,6 +506,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, + break; + + if (minor == MAX_DVB_MINORS) { ++ list_del (&dvbdev->list_head); + kfree(dvbdevfops); + kfree(dvbdev); + up_write(&minor_rwsem); +@@ -526,6 +527,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, + __func__); + + dvb_media_device_free(dvbdev); ++ list_del (&dvbdev->list_head); + kfree(dvbdevfops); + kfree(dvbdev); + mutex_unlock(&dvbdev_register_lock); +@@ -541,6 +543,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, + pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n", + __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); + dvb_media_device_free(dvbdev); ++ list_del (&dvbdev->list_head); + kfree(dvbdevfops); + kfree(dvbdev); + return PTR_ERR(clsdev); +-- +2.35.3 + diff --git a/patches.suse/media-media-dvb-Use-kmemdup-rather-than-duplicating-.patch b/patches.suse/media-media-dvb-Use-kmemdup-rather-than-duplicating-.patch new file mode 100644 index 0000000..09ce1f5 --- /dev/null +++ b/patches.suse/media-media-dvb-Use-kmemdup-rather-than-duplicating-.patch @@ -0,0 +1,71 @@ +From f6af820ef1be58c2e4b81aa479b9f109eb6344ce Mon Sep 17 00:00:00 2001 +From: Fuqian Huang +Date: Wed, 3 Jul 2019 13:28:37 -0300 +Subject: [PATCH] media: media/dvb: Use kmemdup rather than duplicating its implementation +Git-commit: f6af820ef1be58c2e4b81aa479b9f109eb6344ce +Patch-mainline: v5.4-rc1 +References: CVE-2022-45884 bsc#1205756 + +kmemdup is introduced to duplicate a region of memory in a neat way. +Rather than kmalloc/kzalloc + memcpy, which the programmer needs to +write the size twice (sometimes lead to mistakes), kmemdup improves +readability, leads to smaller code and also reduce the chances of mistakes. +Suggestion to use kmemdup rather than using kmalloc/kzalloc + memcpy. + +Signed-off-by: Fuqian Huang +Signed-off-by: Sean Young +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/media/dvb-core/dvbdev.c | 3 +-- + drivers/media/dvb-frontends/drx39xyj/drxj.c | 5 ++--- + 2 files changed, 3 insertions(+), 5 deletions(-) + +diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c +index a3393cd4e584..d7532f5a352a 100644 +--- a/drivers/media/dvb-core/dvbdev.c ++++ b/drivers/media/dvb-core/dvbdev.c +@@ -476,7 +476,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, + return -ENOMEM; + } + +- dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL); ++ dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL); + + if (!dvbdevfops){ + kfree (dvbdev); +@@ -492,7 +492,6 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, + dvbdev->fops = dvbdevfops; + init_waitqueue_head (&dvbdev->wait_queue); + +- memcpy(dvbdevfops, template->fops, sizeof(struct file_operations)); + dvbdevfops->owner = adap->module; + + list_add_tail (&dvbdev->list_head, &adap->device_list); +diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c +index a6876fa48753..2f5af4813a74 100644 +--- a/drivers/media/dvb-frontends/drx39xyj/drxj.c ++++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c +@@ -12287,7 +12287,8 @@ struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c) + if (state == NULL) + goto error; + +- demod = kmalloc(sizeof(struct drx_demod_instance), GFP_KERNEL); ++ demod = kmemdup(&drxj_default_demod_g, ++ sizeof(struct drx_demod_instance), GFP_KERNEL); + if (demod == NULL) + goto error; + +@@ -12311,8 +12312,6 @@ struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c) + state->demod = demod; + + /* setup the demod data */ +- memcpy(demod, &drxj_default_demod_g, sizeof(struct drx_demod_instance)); +- + demod->my_i2c_dev_addr = demod_addr; + demod->my_common_attr = demod_comm_attr; + demod->my_i2c_dev_addr->user_data = state; +-- +2.35.3 + diff --git a/patches.suse/media-ttusb-dec-fix-memory-leak-in-ttusb_dec_exit_dv.patch b/patches.suse/media-ttusb-dec-fix-memory-leak-in-ttusb_dec_exit_dv.patch new file mode 100644 index 0000000..572cc45 --- /dev/null +++ b/patches.suse/media-ttusb-dec-fix-memory-leak-in-ttusb_dec_exit_dv.patch @@ -0,0 +1,43 @@ +From 517a281338322ff8293f988771c98aaa7205e457 Mon Sep 17 00:00:00 2001 +From: Hyunwoo Kim +Date: Thu, 17 Nov 2022 04:59:25 +0000 +Subject: [PATCH] media: ttusb-dec: fix memory leak in ttusb_dec_exit_dvb() +Git-commit: 517a281338322ff8293f988771c98aaa7205e457 +Patch-mainline: v6.4-rc3 +References: CVE-2022-45887 bsc#1205762 + +Since dvb_frontend_detach() is not called in ttusb_dec_exit_dvb(), +which is called when the device is disconnected, dvb_frontend_free() +is not finally called. + +This causes a memory leak just by repeatedly plugging and +unplugging the device. + +Fix this issue by adding dvb_frontend_detach() to ttusb_dec_exit_dvb(). + +Link: https://lore.kernel.org/linux-media/20221117045925.14297-5-imv4bel@gmail.com +Signed-off-by: Hyunwoo Kim +Signed-off-by: Mauro Carvalho Chehab +Acked-by: Takashi Iwai + +--- + drivers/media/usb/ttusb-dec/ttusb_dec.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c +index 38822cedd93a..c4474d4c44e2 100644 +--- a/drivers/media/usb/ttusb-dec/ttusb_dec.c ++++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c +@@ -1544,8 +1544,7 @@ static void ttusb_dec_exit_dvb(struct ttusb_dec *dec) + dvb_dmx_release(&dec->demux); + if (dec->fe) { + dvb_unregister_frontend(dec->fe); +- if (dec->fe->ops.release) +- dec->fe->ops.release(dec->fe); ++ dvb_frontend_detach(dec->fe); + } + dvb_unregister_adapter(&dec->adapter); + } +-- +2.35.3 + diff --git a/patches.suse/net-sched-act_mirred-better-wording-on-protection-ag.patch b/patches.suse/net-sched-act_mirred-better-wording-on-protection-ag.patch new file mode 100644 index 0000000..386477f --- /dev/null +++ b/patches.suse/net-sched-act_mirred-better-wording-on-protection-ag.patch @@ -0,0 +1,81 @@ +From: Davide Caratti +Date: Fri, 20 Jan 2023 18:01:39 +0100 +Subject: net/sched: act_mirred: better wording on protection against excessive stack growth +Patch-mainline: v6.3-rc1 +Git-commit: 78dcdffe0418ac8f3f057f26fe71ccf4d8ed851f +References: CVE-2022-4269 bsc#1206024 + +with commit e2ca070f89ec ("net: sched: protect against stack overflow in +TC act_mirred"), act_mirred protected itself against excessive stack growth +using per_cpu counter of nested calls to tcf_mirred_act(), and capping it +to MIRRED_RECURSION_LIMIT. However, such protection does not detect +recursion/loops in case the packet is enqueued to the backlog (for example, +when the mirred target device has RPS or skb timestamping enabled). Change +the wording from "recursion" to "nesting" to make it more clear to readers. + +CC: Jamal Hadi Salim +Signed-off-by: Davide Caratti +Reviewed-by: Marcelo Ricardo Leitner +Acked-by: Jamal Hadi Salim +Signed-off-by: Paolo Abeni +Acked-by: Michal Kubecek + +--- + net/sched/act_mirred.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +--- a/net/sched/act_mirred.c ++++ b/net/sched/act_mirred.c +@@ -27,8 +27,8 @@ + static LIST_HEAD(mirred_list); + static DEFINE_SPINLOCK(mirred_list_lock); + +-#define MIRRED_RECURSION_LIMIT 4 +-static DEFINE_PER_CPU(unsigned int, mirred_rec_level); ++#define MIRRED_NEST_LIMIT 4 ++static DEFINE_PER_CPU(unsigned int, mirred_nest_level); + + static bool tcf_mirred_is_act_redirect(int action) + { +@@ -226,7 +226,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, + struct sk_buff *skb2 = skb; + bool m_mac_header_xmit; + struct net_device *dev; +- unsigned int rec_level; ++ unsigned int nest_level; + int retval, err = 0; + bool use_reinsert; + bool want_ingress; +@@ -236,11 +236,11 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, + int mac_len; + bool at_nh; + +- rec_level = __this_cpu_inc_return(mirred_rec_level); +- if (unlikely(rec_level > MIRRED_RECURSION_LIMIT)) { ++ nest_level = __this_cpu_inc_return(mirred_nest_level); ++ if (unlikely(nest_level > MIRRED_NEST_LIMIT)) { + net_warn_ratelimited("Packet exceeded mirred recursion limit on dev %s\n", + netdev_name(skb->dev)); +- __this_cpu_dec(mirred_rec_level); ++ __this_cpu_dec(mirred_nest_level); + return TC_ACT_SHOT; + } + +@@ -304,7 +304,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, + err = tcf_mirred_forward(res->ingress, skb); + if (err) + tcf_action_inc_overlimit_qstats(&m->common); +- __this_cpu_dec(mirred_rec_level); ++ __this_cpu_dec(mirred_nest_level); + return TC_ACT_CONSUMED; + } + } +@@ -316,7 +316,7 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, + if (tcf_mirred_is_act_redirect(m_eaction)) + retval = TC_ACT_SHOT; + } +- __this_cpu_dec(mirred_rec_level); ++ __this_cpu_dec(mirred_nest_level); + + return retval; + } diff --git a/patches.suse/net-sched-act_mirred-refactor-the-handle-of-xmit.patch b/patches.suse/net-sched-act_mirred-refactor-the-handle-of-xmit.patch new file mode 100644 index 0000000..0af2471 --- /dev/null +++ b/patches.suse/net-sched-act_mirred-refactor-the-handle-of-xmit.patch @@ -0,0 +1,73 @@ +From: wenxu +Date: Wed, 25 Nov 2020 12:01:22 +0800 +Subject: net/sched: act_mirred: refactor the handle of xmit +Patch-mainline: v5.11-rc1 +Git-commit: fa6d639930ee5cd3f932cc314f3407f07a06582d +References: CVE-2022-4269 bsc#1206024 + +This one is prepare for the next patch. + +Signed-off-by: wenxu +Signed-off-by: Jakub Kicinski +Acked-by: Michal Kubecek + +--- + include/net/sch_generic.h | 5 ----- + net/sched/act_mirred.c | 21 +++++++++++++++------ + 2 files changed, 15 insertions(+), 11 deletions(-) + +--- a/include/net/sch_generic.h ++++ b/include/net/sch_generic.h +@@ -1296,9 +1296,4 @@ void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp, + void mini_qdisc_pair_init(struct mini_Qdisc_pair *miniqp, struct Qdisc *qdisc, + struct mini_Qdisc __rcu **p_miniq); + +-static inline int skb_tc_reinsert(struct sk_buff *skb, struct tcf_result *res) +-{ +- return res->ingress ? netif_receive_skb(skb) : dev_queue_xmit(skb); +-} +- + #endif +--- a/net/sched/act_mirred.c ++++ b/net/sched/act_mirred.c +@@ -207,6 +207,18 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla, + return err; + } + ++static int tcf_mirred_forward(bool want_ingress, struct sk_buff *skb) ++{ ++ int err; ++ ++ if (!want_ingress) ++ err = dev_queue_xmit(skb); ++ else ++ err = netif_receive_skb(skb); ++ ++ return err; ++} ++ + static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, + struct tcf_result *res) + { +@@ -291,18 +303,15 @@ static int tcf_mirred_act(struct sk_buff *skb, const struct tc_action *a, + /* let's the caller reinsert the packet, if possible */ + if (use_reinsert) { + res->ingress = want_ingress; +- if (skb_tc_reinsert(skb, res)) ++ err = tcf_mirred_forward(res->ingress, skb); ++ if (err) + tcf_action_inc_overlimit_qstats(&m->common); + __this_cpu_dec(mirred_rec_level); + return TC_ACT_CONSUMED; + } + } + +- if (!want_ingress) +- err = dev_queue_xmit(skb2); +- else +- err = netif_receive_skb(skb2); +- ++ err = tcf_mirred_forward(want_ingress, skb2); + if (err) { + out: + tcf_action_inc_overlimit_qstats(&m->common); diff --git a/patches.suse/net-sched-sch_qfq-prevent-slab-out-of-bounds-in-qfq_.patch b/patches.suse/net-sched-sch_qfq-prevent-slab-out-of-bounds-in-qfq_.patch new file mode 100644 index 0000000..2a3c1ea --- /dev/null +++ b/patches.suse/net-sched-sch_qfq-prevent-slab-out-of-bounds-in-qfq_.patch @@ -0,0 +1,134 @@ +From 00a67b7f270eace6e88037f39d01271e7282fe3c Mon Sep 17 00:00:00 2001 +From: Gwangun Jung +Date: Thu, 13 Apr 2023 19:35:54 +0900 +Subject: [PATCH] net: sched: sch_qfq: prevent slab-out-of-bounds in + qfq_activate_agg +Git-commit: 3037933448f60f9acb705997eae62013ecb81e0d +Patch-mainline: v6.3 +References: bsc#1210940 CVE-2023-31436 + +If the TCA_QFQ_LMAX value is not offered through nlattr, lmax is determined by the MTU value of the network device. +The MTU of the loopback device can be set up to 2^31-1. +As a result, it is possible to have an lmax value that exceeds QFQ_MIN_LMAX. + +Due to the invalid lmax value, an index is generated that exceeds the QFQ_MAX_INDEX(=24) value, causing out-of-bounds read/write errors. + +The following reports a oob access: + +[ 84.582666] BUG: KASAN: slab-out-of-bounds in qfq_activate_agg.constprop.0 (net/sched/sch_qfq.c:1027 net/sched/sch_qfq.c:1060 net/sched/sch_qfq.c:1313) +[ 84.583267] Read of size 4 at addr ffff88810f676948 by task ping/301 +[ 84.583686] +[ 84.583797] CPU: 3 PID: 301 Comm: ping Not tainted 6.3.0-rc5 #1 +[ 84.584164] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014 +[ 84.584644] Call Trace: +[ 84.584787] +[ 84.584906] dump_stack_lvl (lib/dump_stack.c:107 (discriminator 1)) +[ 84.585108] print_report (mm/kasan/report.c:320 mm/kasan/report.c:430) +[ 84.585570] kasan_report (mm/kasan/report.c:538) +[ 84.585988] qfq_activate_agg.constprop.0 (net/sched/sch_qfq.c:1027 net/sched/sch_qfq.c:1060 net/sched/sch_qfq.c:1313) +[ 84.586599] qfq_enqueue (net/sched/sch_qfq.c:1255) +[ 84.587607] dev_qdisc_enqueue (net/core/dev.c:3776) +[ 84.587749] __dev_queue_xmit (./include/net/sch_generic.h:186 net/core/dev.c:3865 net/core/dev.c:4212) +[ 84.588763] ip_finish_output2 (./include/net/neighbour.h:546 net/ipv4/ip_output.c:228) +[ 84.589460] ip_output (net/ipv4/ip_output.c:430) +[ 84.590132] ip_push_pending_frames (./include/net/dst.h:444 net/ipv4/ip_output.c:126 net/ipv4/ip_output.c:1586 net/ipv4/ip_output.c:1606) +[ 84.590285] raw_sendmsg (net/ipv4/raw.c:649) +[ 84.591960] sock_sendmsg (net/socket.c:724 net/socket.c:747) +[ 84.592084] __sys_sendto (net/socket.c:2142) +[ 84.593306] __x64_sys_sendto (net/socket.c:2150) +[ 84.593779] do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80) +[ 84.593902] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120) +[ 84.594070] RIP: 0033:0x7fe568032066 +[ 84.594192] Code: 0e 0d 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b8 0f 1f 00 41 89 ca 64 8b 04 25 18 00 00 00 85 c09[ 84.594796] RSP: 002b:00007ffce388b4e8 EFLAGS: 00000246 ORIG_RAX: 000000000000002c + +Code starting with the faulting instruction +=========================================== +[ 84.595047] RAX: ffffffffffffffda RBX: 00007ffce388cc70 RCX: 00007fe568032066 +[ 84.595281] RDX: 0000000000000040 RSI: 00005605fdad6d10 RDI: 0000000000000003 +[ 84.595515] RBP: 00005605fdad6d10 R08: 00007ffce388eeec R09: 0000000000000010 +[ 84.595749] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000040 +[ 84.595984] R13: 00007ffce388cc30 R14: 00007ffce388b4f0 R15: 0000001d00000001 +[ 84.596218] +[ 84.596295] +[ 84.596351] Allocated by task 291: +[ 84.596467] kasan_save_stack (mm/kasan/common.c:46) +[ 84.596597] kasan_set_track (mm/kasan/common.c:52) +[ 84.596725] __kasan_kmalloc (mm/kasan/common.c:384) +[ 84.596852] __kmalloc_node (./include/linux/kasan.h:196 mm/slab_common.c:967 mm/slab_common.c:974) +[ 84.596979] qdisc_alloc (./include/linux/slab.h:610 ./include/linux/slab.h:731 net/sched/sch_generic.c:938) +[ 84.597100] qdisc_create (net/sched/sch_api.c:1244) +[ 84.597222] tc_modify_qdisc (net/sched/sch_api.c:1680) +[ 84.597357] rtnetlink_rcv_msg (net/core/rtnetlink.c:6174) +[ 84.597495] netlink_rcv_skb (net/netlink/af_netlink.c:2574) +[ 84.597627] netlink_unicast (net/netlink/af_netlink.c:1340 net/netlink/af_netlink.c:1365) +[ 84.597759] netlink_sendmsg (net/netlink/af_netlink.c:1942) +[ 84.597891] sock_sendmsg (net/socket.c:724 net/socket.c:747) +[ 84.598016] ____sys_sendmsg (net/socket.c:2501) +[ 84.598147] ___sys_sendmsg (net/socket.c:2557) +[ 84.598275] __sys_sendmsg (./include/linux/file.h:31 net/socket.c:2586) +[ 84.598399] do_syscall_64 (arch/x86/entry/common.c:50 arch/x86/entry/common.c:80) +[ 84.598520] entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:120) +[ 84.598688] +[ 84.598744] The buggy address belongs to the object at ffff88810f674000 +[ 84.598744] which belongs to the cache kmalloc-8k of size 8192 +[ 84.599135] The buggy address is located 2664 bytes to the right of +[ 84.599135] allocated 7904-byte region [ffff88810f674000, ffff88810f675ee0) +[ 84.599544] +[ 84.599598] The buggy address belongs to the physical page: +[ 84.599777] page:00000000e638567f refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10f670 +[ 84.600074] head:00000000e638567f order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0 +[ 84.600330] flags: 0x200000000010200(slab|head|node=0|zone=2) +[ 84.600517] raw: 0200000000010200 ffff888100043180 dead000000000122 0000000000000000 +[ 84.600764] raw: 0000000000000000 0000000080020002 00000001ffffffff 0000000000000000 +[ 84.601009] page dumped because: kasan: bad access detected +[ 84.601187] +[ 84.601241] Memory state around the buggy address: +[ 84.601396] ffff88810f676800: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +[ 84.601620] ffff88810f676880: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +[ 84.601845] >ffff88810f676900: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +[ 84.602069] ^ +[ 84.602243] ffff88810f676980: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +[ 84.602468] ffff88810f676a00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc +[ 84.602693] ================================================================== +[ 84.602924] Disabling lock debugging due to kernel taint + +Fixes: 3015f3d2a3cd ("pkt_sched: enable QFQ to support TSO/GSO") +Reported-by: Gwangun Jung +Signed-off-by: Gwangun Jung +Acked-by: Jamal Hadi Salim +Signed-off-by: David S. Miller +Signed-off-by: Denis Kirjanov +--- + net/sched/sch_qfq.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c +index 0b05ac7c848e..05451c33634d 100644 +--- a/net/sched/sch_qfq.c ++++ b/net/sched/sch_qfq.c +@@ -421,15 +421,16 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, + } else + weight = 1; + +- if (tb[TCA_QFQ_LMAX]) { ++ if (tb[TCA_QFQ_LMAX]) + lmax = nla_get_u32(tb[TCA_QFQ_LMAX]); +- if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) { +- pr_notice("qfq: invalid max length %u\n", lmax); +- return -EINVAL; +- } +- } else ++ else + lmax = psched_mtu(qdisc_dev(sch)); + ++ if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) { ++ pr_notice("qfq: invalid max length %u\n", lmax); ++ return -EINVAL; ++ } ++ + inv_w = ONE_FP / weight; + weight = ONE_FP / inv_w; + +-- +2.16.4 + diff --git a/patches.suse/netfilter-nf_tables-deactivate-anonymous-set-from-pr.patch b/patches.suse/netfilter-nf_tables-deactivate-anonymous-set-from-pr.patch new file mode 100644 index 0000000..3d72ddd --- /dev/null +++ b/patches.suse/netfilter-nf_tables-deactivate-anonymous-set-from-pr.patch @@ -0,0 +1,112 @@ +From: Pablo Neira Ayuso +Date: Tue, 2 May 2023 10:25:24 +0200 +Subject: netfilter: nf_tables: deactivate anonymous set from preparation phase +Patch-mainline: v6.4-rc1 +Git-commit: c1592a89942e9678f7d9c8030efa777c0d57edab +References: CVE-2023-32233 bsc#1211043 + +Toggle deleted anonymous sets as inactive in the next generation, so +users cannot perform any update on it. Clear the generation bitmask +in case the transaction is aborted. + +The following KASAN splat shows a set element deletion for a bound +anonymous set that has been already removed in the same transaction. + +[ 64.921510] ================================================================== +[ 64.923123] BUG: KASAN: wild-memory-access in nf_tables_commit+0xa24/0x1490 [nf_tables] +[ 64.924745] Write of size 8 at addr dead000000000122 by task test/890 +[ 64.927903] CPU: 3 PID: 890 Comm: test Not tainted 6.3.0+ #253 +[ 64.931120] Call Trace: +[ 64.932699] +[ 64.934292] dump_stack_lvl+0x33/0x50 +[ 64.935908] ? nf_tables_commit+0xa24/0x1490 [nf_tables] +[ 64.937551] kasan_report+0xda/0x120 +[ 64.939186] ? nf_tables_commit+0xa24/0x1490 [nf_tables] +[ 64.940814] nf_tables_commit+0xa24/0x1490 [nf_tables] +[ 64.942452] ? __kasan_slab_alloc+0x2d/0x60 +[ 64.944070] ? nf_tables_setelem_notify+0x190/0x190 [nf_tables] +[ 64.945710] ? kasan_set_track+0x21/0x30 +[ 64.947323] nfnetlink_rcv_batch+0x709/0xd90 [nfnetlink] +[ 64.948898] ? nfnetlink_rcv_msg+0x480/0x480 [nfnetlink] + +Signed-off-by: Pablo Neira Ayuso +Acked-by: Michal Kubecek + +--- + include/net/netfilter/nf_tables.h | 1 + + net/netfilter/nf_tables_api.c | 12 ++++++++++++ + net/netfilter/nft_dynset.c | 2 +- + net/netfilter/nft_lookup.c | 2 +- + net/netfilter/nft_objref.c | 2 +- + 5 files changed, 16 insertions(+), 3 deletions(-) + +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -507,6 +507,7 @@ struct nft_set_binding { + }; + + enum nft_trans_phase; ++void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set); + void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set, + struct nft_set_binding *binding, + enum nft_trans_phase phase); +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -4431,12 +4431,24 @@ static void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set, + } + } + ++void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set) ++{ ++ if (nft_set_is_anonymous(set)) ++ nft_clear(ctx->net, set); ++ ++ set->use++; ++} ++EXPORT_SYMBOL_GPL(nf_tables_activate_set); ++ + void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set, + struct nft_set_binding *binding, + enum nft_trans_phase phase) + { + switch (phase) { + case NFT_TRANS_PREPARE: ++ if (nft_set_is_anonymous(set)) ++ nft_deactivate_next(ctx->net, set); ++ + set->use--; + return; + case NFT_TRANS_ABORT: +--- a/net/netfilter/nft_dynset.c ++++ b/net/netfilter/nft_dynset.c +@@ -238,7 +238,7 @@ static void nft_dynset_activate(const struct nft_ctx *ctx, + { + struct nft_dynset *priv = nft_expr_priv(expr); + +- priv->set->use++; ++ nf_tables_activate_set(ctx, priv->set); + } + + static void nft_dynset_destroy(const struct nft_ctx *ctx, +--- a/net/netfilter/nft_lookup.c ++++ b/net/netfilter/nft_lookup.c +@@ -132,7 +132,7 @@ static void nft_lookup_activate(const struct nft_ctx *ctx, + { + struct nft_lookup *priv = nft_expr_priv(expr); + +- priv->set->use++; ++ nf_tables_activate_set(ctx, priv->set); + } + + static void nft_lookup_destroy(const struct nft_ctx *ctx, +--- a/net/netfilter/nft_objref.c ++++ b/net/netfilter/nft_objref.c +@@ -180,7 +180,7 @@ static void nft_objref_map_activate(const struct nft_ctx *ctx, + { + struct nft_objref_map *priv = nft_expr_priv(expr); + +- priv->set->use++; ++ nf_tables_activate_set(ctx, priv->set); + } + + static void nft_objref_map_destroy(const struct nft_ctx *ctx, diff --git a/patches.suse/timens-Forbid-changing-time-namespace-for-an-io_urin.patch b/patches.suse/timens-Forbid-changing-time-namespace-for-an-io_urin.patch new file mode 100644 index 0000000..6cc0a41 --- /dev/null +++ b/patches.suse/timens-Forbid-changing-time-namespace-for-an-io_urin.patch @@ -0,0 +1,83 @@ +From 9e9e8c54554066d4ba4bf1eeaba9a3b98c480cc8 Mon Sep 17 00:00:00 2001 +From: Gabriel Krisman Bertazi +Date: Mon, 1 May 2023 23:19:53 -0400 +Subject: [PATCH] timens: Forbid changing time namespace for an io_uring + process +Patch-mainline: Never, specific to 15SP3 +References: bsc#1208474 CVE-2023-23586 + +Even if single-threaded from a userspace point of view, io-uring applications +spawn kernelspace workers that partially share mm_struct with the original task. + +Allowing the time namespace to be changed for such tasks open doors for +race-conditions that can leak kernel memory. Newer kernels already fix this by +completely reworking the way io-workers work that avoid the shared mm issue, but +older kernels are still vulnerable. This patch avoids the issue by preventing +time namespaces from being set when a task has created io-workers. + +Signed-off-by: Gabriel Krisman Bertazi +--- + fs/io_uring.c | 13 +++++++++++++ + include/linux/sched/task.h | 9 +++++++++ + lib/is_single_threaded.c | 3 +++ + 3 files changed, 25 insertions(+) + +diff --git a/fs/io_uring.c b/fs/io_uring.c +index 66d3a2420aaf..6e0cd421aaee 100644 +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -2440,6 +2440,19 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr, + return submitted; + } + ++static int __io_uring_fd(const void *arg, struct file *file, ++ unsigned int fd) ++{ ++ return file->f_op == &io_uring_fops; ++} ++ ++bool current_has_io_workers(void) ++{ ++ if (iterate_fd(current->files, 0, __io_uring_fd, NULL)) ++ return true; ++ return false; ++} ++ + static int io_sq_thread(void *data) + { + struct io_ring_ctx *ctx = data; +diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h +index f1879884238e..4569dd5c2054 100644 +--- a/include/linux/sched/task.h ++++ b/include/linux/sched/task.h +@@ -176,4 +176,13 @@ static inline void task_unlock(struct task_struct *p) + spin_unlock(&p->alloc_lock); + } + ++#if defined(CONFIG_IO_URING) ++extern bool current_has_io_workers(void); ++#else ++static inline bool current_has_io_workers(void) ++{ ++ return false; ++} ++#endif ++ + #endif /* _LINUX_SCHED_TASK_H */ +diff --git a/lib/is_single_threaded.c b/lib/is_single_threaded.c +index 8c98b20bfc41..9717ff883497 100644 +--- a/lib/is_single_threaded.c ++++ b/lib/is_single_threaded.c +@@ -22,6 +22,9 @@ bool current_is_single_threaded(void) + if (atomic_read(&task->signal->live) != 1) + return false; + ++ if (current_has_io_workers()) ++ return false; ++ + if (atomic_read(&mm->mm_users) == 1) + return true; + +-- +2.40.1 + diff --git a/series.conf b/series.conf index c3d205b..ad5c92c 100644 --- a/series.conf +++ b/series.conf @@ -781,6 +781,7 @@ patches.suse/media-fdp1-Reduce-FCP-not-found-message-level-to-deb.patch patches.suse/media-MAINTAINERS-hantro-Fix-typo-in-a-filepath.patch patches.suse/media-MAINTAINERS-Remove-zoran-driver.patch + patches.suse/media-media-dvb-Use-kmemdup-rather-than-duplicating-.patch patches.suse/media-em28xx-modules-workqueue-not-inited-for-2nd-de.patch patches.suse/media-tm6000-double-free-if-usb-disconnect-while-str.patch patches.suse/media-rc-imon-Allow-iMON-RC-protocol-for-ffdc-7e-dev.patch @@ -18155,6 +18156,7 @@ patches.suse/media-ipu3-cio2-Validate-mbus-format-in-setting-subd.patch patches.suse/media-ipu3-cio2-Make-the-field-on-subdev-format-V4L2.patch patches.suse/media-ipu3-cio2-Remove-traces-of-returned-buffers.patch + patches.suse/media-dvbdev-Fix-memleak-in-dvb_register_device.patch patches.suse/media-solo6x10-fix-missing-snd_card_free-in-error-ha.patch patches.suse/media-sunxi-cir-ensure-IR-is-handled-when-it-is-cont.patch patches.suse/media-siano-fix-memory-leak-of-debugfs-members-in-sm.patch @@ -18219,6 +18221,7 @@ patches.suse/ibmvnic-Correctly-re-enable-interrupts-in-NAPI-polli.patch patches.suse/ibmvnic-Use-netdev_alloc_skb-instead-of-alloc_skb-to.patch patches.suse/ibmvnic-Do-not-replenish-RX-buffers-after-every-poll.patch + patches.suse/net-sched-act_mirred-refactor-the-handle-of-xmit.patch patches.suse/samples-bpf-Refactor-test_cgrp2_sock2-program-with-l.patch patches.suse/bpf-fix-bpf_put_raw_tracepoint-s-use-of-_module_address.patch patches.suse/selftests-bpf-Fix-invalid-use-of-strncat-in-test_soc.patch @@ -21278,6 +21281,7 @@ patches.suse/media-dvd_usb-memory-leak-in-cinergyt2_fe_attach.patch patches.suse/media-uvcvideo-Fix-pixel-format-change-for-Elgato-Ca.patch patches.suse/media-dvb_net-avoid-speculation-from-net-slot.patch + patches.suse/media-dvbdev-fix-error-logic-at-dvb_register_device.patch patches.suse/media-siano-fix-device-register-error-path.patch patches.suse/media-imx-csi-Skip-first-few-frames-from-a-BT.656-so.patch patches.suse/media-s5p-g2d-Fix-a-memory-leak-on-ctx-fh.m2m_ctx.patch @@ -23466,6 +23470,8 @@ patches.suse/msft-hv-2623-net-mana-Add-the-Linux-MANA-PF-driver.patch patches.suse/ath9k-fix-use-after-free-in-ath9k_hif_usb_rx_cb.patch patches.suse/wifi-mac80211-refactor-elements-parsing-with-paramet.patch + patches.suse/ext4-add-EXT4_INODE_HAS_XATTR_SPACE-macro-in-xattr.h.patch + patches.suse/ext4-fix-use-after-free-in-ext4_xattr_set_entry.patch patches.suse/ext4-check-if-directory-block-is-within-i_size.patch patches.suse/ext4-make-sure-ext4_append-always-allocates-new-bloc.patch patches.suse/exfat-Return-ENAMETOOLONG-consistently-for-oversized.patch @@ -23494,6 +23500,7 @@ patches.suse/efi-capsule-loader-Fix-use-after-free-in-efi_capsule.patch patches.suse/sch_sfb-Don-t-assume-the-skb-is-still-around-after-e.patch patches.suse/netfilter-nf_conntrack_irc-Fix-forged-IP-logic.patch + patches.suse/ipv6-sr-fix-out-of-bounds-read-when-setting-HMAC-dat.patch patches.suse/sch_sfb-Also-store-skb-len-before-calling-child-enqu.patch patches.suse/ALSA-pcm-oss-Fix-race-at-SNDCTL_DSP_SYNC.patch patches.suse/netfilter-nfnetlink_osf-fix-possible-bogus-match-in-.patch @@ -23577,6 +23584,7 @@ patches.suse/netlink-prevent-potential-spectre-v1-gadgets.patch patches.suse/net-mana-Fix-IRQ-name-add-PCI-and-queue-number.patch patches.suse/sctp-fail-if-no-bound-addresses-can-be-used-for-a-gi.patch + patches.suse/0001-netrom-Fix-use-after-free-caused-by-accept-on-alread.patch patches.suse/net-tls-tls_is_tx_ready-checked-list_entry.patch patches.suse/net-mana-Fix-accessing-freed-irq-affinity_hint.patch patches.suse/rds-rds_rm_zerocopy_callback-use-list_first_entry.patch @@ -23584,6 +23592,8 @@ patches.suse/net-sched-tcindex-update-imperfect-hash-filters-resp.patch patches.suse/net-mpls-fix-stale-pointer-if-allocation-fails-durin.patch patches.suse/0001-kvm-initialize-all-of-the-kvm_debugregs-structure-be.patch + patches.suse/net-sched-act_mirred-better-wording-on-protection-ag.patch + patches.suse/act_mirred-use-the-backlog-for-nested-calls-to-mirre.patch patches.suse/net-add-sock_init_data_uid.patch patches.suse/tun-tun_chr_open-correctly-initialize-socket-uid.patch patches.suse/tap-tap_open-correctly-initialize-socket-uid.patch @@ -23600,12 +23610,21 @@ patches.suse/xirc2ps_cs-Fix-use-after-free-bug-in-xirc2ps_detach.patch patches.suse/net-qcom-emac-Fix-use-after-free-bug-in-emac_remove-.patch patches.suse/Bluetooth-btsdio-fix-use-after-free-bug-in-btsdio_re.patch + patches.suse/i2c-xgene-slimpro-Fix-out-of-bounds-bug-in-xgene_sli.patch patches.suse/power-supply-da9150-Fix-use-after-free-bug-in-da9150.patch patches.suse/btrfs-fix-race-between-quota-disable-and-quota-assig.patch patches.suse/msft-hv-2770-Drivers-vmbus-Check-for-channel-allocation-before-lo.patch patches.suse/cifs-fix-negotiate-context-parsing.patch + patches.suse/net-sched-sch_qfq-prevent-slab-out-of-bounds-in-qfq_.patch patches.suse/0001-wifi-brcmfmac-slab-out-of-bounds-read-in-brcmf_get_a.patch patches.suse/xfs-verify-buffer-contents-when-we-skip-log-replay.patch + patches.suse/netfilter-nf_tables-deactivate-anonymous-set-from-pr.patch + patches.suse/media-ttusb-dec-fix-memory-leak-in-ttusb_dec_exit_dv.patch + patches.suse/media-dvb-core-Fix-use-after-free-on-race-condition-.patch + patches.suse/media-dvb-core-Fix-use-after-free-due-on-race-condit.patch + patches.suse/media-dvb-core-Fix-use-after-free-due-to-race-at-dvb.patch + patches.suse/media-dvb-core-Fix-kernel-WARNING-for-blocking-opera.patch + patches.suse/media-dvb-core-Fix-use-after-free-due-to-race-condit.patch ######################################################## # end of sorted patches @@ -23802,6 +23821,7 @@ patches.suse/io_uring-Fix-current-fs-handling-in-io_sq_wq_submit_.patch patches.suse/io_uring-disable-polling-signalfd-pollfree-files.patch patches.suse/io_uring-prevent-race-on-registering-fixed-files.patch + patches.suse/timens-Forbid-changing-time-namespace-for-an-io_urin.patch ######################################################## # Block layer @@ -24212,6 +24232,8 @@ patches.kabi/suse-hv-struct-vmbus_channel.patch patches.kabi/kabi-sk_buff_scm_io_uring.patch patches.kabi/usb.h-struct-usb_device-hide-new-member.patch + patches.kabi/media-dvb_frontend-kabi-workaround.patch + patches.kabi/media-dvb_net-kabi-workaround.patch ######################################################## # You'd better have a good reason for adding a patch