• Djalal Harouni's avatar
    proc: environ_read() make sure offset points to environment address range · e8905ec2
    Djalal Harouni authored
    Currently the following offset and environment address range check in
    environ_read() of /proc/<pid>/environ is buggy:
    
      int this_len = mm->env_end - (mm->env_start + src);
      if (this_len <= 0)
        break;
    
    Large or negative offsets on /proc/<pid>/environ converted to 'unsigned
    long' may pass this check since '(mm->env_start + src)' can overflow and
    'this_len' will be positive.
    
    This can turn /proc/<pid>/environ to act like /proc/<pid>/mem since
    (mm->env_start + src) will point and read from another VMA.
    
    There are two fixes here plus some code cleaning:
    
    1) Fix the overflow by checking if the offset that was converted to
       unsigned long will always point to the [mm->env_start, mm->env_end]
       address range.
    
    2) Remove the truncation that was made to the result of the check,
       storing the result in 'int this_len' will alter its value and we can
       not depend on it.
    
    For kernels that have commit b409e578 ("proc: clean up
    /proc/<pid>/environ handling") which adds the appropriate ptrace check and
    saves the 'mm' at ->open() time, this is not a security issue.
    
    This patch is taken from the grsecurity patch since it was just made
    available.
    Signed-off-by: default avatarDjalal Harouni <tixxdz@opendz.org>
    Cc: Oleg Nesterov <oleg@redhat.com>
    Cc: Brad Spengler <spender@grsecurity.net>
    Acked-by: default avatarKees Cook <keescook@chromium.org>
    Cc: David Rientjes <rientjes@google.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    e8905ec2
base.c 87.4 KB