git: 6ceede7d3669 - stable/13 - swapoff(2): replace special device name argument with a structure

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Mon, 20 Dec 2021 00:38:06 UTC
The branch stable/13 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=6ceede7d36691d3daa736e73fe6a0b52479bfeb2

commit 6ceede7d36691d3daa736e73fe6a0b52479bfeb2
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-11-29 16:26:31 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-12-20 00:29:11 +0000

    swapoff(2): replace special device name argument with a structure
    
    (cherry picked from commit a4e4132fa3bfadb6047fc0fa5f399f4640460300)
---
 sys/vm/swap_pager.c | 27 +++++++++++++++++++++++++--
 sys/vm/swap_pager.h |  8 ++++++++
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 3893199e30b5..17722f314650 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -2485,15 +2485,38 @@ sys_swapoff(struct thread *td, struct swapoff_args *uap)
 	struct vnode *vp;
 	struct nameidata nd;
 	struct swdevt *sp;
-	int error;
+	struct swapoff_new_args sa;
+	int error, probe_byte;
 
 	error = priv_check(td, PRIV_SWAPOFF);
 	if (error)
 		return (error);
 
+	/*
+	 * Detect old vs. new-style swapoff(2) syscall.  The first
+	 * pointer in the memory pointed to by uap->name is NULL for
+	 * the new variant.
+	 */
+	probe_byte = fubyte(uap->name);
+	switch (probe_byte) {
+	case -1:
+		return (EFAULT);
+	case 0:
+		error = copyin(uap->name, &sa, sizeof(sa));
+		if (error != 0)
+			return (error);
+		if (sa.flags != 0)
+			return (EINVAL);
+		break;
+	default:
+		bzero(&sa, sizeof(sa));
+		sa.name = uap->name;
+		break;
+	}
+
 	sx_xlock(&swdev_syscall_lock);
 
-	NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, UIO_USERSPACE, uap->name,
+	NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, UIO_USERSPACE, sa.name,
 	    td);
 	error = namei(&nd);
 	if (error)
diff --git a/sys/vm/swap_pager.h b/sys/vm/swap_pager.h
index 6761d4f99ee4..ed0abdee7d3f 100644
--- a/sys/vm/swap_pager.h
+++ b/sys/vm/swap_pager.h
@@ -68,6 +68,14 @@ struct swdevt {
 #define	SW_UNMAPPED	0x01
 #define	SW_CLOSING	0x04
 
+struct swapoff_new_args {
+	const char *name_old_syscall;
+	const char *name;
+	u_int flags;
+	u_int pad0;
+	uintptr_t pad1[8];
+};
+
 #ifdef _KERNEL
 
 extern int swap_pager_avail;