summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbluhm <bluhm@openbsd.org>2019-07-16 17:39:02 +0000
committerbluhm <bluhm@openbsd.org>2019-07-16 17:39:02 +0000
commit9392a7356dcbb9aa55ba792313ca7916e2904c2b (patch)
tree0eeb34843cca395b3f239f3bf57262082a25e97d
parent1) Re-resolve and re-get constraints once the clock is synced. Constraints (diff)
downloadwireguard-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.c4
-rw-r--r--sys/kern/kern_sysctl.c14
-rw-r--r--sys/kern/uipc_mbuf.c20
-rw-r--r--sys/sys/mbuf.h5
-rw-r--r--usr.bin/netstat/mbuf.c14
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 "