From 78a9ad62ee116e1e41b05f75f285117080e84aef Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Sat, 25 Jul 2026 00:08:37 +0800 Subject: [PATCH] libc/stdio: allocate a buffer in getdelim() when *lineptr is NULL POSIX requires getdelim()/getline() to allocate a new buffer whenever *lineptr is NULL, regardless of the value of *n. The previous code read the buffer size from *n unconditionally and only fell back to the initial size when *n was zero, so a caller that passes *lineptr == NULL together with an uninitialized (non-zero) *n caused lib_malloc() to be invoked with that garbage size and typically fail with ENOMEM. Treat a NULL *lineptr the same as a zero *n: (re)allocate from the known BUFSIZE_INIT and ignore the untrusted *n. This matches the glibc behaviour that portable code relies on (for example toybox grep, which calls getdelim() with an uninitialized size variable). Signed-off-by: Xiang Xiao --- libs/libc/stdio/lib_getdelim.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libs/libc/stdio/lib_getdelim.c b/libs/libc/stdio/lib_getdelim.c index 3eaed14caa33f..1df381c231cd9 100644 --- a/libs/libc/stdio/lib_getdelim.c +++ b/libs/libc/stdio/lib_getdelim.c @@ -99,10 +99,14 @@ ssize_t getdelim(FAR char **lineptr, size_t *n, int delimiter, goto errout; } - /* Verify the buffer size */ + /* Verify the buffer size. POSIX requires that a NULL *lineptr be + * (re)allocated regardless of the value of *n, so do not trust *n when + * there is no buffer: a caller may legitimately pass *lineptr == NULL with + * an uninitialized *n. + */ bufsize = *n; - if (bufsize == 0) + if (*lineptr == NULL || bufsize == 0) { /* Pick an initial buffer size */