Lock before calling uvm_swap_stats(). Otherwise a race condition could
corrupt memory.
This commit is contained in:
parent
7a175f4063
commit
70f013c0c3
@ -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 @@ netbsd32_swapctl_stats(struct lwp *l, struct sys_swapctl_args *uap, register_t *
|
||||
|
||||
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 @@ netbsd32_swapctl_stats(struct lwp *l, struct sys_swapctl_args *uap, register_t *
|
||||
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;
|
||||
|
@ -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 @@ swapdrum_getsdp(int pgno)
|
||||
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 @@ uvm_swap_stats(int cmd, struct swapent *sep, int sec, register_t *retval)
|
||||
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;
|
||||
|
@ -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 @@ int uvm_swap_alloc(int *, bool);
|
||||
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; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user