92 lines
3.0 KiB
Diff
92 lines
3.0 KiB
Diff
From d7824370e26325c881b665350ce64fb0a4fde24a Mon Sep 17 00:00:00 2001
|
|
From: Linus Torvalds <torvalds@linux-foundation.org>
|
|
Date: Sun, 15 Aug 2010 11:35:52 -0700
|
|
Subject: [PATCH] mm: fix up some user-visible effects of the stack guard page
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
This commit makes the stack guard page somewhat less visible to user
|
|
space. It does this by:
|
|
|
|
- not showing the guard page in /proc/<pid>/maps
|
|
|
|
It looks like lvm-tools will actually read /proc/self/maps to figure
|
|
out where all its mappings are, and effectively do a specialized
|
|
"mlockall()" in user space. By not showing the guard page as part of
|
|
the mapping (by just adding PAGE_SIZE to the start for grows-up
|
|
pages), lvm-tools ends up not being aware of it.
|
|
|
|
- by also teaching the _real_ mlock() functionality not to try to lock
|
|
the guard page.
|
|
|
|
That would just expand the mapping down to create a new guard page,
|
|
so there really is no point in trying to lock it in place.
|
|
|
|
It would perhaps be nice to show the guard page specially in
|
|
/proc/<pid>/maps (or at least mark grow-down segments some way), but
|
|
let's not open ourselves up to more breakage by user space from programs
|
|
that depends on the exact deails of the 'maps' file.
|
|
|
|
Special thanks to Henrique de Moraes Holschuh for diving into lvm-tools
|
|
source code to see what was going on with the whole new warning.
|
|
|
|
Reported-and-tested-by: François Valenduc <francois.valenduc@tvcablenet.be
|
|
Reported-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
|
|
Cc: stable@kernel.org
|
|
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
---
|
|
fs/proc/task_mmu.c | 8 +++++++-
|
|
mm/mlock.c | 8 ++++++++
|
|
2 files changed, 15 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
|
|
index aea1d3f..439fc1f 100644
|
|
--- a/fs/proc/task_mmu.c
|
|
+++ b/fs/proc/task_mmu.c
|
|
@@ -210,6 +210,7 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
|
|
int flags = vma->vm_flags;
|
|
unsigned long ino = 0;
|
|
unsigned long long pgoff = 0;
|
|
+ unsigned long start;
|
|
dev_t dev = 0;
|
|
int len;
|
|
|
|
@@ -220,8 +221,13 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
|
|
pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
|
|
}
|
|
|
|
+ /* We don't show the stack guard page in /proc/maps */
|
|
+ start = vma->vm_start;
|
|
+ if (vma->vm_flags & VM_GROWSDOWN)
|
|
+ start += PAGE_SIZE;
|
|
+
|
|
seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
|
|
- vma->vm_start,
|
|
+ start,
|
|
vma->vm_end,
|
|
flags & VM_READ ? 'r' : '-',
|
|
flags & VM_WRITE ? 'w' : '-',
|
|
diff --git a/mm/mlock.c b/mm/mlock.c
|
|
index 3f82720..49e5e4c 100644
|
|
--- a/mm/mlock.c
|
|
+++ b/mm/mlock.c
|
|
@@ -167,6 +167,14 @@ static long __mlock_vma_pages_range(struct vm_area_struct *vma,
|
|
if (vma->vm_flags & VM_WRITE)
|
|
gup_flags |= FOLL_WRITE;
|
|
|
|
+ /* We don't try to access the guard page of a stack vma */
|
|
+ if (vma->vm_flags & VM_GROWSDOWN) {
|
|
+ if (start == vma->vm_start) {
|
|
+ start += PAGE_SIZE;
|
|
+ nr_pages--;
|
|
+ }
|
|
+ }
|
|
+
|
|
while (nr_pages > 0) {
|
|
int i;
|
|
|
|
--
|
|
1.7.1
|
|
|