summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brown2014-05-18 22:05:39 +0200
committerMichael Brown2014-05-18 22:09:49 +0200
commit2b4be69eee372e1010af2302e82c3d0cf1d875e9 (patch)
tree29a68f744d7df70437b8e3ede82e98c3d4c9de9e /src
parent[test] Add self-tests for strdup() (diff)
downloadipxe-2b4be69eee372e1010af2302e82c3d0cf1d875e9.tar.gz
ipxe-2b4be69eee372e1010af2302e82c3d0cf1d875e9.tar.xz
ipxe-2b4be69eee372e1010af2302e82c3d0cf1d875e9.zip
[libc] Prevent strndup() from reading beyond the end of the string
strndup() may be called on a string which is not NUL-terminated. Use strnlen() instead of strlen() to ensure that we do not read beyond the end of such a string. Add self-tests for strndup(), including a test case with an unterminated string. Originally-fixed-by: Marin Hannache <git@mareo.fr> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src')
-rw-r--r--src/core/string.c4
-rw-r--r--src/tests/string_test.c20
2 files changed, 21 insertions, 3 deletions
diff --git a/src/core/string.c b/src/core/string.c
index 190007a47..e53c283c2 100644
--- a/src/core/string.c
+++ b/src/core/string.c
@@ -337,11 +337,9 @@ void * memchr(const void *s, int c, size_t n)
char * strndup(const char *s, size_t n)
{
- size_t len = strlen(s);
+ size_t len = strnlen(s,n);
char *new;
- if (len>n)
- len = n;
new = malloc(len+1);
if (new) {
new[len] = '\0';
diff --git a/src/tests/string_test.c b/src/tests/string_test.c
index 934c537cf..3b48d9f3d 100644
--- a/src/tests/string_test.c
+++ b/src/tests/string_test.c
@@ -134,6 +134,26 @@ static void string_test_exec ( void ) {
ok ( strcmp ( dup, orig ) == 0 );
free ( dup );
}
+
+ /* Test strndup() */
+ {
+ const char *normal = "testing testing";
+ const char unterminated[6] = { 'h', 'e', 'l', 'l', 'o', '!' };
+ char *dup;
+ dup = strndup ( normal, 32 );
+ ok ( dup != NULL );
+ ok ( dup != normal );
+ ok ( strcmp ( dup, normal ) == 0 );
+ free ( dup );
+ dup = strndup ( normal, 4 );
+ ok ( dup != NULL );
+ ok ( strcmp ( dup, "test" ) == 0 );
+ free ( dup );
+ dup = strndup ( unterminated, 5 );
+ ok ( dup != NULL );
+ ok ( strcmp ( dup, "hello" ) == 0 );
+ free ( dup );
+ }
}
/** String self-test */