PERFORCE change 101488 for review

John Baldwin jhb at FreeBSD.org
Thu Jul 13 20:50:16 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=101488

Change 101488 by jhb at jhb_mutex on 2006/07/13 20:50:08

	- Add conditional VFS Giant locking to linux_uselib() and mark it
	  MPSAFE.
	- Remove a Doesn't-Ever-Happen(tm) error case.
	- Hold the vnode lock longer to protect setting VV_TEXT and note that
	  we don't clear it later on if we get an error.
	- Document where the error return values differ from
	  exec_check_permissions() and add a competing XXX to rwatson's
	  explaining that vn_open() would be a poor choice here.  This
	  code is much closer to exec_check_permissions().
	- Audit the pathname lookup for the library.

Affected files ...

.. //depot/projects/smpng/sys/compat/linux/linux_misc.c#66 edit
.. //depot/projects/smpng/sys/i386/linux/syscalls.master#35 edit
.. //depot/projects/smpng/sys/notes#79 edit

Differences ...

==== //depot/projects/smpng/sys/compat/linux/linux_misc.c#66 (text+ko) ====

@@ -229,7 +229,7 @@
 	unsigned long bss_size;
 	char *library;
 	int error;
-	int locked;
+	int locked, vfslocked;
 
 	LCONVPATHEXIST(td, args->library, &library);
 
@@ -239,32 +239,24 @@
 #endif
 
 	a_out = NULL;
+	vfslocked = 0;
 	locked = 0;
 	vp = NULL;
 
-	/*
-	 * XXX: This code should make use of vn_open(), rather than doing
-	 * all this stuff itself.
-	 */
-	NDINIT(&ni, LOOKUP, ISOPEN|FOLLOW|LOCKLEAF, UIO_SYSSPACE, library, td);
+	NDINIT(&ni, LOOKUP, ISOPEN | FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
+	    UIO_SYSSPACE, library, td);
 	error = namei(&ni);
 	LFREEPATH(library);
 	if (error)
 		goto cleanup;
 
 	vp = ni.ni_vp;
-	/*
-	 * XXX - This looks like a bogus check. A LOCKLEAF namei should not
-	 * succeed without returning a vnode.
-	 */
-	if (vp == NULL) {
-		error = ENOEXEC;	/* ?? */
-		goto cleanup;
-	}
+	vfslocked = NDHASGIANT(&ni);
 	NDFREE(&ni, NDF_ONLY_PNBUF);
 
 	/*
 	 * From here on down, we have a locked vnode that must be unlocked.
+	 * XXX: The code below largely duplicates exec_check_permissions().
 	 */
 	locked++;
 
@@ -281,6 +273,7 @@
 
 	if ((vp->v_mount->mnt_flag & MNT_NOEXEC) ||
 	    ((attr.va_mode & 0111) == 0) || (attr.va_type != VREG)) {
+		/* EACCESS is what exec(2) returns. */
 		error = ENOEXEC;
 		goto cleanup;
 	}
@@ -299,6 +292,8 @@
 	/*
 	 * XXX: This should use vn_open() so that it is properly authorized,
 	 * and to reduce code redundancy all over the place here.
+	 * XXX: Not really, it duplicates far more of exec_check_permissions()
+	 * than vn_open().
 	 */
 #ifdef MAC
 	error = mac_check_vnode_open(td->td_ucred, vp, FREAD);
@@ -312,12 +307,6 @@
 	/* Pull in executable header into kernel_map */
 	error = vm_mmap(kernel_map, (vm_offset_t *)&a_out, PAGE_SIZE,
 	    VM_PROT_READ, VM_PROT_READ, 0, OBJT_VNODE, vp, 0);
-	/*
-	 * Lock no longer needed
-	 */
-	locked = 0;
-	VOP_UNLOCK(vp, 0, td);
-
 	if (error)
 		goto cleanup;
 
@@ -372,11 +361,21 @@
 	}
 	PROC_UNLOCK(td->td_proc);
 
-	mp_fixme("Unlocked vflags access.");
-	/* prevent more writers */
+	/*
+	 * Prevent more writers.
+	 * XXX: Note that if any of the VM operations fail below we don't
+	 * clear this flag.
+	 */
 	vp->v_vflag |= VV_TEXT;
 
 	/*
+	 * Lock no longer needed
+	 */
+	locked = 0;
+	VOP_UNLOCK(vp, 0, td);
+	VFS_UNLOCK_GIANT(vfslocked);
+
+	/*
 	 * Check if file_offset page aligned. Currently we cannot handle
 	 * misalinged file offsets, and so we read in the entire image
 	 * (what a waste).
@@ -453,8 +452,10 @@
 
 cleanup:
 	/* Unlock vnode if needed */
-	if (locked)
+	if (locked) {
 		VOP_UNLOCK(vp, 0, td);
+		VFS_UNLOCK_GIANT(vfslocked);
+	}
 
 	/* Release the kernel mapping. */
 	if (a_out)

==== //depot/projects/smpng/sys/i386/linux/syscalls.master#35 (text+ko) ====

@@ -165,7 +165,7 @@
 84	AUE_LSTAT	MSTD	{ int linux_lstat(char *path, struct ostat *up); }
 85	AUE_READLINK	MSTD	{ int linux_readlink(char *name, char *buf, \
 				    l_int count); }
-86	AUE_USELIB	STD	{ int linux_uselib(char *library); }
+86	AUE_USELIB	MSTD	{ int linux_uselib(char *library); }
 87	AUE_SWAPON	MNOPROTO	{ int swapon(char *name); }
 88	AUE_REBOOT	MSTD	{ int linux_reboot(l_int magic1, \
 				    l_int magic2, l_uint cmd, void *arg); }

==== //depot/projects/smpng/sys/notes#79 (text+ko) ====

@@ -90,8 +90,8 @@
 	- svr4_sys_waitsys()
 	- svr4_sys_fchroot()
 	- svr4_sys_resolvepath()
-    - linux
-	- linux_uselib()
+    + linux
+	+ linux_uselib()
     - ibcs2
 	- ibcs2_mount()
 	- ibcs2_umount()


More information about the p4-projects mailing list