summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2024-05-27 13:04:16 -0400
committerJakob Kaivo <jkk@ung.org>2024-05-27 13:04:16 -0400
commite6ef806ef40a421435b1209f0f79d778c03fe04a (patch)
tree4a099e9cfe1084f24b990c833a97285c2b442990
parent7d71ad2b8589bef1bdf26c3cfec5ab99b6bba3b9 (diff)
handle use-after-close
-rw-r--r--src/stdio/_stdio.h11
-rw-r--r--src/stdio/fclose.c3
-rw-r--r--src/stdio/fflush.c2
-rw-r--r--src/stdio/getc_unlocked.c4
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");