Fix for ability of users to bypass memory ulimits using mmap() instead of brk()

Greg Alexander (galexand@sietch.bloomington.in.us)
Sun, 18 May 1997 16:39:29 -0500 (EST)


A while back, I posted a useful but not-appropriate-for-inclusion patch to
fix this problem. This one should be appropriate for inclusion into a
mainstream kernel and merely fixes the bug but changes no semantics. I
haven't checeked 2.0.30 or any of the 2.1.x (x>30) kernels, so if something
similar is already there, I'm pretty dumb and just ignore me.

Greg Alexander
http://www.cia-g.com/~sietch/
-------------------------------------------------------------------
--- mmap.c.orig Fri Mar 28 03:15:00 1997
+++ mmap.c Sun May 18 06:27:05 1997
@@ -64,7 +64,6 @@

asmlinkage unsigned long sys_brk(unsigned long brk)
{
- unsigned long rlim;
unsigned long newbrk, oldbrk;
struct mm_struct *mm = current->mm;

@@ -83,14 +82,6 @@
do_munmap(newbrk, oldbrk-newbrk);
return brk;
}
- /*
- * Check against rlimit and stack..
- */
- rlim = current->rlim[RLIMIT_DATA].rlim_cur;
- if (rlim >= RLIM_INFINITY)
- rlim = ~0;
- if (brk - mm->end_code > rlim)
- return mm->brk;

/*
* Check against existing mmap mappings.
@@ -256,6 +247,19 @@
/* Check against address space limit. */
if ((mm->total_vm << PAGE_SHIFT) + len
> current->rlim[RLIMIT_AS].rlim_cur) {
+ kfree(vma);
+ return -ENOMEM;
+ }
+
+ /* Check against data size -- if uid == 0, you are exempted.
+ * This does not use euid (and hence suser()) so that users cannot
+ * avoid their limits by abusing suid root programs. */
+ if ((current->rlim[RLIMIT_DATA].rlim_cur < RLIM_INFINITY) &&
+ (prot & PROT_WRITE) &&
+ (flags & MAP_PRIVATE) &&
+ current->uid &&
+ (current->mm->total_vm<<PAGE_SHIFT + len >
+ current->rlim[RLIMIT_DATA].rlim_cur)) {
kfree(vma);
return -ENOMEM;
}