Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-8]: src/sys/netsmb Pull up following revision(s) (requested by sp...



details:   https://anonhg.NetBSD.org/src/rev/e2718d6bc28f
branches:  netbsd-8
changeset: 434199:e2718d6bc28f
user:      snj <snj%NetBSD.org@localhost>
date:      Wed Aug 09 05:27:14 2017 +0000

description:
Pull up following revision(s) (requested by spz in ticket #197):
        sys/netsmb/smb_dev.c: revision 1.50
        sys/netsmb/smb_subr.c: revision 1.38
        sys/netsmb/smb_subr.h: revision 1.22
        sys/netsmb/smb_usr.c: revision 1.17-1.19
Reject allocations for too-small buffers from userland.
>From Ilja Van Sprundel.
--
Plug another overflow: refuse bogus sa_len from user.
--
Reject negative ioc_setupcnt.
--
Reject negative offset/count for smb read/write.
Not clear that this is actually a problem for the kernel -- might
overwrite user's buffers or return garbage to user, but that's their
own damn fault.  But it's hard to imagine that negative offset/count
ever makes sense, and I haven't ruled out a problem for the kernel.

diffstat:

 sys/netsmb/smb_dev.c  |   6 ++++--
 sys/netsmb/smb_subr.c |  33 +++++++++++++++++++++++++++++++--
 sys/netsmb/smb_subr.h |   3 ++-
 sys/netsmb/smb_usr.c  |  20 +++++++++++---------
 4 files changed, 48 insertions(+), 14 deletions(-)

diffs (151 lines):

diff -r 89193ed6ad5a -r e2718d6bc28f sys/netsmb/smb_dev.c
--- a/sys/netsmb/smb_dev.c      Wed Aug 09 05:18:26 2017 +0000
+++ b/sys/netsmb/smb_dev.c      Wed Aug 09 05:27:14 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: smb_dev.c,v 1.49 2016/07/18 21:03:01 pgoyette Exp $    */
+/*     $NetBSD: smb_dev.c,v 1.49.8.1 2017/08/09 05:27:14 snj Exp $     */
 
 /*
  * Copyright (c) 2000-2001 Boris Popov
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smb_dev.c,v 1.49 2016/07/18 21:03:01 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smb_dev.c,v 1.49.8.1 2017/08/09 05:27:14 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -345,6 +345,8 @@
                struct uio auio;
                struct iovec iov;
 
+               if (rwrq->ioc_cnt < 0 || rwrq->ioc_offset < 0)
+                       return EINVAL;
                if ((ssp = sdp->sd_share) == NULL)
                        return ENOTCONN;
                iov.iov_base = rwrq->ioc_base;
diff -r 89193ed6ad5a -r e2718d6bc28f sys/netsmb/smb_subr.c
--- a/sys/netsmb/smb_subr.c     Wed Aug 09 05:18:26 2017 +0000
+++ b/sys/netsmb/smb_subr.c     Wed Aug 09 05:27:14 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: smb_subr.c,v 1.37 2014/11/15 18:52:45 nakayama Exp $   */
+/*     $NetBSD: smb_subr.c,v 1.37.12.1 2017/08/09 05:27:14 snj Exp $   */
 
 /*
  * Copyright (c) 2000-2001 Boris Popov
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smb_subr.c,v 1.37 2014/11/15 18:52:45 nakayama Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smb_subr.c,v 1.37.12.1 2017/08/09 05:27:14 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -380,3 +380,32 @@
                memcpy(sa2, sa, sa->sa_len);
        return sa2;
 }
+
+int
+dup_sockaddr_copyin(struct sockaddr **ksap, struct sockaddr *usa,
+    size_t usalen)
+{
+       struct sockaddr *ksa;
+
+       /* Make sure user provided enough data for a generic sockaddr.  */
+       if (usalen < sizeof(*ksa))
+               return EINVAL;
+
+       /* Don't let the user overfeed us.  */
+       usalen = MIN(usalen, sizeof(struct sockaddr_storage));
+
+       /* Copy the buffer in from userland.  */
+       ksa = smb_memdupin(usa, usalen);
+       if (ksa == NULL)
+               return ENOMEM;
+
+       /* Make sure the user's idea of sa_len is reasonable.  */
+       if (ksa->sa_len > usalen) {
+               smb_memfree(ksa);
+               return EINVAL;
+       }
+
+       /* Success!  */
+       *ksap = ksa;
+       return 0;
+}
diff -r 89193ed6ad5a -r e2718d6bc28f sys/netsmb/smb_subr.h
--- a/sys/netsmb/smb_subr.h     Wed Aug 09 05:18:26 2017 +0000
+++ b/sys/netsmb/smb_subr.h     Wed Aug 09 05:27:14 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: smb_subr.h,v 1.21 2012/03/13 18:41:01 elad Exp $       */
+/*     $NetBSD: smb_subr.h,v 1.21.32.1 2017/08/09 05:27:14 snj Exp $   */
 
 /*
  * Copyright (c) 2000-2001, Boris Popov
@@ -128,5 +128,6 @@
 #endif
 
 struct sockaddr *dup_sockaddr(struct sockaddr *, int);
+int dup_sockaddr_copyin(struct sockaddr **, struct sockaddr *, size_t);
 
 #endif /* !_NETSMB_SMB_SUBR_H_ */
diff -r 89193ed6ad5a -r e2718d6bc28f sys/netsmb/smb_usr.c
--- a/sys/netsmb/smb_usr.c      Wed Aug 09 05:18:26 2017 +0000
+++ b/sys/netsmb/smb_usr.c      Wed Aug 09 05:27:14 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: smb_usr.c,v 1.16 2009/03/18 16:00:24 cegger Exp $      */
+/*     $NetBSD: smb_usr.c,v 1.16.56.1 2017/08/09 05:27:14 snj Exp $    */
 
 /*
  * Copyright (c) 2000-2001 Boris Popov
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smb_usr.c,v 1.16 2009/03/18 16:00:24 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smb_usr.c,v 1.16.56.1 2017/08/09 05:27:14 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/malloc.h>
@@ -65,6 +65,7 @@
 smb_usr_vc2spec(struct smbioc_ossn *dp, struct smb_vcspec *spec)
 {
        int flags = 0;
+       int error;
 
        memset(spec, 0, sizeof(*spec));
        if (dp->ioc_user[0] == 0)
@@ -76,14 +77,15 @@
                return EINVAL;
        }
 
-       spec->sap = smb_memdupin(dp->ioc_server, dp->ioc_svlen);
-       if (spec->sap == NULL)
-               return ENOMEM;
+       error = dup_sockaddr_copyin(&spec->sap, dp->ioc_server, dp->ioc_svlen);
+       if (error)
+               return error;
        if (dp->ioc_local) {
-               spec->lap = smb_memdupin(dp->ioc_local, dp->ioc_lolen);
-               if (spec->lap == NULL) {
+               error = dup_sockaddr_copyin(&spec->lap, dp->ioc_local,
+                   dp->ioc_lolen);
+               if (error) {
                        smb_usr_vcspec_free(spec);
-                       return ENOMEM;
+                       return error;
                }
        }
        spec->srvname = dp->ioc_srvname;
@@ -298,7 +300,7 @@
        struct mdchain *mdp;
        int error, len;
 
-       if (dp->ioc_setupcnt > 3)
+       if (dp->ioc_setupcnt < 0 || dp->ioc_setupcnt > 3)
                return EINVAL;
        error = smb_t2_alloc(SSTOCP(ssp), dp->ioc_setup[0], scred, &t2p);
        if (error)



Home | Main Index | Thread Index | Old Index