git: aa42e4984997 - main - sys_swapon: reject too small devices
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 29 Jul 2025 20:54:41 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=aa42e4984997c9d3aa5d30534bdaf760e613e97b
commit aa42e4984997c9d3aa5d30534bdaf760e613e97b
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-07-29 16:30:28 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-07-29 20:54:16 +0000
sys_swapon: reject too small devices
blist_create() panics on zero nblks.
Reported by: olivier
Reviewed by: alc, markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D51618
---
sys/sys/exterr_cat.h | 1 +
sys/vm/swap_pager.c | 17 +++++++++++------
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/sys/sys/exterr_cat.h b/sys/sys/exterr_cat.h
index a8e1f56e132e..80cff53b3576 100644
--- a/sys/sys/exterr_cat.h
+++ b/sys/sys/exterr_cat.h
@@ -19,6 +19,7 @@
#define EXTERR_CAT_INOTIFY 5
#define EXTERR_CAT_GENIO 6
#define EXTERR_CAT_BRIDGE 7
+#define EXTERR_CAT_SWAP 8
#endif
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index d6bd06226d04..327cac661044 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -65,9 +65,9 @@
* from: Utah $Hdr: swap_pager.c 1.4 91/04/30$
*/
-#include <sys/cdefs.h>
#include "opt_vm.h"
+#define EXTERR_CATEGORY EXTERR_CAT_SWAP
#include <sys/param.h>
#include <sys/bio.h>
#include <sys/blist.h>
@@ -76,6 +76,7 @@
#include <sys/disk.h>
#include <sys/disklabel.h>
#include <sys/eventhandler.h>
+#include <sys/exterrvar.h>
#include <sys/fcntl.h>
#include <sys/limits.h>
#include <sys/lock.h>
@@ -2686,7 +2687,7 @@ swapon_check_swzone(void)
}
}
-static void
+static int
swaponsomething(struct vnode *vp, void *id, u_long nblks,
sw_strategy_t *strategy, sw_close_t *close, dev_t dev, int flags)
{
@@ -2701,6 +2702,8 @@ swaponsomething(struct vnode *vp, void *id, u_long nblks,
*/
nblks &= ~(ctodb(1) - 1);
nblks = dbtoc(nblks);
+ if (nblks == 0)
+ return (EXTERROR(EINVAL, "swap device too small"));
sp = malloc(sizeof *sp, M_VMPGDATA, M_WAITOK | M_ZERO);
sp->sw_blist = blist_create(nblks, M_WAITOK);
@@ -2742,6 +2745,8 @@ swaponsomething(struct vnode *vp, void *id, u_long nblks,
swp_sizecheck();
mtx_unlock(&sw_dev_mtx);
EVENTHANDLER_INVOKE(swapon, sp);
+
+ return (0);
}
/*
@@ -3286,10 +3291,10 @@ swapongeom_locked(struct cdev *dev, struct vnode *vp)
return (error);
}
nblks = pp->mediasize / DEV_BSIZE;
- swaponsomething(vp, cp, nblks, swapgeom_strategy,
+ error = swaponsomething(vp, cp, nblks, swapgeom_strategy,
swapgeom_close, dev2udev(dev),
(pp->flags & G_PF_ACCEPT_UNMAPPED) != 0 ? SW_UNMAPPED : 0);
- return (0);
+ return (error);
}
static int
@@ -3378,9 +3383,9 @@ swaponvp(struct thread *td, struct vnode *vp, u_long nblks)
if (error != 0)
return (error);
- swaponsomething(vp, vp, nblks, swapdev_strategy, swapdev_close,
+ error = swaponsomething(vp, vp, nblks, swapdev_strategy, swapdev_close,
NODEV, 0);
- return (0);
+ return (error);
}
static int