| From: Linus Torvalds <torvalds@linux-foundation.org> |
| Date: Sun, 15 Aug 2010 18:35:52 +0000 (-0700) |
| Subject: mm: fix up some user-visible effects of the stack guard page |
| X-Git-Tag: v2.6.36-rc1~5 |
| X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=d7824370e26325c881b665350ce64fb0a4fde24a |
| |
| mm: fix up some user-visible effects of the stack guard page |
| |
| 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> |
| |
| |
| diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c |
| index aea1d3f..439fc1f 100644 |
| |
| |
| @@ -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 |
| |
| |
| @@ -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; |
| |