Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

openvswitch: fix flow actions reallocation

The flow action buffer can be resized if it's not big enough to contain
all the requested flow actions. However, this resize doesn't take into
account the new requested size, the buffer is only increased by a factor
of 2x. This might be not enough to contain the new data, causing a
buffer overflow, for example:

[ 42.044472] =============================================================================
[ 42.045608] BUG kmalloc-96 (Not tainted): Redzone overwritten
[ 42.046415] -----------------------------------------------------------------------------

[ 42.047715] Disabling lock debugging due to kernel taint
[ 42.047716] INFO: 0x8bf2c4a5-0x720c0928. First byte 0x0 instead of 0xcc
[ 42.048677] INFO: Slab 0xbc6d2040 objects=29 used=18 fp=0xdc07dec4 flags=0x2808101
[ 42.049743] INFO: Object 0xd53a3464 @offset=2528 fp=0xccdcdebb

[ 42.050747] Redzone 76f1b237: cc cc cc cc cc cc cc cc ........
[ 42.051839] Object d53a3464: 6b 6b 6b 6b 6b 6b 6b 6b 0c 00 00 00 6c 00 00 00 kkkkkkkk....l...
[ 42.053015] Object f49a30cc: 6c 00 0c 00 00 00 00 00 00 00 00 03 78 a3 15 f6 l...........x...
[ 42.054203] Object acfe4220: 20 00 02 00 ff ff ff ff 00 00 00 00 00 00 00 00 ...............
[ 42.055370] Object 21024e91: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
[ 42.056541] Object 070e04c3: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
[ 42.057797] Object 948a777a: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
[ 42.059061] Redzone 8bf2c4a5: 00 00 00 00 ....
[ 42.060189] Padding a681b46e: 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZ

Fix by making sure the new buffer is properly resized to contain all the
requested data.

BugLink: https://bugs.launchpad.net/bugs/1813244
Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
Acked-by: Pravin B Shelar <pshelar@ovn.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Andrea Righi and committed by
David S. Miller
f28cd2af 577dd43a

+2 -2
+2 -2
net/openvswitch/flow_netlink.c
··· 2306 2306 2307 2307 struct sw_flow_actions *acts; 2308 2308 int new_acts_size; 2309 - int req_size = NLA_ALIGN(attr_len); 2309 + size_t req_size = NLA_ALIGN(attr_len); 2310 2310 int next_offset = offsetof(struct sw_flow_actions, actions) + 2311 2311 (*sfa)->actions_len; 2312 2312 2313 2313 if (req_size <= (ksize(*sfa) - next_offset)) 2314 2314 goto out; 2315 2315 2316 - new_acts_size = ksize(*sfa) * 2; 2316 + new_acts_size = max(next_offset + req_size, ksize(*sfa) * 2); 2317 2317 2318 2318 if (new_acts_size > MAX_ACTIONS_BUFSIZE) { 2319 2319 if ((MAX_ACTIONS_BUFSIZE - next_offset) < req_size) {