Criterion
Criterion copied to clipboard
redirect: fix double free due to fclose multiple times the same fd
fixed with a PIPE_DUP
flag
#314
fclose
close the associated fd
when called. In order to avoid an invalid read/free
afterwards, when calling pipe_in
with the same fd
, the argument PIPE_DUP
is passed as opt to the pipe_in
function.
See also: #382
update: from what i'm seeing, passing PIPE_DUP
does prevent a crash, but the 2nd following fread
returns 0
aside that, only commenting fclose
and keeping PIPE_NOOPT
works perfectly, but it will leak some memory, so it's not viable
I don't think this is necessarily the right fix -- in particular, I think that, semantically speaking, fclosing the returned FILE* handle is the right thing to do from inside the test. This mostly makes the behaviour of the whole thing non-surprising, and mirrors the normal fopen/use/fclose sequence of operations for normal files.
If fclose gets called too many times, is it criterion itself that's trying to close the handle to be "helpful", but shouldn't?
The problem is that the first call to fclose
closes the fd
associated, and as it not duped, the following fclose
call crashes with an invalid free()
==26727== Address 0x5ac14a0 is 0 bytes inside a block of size 552 free'd
==26727== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26727== by 0x51202FD: fclose@@GLIBC_2.2.5 (iofclose.c:77)
==26727== by 0x4E4A6D5: cr_stdout_match_str (in /usr/lib/libcriterion.so.3.1.0)
I still have a whole valgrind log at #314 if needed but i'll need to dig again in the code.
The thing is, I don't know why the fdopen
call does not fail, there is probably no tests made on the fd
provided to it, and so, builds a FILE *
around a closed fd
OK, so the main issue is that cr_assert_stderr_eq_str
and friends are in fact closing the input, which kind of violates all expectation about how FILE*
should be used.
The right fix is to probably have it not close the stream. I'm not sure if that introduces breakages though, but I'd gladly accept a fix for that.
The associated problem, is that we use FILE *
everywhere, which is convenient for a lot of operations, but it's impossible to release the allocated FILE
structure that comes with the associated fd
, without closing the fd
.
That's why my first suggestion was to dup
the fd
, and use this duped fd
in the fdopen
call, so that we can fclose
it afterwards.