On Tue, 2006-08-29 at 21:44 -0700, David Miller wrote:
> From: Sridhar Samudrala <[EMAIL PROTECTED]>
> Date: Tue, 29 Aug 2006 10:55:29 -0700
> 
> > verify_iovec() has the following piece of code that allows overflow
> > of iov_len values in an iovec.
> > 
> >         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;
> >         }
> > 
> > The comment specifically says that overflow is harmless, but I don't see any
> > valid reason to allow overflow.
> > 
> > Also, iov_len is of type size_t which is a 64-bit value on 64-bit systems,
> > but we store and return the overall iovec length in an int.
> 
> Just some notes so that it is understood the context in which
> such changes are being proposed.
> 
> First of all, several memcpy() and copy_{to,from}_user()
> implementations BUG trap on lengths which have bit 31 or higher set.
> It always indicates a bug of some sort in the call chain, so behaving
> as if we support larger than positive signed 32-bit lengths here is
> probably asking for trouble.
> 
> Also, the protocol downcalls all return "int", not "long" so it's even
> impossible to report successful sending of larger than positive signed
> 32-bit lengths.  Even kernel_sendmsg() and friends return "int".
> 
> We can pretend that larger than positive signed 32-bit lengths in an
> iovec will work, but they surely won't.
> 
> And since the sendmsg() man page was quoted:
> 
>        If the message is too long to pass atomically  through  the  underlying
>        protocol, the error EMSGSIZE is returned, and the message is not 
> trans$,1rp
>        mitted.
> 
> which matches perfectly with the fact that the protocol downcalls
> return "int"  not "size_t" nor  "ssize_t".

OK. So the maximum message size that can be supported via sendmsg/recvmsg
is limited to INT_MAX. Then i think we should limit each iov_len value
and the sum of all iov_len values to INT_MAX.
It looks like copy_{to,from}_user() support upto LONG_MAX but most of the
networking routines return only an int.

Currently if we pass an iovec with 2 iov_len values 0x7fffffff and 
0x80000002, verify_iovec returns a total length as 1 and we proceed
without any error with a truncated user message.

The following patch avoids overflow of iov_len values beyond INT_MAX.

diff --git a/net/compat.c b/net/compat.c
index d5d69fa..e8f5345 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -44,7 +44,11 @@ static inline int iov_from_user_compat_t
                        tot_len = -EFAULT;
                        break;
                }
+               if (unlikely(len > INT_MAX))
+                       return -EMSGSIZE;
                tot_len += len;
+               if (unlikely(tot_len < 0))
+                       return -EMSGSIZE;
                kiov->iov_base = compat_ptr(buf);
                kiov->iov_len = (__kernel_size_t) len;
                uiov32++;
diff --git a/net/core/iovec.c b/net/core/iovec.c
index 65e4b56..ee5a265 100644
--- a/net/core/iovec.c
+++ b/net/core/iovec.c
@@ -61,11 +61,12 @@ int verify_iovec(struct msghdr *m, struc
        err = 0;
 
        for (ct = 0; ct < m->msg_iovlen; ct++) {
+               if (unlikely(iov[ct].iov_len > INT_MAX))
+                       return -EMSGSIZE;
                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;


-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to