Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 19 Jan 2007 21:47:37 GMT
From:      Jung-uk Kim <jkim@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 113177 for review
Message-ID:  <200701192147.l0JLlbYa096265@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=113177

Change 113177 by jkim@jkim_hammer on 2007/01/19 21:47:34

	- Move vm_maxsaddr adjustment after file descriptor check.
	- Add linux_mprotect() for i386 and synchronize with amd64.
	  Supposedly NX/XD bit should affect this arch as well.
	- Fix broken prot on amd64 from the previous commit.
	
	mmap finger print is now identical to Linux's one.
	
	MFP4 after:	1 week

Affected files ...

.. //depot/projects/linuxolator/src/sys/amd64/linux32/linux32_machdep.c#26 edit
.. //depot/projects/linuxolator/src/sys/i386/linux/linux_machdep.c#19 edit
.. //depot/projects/linuxolator/src/sys/i386/linux/linux_proto.h#18 edit
.. //depot/projects/linuxolator/src/sys/i386/linux/linux_syscall.h#17 edit
.. //depot/projects/linuxolator/src/sys/i386/linux/linux_sysent.c#17 edit
.. //depot/projects/linuxolator/src/sys/i386/linux/syscalls.master#16 edit

Differences ...

==== //depot/projects/linuxolator/src/sys/amd64/linux32/linux32_machdep.c#26 (text+ko) ====

@@ -824,16 +824,47 @@
 		bsd_args.flags |= MAP_PRIVATE;
 	if (linux_args->flags & LINUX_MAP_FIXED)
 		bsd_args.flags |= MAP_FIXED;
-	if (linux_args->flags & LINUX_MAP_ANON) {
+	if (linux_args->flags & LINUX_MAP_ANON)
 		bsd_args.flags |= MAP_ANON;
-		bsd_args.fd = -1;
-	} else {
+	else
 		bsd_args.flags |= MAP_NOSYNC;
-		bsd_args.fd = linux_args->fd;
+	if (linux_args->flags & LINUX_MAP_GROWSDOWN)
+		bsd_args.flags |= MAP_STACK;
+
+	/*
+	 * Linux has added READ_IMPLIES_EXEC personality but we do not support
+	 * the feature yet. We just assume READ_IMPLIES_EXEC is always on.
+	 */
+	bsd_args.prot = linux_args->prot;
+	if (bsd_args.prot & PROT_READ)
+		bsd_args.prot |= PROT_EXEC;
+
+	if (linux_args->fd != -1) {
+		/*
+		 * Linux follows Solaris mmap(2) description:
+		 * The file descriptor fildes is opened with
+		 * read permission, regardless of the
+		 * protection options specified.
+		 */
+
+		if ((error = fget(td, linux_args->fd, &fp)) != 0)
+			return (error);
+		if (fp->f_type != DTYPE_VNODE) {
+			fdrop(fp, td);
+			return (EINVAL);
+		}
+
+		/* Linux mmap() just fails for O_WRONLY files */
+		if (!(fp->f_flag & FREAD)) {
+			fdrop(fp, td);
+			return (EACCES);
+		}
+
+		fdrop(fp, td);
 	}
+	bsd_args.fd = linux_args->fd;
+
 	if (linux_args->flags & LINUX_MAP_GROWSDOWN) {
-		bsd_args.flags |= MAP_STACK;
-
 		/* 
 		 * The linux MAP_GROWSDOWN option does not limit auto
 		 * growth of the region.  Linux mmap with this option
@@ -875,8 +906,7 @@
 			 * mmap's return value.
 			 */
 			PROC_LOCK(p);
-			p->p_vmspace->vm_maxsaddr =
-			    (char *)LINUX32_USRSTACK -
+			p->p_vmspace->vm_maxsaddr = (char *)LINUX32_USRSTACK -
 			    lim_cur(p, RLIMIT_STACK);
 			PROC_UNLOCK(p);
 		}
@@ -900,42 +930,6 @@
 		bsd_args.addr = (caddr_t)PTRIN(linux_args->addr);
 		bsd_args.len  = linux_args->len;
 	}
-
-	/*
-	 * Linux has added READ_IMPLIES_EXEC personality but we do not support
-	 * the feature yet. We just assume READ_IMPLIES_EXEC is always on.
-	 */
-	if (linux_args->prot & PROT_READ)
-		bsd_args.prot = linux_args->prot | PROT_EXEC;
-
-	if (bsd_args.fd != -1) {
-		/*
-		 * Linux follows Solaris mmap(2) description:
-		 * The file descriptor fildes is opened with
-		 * read permission, regardless of the
-		 * protection options specified.
-		 * If PROT_WRITE is specified, the application
-		 * must have opened the file descriptor
-		 * fildes with write permission unless
-		 * MAP_PRIVATE is specified in the flag
-		 * argument as described below.
-		 */
-
-		if ((error = fget(td, bsd_args.fd, &fp)) != 0)
-			return (error);
-		if (fp->f_type != DTYPE_VNODE) {
-			fdrop(fp, td);
-			return (EINVAL);
-		}
-
-		/* Linux mmap() just fails for O_WRONLY files */
-		if (! (fp->f_flag & FREAD)) {
-			fdrop(fp, td);
-			return (EACCES);
-		}
-
-		fdrop(fp, td);
-	}
 	bsd_args.pos = (off_t)linux_args->pgoff * PAGE_SIZE;
 	bsd_args.pad = 0;
 
@@ -956,6 +950,20 @@
 }
 
 int
+linux_mprotect(struct thread *td, struct linux_mprotect_args *uap)
+{
+	struct mprotect_args bsd_args;
+
+	bsd_args.addr = uap->addr;
+	bsd_args.len = uap->len;
+	bsd_args.prot = uap->prot;
+	/* XXX PROT_READ implies PROT_EXEC; see linux_mmap_common(). */
+	if (bsd_args.prot & PROT_READ)
+		bsd_args.prot |= PROT_EXEC;
+	return (mprotect(td, &bsd_args));
+}
+
+int
 linux_iopl(struct thread *td, struct linux_iopl_args *args)
 {
 	int error;
@@ -1228,20 +1236,6 @@
 }
 
 int
-linux_mprotect(struct thread *td, struct linux_mprotect_args *uap)
-{
-	struct mprotect_args bsd_args;
-
-	bsd_args.addr = uap->addr;
-	bsd_args.len = uap->len;
-	bsd_args.prot = uap->prot;
-	/* XXX PROT_READ implies PROT_EXEC; see linux_mmap_common(). */
-	if ((bsd_args.prot & PROT_READ) != 0)
-		bsd_args.prot |= PROT_EXEC;
-	return (mprotect(td, &bsd_args));
-}
-
-int
 linux_set_thread_area(struct thread *td, struct linux_set_thread_area_args *args)
 {
 	struct l_user_desc info;

==== //depot/projects/linuxolator/src/sys/i386/linux/linux_machdep.c#19 (text+ko) ====

@@ -657,16 +657,47 @@
 		bsd_args.flags |= MAP_PRIVATE;
 	if (linux_args->flags & LINUX_MAP_FIXED)
 		bsd_args.flags |= MAP_FIXED;
-	if (linux_args->flags & LINUX_MAP_ANON) {
+	if (linux_args->flags & LINUX_MAP_ANON)
 		bsd_args.flags |= MAP_ANON;
-		bsd_args.fd = -1;
-	} else {
+	else
 		bsd_args.flags |= MAP_NOSYNC;
-		bsd_args.fd = linux_args->fd;
+	if (linux_args->flags & LINUX_MAP_GROWSDOWN)
+		bsd_args.flags |= MAP_STACK;
+
+	/*
+	 * Linux has added READ_IMPLIES_EXEC personality but we do not support
+	 * the feature yet. We just assume READ_IMPLIES_EXEC is always on.
+	 */
+	bsd_args.prot = linux_args->prot;
+	if (bsd_args.prot & PROT_READ)
+		bsd_args.prot |= PROT_EXEC;
+
+	if (linux_args->fd != -1) {
+		/*
+		 * Linux follows Solaris mmap(2) description:
+		 * The file descriptor fildes is opened with
+		 * read permission, regardless of the
+		 * protection options specified.
+		 */
+
+		if ((error = fget(td, linux_args->fd, &fp)) != 0)
+			return (error);
+		if (fp->f_type != DTYPE_VNODE) {
+			fdrop(fp, td);
+			return (EINVAL);
+		}
+
+		/* Linux mmap() just fails for O_WRONLY files */
+		if (!(fp->f_flag & FREAD)) {
+			fdrop(fp, td);
+			return (EACCES);
+		}
+
+		fdrop(fp, td);
 	}
+	bsd_args.fd = linux_args->fd;
+
 	if (linux_args->flags & LINUX_MAP_GROWSDOWN) {
-		bsd_args.flags |= MAP_STACK;
-
 		/* 
 		 * The linux MAP_GROWSDOWN option does not limit auto
 		 * growth of the region.  Linux mmap with this option
@@ -732,36 +763,6 @@
 		bsd_args.addr = (caddr_t)PTRIN(linux_args->addr);
 		bsd_args.len  = linux_args->len;
 	}
-
-	bsd_args.prot = linux_args->prot;
-	if (bsd_args.fd != -1) {
-		/*
-		 * Linux follows Solaris mmap(2) description:
-		 * The file descriptor fildes is opened with
-		 * read permission, regardless of the
-		 * protection options specified.
-		 * If PROT_WRITE is specified, the application
-		 * must have opened the file descriptor
-		 * fildes with write permission unless
-		 * MAP_PRIVATE is specified in the flag
-		 * argument as described below.
-		 */
-
-		if ((error = fget(td, bsd_args.fd, &fp)) != 0)
-			return (error);
-		if (fp->f_type != DTYPE_VNODE) {
-			fdrop(fp, td);
-			return (EINVAL);
-		}
-
-		/* Linux mmap() just fails for O_WRONLY files */
-		if (! (fp->f_flag & FREAD)) {
-			fdrop(fp, td);
-			return (EACCES);
-		}
-
-		fdrop(fp, td);
-	}
 	bsd_args.pos = linux_args->pos;
 	bsd_args.pad = 0;
 
@@ -782,6 +783,20 @@
 }
 
 int
+linux_mprotect(struct thread *td, struct linux_mprotect_args *uap)
+{
+	struct mprotect_args bsd_args;
+
+	bsd_args.addr = uap->addr;
+	bsd_args.len = uap->len;
+	bsd_args.prot = uap->prot;
+	/* XXX PROT_READ implies PROT_EXEC; see linux_mmap_common(). */
+	if (bsd_args.prot & PROT_READ)
+		bsd_args.prot |= PROT_EXEC;
+	return (mprotect(td, &bsd_args));
+}
+
+int
 linux_pipe(struct thread *td, struct linux_pipe_args *args)
 {
 	int error;

==== //depot/projects/linuxolator/src/sys/i386/linux/linux_proto.h#18 (text+ko) ====

@@ -394,6 +394,11 @@
 struct linux_adjtimex_args {
 	register_t dummy;
 };
+struct linux_mprotect_args {
+	char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)];
+	char len_l_[PADL_(int)]; int len; char len_r_[PADR_(int)];
+	char prot_l_[PADL_(int)]; int prot; char prot_r_[PADR_(int)];
+};
 struct linux_sigprocmask_args {
 	char how_l_[PADL_(l_int)]; l_int how; char how_r_[PADR_(l_int)];
 	char mask_l_[PADL_(l_osigset_t *)]; l_osigset_t * mask; char mask_r_[PADR_(l_osigset_t *)];
@@ -1061,6 +1066,7 @@
 int	linux_newuname(struct thread *, struct linux_newuname_args *);
 int	linux_modify_ldt(struct thread *, struct linux_modify_ldt_args *);
 int	linux_adjtimex(struct thread *, struct linux_adjtimex_args *);
+int	linux_mprotect(struct thread *, struct linux_mprotect_args *);
 int	linux_sigprocmask(struct thread *, struct linux_sigprocmask_args *);
 int	linux_create_module(struct thread *, struct linux_create_module_args *);
 int	linux_init_module(struct thread *, struct linux_init_module_args *);
@@ -1314,6 +1320,7 @@
 #define	LINUX_SYS_AUE_linux_newuname	AUE_NULL
 #define	LINUX_SYS_AUE_linux_modify_ldt	AUE_NULL
 #define	LINUX_SYS_AUE_linux_adjtimex	AUE_ADJTIME
+#define	LINUX_SYS_AUE_linux_mprotect	AUE_MPROTECT
 #define	LINUX_SYS_AUE_linux_sigprocmask	AUE_SIGPROCMASK
 #define	LINUX_SYS_AUE_linux_create_module	AUE_NULL
 #define	LINUX_SYS_AUE_linux_init_module	AUE_NULL

==== //depot/projects/linuxolator/src/sys/i386/linux/linux_syscall.h#17 (text+ko) ====

@@ -120,7 +120,7 @@
 #define	LINUX_SYS_linux_newuname	122
 #define	LINUX_SYS_linux_modify_ldt	123
 #define	LINUX_SYS_linux_adjtimex	124
-#define	LINUX_SYS_mprotect	125
+#define	LINUX_SYS_linux_mprotect	125
 #define	LINUX_SYS_linux_sigprocmask	126
 #define	LINUX_SYS_linux_create_module	127
 #define	LINUX_SYS_linux_init_module	128

==== //depot/projects/linuxolator/src/sys/i386/linux/linux_sysent.c#17 (text+ko) ====

@@ -144,7 +144,7 @@
 	{ AS(linux_newuname_args), (sy_call_t *)linux_newuname, AUE_NULL, NULL, 0, 0 },	/* 122 = linux_newuname */
 	{ AS(linux_modify_ldt_args), (sy_call_t *)linux_modify_ldt, AUE_NULL, NULL, 0, 0 },	/* 123 = linux_modify_ldt */
 	{ 0, (sy_call_t *)linux_adjtimex, AUE_ADJTIME, NULL, 0, 0 },	/* 124 = linux_adjtimex */
-	{ AS(mprotect_args), (sy_call_t *)mprotect, AUE_MPROTECT, NULL, 0, 0 },	/* 125 = mprotect */
+	{ AS(linux_mprotect_args), (sy_call_t *)linux_mprotect, AUE_MPROTECT, NULL, 0, 0 },	/* 125 = linux_mprotect */
 	{ AS(linux_sigprocmask_args), (sy_call_t *)linux_sigprocmask, AUE_SIGPROCMASK, NULL, 0, 0 },	/* 126 = linux_sigprocmask */
 	{ 0, (sy_call_t *)linux_create_module, AUE_NULL, NULL, 0, 0 },	/* 127 = linux_create_module */
 	{ 0, (sy_call_t *)linux_init_module, AUE_NULL, NULL, 0, 0 },	/* 128 = linux_init_module */

==== //depot/projects/linuxolator/src/sys/i386/linux/syscalls.master#16 (text+ko) ====

@@ -224,7 +224,7 @@
 123	AUE_NULL	STD	{ int linux_modify_ldt(l_int func, \
 				    void *ptr, l_ulong bytecount); }
 124	AUE_ADJTIME	STD	{ int linux_adjtimex(void); }
-125	AUE_MPROTECT	NOPROTO	{ int mprotect(caddr_t addr, int len, \
+125	AUE_MPROTECT	STD	{ int linux_mprotect(caddr_t addr, int len, \
 				    int prot); }
 126	AUE_SIGPROCMASK	STD	{ int linux_sigprocmask(l_int how, \
 				    l_osigset_t *mask, l_osigset_t *omask); }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200701192147.l0JLlbYa096265>