The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=aa42e4984997c9d3aa5d30534bdaf760e613e97b
commit aa42e4984997c9d3aa5d30534bdaf760e613e97b Author: Konstantin Belousov <k...@freebsd.org> AuthorDate: 2025-07-29 16:30:28 +0000 Commit: Konstantin Belousov <k...@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