From c9776bf8a698d5b871522deeb0340f2b741ca6a4 Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Tue, 9 Sep 2025 12:28:24 +0300 Subject: [PATCH] libc/fclose: Validate the user provided stream pointer Check that the provided stream pointer is really opened for the group before closing & freeing it. Signed-off-by: Jukka Laitinen --- libs/libc/stdio/lib_fclose.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/libs/libc/stdio/lib_fclose.c b/libs/libc/stdio/lib_fclose.c index cee301e1f2..6a5e178750 100644 --- a/libs/libc/stdio/lib_fclose.c +++ b/libs/libc/stdio/lib_fclose.c @@ -36,6 +36,8 @@ # include #endif +#include + #include "libc.h" /**************************************************************************** @@ -69,6 +71,33 @@ int fclose(FAR FILE *stream) if (stream) { + bool stdstream = (stream == stdin || stream == stdout || + stream == stderr); + bool found = stdstream; + FAR sq_entry_t *curr; + + slist = lib_get_streams(); + + nxmutex_lock(&slist->sl_lock); + + /* Verify that the stream pointer is valid. */ + + for (curr = sq_peek(&slist->sl_queue); curr && !found; + curr = sq_next(curr)) + { + if (stream == (FAR FILE *)curr) + { + found = true; + } + } + + if (!found) + { + nxmutex_unlock(&slist->sl_lock); + errcode = EINVAL; + goto done; + } + ret = OK; /* If the stream was opened for writing, then flush the stream */ @@ -81,16 +110,14 @@ int fclose(FAR FILE *stream) /* Skip close the builtin streams(stdin, stdout and stderr) */ - if (stream == stdin || stream == stdout || stream == stderr) + if (stdstream) { + nxmutex_unlock(&slist->sl_lock); goto done; } /* Remove FILE structure from the stream list */ - slist = lib_get_streams(); - nxmutex_lock(&slist->sl_lock); - sq_rem(&stream->fs_entry, &slist->sl_queue); nxmutex_unlock(&slist->sl_lock);