Subject: CVE-2021-46955: openvswitch: fix stack OOB read while fragmenting IPv4 packets

From: Greg Kroah-Hartman <[email-masked]>

Description
===========

In the Linux kernel, the following vulnerability has been resolved:

openvswitch: fix stack OOB read while fragmenting IPv4 packets

running openvswitch on kernels built with KASAN, it's possible to see the
following splat while testing fragmentation of IPv4 packets:

 BUG: KASAN: stack-out-of-bounds in ip_do_fragment+0x1b03/0x1f60
 Read of size 1 at addr ffff888112fc713c by task handler2/1367

 CPU: 0 PID: 1367 Comm: handler2 Not tainted 5.12.0-rc6+ #418
 Hardware name: Red Hat KVM, BIOS 1.11.1-4.module+el8.1.0+4066+0f1aadab 04/01/2014
 Call Trace:
  dump_stack+0x92/0xc1
  print_address_description.constprop.7+0x1a/0x150
  kasan_report.cold.13+0x7f/0x111
  ip_do_fragment+0x1b03/0x1f60
  ovs_fragment+0x5bf/0x840 [openvswitch]
  do_execute_actions+0x1bd5/0x2400 [openvswitch]
  ovs_execute_actions+0xc8/0x3d0 [openvswitch]
  ovs_packet_cmd_execute+0xa39/0x1150 [openvswitch]
  genl_family_rcv_msg_doit.isra.15+0x227/0x2d0
  genl_rcv_msg+0x287/0x490
  netlink_rcv_skb+0x120/0x380
  genl_rcv+0x24/0x40
  netlink_unicast+0x439/0x630
  netlink_sendmsg+0x719/0xbf0
  sock_sendmsg+0xe2/0x110
  ____sys_sendmsg+0x5ba/0x890
  ___sys_sendmsg+0xe9/0x160
  __sys_sendmsg+0xd3/0x170
  do_syscall_64+0x33/0x40
  entry_SYSCALL_64_after_hwframe+0x44/0xae
 RIP: 0033:0x7f957079db07
 Code: c3 66 90 41 54 41 89 d4 55 48 89 f5 53 89 fb 48 83 ec 10 e8 eb ec ff ff 44 89 e2 48 89 ee 89 df 41 89 c0 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 35 44 89 c7 48 89 44 24 08 e8 24 ed ff ff 48
 RSP: 002b:00007f956ce35a50 EFLAGS: 00000293 ORIG_RAX: 000000000000002e
 RAX: ffffffffffffffda RBX: 0000000000000019 RCX: 00007f957079db07
 RDX: 0000000000000000 RSI: 00007f956ce35ae0 RDI: 0000000000000019
 RBP: 00007f956ce35ae0 R08: 0000000000000000 R09: 00007f9558006730
 R10: 0000000000000000 R11: 0000000000000293 R12: 0000000000000000
 R13: 00007f956ce37308 R14: 00007f956ce35f80 R15: 00007f956ce35ae0

 The buggy address belongs to the page:
 page:00000000af2a1d93 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x112fc7
 flags: 0x17ffffc0000000()
 raw: 0017ffffc0000000 0000000000000000 dead000000000122 0000000000000000
 raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
 page dumped because: kasan: bad access detected

 addr ffff888112fc713c is located in stack of task handler2/1367 at offset 180 in frame:
  ovs_fragment+0x0/0x840 [openvswitch]

 this frame has 2 objects:
  [32, 144) 'ovs_dst'
  [192, 424) 'ovs_rt'

 Memory state around the buggy address:
  ffff888112fc7000: f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  ffff888112fc7080: 00 f1 f1 f1 f1 00 00 00 00 00 00 00 00 00 00 00
 >ffff888112fc7100: 00 00 00 f2 f2 f2 f2 f2 f2 00 00 00 00 00 00 00
                                         ^
  ffff888112fc7180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  ffff888112fc7200: 00 00 00 00 00 00 f2 f2 f2 00 00 00 00 00 00 00

for IPv4 packets, ovs_fragment() uses a temporary struct dst_entry. Then,
in the following call graph:

  ip_do_fragment()
    ip_skb_dst_mtu()
      ip_dst_mtu_maybe_forward()
        ip_mtu_locked()

the pointer to struct dst_entry is used as pointer to struct rtable: this
turns the access to struct members like rt_mtu_locked into an OOB read in
the stack. Fix this changing the temporary variable used for IPv4 packets
in ovs_fragment(), similarly to what is done for IPv6 few lines below.

The Linux kernel CVE team has assigned CVE-2021-46955 to this issue.

Affected and fixed versions
===========================

	Issue introduced in 4.4.134 with commit 119bbaa6795a and fixed in 4.4.269 with commit b1d7280f9ba1
	Issue introduced in 4.9.104 with commit d543907a4730 and fixed in 4.9.269 with commit 23e17ec1a5eb
	Issue introduced in 4.14.45 with commit 8387fbac8e18 and fixed in 4.14.233 with commit 5a52fa8ad45b
	Issue introduced in 4.16 with commit d52e5a7e7ca4 and fixed in 4.19.191 with commit df9e900de246
	Issue introduced in 4.16 with commit d52e5a7e7ca4 and fixed in 5.4.118 with commit 490ad0a23904
	Issue introduced in 4.16 with commit d52e5a7e7ca4 and fixed in 5.10.36 with commit a1478374b0bd
	Issue introduced in 4.16 with commit d52e5a7e7ca4 and fixed in 5.11.20 with commit d841d3cf5297
	Issue introduced in 4.16 with commit d52e5a7e7ca4 and fixed in 5.12.3 with commit b3502b04e84a
	Issue introduced in 4.16 with commit d52e5a7e7ca4 and fixed in 5.13 with commit 7c0ea5930c1c
	Issue introduced in 3.16.57 with commit df9ece1148e2

Please see https://www.kernel.org for a full list of currently supported
kernel versions by the kernel community.

Unaffected versions might change over time as fixes are backported to
older supported kernel versions.  The official CVE entry at
	https://cve.org/CVERecord/?id=CVE-2021-46955
will be updated if fixes are backported, please check that for the most
up to date information about this issue.

Affected files
==============

The file(s) affected by this issue are:
	net/openvswitch/actions.c

Mitigation
==========

The Linux kernel CVE team recommends that you update to the latest
stable kernel version for this, and many other bugfixes.  Individual
changes are never tested alone, but rather are part of a larger kernel
release.  Cherry-picking individual commits is not recommended or
supported by the Linux kernel community at all.  If however, updating to
the latest release is impossible, the individual changes to resolve this
issue can be found at these commits:
	https://git.kernel.org/stable/c/b1d7280f9ba1bfdbc3af5bdb82e51f014854f26f
	https://git.kernel.org/stable/c/23e17ec1a5eb53fe39cc34fa5592686d5acd0dac
	https://git.kernel.org/stable/c/5a52fa8ad45b5a593ed416adf326538638454ff1
	https://git.kernel.org/stable/c/df9e900de24637be41879e2c50afb713ec4e8b2e
	https://git.kernel.org/stable/c/490ad0a2390442d0a7b8c00972a83dbb09cab142
	https://git.kernel.org/stable/c/a1478374b0bda89b4277a8afd39208271faad4be
	https://git.kernel.org/stable/c/d841d3cf5297fde4ce6a41ff35451d0e82917f3e
	https://git.kernel.org/stable/c/b3502b04e84ac5349be95fc033c17bd701d2787a
	https://git.kernel.org/stable/c/7c0ea5930c1c211931819d83cfb157bff1539a4c