Module Name:    src
Committed By:   pooka
Date:           Tue Nov  9 15:22:47 UTC 2010

Modified Files:
        src/sys/rump/librump/rumpkern: rumpcopy.c

Log Message:
fix copystr/copyinstr/copyoutstr to return ENAMETOOLONG where appropriate


To generate a diff of this commit:
cvs rdiff -u -r1.7 -r1.8 src/sys/rump/librump/rumpkern/rumpcopy.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/rump/librump/rumpkern/rumpcopy.c
diff -u src/sys/rump/librump/rumpkern/rumpcopy.c:1.7 src/sys/rump/librump/rumpkern/rumpcopy.c:1.8
--- src/sys/rump/librump/rumpkern/rumpcopy.c:1.7	Fri Oct 29 15:27:50 2010
+++ src/sys/rump/librump/rumpkern/rumpcopy.c	Tue Nov  9 15:22:47 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: rumpcopy.c,v 1.7 2010/10/29 15:27:50 pooka Exp $	*/
+/*	$NetBSD: rumpcopy.c,v 1.8 2010/11/09 15:22:47 pooka Exp $	*/
 
 /*
  * Copyright (c) 2009 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rumpcopy.c,v 1.7 2010/10/29 15:27:50 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rumpcopy.c,v 1.8 2010/11/09 15:22:47 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/lwp.h>
@@ -82,36 +82,65 @@
 int
 copystr(const void *kfaddr, void *kdaddr, size_t len, size_t *done)
 {
+	uint8_t *to = kdaddr;
+	const uint8_t *from = kfaddr;
+	size_t actlen = 0;
+
+	while (len-- > 0 && (*to++ = *from++) != 0)
+		actlen++;
+
+	if (len+1 == 0 && *(to-1) != 0)
+		return ENAMETOOLONG;
 
-	strlcpy(kdaddr, kfaddr, len);
 	if (done)
-		*done = strlen(kdaddr)+1; /* includes termination */
+		*done = actlen+1; /* + '\0' */
 	return 0;
 }
 
 int
 copyinstr(const void *uaddr, void *kaddr, size_t len, size_t *done)
 {
+	uint8_t *to;
+	int rv;
 
 	if (curproc->p_vmspace == &vmspace0)
-		strlcpy(kaddr, uaddr, len);
-	else
-		rumpuser_sp_copyin(uaddr, kaddr, len);
+		return copystr(uaddr, kaddr, len, done);
+
+	if ((rv = rumpuser_sp_copyin(uaddr, kaddr, len)) != 0)
+		return rv;
+
+	/* figure out if we got a terminate string or not */
+	to = (uint8_t *)kaddr + len;
+	while (to != kaddr) {
+		if (*to == 0)
+			goto found;
+		to--;
+	}
+	return ENAMETOOLONG;
+
+ found:
 	if (done)
 		*done = strlen(kaddr)+1; /* includes termination */
+
 	return 0;
 }
 
 int
 copyoutstr(const void *kaddr, void *uaddr, size_t len, size_t *done)
 {
+	size_t slen;
 
 	if (curproc->p_vmspace == &vmspace0)
-		strlcpy(uaddr, kaddr, len);
-	else
-		rumpuser_sp_copyout(kaddr, uaddr, len);
+		return copystr(kaddr, uaddr, len, done);
+
+	slen = strlen(kaddr)+1;
+	if (slen > len)
+		return ENAMETOOLONG;
+
+	rumpuser_sp_copyout(kaddr, uaddr, slen);
 	if (done)
-		*done = strlen(uaddr)+1; /* includes termination */
+		*done = slen;
+
 	return 0;
 }
 

Reply via email to