* [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).