netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] NET: Fix function put_cmsg() which may cause usr application memory overflow
@ 2007-12-18  6:19 Wei Yongjun
  2007-12-20 22:39 ` David Miller
  0 siblings, 1 reply; 2+ messages in thread
From: Wei Yongjun @ 2007-12-18  6:19 UTC (permalink / raw)
  To: netdev

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 <yjwei@cn.fujitsu.com>

--- a/net/core/scm.c	2007-12-11 08:41:57.000000000 -0500
+++ b/net/core/scm.c	2007-12-11 12:10:25.000000000 -0500
@@ -196,6 +196,8 @@ int put_cmsg(struct msghdr * msg, int le
 	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;
--- a/net/compat.c	2007-12-11 12:10:32.000000000 -0500
+++ b/net/compat.c	2007-12-11 12:11:08.000000000 -0500
@@ -254,6 +254,8 @@ int put_cmsg_compat(struct msghdr *kmsg,
 	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;






^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [PATCH] NET: Fix function put_cmsg() which may cause usr application memory overflow
  2007-12-18  6:19 [PATCH] NET: Fix function put_cmsg() which may cause usr application memory overflow Wei Yongjun
@ 2007-12-20 22:39 ` David Miller
  0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2007-12-20 22:39 UTC (permalink / raw)
  To: yjwei; +Cc: netdev

From: Wei Yongjun <yjwei@cn.fujitsu.com>
Date: Tue, 18 Dec 2007 15:19:09 +0900

> 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.
 ...
> The same promble exists in put_cmsg_compat(). This patch can fix this 
> problem.
> 
> Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com>

Thank you for fixing this bug, patch applied.

put_cmsg() is a confusing function, it takes a while to understand
what it is trying to accomplish.  And this explains why this bug
lived for so long.

Each CMSG entry has to be aligned, but put_cmsg() will allow to
put the full final message into the CMSG area if there is enough
room to fit the message without the added alignment.

So, with Wei's fix, we now have:

	int cmlen = CMSG_LEN(len);
 ...
	if (msg->msg_controllen < cmlen) {
		msg->msg_flags |= MSG_CTRUNC;
		cmlen = msg->msg_controllen;
	}
 ...
	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->msg_controllen < cmlen)
		cmlen = msg->msg_controllen;
	msg->msg_control += cmlen;
	msg->msg_controllen -= cmlen;
 ...

which I think finally implements the intended behavior
accurately.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2007-12-20 22:39 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-18  6:19 [PATCH] NET: Fix function put_cmsg() which may cause usr application memory overflow Wei Yongjun
2007-12-20 22:39 ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).