Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Lock before calling uvm_swap_stats(). Otherwise a race c...
details: https://anonhg.NetBSD.org/src/rev/fbb4b1f50ec9
branches: trunk
changeset: 339611:fbb4b1f50ec9
user: maxv <maxv%NetBSD.org@localhost>
date: Thu Jul 30 09:55:57 2015 +0000
description:
Lock before calling uvm_swap_stats(). Otherwise a race condition could
corrupt memory.
diffstat:
sys/compat/netbsd32/netbsd32_netbsd.c | 17 ++++++++++++-----
sys/uvm/uvm_swap.c | 15 +++++++++++++--
sys/uvm/uvm_swap.h | 5 ++++-
3 files changed, 29 insertions(+), 8 deletions(-)
diffs (110 lines):
diff -r 7bec83e7e3b0 -r fbb4b1f50ec9 sys/compat/netbsd32/netbsd32_netbsd.c
--- a/sys/compat/netbsd32/netbsd32_netbsd.c Thu Jul 30 08:41:18 2015 +0000
+++ b/sys/compat/netbsd32/netbsd32_netbsd.c Thu Jul 30 09:55:57 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: netbsd32_netbsd.c,v 1.196 2015/06/21 12:54:33 martin Exp $ */
+/* $NetBSD: netbsd32_netbsd.c,v 1.197 2015/07/30 09:55:57 maxv Exp $ */
/*
* Copyright (c) 1998, 2001, 2008 Matthew R. Green
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_netbsd.c,v 1.196 2015/06/21 12:54:33 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_netbsd.c,v 1.197 2015/07/30 09:55:57 maxv Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ddb.h"
@@ -1747,11 +1747,16 @@
if (count < 0)
return EINVAL;
- if (count == 0 || uvmexp.nswapdev == 0)
- return 0;
- /* Make sure userland cannot exhaust kernel memory */
+
+ swapsys_lock(RW_WRITER);
+
if ((size_t)count > (size_t)uvmexp.nswapdev)
count = uvmexp.nswapdev;
+ if (count == 0) {
+ /* No swap device */
+ swapsys_unlock();
+ return 0;
+ }
ksep_len = sizeof(*ksep) * count;
ksep = kmem_alloc(ksep_len, KM_SLEEP);
@@ -1760,6 +1765,8 @@
uvm_swap_stats(SWAP_STATS, ksep, count, retval);
count = *retval;
+ swapsys_unlock();
+
for (i = 0; i < count; i++) {
se32.se_dev = ksep[i].se_dev;
se32.se_flags = ksep[i].se_flags;
diff -r 7bec83e7e3b0 -r fbb4b1f50ec9 sys/uvm/uvm_swap.c
--- a/sys/uvm/uvm_swap.c Thu Jul 30 08:41:18 2015 +0000
+++ b/sys/uvm/uvm_swap.c Thu Jul 30 09:55:57 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_swap.c,v 1.172 2014/07/25 08:10:40 dholland Exp $ */
+/* $NetBSD: uvm_swap.c,v 1.173 2015/07/30 09:55:57 maxv Exp $ */
/*
* Copyright (c) 1995, 1996, 1997, 2009 Matthew R. Green
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_swap.c,v 1.172 2014/07/25 08:10:40 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_swap.c,v 1.173 2015/07/30 09:55:57 maxv Exp $");
#include "opt_uvmhist.h"
#include "opt_compat_netbsd.h"
@@ -430,6 +430,15 @@
return NULL;
}
+void swapsys_lock(krw_t op)
+{
+ rw_enter(&swap_syscall_lock, op);
+}
+
+void swapsys_unlock(void)
+{
+ rw_exit(&swap_syscall_lock);
+}
/*
* sys_swapctl: main entry point for swapctl(2) system call
@@ -741,6 +750,8 @@
struct swapdev *sdp;
int count = 0;
+ KASSERT(rw_lock_held(&swap_syscall_lock));
+
LIST_FOREACH(spp, &swap_priority, spi_swappri) {
TAILQ_FOREACH(sdp, &spp->spi_swapdev, swd_next) {
int inuse;
diff -r 7bec83e7e3b0 -r fbb4b1f50ec9 sys/uvm/uvm_swap.h
--- a/sys/uvm/uvm_swap.h Thu Jul 30 08:41:18 2015 +0000
+++ b/sys/uvm/uvm_swap.h Thu Jul 30 09:55:57 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_swap.h,v 1.20 2014/02/03 13:20:21 manu Exp $ */
+/* $NetBSD: uvm_swap.h,v 1.21 2015/07/30 09:55:57 maxv Exp $ */
/*
* Copyright (c) 1997 Matthew R. Green
@@ -48,7 +48,10 @@
void uvm_swap_free(int, int);
void uvm_swap_markbad(int, int);
bool uvm_swapisfull(void);
+void swapsys_lock(krw_t);
+void swapsys_unlock(void);
void uvm_swap_stats(int, struct swapent *, int, register_t *);
+
#else /* defined(VMSWAP) */
#define uvm_swapisfull() true
#define uvm_swap_stats(c, sep, count, retval) { *retval = 0; }
Home |
Main Index |
Thread Index |
Old Index