tree-wide: check memstream buffer after closing the handle
When closing the FILE handle attached to a memstream, it may attempt to
do a realloc() that may fail during OOM situations, in which case we are
left with the buffer pointer pointing to NULL and buffer size > 0. For
example:
```
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
void *realloc(void *ptr, size_t size) {
return NULL;
}
int main(int argc, char *argv[])
{
FILE *f;
char *buf;
size_t sz = 0;
f = open_memstream(&buf, &sz);
if (!f)
return -ENOMEM;
fputs("Hello", f);
fflush(f);
printf("buf: 0x%lx, sz: %lu, errno: %d\n",
(unsigned long) buf, sz, errno);
fclose(f);
printf("buf: 0x%lx, sz: %lu, errno: %d\n",
(unsigned long) buf, sz, errno);
return 0;
}
```
```
$ gcc -o main main.c
$ ./main
buf: 0x74d4a0, sz: 5, errno: 0
buf: 0x0, sz: 5, errno: 0
```
This might do unexpected things if the underlying code expects a valid
pointer to the memstream buffer after closing the handle.
Found by Nallocfuzz.
This commit is contained in:
+10
-7
@@ -9,6 +9,7 @@
|
||||
#include "alloc-util.h"
|
||||
#include "escape.h"
|
||||
#include "extract-word.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "gunicode.h"
|
||||
#include "locale-util.h"
|
||||
@@ -603,9 +604,9 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) {
|
||||
STATE_CSI,
|
||||
STATE_CSO,
|
||||
} state = STATE_OTHER;
|
||||
char *obuf = NULL;
|
||||
_cleanup_free_ char *obuf = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
size_t osz = 0, isz, shift[2] = {}, n_carriage_returns = 0;
|
||||
FILE *f;
|
||||
|
||||
assert(ibuf);
|
||||
assert(*ibuf);
|
||||
@@ -713,11 +714,13 @@ char *strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]) {
|
||||
}
|
||||
}
|
||||
|
||||
if (fflush_and_check(f) < 0) {
|
||||
fclose(f);
|
||||
return mfree(obuf);
|
||||
}
|
||||
fclose(f);
|
||||
if (fflush_and_check(f) < 0)
|
||||
return NULL;
|
||||
|
||||
f = safe_fclose(f);
|
||||
|
||||
if (!obuf)
|
||||
return NULL;
|
||||
|
||||
free_and_replace(*ibuf, obuf);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user