Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/uvm - sys_swapctl: validate the number of swap devices a...
details: https://anonhg.NetBSD.org/src/rev/c9d0b87660d0
branches: trunk
changeset: 773540:c9d0b87660d0
user: rmind <rmind%NetBSD.org@localhost>
date: Sun Feb 05 16:08:28 2012 +0000
description:
- sys_swapctl: validate the number of swap devices argument for SWAP_STATS.
- uvm_swap_stats: fix a buffer overrun, add some asserts.
Reviewed by mrg@
diffstat:
sys/uvm/uvm_swap.c | 68 +++++++++++++++++++++++++++++------------------------
1 files changed, 37 insertions(+), 31 deletions(-)
diffs (162 lines):
diff -r da18e8231fb8 -r c9d0b87660d0 sys/uvm/uvm_swap.c
--- a/sys/uvm/uvm_swap.c Sun Feb 05 14:27:08 2012 +0000
+++ b/sys/uvm/uvm_swap.c Sun Feb 05 16:08:28 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_swap.c,v 1.160 2012/01/28 00:00:06 rmind Exp $ */
+/* $NetBSD: uvm_swap.c,v 1.161 2012/02/05 16:08:28 rmind 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.160 2012/01/28 00:00:06 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_swap.c,v 1.161 2012/02/05 16:08:28 rmind Exp $");
#include "opt_uvmhist.h"
#include "opt_compat_netbsd.h"
@@ -398,8 +398,7 @@
{
struct swappri *spp, *nextspp;
- for (spp = LIST_FIRST(&swap_priority); spp != NULL; spp = nextspp) {
- nextspp = LIST_NEXT(spp, spi_swappri);
+ LIST_FOREACH_SAFE(spp, &swap_priority, spi_swappri, nextspp) {
if (CIRCLEQ_FIRST(&spp->spi_swapdev) !=
(void *)&spp->spi_swapdev)
continue;
@@ -454,20 +453,11 @@
struct swapent *sep;
#define SWAP_PATH_MAX (PATH_MAX + 1)
char *userpath;
- size_t len;
+ size_t len = 0;
int error, misc;
int priority;
UVMHIST_FUNC("sys_swapctl"); UVMHIST_CALLED(pdhist);
- misc = SCARG(uap, misc);
-
- userpath = kmem_alloc(SWAP_PATH_MAX, KM_SLEEP);
-
- /*
- * ensure serialized syscall access by grabbing the swap_syscall_lock
- */
- rw_enter(&swap_syscall_lock, RW_WRITER);
-
/*
* we handle the non-priv NSWAP and STATS request first.
*
@@ -475,13 +465,20 @@
* [can also be obtained with uvmexp sysctl]
*/
if (SCARG(uap, cmd) == SWAP_NSWAP) {
- UVMHIST_LOG(pdhist, "<- done SWAP_NSWAP=%d", uvmexp.nswapdev,
- 0, 0, 0);
- *retval = uvmexp.nswapdev;
- error = 0;
- goto out;
+ const int nswapdev = uvmexp.nswapdev;
+ UVMHIST_LOG(pdhist, "<- done SWAP_NSWAP=%d", nswapdev, 0, 0, 0);
+ *retval = nswapdev;
+ return 0;
}
+ misc = SCARG(uap, misc);
+ userpath = kmem_alloc(SWAP_PATH_MAX, KM_SLEEP);
+
+ /*
+ * ensure serialized syscall access by grabbing the swap_syscall_lock
+ */
+ rw_enter(&swap_syscall_lock, RW_WRITER);
+
/*
* SWAP_STATS: get stats on current # of configured swap devs
*
@@ -500,6 +497,12 @@
) {
if ((size_t)misc > (size_t)uvmexp.nswapdev)
misc = uvmexp.nswapdev;
+
+ if (misc == 0) {
+ error = EINVAL;
+ goto out;
+ }
+ KASSERT(misc > 0);
#if defined(COMPAT_13)
if (SCARG(uap, cmd) == SWAP_STATS13)
len = sizeof(struct swapent13) * misc;
@@ -561,6 +564,7 @@
if (SCARG(uap, cmd) == SWAP_ON &&
copystr("miniroot", userpath, SWAP_PATH_MAX, &len))
panic("swapctl: miniroot copy failed");
+ KASSERT(len > 0);
} else {
struct pathbuf *pb;
@@ -656,9 +660,10 @@
swaplist_insert(sdp, spp, priority);
mutex_exit(&uvm_swap_data_lock);
+ KASSERT(len > 0);
sdp->swd_pathlen = len;
- sdp->swd_path = kmem_alloc(sdp->swd_pathlen, KM_SLEEP);
- if (copystr(userpath, sdp->swd_path, sdp->swd_pathlen, 0) != 0)
+ sdp->swd_path = kmem_alloc(len, KM_SLEEP);
+ if (copystr(userpath, sdp->swd_path, len, 0) != 0)
panic("swapctl: copystr");
/*
@@ -737,12 +742,13 @@
int count = 0;
LIST_FOREACH(spp, &swap_priority, spi_swappri) {
- for (sdp = CIRCLEQ_FIRST(&spp->spi_swapdev);
- sdp != (void *)&spp->spi_swapdev && sec-- > 0;
- sdp = CIRCLEQ_NEXT(sdp, swd_next)) {
+ CIRCLEQ_FOREACH(sdp, &spp->spi_swapdev, swd_next) {
int inuse;
- /*
+ if (sec-- <= 0)
+ break;
+
+ /*
* backwards compatibility for system call.
* For NetBSD 1.3 and 5.0, we have to use
* the 32 bit dev_t. For 5.0 and -current
@@ -759,8 +765,9 @@
sep->se_nblks = sdp->swd_nblks;
sep->se_inuse = inuse;
sep->se_priority = sdp->swd_priority;
- memcpy(&sep->se_path, sdp->swd_path,
- sizeof sep->se_path);
+ KASSERT(sdp->swd_pathlen <
+ sizeof(sep->se_path));
+ strcpy(sep->se_path, sdp->swd_path);
sep++;
#if defined(COMPAT_13)
} else if (cmd == SWAP_STATS13) {
@@ -784,8 +791,9 @@
sep50->se50_nblks = sdp->swd_nblks;
sep50->se50_inuse = inuse;
sep50->se50_priority = sdp->swd_priority;
- memcpy(&sep50->se50_path, sdp->swd_path,
- sizeof sep50->se50_path);
+ KASSERT(sdp->swd_pathlen <
+ sizeof(sep50->se50_path));
+ strcpy(sep50->se50_path, sdp->swd_path);
sep = (struct swapent *)(sep50 + 1);
#endif
#if defined(COMPAT_13) || defined(COMPAT_50)
@@ -794,9 +802,7 @@
count++;
}
}
-
*retval = count;
- return;
}
/*
Home |
Main Index |
Thread Index |
Old Index