• Alexey Dobriyan's avatar
    prctl: more prctl(PR_SET_MM_*) checks · 4a00e9df
    Alexey Dobriyan authored
    Individual prctl(PR_SET_MM_*) calls do some checking to maintain a
    consistent view of mm->arg_start et al fields, but not enough.  In
    particular PR_SET_MM_ARG_START/PR_SET_MM_ARG_END/ R_SET_MM_ENV_START/
    PR_SET_MM_ENV_END only check that the address lies in an existing VMA,
    but don't check that the start address is lower than the end address _at
    all_.
    
    Consolidate all consistency checks, so there will be no difference in
    the future between PR_SET_MM_MAP and individual PR_SET_MM_* calls.
    
    The program below makes both ARGV and ENVP areas be reversed.  It makes
    /proc/$PID/cmdline show garbage (it doesn't oops by luck).
    
    #include <sys/mman.h>
    #include <sys/prctl.h>
    #include <unistd.h>
    
    enum {PAGE_SIZE=4096};
    
    int main(void)
    {
    	void *p;
    
    	p = mmap(NULL, PAGE_SIZE, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
    
    #define PR_SET_MM               35
    #define PR_SET_MM_ARG_START     8
    #define PR_SET_MM_ARG_END       9
    #define PR_SET_MM_ENV_START     10
    #define PR_SET_MM_ENV_END       11
    	prctl(PR_SET_MM, PR_SET_MM_ARG_START, (unsigned long)p + PAGE_SIZE - 1, 0, 0);
    	prctl(PR_SET_MM, PR_SET_MM_ARG_END,   (unsigned long)p, 0, 0);
    	prctl(PR_SET_MM, PR_SET_MM_ENV_START, (unsigned long)p + PAGE_SIZE - 1, 0, 0);
    	prctl(PR_SET_MM, PR_SET_MM_ENV_END,   (unsigned long)p, 0, 0);
    
    	pause();
    	return 0;
    }
    
    [akpm@linux-foundation.org: tidy code, tweak comment]
    Signed-off-by: default avatarAlexey Dobriyan <adobriyan@gmail.com>
    Acked-by: default avatarCyrill Gorcunov <gorcunov@openvz.org>
    Cc: Jarod Wilson <jarod@redhat.com>
    Cc: Jan Stancek <jstancek@redhat.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    4a00e9df
sys.c 57.5 KB