diff options
author | 2019-07-16 17:39:02 +0000 | |
---|---|---|
committer | 2019-07-16 17:39:02 +0000 | |
commit | 9392a7356dcbb9aa55ba792313ca7916e2904c2b (patch) | |
tree | 0eeb34843cca395b3f239f3bf57262082a25e97d | |
parent | 1) Re-resolve and re-get constraints once the clock is synced. Constraints (diff) | |
download | wireguard-openbsd-9392a7356dcbb9aa55ba792313ca7916e2904c2b.tar.xz wireguard-openbsd-9392a7356dcbb9aa55ba792313ca7916e2904c2b.zip |
Prevent integer overflow in kernel and userland when checking mbuf
limits. Convert kernel variables and calculations for mbuf memory
into long to allow larger values on 64 bit machines. Put a range
check into the kernel sysctl. For the interface itself int is still
sufficient. In netstat -m cast all multiplications to unsigned
long to hold the product of two unsigned int.
input and OK visa@
-rw-r--r-- | sys/conf/param.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_sysctl.c | 14 | ||||
-rw-r--r-- | sys/kern/uipc_mbuf.c | 20 | ||||
-rw-r--r-- | sys/sys/mbuf.h | 5 | ||||
-rw-r--r-- | usr.bin/netstat/mbuf.c | 14 |
5 files changed, 32 insertions, 25 deletions
diff --git a/sys/conf/param.c b/sys/conf/param.c index 28b54ba5bfd..b25e1995e90 100644 --- a/sys/conf/param.c +++ b/sys/conf/param.c @@ -1,4 +1,4 @@ -/* $OpenBSD: param.c,v 1.41 2019/07/08 23:59:32 mlarkin Exp $ */ +/* $OpenBSD: param.c,v 1.42 2019/07/16 17:39:02 bluhm Exp $ */ /* $NetBSD: param.c,v 1.16 1996/03/12 03:08:40 mrg Exp $ */ /* @@ -89,7 +89,7 @@ int initialvnodes = NVNODE; int maxprocess = NPROCESS; int maxthread = NPROCESS + 8 * MAXUSERS; int maxfiles = 5 * (NPROCESS + MAXUSERS) + 80; -int nmbclust = NMBCLUSTERS; +long nmbclust = NMBCLUSTERS; #ifndef MBLOWAT #define MBLOWAT 16 diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 1cdaf84f032..f3bef1a20c0 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sysctl.c,v 1.363 2019/07/12 13:56:27 solene Exp $ */ +/* $OpenBSD: kern_sysctl.c,v 1.364 2019/07/16 17:39:02 bluhm Exp $ */ /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ /*- @@ -129,8 +129,6 @@ extern int audio_record_enable; int allowkmem; -extern void nmbclust_update(void); - int sysctl_diskinit(int, struct proc *); int sysctl_proc_args(int *, u_int, void *, size_t *, struct proc *); int sysctl_proc_cwd(int *, u_int, void *, size_t *, struct proc *); @@ -590,11 +588,13 @@ kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, return (sysctl_wdog(name + 1, namelen - 1, oldp, oldlenp, newp, newlen)); #endif - case KERN_MAXCLUSTERS: - error = sysctl_int(oldp, oldlenp, newp, newlen, &nmbclust); - if (!error) - nmbclust_update(); + case KERN_MAXCLUSTERS: { + int val = nmbclust; + error = sysctl_int(oldp, oldlenp, newp, newlen, &val); + if (error == 0 && val != nmbclust) + error = nmbclust_update(val); return (error); + } #ifndef SMALL_KERNEL case KERN_EVCOUNT: return (evcount_sysctl(name + 1, namelen - 1, oldp, oldlenp, diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 019d0296a8d..d6bbafbdf93 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_mbuf.c,v 1.269 2019/06/10 23:45:19 dlg Exp $ */ +/* $OpenBSD: uipc_mbuf.c,v 1.270 2019/07/16 17:39:02 bluhm Exp $ */ /* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */ /* @@ -131,12 +131,11 @@ int max_hdr; /* largest link+protocol header */ struct mutex m_extref_mtx = MUTEX_INITIALIZER(IPL_NET); void m_extfree(struct mbuf *); -void nmbclust_update(void); void m_zero(struct mbuf *); struct mutex m_pool_mtx = MUTEX_INITIALIZER(IPL_NET); -unsigned int mbuf_mem_limit; /* how much memory can be allocated */ -unsigned int mbuf_mem_alloc; /* how much memory has been allocated */ +unsigned long mbuf_mem_limit; /* how much memory can be allocated */ +unsigned long mbuf_mem_alloc; /* how much memory has been allocated */ void *m_pool_alloc(struct pool *, int, int *); void m_pool_free(struct pool *, void *); @@ -161,14 +160,15 @@ static u_int num_extfree_fns; void mbinit(void) { - int i; + int i, error; unsigned int lowbits; CTASSERT(MSIZE == sizeof(struct mbuf)); m_pool_allocator.pa_pagesz = pool_allocator_multi.pa_pagesz; - nmbclust_update(); + error = nmbclust_update(nmbclust); + KASSERT(error == 0); mbuf_mem_alloc = 0; #if DIAGNOSTIC @@ -214,11 +214,15 @@ mbcpuinit() pool_cache_init(&mclpools[i]); } -void -nmbclust_update(void) +int +nmbclust_update(long newval) { + if (newval < 0 || newval > LONG_MAX / MCLBYTES) + return ERANGE; /* update the global mbuf memory limit */ + nmbclust = newval; mbuf_mem_limit = nmbclust * MCLBYTES; + return 0; } /* diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h index 60cd99f40c4..4c33080404b 100644 --- a/sys/sys/mbuf.h +++ b/sys/sys/mbuf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mbuf.h,v 1.244 2019/06/10 23:45:19 dlg Exp $ */ +/* $OpenBSD: mbuf.h,v 1.245 2019/07/16 17:39:02 bluhm Exp $ */ /* $NetBSD: mbuf.h,v 1.19 1996/02/09 18:25:14 christos Exp $ */ /* @@ -402,7 +402,7 @@ struct mbuf_queue { #ifdef _KERNEL struct pool; -extern int nmbclust; /* limit on the # of clusters */ +extern long nmbclust; /* limit on the # of clusters */ extern int mblowat; /* mbuf low water mark */ extern int mcllowat; /* mbuf cluster low water mark */ extern int max_linkhdr; /* largest link-level header */ @@ -411,6 +411,7 @@ extern int max_hdr; /* largest link+protocol header */ void mbinit(void); void mbcpuinit(void); +int nmbclust_update(long); struct mbuf *m_copym(struct mbuf *, int, int, int); struct mbuf *m_free(struct mbuf *); struct mbuf *m_get(int, int); diff --git a/usr.bin/netstat/mbuf.c b/usr.bin/netstat/mbuf.c index fbc6635f247..b52a76f596c 100644 --- a/usr.bin/netstat/mbuf.c +++ b/usr.bin/netstat/mbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mbuf.c,v 1.42 2019/06/28 13:35:02 deraadt Exp $ */ +/* $OpenBSD: mbuf.c,v 1.43 2019/07/16 17:39:02 bluhm Exp $ */ /* $NetBSD: mbuf.c,v 1.9 1996/05/07 02:55:03 thorpej Exp $ */ /* @@ -184,17 +184,19 @@ mbpr(void) mbstat.m_mtypes[i], plural(mbstat.m_mtypes[i]), i); } - totmem = (mbpool.pr_npages * mbpool.pr_pgsize); - totpeak = mbpool.pr_hiwat * mbpool.pr_pgsize; + totmem = (unsigned long)mbpool.pr_npages * mbpool.pr_pgsize; + totpeak = (unsigned long)mbpool.pr_hiwat * mbpool.pr_pgsize; for (i = 0; i < mclp; i++) { printf("%u/%lu mbuf %d byte clusters in use" " (current/peak)\n", mclpools[i].pr_nout, (unsigned long) - (mclpools[i].pr_hiwat * mclpools[i].pr_itemsperpage), + mclpools[i].pr_hiwat * mclpools[i].pr_itemsperpage, mclpools[i].pr_size); - totmem += (mclpools[i].pr_npages * mclpools[i].pr_pgsize); - totpeak += mclpools[i].pr_hiwat * mclpools[i].pr_pgsize; + totmem += (unsigned long) + mclpools[i].pr_npages * mclpools[i].pr_pgsize; + totpeak += (unsigned long) + mclpools[i].pr_hiwat * mclpools[i].pr_pgsize; } printf("%lu/%lu/%lu Kbytes allocated to network " |