Skip to content

Commit 5fc644a

Browse files
Kenotkelman
authored andcommitted
Disable /proc/self/mem memmgr on Linux < 4.10
The DirtyCOW exploit mitigation patch in Linux (torvalds/linux@19be0eaff), introduced a kernel bug, that would cause the kernel to hang if an application tries to use /proc/<pid>/mem (or ptrace) to bypass page protections on pages that are backed by transparent huge pages (though only if the write causes a COW resolution). We make use of this feature in our cg memory manager on Linux, but since we can't predict whether or not our mappings will be backed by transparent huge pages, the only safe thing to do is to fall back to dual maps on kernels that potentially have this issue. Since the problematic commit is a fix for a high-profile exploit, it is quite likely that it is included in most stable kernels by now. I have a patch pending at http://marc.info/?l=linux-mm&m=148359462417378&w=2, which I expect will fix this in the kernel for 4.10. However, we'll have to disable the use of /proc/self/mem for all prior kernel versions to avoid locking up the kernel. (cherry picked from commit c8312d3) ref #19887
1 parent 4be8a3f commit 5fc644a

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

src/cgmemmgr.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#endif
1616
#ifdef _OS_LINUX_
1717
# include <sys/syscall.h>
18+
# include <sys/utsname.h>
1819
#endif
1920
#ifndef _OS_WINDOWS_
2021
# include <sys/mman.h>
@@ -265,6 +266,16 @@ static int self_mem_fd = -1;
265266

266267
static int init_self_mem()
267268
{
269+
struct utsname kernel;
270+
uname(&kernel);
271+
int major, minor;
272+
if (-1 == sscanf(kernel.release, "%d.%d", &major, &minor))
273+
return -1;
274+
// Can't risk getting a memory block backed by transparent huge pages,
275+
// which cause the kernel to freeze on systems that have the DirtyCOW
276+
// mitigation patch, but are < 4.10.
277+
if (!(major > 4 || (major == 4 && minor >= 10)))
278+
return -1;
268279
#ifdef O_CLOEXEC
269280
int fd = open("/proc/self/mem", O_RDWR | O_SYNC | O_CLOEXEC);
270281
if (fd == -1)

0 commit comments

Comments
 (0)