]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
lib/nolibc,lib/isrlib: Fix strncpy
authorChristiano Haesbaert <haesbaert@haesbaert.org>
Wed, 5 Jul 2023 13:00:11 +0000 (15:00 +0200)
committerSimon Kuenzer <simon@unikraft.io>
Tue, 28 Nov 2023 13:17:07 +0000 (14:17 +0100)
strncpy will produce different results for an empty string depending on the
preceding value of dst:

char buf[4];

bzero(buf, sizeof(buf));
buf[0] = 0;
buf[1] = 9;
strncpy(&buf[1], "", 3);

"clen" will be 0 since strnlen("") is 0, which will then look into dst[-1]
(buf[0]) to decide if it terminates dst or not.

Instead of working around, replace strncpy for a conformant version, taken
from OpenBSD libkern, as a bonus we zero out the remaining buffer.

https://github.com/openbsd/src/blob/master/sys/lib/libkern/strncpy.c

Signed-off-by: Christiano Haesbaert <haesbaert@haesbaert.org>
Reviewed-by: Eduard-Florin Mihailescu <mihailescu.eduard@gmail.com>
Approved-by: Simon Kuenzer <simon@unikraft.io>
GitHub-Closes: #973

lib/isrlib/string.c
lib/nolibc/string.c

index a76aaf73288226b0ac95419de9cc2b255c0ccee4..6de518554713bf403c264c32a1791ab2f99ce2b6 100644 (file)
@@ -152,16 +152,20 @@ size_t strnlen_isr(const char *str, size_t len)
 
 char *strncpy_isr(char *dst, const char *src, size_t len)
 {
-       size_t clen;
-
-       clen = strnlen_isr(src, len);
-       memcpy_isr(dst, src, clen);
+       if (len != 0) {
+               char *d = dst;
+               const char *s = src;
+
+               do {
+                       if ((*d++ = *s++) == 0) {
+                               /* NUL pad the remaining n-1 bytes */
+                               while (--len != 0)
+                                       *d++ = 0;
+                               break;
+                       }
+               } while (--len != 0);
+       }
 
-       /* instead of filling up the rest of left space with zeros,
-        * append a termination character if we did not copy one
-        */
-       if (clen < len && dst[clen - 1] != '\0')
-               dst[clen] = '\0';
        return dst;
 }
 
index 50023875fe939178003eaff7e8f820409f2aba34..801795ad7daa51eeba642507a7c1f79afd48ce74 100644 (file)
@@ -152,16 +152,20 @@ size_t strnlen(const char *str, size_t len)
 
 char *strncpy(char *dst, const char *src, size_t len)
 {
-       size_t clen;
-
-       clen = strnlen(src, len);
-       memcpy(dst, src, clen);
+       if (len != 0) {
+               char *d = dst;
+               const char *s = src;
+
+               do {
+                       if ((*d++ = *s++) == 0) {
+                               /* NUL pad the remaining n-1 bytes */
+                               while (--len != 0)
+                                       *d++ = 0;
+                               break;
+                       }
+               } while (--len != 0);
+       }
 
-       /* instead of filling up the rest of left space with zeros,
-        * append a termination character if we did not copy one
-        */
-       if (clen < len && dst[clen - 1] != '\0')
-               dst[clen] = '\0';
        return dst;
 }