diff options
author | Jakob Kaivo <jkk@ung.org> | 2024-05-27 13:04:16 -0400 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2024-05-27 13:04:16 -0400 |
commit | e6ef806ef40a421435b1209f0f79d778c03fe04a (patch) | |
tree | 4a099e9cfe1084f24b990c833a97285c2b442990 | |
parent | 7d71ad2b8589bef1bdf26c3cfec5ab99b6bba3b9 (diff) |
handle use-after-close
-rw-r--r-- | src/stdio/_stdio.h | 11 | ||||
-rw-r--r-- | src/stdio/fclose.c | 3 | ||||
-rw-r--r-- | src/stdio/fflush.c | 2 | ||||
-rw-r--r-- | src/stdio/getc_unlocked.c | 4 |
4 files changed, 15 insertions, 5 deletions
diff --git a/src/stdio/_stdio.h b/src/stdio/_stdio.h index cf53179d..f02715c6 100644 --- a/src/stdio/_stdio.h +++ b/src/stdio/_stdio.h @@ -34,7 +34,16 @@ #else #define ASSERT_STREAM(__stream, __orientation, __operation) do { \ ASSERT_NONNULL(__stream); \ - if (((__orientation) && stream->orientation) && ((__orientation) != stream->orientation)) { \ + if ((__stream)->fd == -1) { \ + UNDEFINED("In call to %s: Stream is not open (use after close?)", __func__); \ + } \ + if (((__operation) == OP_INPUT) && !(__stream)->read) { \ + UNDEFINED("In call to %s: Attempted input operation on output stream", __func__); \ + } \ + if (((__operation) == OP_OUTPUT) && !(__stream)->write) { \ + UNDEFINED("In call to %s: Attempted output operation on input stream", __func__); \ + } \ + if (((__orientation) && (__stream)->orientation) && ((__orientation) != (__stream)->orientation)) { \ UNDEFINED("In call to %s(): Requested %s operation on %s oriented stream", __func__, (__orientation) > 0 ? "wide" : "byte", (stream->orientation) > 0 ? "wide" : "byte"); \ } \ } while (0) diff --git a/src/stdio/fclose.c b/src/stdio/fclose.c index f438a9c2..37198fcb 100644 --- a/src/stdio/fclose.c +++ b/src/stdio/fclose.c @@ -26,7 +26,7 @@ int fclose(FILE *stream) SIGNAL_SAFE(0); flockfile(stream); - if (fflush(stream) == EOF) { + if (stream->operation == OP_OUTPUT && fflush(stream) == EOF) { /* set errno */ return EOF; } @@ -44,6 +44,7 @@ int fclose(FILE *stream) } memset(stream, '\0', sizeof(*stream)); + stream->fd = -1; /* RETURN_SUCCESS(0); diff --git a/src/stdio/fflush.c b/src/stdio/fflush.c index a653e0d1..6c1e78f5 100644 --- a/src/stdio/fflush.c +++ b/src/stdio/fflush.c @@ -27,6 +27,8 @@ int fflush(FILE *stream) return 0; } + ASSERT_STREAM(stream, 0, 0); + if (!stream->write) { UNDEFINED("attempt to fflush() an input stream"); } diff --git a/src/stdio/getc_unlocked.c b/src/stdio/getc_unlocked.c index 0e68eb79..13c9f867 100644 --- a/src/stdio/getc_unlocked.c +++ b/src/stdio/getc_unlocked.c @@ -15,9 +15,7 @@ int getc_unlocked(FILE * stream) SIGNAL_SAFE(0); - if (!stream) { - return EOF; - } + ASSERT_STREAM(stream, 0, OP_INPUT); if (stream->operation == OP_OUTPUT) { UNDEFINED("attempted input on stream immediately after output"); |