Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=1ac70e7ad24a88710cf9b6d7ababaefa2b575df0
Commit:     1ac70e7ad24a88710cf9b6d7ababaefa2b575df0
Parent:     c5c0f33d8e5b1219c86757e6afffd6f96823e521
Author:     Wei Yongjun <[EMAIL PROTECTED]>
AuthorDate: Thu Dec 20 14:36:44 2007 -0800
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Thu Dec 20 14:36:44 2007 -0800

    [NET]: Fix function put_cmsg() which may cause usr application memory 
overflow
    
    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: Wei Yongjun <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 net/compat.c   |    2 ++
 net/core/scm.c |    2 ++
 2 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/net/compat.c b/net/compat.c
index d74d821..377e560 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -254,6 +254,8 @@ int put_cmsg_compat(struct msghdr *kmsg, int level, int 
type, int len, void *dat
        if (copy_to_user(CMSG_COMPAT_DATA(cm), data, cmlen - sizeof(struct 
compat_cmsghdr)))
                return -EFAULT;
        cmlen = CMSG_COMPAT_SPACE(len);
+       if (kmsg->msg_controllen < cmlen)
+               cmlen = kmsg->msg_controllen;
        kmsg->msg_control += cmlen;
        kmsg->msg_controllen -= cmlen;
        return 0;
diff --git a/net/core/scm.c b/net/core/scm.c
index 100ba6d..10f5c65 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -196,6 +196,8 @@ int put_cmsg(struct msghdr * msg, int level, int type, int 
len, void *data)
        if (copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr)))
                goto out;
        cmlen = CMSG_SPACE(len);
+       if (msg->msg_controllen < cmlen)
+               cmlen = msg->msg_controllen;
        msg->msg_control += cmlen;
        msg->msg_controllen -= cmlen;
        err = 0;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to