git: 01ce7fca440c - main - ommap: fix signed len and pos arguments

From: Brooks Davis <brooks_at_FreeBSD.org>
Date: Mon, 15 Nov 2021 18:37:03 UTC
The branch main has been updated by brooks:

URL: https://cgit.FreeBSD.org/src/commit/?id=01ce7fca440cbb63275c8554049f0594602b173b

commit 01ce7fca440cbb63275c8554049f0594602b173b
Author:     Brooks Davis <brooks@FreeBSD.org>
AuthorDate: 2021-11-15 18:34:28 +0000
Commit:     Brooks Davis <brooks@FreeBSD.org>
CommitDate: 2021-11-15 18:34:28 +0000

    ommap: fix signed len and pos arguments
    
    4.3 BSD's mmap took an int len and long pos.  Reject negative lengths
    and in freebsd32 sign-extend pos correctly rather than mis-handling
    negative positions as large positive ones.
    
    Reviewed by:    kib
---
 sys/compat/freebsd32/freebsd32_misc.c |  9 +++++++++
 sys/compat/freebsd32/syscalls.master  |  4 ++--
 sys/sys/syscallsubr.h                 |  2 ++
 sys/vm/vm_mmap.c                      | 29 ++++++++++++++++++++---------
 4 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index f05b63e5b0ac..4375d88fdb93 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -535,6 +535,15 @@ freebsd6_freebsd32_mmap(struct thread *td,
 }
 #endif
 
+#ifdef COMPAT_43
+int
+ofreebsd32_mmap(struct thread *td, struct ofreebsd32_mmap_args *uap)
+{
+	return (kern_ommap(td, (uintptr_t)uap->addr, uap->len, uap->prot,
+	    uap->flags, uap->fd, uap->pos));
+}
+#endif
+
 int
 freebsd32_setitimer(struct thread *td, struct freebsd32_setitimer_args *uap)
 {
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
index 3d676fa9c3c8..c76e6b426b2e 100644
--- a/sys/compat/freebsd32/syscalls.master
+++ b/sys/compat/freebsd32/syscalls.master
@@ -176,8 +176,8 @@
 68	AUE_NULL	OBSOL	vwrite
 69	AUE_SBRK	NOPROTO	{ int sbrk(int incr); }
 70	AUE_SSTK	NOPROTO	{ int sstk(int incr); }
-71	AUE_MMAP	COMPAT|NOPROTO	{ void *mmap(void *addr, int len, \
-				    int prot, int flags, int fd, int pos); }
+71	AUE_MMAP	COMPAT	{ void *freebsd32_mmap(void *addr, int len, \
+				    int prot, int flags, int fd, int32_t pos); }
 72	AUE_O_VADVISE	COMPAT11|NOPROTO	{ int vadvise(int anom); }
 73	AUE_MUNMAP	NOPROTO	{ int munmap(void *addr, size_t len); }
 74	AUE_MPROTECT	STD	{ int freebsd32_mprotect(void *addr, \
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index 4b57ae5cf938..ecd0da74329f 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -218,6 +218,8 @@ int     kern_nanosleep(struct thread *td, struct timespec *rqt,
 int	kern_ntp_adjtime(struct thread *td, struct timex *ntv, int *retvalp);
 int	kern_ogetdirentries(struct thread *td, struct ogetdirentries_args *uap,
 	    long *ploff);
+int	kern_ommap(struct thread *td, uintptr_t hint, int len, int oprot,
+	    int oflags, int fd, long pos);
 int	kern_openat(struct thread *td, int fd, const char *path,
 	    enum uio_seg pathseg, int flags, int mode);
 int	kern_pathconf(struct thread *td, const char *path,
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 21fe6d82ec6a..8ad049ed6d5e 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -456,6 +456,14 @@ struct ommap_args {
 #endif
 int
 ommap(struct thread *td, struct ommap_args *uap)
+{
+	return (kern_ommap(td, (uintptr_t)uap->addr, uap->len, uap->prot,
+	    uap->flags, uap->fd, uap->pos));
+}
+
+int
+kern_ommap(struct thread *td, uintptr_t hint, int len, int oprot,
+    int oflags, int fd, long pos)
 {
 	static const char cvtbsdprot[8] = {
 		0,
@@ -469,35 +477,38 @@ ommap(struct thread *td, struct ommap_args *uap)
 	};
 	int flags, prot;
 
+	if (len < 0)
+		return (EINVAL);
+
 #define	OMAP_ANON	0x0002
 #define	OMAP_COPY	0x0020
 #define	OMAP_SHARED	0x0010
 #define	OMAP_FIXED	0x0100
 
-	prot = cvtbsdprot[uap->prot & 0x7];
+	prot = cvtbsdprot[oprot & 0x7];
 #if (defined(COMPAT_FREEBSD32) && defined(__amd64__)) || defined(__i386__)
 	if (i386_read_exec && SV_PROC_FLAG(td->td_proc, SV_ILP32) &&
 	    prot != 0)
 		prot |= PROT_EXEC;
 #endif
 	flags = 0;
-	if (uap->flags & OMAP_ANON)
+	if (oflags & OMAP_ANON)
 		flags |= MAP_ANON;
-	if (uap->flags & OMAP_COPY)
+	if (oflags & OMAP_COPY)
 		flags |= MAP_COPY;
-	if (uap->flags & OMAP_SHARED)
+	if (oflags & OMAP_SHARED)
 		flags |= MAP_SHARED;
 	else
 		flags |= MAP_PRIVATE;
-	if (uap->flags & OMAP_FIXED)
+	if (oflags & OMAP_FIXED)
 		flags |= MAP_FIXED;
 	return (kern_mmap(td, &(struct mmap_req){
-		.mr_hint = (uintptr_t)uap->addr,
-		.mr_len = uap->len,
+		.mr_hint = hint,
+		.mr_len = len,
 		.mr_prot = prot,
 		.mr_flags = flags,
-		.mr_fd = uap->fd,
-		.mr_pos = uap->pos,
+		.mr_fd = fd,
+		.mr_pos = pos,
 	    }));
 }
 #endif				/* COMPAT_43 */