• Wei Yongjun's avatar
    [NET]: Fix function put_cmsg() which may cause usr application memory overflow · 1ac70e7a
    Wei Yongjun authored
    When used function put_cmsg() to copy kernel information to user 
    application memory, if the memory length given by user application is 
    not enough, by the bad length calculate of msg.msg_controllen, 
    put_cmsg() function may cause the msg.msg_controllen to be a large 
    value, such as 0xFFFFFFF0, so the following put_cmsg() can also write 
    data to usr application memory even usr has no valid memory to store 
    this. This may cause usr application memory overflow.
    
    int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data)
    {
        struct cmsghdr __user *cm
            = (__force struct cmsghdr __user *)msg->msg_control;
        struct cmsghdr cmhdr;
        int cmlen = CMSG_LEN(len);
        ~~~~~~~~~~~~~~~~~~~~~
        int err;
    
        if (MSG_CMSG_COMPAT & msg->msg_flags)
            return put_cmsg_compat(msg, level, type, len, data);
    
        if (cm==NULL || msg->msg_controllen < sizeof(*cm)) {
            msg->msg_flags |= MSG_CTRUNC;
            return 0; /* XXX: return error? check spec. */
        }
        if (msg->msg_controllen < cmlen) {
        ~~~~~~~~~~~~~~~~~~~~~~~~
            msg->msg_flags |= MSG_CTRUNC;
            cmlen = msg->msg_controllen;
        }
        cmhdr.cmsg_level = level;
        cmhdr.cmsg_type = type;
        cmhdr.cmsg_len = cmlen;
    
        err = -EFAULT;
        if (copy_to_user(cm, &cmhdr, sizeof cmhdr))
            goto out;
        if (copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr)))
            goto out;
        cmlen = CMSG_SPACE(len);
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
        If MSG_CTRUNC flags is set, msg->msg_controllen is less than 
    CMSG_SPACE(len), "msg->msg_controllen -= cmlen" will cause unsinged int 
    type msg->msg_controllen to be a large value.
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
        msg->msg_control += cmlen;
        msg->msg_controllen -= cmlen;
        ~~~~~~~~~~~~~~~~~~~~~
        err = 0;
    out:
        return err;
    }
    
    The same promble exists in put_cmsg_compat(). This patch can fix this 
    problem.
    Signed-off-by: default avatarWei Yongjun <yjwei@cn.fujitsu.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    1ac70e7a
compat.c 19.5 KB