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; }