Message ID | 20110127212033.43C4732E39@sepang.rtg.net |
---|---|
State | Accepted |
Delegated to: | Stefan Bader |
Headers | show |
On 01/27/2011 10:20 PM, Tim Gardner wrote: > The following changes since commit 9085d9652a762dc247db5afa749b4c22a8280140: > Tim Gardner (1): > UBUNTU: xen unified block-device I/O interface back end can orphan devices, CVE-2010-3699 > > are available in the git repository at: > > git://kernel.ubuntu.com/rtg/ubuntu-hardy.git CVE-2010-3859 > > David S. Miller (1): > net: Limit socket I/O iovec total length to INT_MAX., CVE-2010-3859 > > Linus Torvalds (1): > net: Truncate recvfrom and sendto length to INT_MAX., CVE-2010-3859 > > net/compat.c | 10 ++++++---- > net/core/iovec.c | 15 +++++++-------- > net/socket.c | 6 ++++++ > 3 files changed, 19 insertions(+), 12 deletions(-) > > From 59d4dcd44ef01ebe655d1fe2ee6b77707c3e038c Mon Sep 17 00:00:00 2001 > From: David S. Miller <davem@davemloft.net> > Date: Thu, 28 Oct 2010 11:41:55 -0700 > Subject: [PATCH 1/2] net: Limit socket I/O iovec total length to INT_MAX., CVE-2010-3859 > > BugLink: http://bugs.launchpad.net/bugs/708839 > > CVE-2010-3859 > > commit 8acfe468b0384e834a303f08ebc4953d72fb690a upstream. > Backported as far as 2.6.23.26 > > This helps protect us from overflow issues down in the > individual protocol sendmsg/recvmsg handlers. Once > we hit INT_MAX we truncate out the rest of the iovec > by setting the iov_len members to zero. > > This works because: > > 1) For SOCK_STREAM and SOCK_SEQPACKET sockets, partial > writes are allowed and the application will just continue > with another write to send the rest of the data. > > 2) For datagram oriented sockets, where there must be a > one-to-one correspondance between write() calls and > packets on the wire, INT_MAX is going to be far larger > than the packet size limit the protocol is going to > check for and signal with -EMSGSIZE. > > Based upon a patch by Linus Torvalds. > > Signed-off-by: David S. Miller <davem@davemloft.net> > Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> > Signed-off-by: Tim Gardner <tim.gardner@canonical.com> Acked-by: Stefan Bader <stefan.bader@canonical.com> > --- > net/compat.c | 10 ++++++---- > net/core/iovec.c | 15 +++++++-------- > 2 files changed, 13 insertions(+), 12 deletions(-) > > diff --git a/net/compat.c b/net/compat.c > index 377e560..6d3eea3 100644 > --- a/net/compat.c > +++ b/net/compat.c > @@ -39,10 +39,12 @@ static inline int iov_from_user_compat_to_kern(struct iovec *kiov, > compat_size_t len; > > if (get_user(len, &uiov32->iov_len) || > - get_user(buf, &uiov32->iov_base)) { > - tot_len = -EFAULT; > - break; > - } > + get_user(buf, &uiov32->iov_base)) > + return -EFAULT; > + > + if (len > INT_MAX - tot_len) > + len = INT_MAX - tot_len; > + > tot_len += len; > kiov->iov_base = compat_ptr(buf); > kiov->iov_len = (__kernel_size_t) len; > diff --git a/net/core/iovec.c b/net/core/iovec.c > index 755c37f..7f1fb83 100644 > --- a/net/core/iovec.c > +++ b/net/core/iovec.c > @@ -60,14 +60,13 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode) > err = 0; > > for (ct = 0; ct < m->msg_iovlen; ct++) { > - err += iov[ct].iov_len; > - /* > - * Goal is not to verify user data, but to prevent returning > - * negative value, which is interpreted as errno. > - * Overflow is still possible, but it is harmless. > - */ > - if (err < 0) > - return -EMSGSIZE; > + size_t len = iov[ct].iov_len; > + > + if (len > INT_MAX - err) { > + len = INT_MAX - err; > + iov[ct].iov_len = len; > + } > + err += len; > } > > return err;
On 01/27/2011 01:20 PM, Tim Gardner wrote: > The following changes since commit 9085d9652a762dc247db5afa749b4c22a8280140: > Tim Gardner (1): > UBUNTU: xen unified block-device I/O interface back end can orphan devices, CVE-2010-3699 > > are available in the git repository at: > > git://kernel.ubuntu.com/rtg/ubuntu-hardy.git CVE-2010-3859 > > David S. Miller (1): > net: Limit socket I/O iovec total length to INT_MAX., CVE-2010-3859 > > Linus Torvalds (1): > net: Truncate recvfrom and sendto length to INT_MAX., CVE-2010-3859 > > net/compat.c | 10 ++++++---- > net/core/iovec.c | 15 +++++++-------- > net/socket.c | 6 ++++++ > 3 files changed, 19 insertions(+), 12 deletions(-) > > From 59d4dcd44ef01ebe655d1fe2ee6b77707c3e038c Mon Sep 17 00:00:00 2001 > From: David S. Miller<davem@davemloft.net> > Date: Thu, 28 Oct 2010 11:41:55 -0700 > Subject: [PATCH 1/2] net: Limit socket I/O iovec total length to INT_MAX., CVE-2010-3859 > > BugLink: http://bugs.launchpad.net/bugs/708839 > > CVE-2010-3859 > > commit 8acfe468b0384e834a303f08ebc4953d72fb690a upstream. > Backported as far as 2.6.23.26 > > This helps protect us from overflow issues down in the > individual protocol sendmsg/recvmsg handlers. Once > we hit INT_MAX we truncate out the rest of the iovec > by setting the iov_len members to zero. > > This works because: > > 1) For SOCK_STREAM and SOCK_SEQPACKET sockets, partial > writes are allowed and the application will just continue > with another write to send the rest of the data. > > 2) For datagram oriented sockets, where there must be a > one-to-one correspondance between write() calls and > packets on the wire, INT_MAX is going to be far larger > than the packet size limit the protocol is going to > check for and signal with -EMSGSIZE. > > Based upon a patch by Linus Torvalds. > > Signed-off-by: David S. Miller<davem@davemloft.net> > Signed-off-by: Greg Kroah-Hartman<gregkh@suse.de> > Signed-off-by: Tim Gardner<tim.gardner@canonical.com> > --- > net/compat.c | 10 ++++++---- > net/core/iovec.c | 15 +++++++-------- > 2 files changed, 13 insertions(+), 12 deletions(-) > > diff --git a/net/compat.c b/net/compat.c > index 377e560..6d3eea3 100644 > --- a/net/compat.c > +++ b/net/compat.c > @@ -39,10 +39,12 @@ static inline int iov_from_user_compat_to_kern(struct iovec *kiov, > compat_size_t len; > > if (get_user(len,&uiov32->iov_len) || > - get_user(buf,&uiov32->iov_base)) { > - tot_len = -EFAULT; > - break; > - } > + get_user(buf,&uiov32->iov_base)) > + return -EFAULT; > + > + if (len> INT_MAX - tot_len) > + len = INT_MAX - tot_len; > + > tot_len += len; > kiov->iov_base = compat_ptr(buf); > kiov->iov_len = (__kernel_size_t) len; > diff --git a/net/core/iovec.c b/net/core/iovec.c > index 755c37f..7f1fb83 100644 > --- a/net/core/iovec.c > +++ b/net/core/iovec.c > @@ -60,14 +60,13 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode) > err = 0; > > for (ct = 0; ct< m->msg_iovlen; ct++) { > - err += iov[ct].iov_len; > - /* > - * Goal is not to verify user data, but to prevent returning > - * negative value, which is interpreted as errno. > - * Overflow is still possible, but it is harmless. > - */ > - if (err< 0) > - return -EMSGSIZE; > + size_t len = iov[ct].iov_len; > + > + if (len> INT_MAX - err) { > + len = INT_MAX - err; > + iov[ct].iov_len = len; > + } > + err += len; > } > > return err; Acked-by: Brad Figg <brad.figg@canonical.com>
applied and pushed