aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-15 14:35:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-15 14:35:52 -0400
commitd7824370e26325c881b665350ce64fb0a4fde24a (patch)
treec3fb9ceb074d52c3edd166a927314c642f2fe631
parent1b68c9596ce17a1e06918ed65fc3d19b92b04aab (diff)
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>
-rw-r--r--fs/proc/task_mmu.c8
-rw-r--r--mm/mlock.c8
2 files changed, 15 insertions, 1 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index aea1d3f1ffb5..439fc1f1c1c4 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)
210 int flags = vma->vm_flags; 210 int flags = vma->vm_flags;
211 unsigned long ino = 0; 211 unsigned long ino = 0;
212 unsigned long long pgoff = 0; 212 unsigned long long pgoff = 0;
213 unsigned long start;
213 dev_t dev = 0; 214 dev_t dev = 0;
214 int len; 215 int len;
215 216
@@ -220,8 +221,13 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
220 pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT; 221 pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
221 } 222 }
222 223
224 /* We don't show the stack guard page in /proc/maps */
225 start = vma->vm_start;
226 if (vma->vm_flags & VM_GROWSDOWN)
227 start += PAGE_SIZE;
228
223 seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n", 229 seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
224 vma->vm_start, 230 start,
225 vma->vm_end, 231 vma->vm_end,
226 flags & VM_READ ? 'r' : '-', 232 flags & VM_READ ? 'r' : '-',
227 flags & VM_WRITE ? 'w' : '-', 233 flags & VM_WRITE ? 'w' : '-',
diff --git a/mm/mlock.c b/mm/mlock.c
index 3f82720e0515..49e5e4cb8232 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -167,6 +167,14 @@ static long __mlock_vma_pages_range(struct vm_area_struct *vma,
167 if (vma->vm_flags & VM_WRITE) 167 if (vma->vm_flags & VM_WRITE)
168 gup_flags |= FOLL_WRITE; 168 gup_flags |= FOLL_WRITE;
169 169
170 /* We don't try to access the guard page of a stack vma */
171 if (vma->vm_flags & VM_GROWSDOWN) {
172 if (start == vma->vm_start) {
173 start += PAGE_SIZE;
174 nr_pages--;
175 }
176 }
177
170 while (nr_pages > 0) { 178 while (nr_pages > 0) {
171 int i; 179 int i;
172 180