PERFORCE change 100894 for review

John Baldwin jhb at FreeBSD.org
Fri Jul 7 16:16:16 UTC 2006


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

Change 100894 by jhb at jhb_mutex on 2006/07/07 16:15:44

	accept1() had a bug in that tried to free 'name' in the
	uap->name == NULL case which resulted in garbage.  Fix that and
	clean up accept1/kern_accept some more via the following:
	- Handle the uap->name == NULL case right up front in accept1()
	  with a single call to kern_accept().  This also gets rid of the
	  slight obfuscation of the 'sap' variable.
	- Move the COMPAT_OLDSOCK handling up into accept1() and out of
	  kern_accept().

Affected files ...

.. //depot/projects/smpng/sys/compat/svr4/svr4_stream.c#31 edit
.. //depot/projects/smpng/sys/kern/uipc_syscalls.c#82 edit
.. //depot/projects/smpng/sys/sys/syscallsubr.h#42 edit

Differences ...

==== //depot/projects/smpng/sys/compat/svr4/svr4_stream.c#31 (text+ko) ====

@@ -1783,7 +1783,7 @@
 		 * We are after a listen, so we try to accept...
 		 */
 
-		error = kern_accept(td, uap->fd, &sa, &sasize, 0);
+		error = kern_accept(td, uap->fd, &sa, &sasize);
 		if (error) {
 			DPRINTF(("getmsg: accept failed %d\n", error));
 			return error;

==== //depot/projects/smpng/sys/kern/uipc_syscalls.c#82 (text+ko) ====

@@ -296,46 +296,46 @@
 	} */ *uap;
 	int compat;
 {
-	struct sockaddr *name, **sap;
+	struct sockaddr *name;
 	socklen_t namelen;
 	int error;
 
-	if (uap->name) {
-		error = copyin(uap->anamelen, &namelen, sizeof (namelen));
-		if (error)
-			return (error);
-		sap = &name;
-	} else
-		sap = NULL;
+	if (uap->name == NULL)
+		return (kern_accept(td, uap->s, NULL, NULL));
+
+	error = copyin(uap->anamelen, &namelen, sizeof (namelen));
+	if (error)
+		return (error);
 
-	error = kern_accept(td, uap->s, sap, &namelen, compat);
+	error = kern_accept(td, uap->s, &name, &namelen, compat);
 
-	if (uap->name) {
-		/*
-		 * return a namelen of zero for older code which might
-		 * ignore the return value from accept.
-		 */
-		if (error && name == NULL) {
-			(void) copyout(&namelen,
-			    uap->anamelen, sizeof(*uap->anamelen));
-			return (error);
-		}
-		if (error == 0) {
-			KASSERT(name != NULL,
-			    ("%s: success but no sockaddr", __func__));
-			error = copyout(name, uap->name, namelen);
-		}
-		if (error == 0)
-			error = copyout(&namelen, uap->anamelen,
-			    sizeof(namelen));
-		free(name, M_SONAME);
+	/*
+	 * return a namelen of zero for older code which might
+	 * ignore the return value from accept.
+	 */
+	if (error && name == NULL) {
+		(void) copyout(&namelen,
+		    uap->anamelen, sizeof(*uap->anamelen));
+		return (error);
+	}
+	if (error == 0 && name != NULL) {
+#ifdef COMPAT_OLDSOCK
+		if (compat)
+			((struct osockaddr *)name)->sa_family =
+			    name->sa_family;
+#endif
+		error = copyout(name, uap->name, namelen);
 	}
+	if (error == 0)
+		error = copyout(&namelen, uap->anamelen,
+		    sizeof(namelen));
+	free(name, M_SONAME);
 	return (error);
 }
 
 int
 kern_accept(struct thread *td, int s, struct sockaddr **name,
-    socklen_t *namelen, int compat)
+    socklen_t *namelen)
 {
 	struct filedesc *fdp;
 	struct file *headfp, *nfp = NULL;
@@ -459,11 +459,6 @@
 		/* check sa_len before it is destroyed */
 		if (*namelen > sa->sa_len)
 			*namelen = sa->sa_len;
-#ifdef COMPAT_OLDSOCK
-		if (compat)
-			((struct osockaddr *)sa)->sa_family =
-			    sa->sa_family;
-#endif
 		*name = sa;
 		sa = NULL;
 	}

==== //depot/projects/smpng/sys/sys/syscallsubr.h#42 (text+ko) ====

@@ -51,7 +51,7 @@
 int	kern___getcwd(struct thread *td, u_char *buf, enum uio_seg bufseg,
 	    u_int buflen);
 int	kern_accept(struct thread *td, int s, struct sockaddr **name,
-	    socklen_t *namelen, int compat);
+	    socklen_t *namelen);
 int	kern_access(struct thread *td, char *path, enum uio_seg pathseg,
 	    int flags);
 int	kern_adjtime(struct thread *td, struct timeval *delta,


More information about the p4-projects mailing list