Takashi Iwai 0d3637
From cefa91b2332d7009bc0be5d951d6cbbf349f90f8 Mon Sep 17 00:00:00 2001
Takashi Iwai 0d3637
From: Paolo Valerio <pvalerio@redhat.com>
Takashi Iwai 0d3637
Date: Fri, 15 Apr 2022 10:08:41 +0200
Takashi Iwai 0d3637
Subject: [PATCH] openvswitch: fix OOB access in reserve_sfa_size()
Takashi Iwai 0d3637
Git-commit: cefa91b2332d7009bc0be5d951d6cbbf349f90f8
Takashi Iwai 0d3637
Patch-mainline: v5.18-rc4
Takashi Iwai 0d3637
References: CVE-2022-2639 bsc#1202154
Takashi Iwai 0d3637
Takashi Iwai 0d3637
Given a sufficiently large number of actions, while copying and
Takashi Iwai 0d3637
reserving memory for a new action of a new flow, if next_offset is
Takashi Iwai 0d3637
greater than MAX_ACTIONS_BUFSIZE, the function reserve_sfa_size() does
Takashi Iwai 0d3637
not return -EMSGSIZE as expected, but it allocates MAX_ACTIONS_BUFSIZE
Takashi Iwai 0d3637
bytes increasing actions_len by req_size. This can then lead to an OOB
Takashi Iwai 0d3637
write access, especially when further actions need to be copied.
Takashi Iwai 0d3637
Takashi Iwai 0d3637
Fix it by rearranging the flow action size check.
Takashi Iwai 0d3637
Takashi Iwai 0d3637
KASAN splat below:
Takashi Iwai 0d3637
Takashi Iwai 0d3637
==================================================================
Takashi Iwai 0d3637
Bug: KASAN: slab-out-of-bounds in reserve_sfa_size+0x1ba/0x380 [openvswitch]
Takashi Iwai 0d3637
Write of size 65360 at addr ffff888147e4001c by task handler15/836
Takashi Iwai 0d3637
Takashi Iwai 0d3637
Cpu: 1 PID: 836 Comm: handler15 Not tainted 5.18.0-rc1+ #27
Takashi Iwai 0d3637
...
Takashi Iwai 0d3637
Call Trace:
Takashi Iwai 0d3637
 <TASK>
Takashi Iwai 0d3637
 dump_stack_lvl+0x45/0x5a
Takashi Iwai 0d3637
 print_report.cold+0x5e/0x5db
Takashi Iwai 0d3637
 ? __lock_text_start+0x8/0x8
Takashi Iwai 0d3637
 ? reserve_sfa_size+0x1ba/0x380 [openvswitch]
Takashi Iwai 0d3637
 kasan_report+0xb5/0x130
Takashi Iwai 0d3637
 ? reserve_sfa_size+0x1ba/0x380 [openvswitch]
Takashi Iwai 0d3637
 kasan_check_range+0xf5/0x1d0
Takashi Iwai 0d3637
 memcpy+0x39/0x60
Takashi Iwai 0d3637
 reserve_sfa_size+0x1ba/0x380 [openvswitch]
Takashi Iwai 0d3637
 __add_action+0x24/0x120 [openvswitch]
Takashi Iwai 0d3637
 ovs_nla_add_action+0xe/0x20 [openvswitch]
Takashi Iwai 0d3637
 ovs_ct_copy_action+0x29d/0x1130 [openvswitch]
Takashi Iwai 0d3637
 ? __kernel_text_address+0xe/0x30
Takashi Iwai 0d3637
 ? unwind_get_return_address+0x56/0xa0
Takashi Iwai 0d3637
 ? create_prof_cpu_mask+0x20/0x20
Takashi Iwai 0d3637
 ? ovs_ct_verify+0xf0/0xf0 [openvswitch]
Takashi Iwai 0d3637
 ? prep_compound_page+0x198/0x2a0
Takashi Iwai 0d3637
 ? __kasan_check_byte+0x10/0x40
Takashi Iwai 0d3637
 ? kasan_unpoison+0x40/0x70
Takashi Iwai 0d3637
 ? ksize+0x44/0x60
Takashi Iwai 0d3637
 ? reserve_sfa_size+0x75/0x380 [openvswitch]
Takashi Iwai 0d3637
 __ovs_nla_copy_actions+0xc26/0x2070 [openvswitch]
Takashi Iwai 0d3637
 ? __zone_watermark_ok+0x420/0x420
Takashi Iwai 0d3637
 ? validate_set.constprop.0+0xc90/0xc90 [openvswitch]
Takashi Iwai 0d3637
 ? __alloc_pages+0x1a9/0x3e0
Takashi Iwai 0d3637
 ? __alloc_pages_slowpath.constprop.0+0x1da0/0x1da0
Takashi Iwai 0d3637
 ? unwind_next_frame+0x991/0x1e40
Takashi Iwai 0d3637
 ? __mod_node_page_state+0x99/0x120
Takashi Iwai 0d3637
 ? __mod_lruvec_page_state+0x2e3/0x470
Takashi Iwai 0d3637
 ? __kasan_kmalloc_large+0x90/0xe0
Takashi Iwai 0d3637
 ovs_nla_copy_actions+0x1b4/0x2c0 [openvswitch]
Takashi Iwai 0d3637
 ovs_flow_cmd_new+0x3cd/0xb10 [openvswitch]
Takashi Iwai 0d3637
 ...
Takashi Iwai 0d3637
Takashi Iwai 0d3637
Cc: stable@vger.kernel.org
Takashi Iwai 0d3637
Fixes: f28cd2af22a0 ("openvswitch: fix flow actions reallocation")
Takashi Iwai 0d3637
Signed-off-by: Paolo Valerio <pvalerio@redhat.com>
Takashi Iwai 0d3637
Acked-by: Eelco Chaudron <echaudro@redhat.com>
Takashi Iwai 0d3637
Signed-off-by: David S. Miller <davem@davemloft.net>
Takashi Iwai 0d3637
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 0d3637
Takashi Iwai 0d3637
---
Takashi Iwai 0d3637
 net/openvswitch/flow_netlink.c | 2 +-
Takashi Iwai 0d3637
 1 file changed, 1 insertion(+), 1 deletion(-)
Takashi Iwai 0d3637
Takashi Iwai 0d3637
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
Takashi Iwai 0d3637
index 7176156d3844..4c09cf8a0ab2 100644
Takashi Iwai 0d3637
--- a/net/openvswitch/flow_netlink.c
Takashi Iwai 0d3637
+++ b/net/openvswitch/flow_netlink.c
Takashi Iwai 0d3637
@@ -2465,7 +2465,7 @@ static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa,
Takashi Iwai 0d3637
 	new_acts_size = max(next_offset + req_size, ksize(*sfa) * 2);
Takashi Iwai 0d3637
 
Takashi Iwai 0d3637
 	if (new_acts_size > MAX_ACTIONS_BUFSIZE) {
Takashi Iwai 0d3637
-		if ((MAX_ACTIONS_BUFSIZE - next_offset) < req_size) {
Takashi Iwai 0d3637
+		if ((next_offset + req_size) > MAX_ACTIONS_BUFSIZE) {
Takashi Iwai 0d3637
 			OVS_NLERR(log, "Flow action size exceeds max %u",
Takashi Iwai 0d3637
 				  MAX_ACTIONS_BUFSIZE);
Takashi Iwai 0d3637
 			return ERR_PTR(-EMSGSIZE);
Takashi Iwai 0d3637
-- 
Takashi Iwai 0d3637
2.35.3
Takashi Iwai 0d3637