CVE-2022-49049 Information
Description
In the Linux kernel the following vulnerability has been resolved:
mm/secretmem: fix panic when growing a memfd_secret
When one tries to grow an existing memfd_secret with ftruncate one gets a panic [1]. For example doing the following reliably induces the panic:
fd = memfd_secret();
ftruncate(fd 10);
ptr = mmap(NULL 10 PROT_READ | PROT_WRITE MAP_SHARED fd 0);
strcpy(ptr \123456789\);
munmap(ptr 10);
ftruncate(fd 20);
The basic reason for this is when we grow with ftruncate we call down into simple_setattr and then truncate_inode_pages_range and eventually we try to zero part of the memory. The normal truncation code does this via the direct map (i.e. it calls page_address() and hands that to memset()).
For memfd_secret though we specifically don’t map our pages via the direct map (i.e. we call set_direct_map_invalid_noflush() on every fault). So the address returned by page_address() isn’t useful and when we try to memset() with it we panic.
This patch avoids the panic by implementing a custom setattr for memfd_secret which detects resizes specifically (setting the size for the first time works just fine since there are no existing pages to try to zero) and rejects them with EINVAL.
One could argue growing should be supported but I think that will require a significantly more lengthy change. So I propose a minimal fix for the benefit of stable kernels and then perhaps to extend memfd_secret to support growing in a separate patch.
[1]:
BUG: unable to handle page fault for address: ffffa0a889277028
PF: supervisor write access in kernel mode
PF: error_code(0x0002) - not-present page
PGD afa01067 P4D afa01067 PUD 83f909067 PMD 83f8bf067 PTE 800ffffef6d88060
Oops: 0002 [1] PREEMPT SMP DEBUG_PAGEALLOC PTI
CPU: 0 PID: 281 Comm: repro Not tainted 5.17.0-dbg-DEV 1
Hardware name: QEMU Standard PC (i440FX + PIIX 1996) BIOS 1.15.0-1 04/01/2014
RIP: 0010:memset_erms+0x9/0x10
Code: c1 e9 03 40 0f b6 f6 48 b8 01 01 01 01 01 01 01 01 48 0f af c6 f3 48 ab 89 d1 f3 aa 4c 89 c8 c3 90 49 89 f9 40 88 f0 48 89 d1
[lkp@intel.com: secretmem_iops can be static] Signed-off-by: kernel test robot lkp@intel.com [axelrasmussen@google.com: return EINVAL]
Reference
https://git.kernel.org/stable/c/9d3b877daf805fed29be8f61aa3d0ea37df82c7b https://git.kernel.org/stable/c/b6d17c67885a5624e96eb30c4178c65eea8374bf https://git.kernel.org/stable/c/f9b141f93659e09a52e28791ccbaf69c273b8e92
Share on: