• Jann Horn's avatar
    compat_ioctl: don't look up the fd twice · b4341721
    Jann Horn authored
    In code in fs/compat_ioctl.c that translates ioctl arguments
    into a in-kernel structure, then performs sys_ioctl, possibly
    under set_fs(KERNEL_DS), this commit changes the sys_ioctl
    calls to do_ioctl calls. do_ioctl is a new function that does
    the same thing as sys_ioctl, but doesn't look up the fd again.
    
    This change is made to avoid (potential) security issues
    because of ioctl handlers that accept one of the ioctl
    commands I2C_FUNCS, VIDEO_GET_EVENT, MTIOCPOS, MTIOCGET,
    TIOCGSERIAL, TIOCSSERIAL, RTC_IRQP_READ, RTC_EPOCH_READ.
    This can happen for multiple reasons:
    
     - The ioctl command number could be reused.
     - The ioctl handler might not check the full ioctl
       command. This is e.g. true for drm_ioctl.
     - The ioctl handler is very special, e.g. cuse_file_ioctl
    
    The real issue is that set_fs(KERNEL_DS) is used here,
    but that's fixed in a separate commit
    "compat_ioctl: don't call do_ioctl under set_fs(KERNEL_DS)".
    
    This change mitigates potential security issues by
    preventing a race that permits invocation of
    unlocked_ioctl handlers under KERNEL_DS through compat
    code even if a corresponding compat_ioctl handler exists.
    
    So far, no way has been identified to use this to damage
    kernel memory without having CAP_SYS_ADMIN in the init ns
    (with the capability, doing reads/writes at arbitrary
    kernel addresses should be easy through CUSE's ioctl
    handler with FUSE_IOCTL_UNRESTRICTED set).
    
    [AV: two missed sys_ioctl() taken care of]
    Signed-off-by: default avatarJann Horn <jann@thejh.net>
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    b4341721
compat_ioctl.c 46.1 KB