Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1735110 > unrolled thread
| Started by | Meng Xu <mengxu.gatech@gmail.com> |
|---|---|
| First post | 2017-09-19 19:20 +0200 |
| Last post | 2017-09-21 00:40 +0200 |
| Articles | 2 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH] net: compat: assert the size of cmsg copied in is as expected Meng Xu <mengxu.gatech@gmail.com> - 2017-09-19 19:20 +0200
Re: [PATCH] net: compat: assert the size of cmsg copied in is as expected David Miller <davem@davemloft.net> - 2017-09-21 00:40 +0200
| From | Meng Xu <mengxu.gatech@gmail.com> |
|---|---|
| Date | 2017-09-19 19:20 +0200 |
| Subject | [PATCH] net: compat: assert the size of cmsg copied in is as expected |
| Message-ID | <urulI-8fP-7@gated-at.bofh.it> |
The actual length of cmsg fetched in during the second loop (i.e., kcmsg - kcmsg_base) could be different from what we get from the first loop (i.e., kcmlen). The main reason is that the two get_user() calls in the two loops (i.e., get_user(ucmlen, &ucmsg->cmsg_len) and __get_user(ucmlen, &ucmsg->cmsg_len)) could cause ucmlen to have different values even they fetch from the same userspace address, as user can race to change the memory content in &ucmsg->cmsg_len across fetches. Although in the second loop, the sanity check if ((char *)kcmsg_base + kcmlen - (char *)kcmsg < CMSG_ALIGN(tmp)) is inplace, it only ensures that the cmsg fetched in during the second loop does not exceed the length of kcmlen, but not necessarily equal to kcmlen. But indicated by the assignment kmsg->msg_controllen = kcmlen, we should enforce that. This patch adds this additional sanity check and ensures that what is recorded in kmsg->msg_controllen is the actual cmsg length. Signed-off-by: Meng Xu <mengxu.gatech@gmail.com> --- net/compat.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/compat.c b/net/compat.c index 6ded6c8..2238171 100644 --- a/net/compat.c +++ b/net/compat.c @@ -185,6 +185,13 @@ int cmsghdr_from_user_compat_to_kern(struct msghdr *kmsg, struct sock *sk, ucmsg = cmsg_compat_nxthdr(kmsg, ucmsg, ucmlen); } + /* + * check the length of messages copied in is the same as the + * what we get from the first loop + */ + if ((char *)kcmsg - (char *)kcmsg_base != kcmlen) + goto Einval; + /* Ok, looks like we made it. Hook it up and return success. */ kmsg->msg_control = kcmsg_base; kmsg->msg_controllen = kcmlen; -- 2.7.4
[toc] | [next] | [standalone]
| From | David Miller <davem@davemloft.net> |
|---|---|
| Date | 2017-09-21 00:40 +0200 |
| Subject | Re: [PATCH] net: compat: assert the size of cmsg copied in is as expected |
| Message-ID | <urVOW-J7-23@gated-at.bofh.it> |
| In reply to | #1735110 |
From: Meng Xu <mengxu.gatech@gmail.com> Date: Tue, 19 Sep 2017 13:19:13 -0400 > The actual length of cmsg fetched in during the second loop > (i.e., kcmsg - kcmsg_base) could be different from what we > get from the first loop (i.e., kcmlen). > > The main reason is that the two get_user() calls in the two > loops (i.e., get_user(ucmlen, &ucmsg->cmsg_len) and > __get_user(ucmlen, &ucmsg->cmsg_len)) could cause ucmlen > to have different values even they fetch from the same userspace > address, as user can race to change the memory content in > &ucmsg->cmsg_len across fetches. > > Although in the second loop, the sanity check > if ((char *)kcmsg_base + kcmlen - (char *)kcmsg < CMSG_ALIGN(tmp)) > is inplace, it only ensures that the cmsg fetched in during the > second loop does not exceed the length of kcmlen, but not > necessarily equal to kcmlen. But indicated by the assignment > kmsg->msg_controllen = kcmlen, we should enforce that. > > This patch adds this additional sanity check and ensures that > what is recorded in kmsg->msg_controllen is the actual cmsg length. > > Signed-off-by: Meng Xu <mengxu.gatech@gmail.com> Applied, thanks.
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web