Criterion icon indicating copy to clipboard operation
Criterion copied to clipboard

redirect: fix double free due to fclose multiple times the same fd

Open LeandreBl opened this issue 4 years ago • 5 comments

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

LeandreBl avatar May 29 '20 12:05 LeandreBl

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

LeandreBl avatar May 29 '20 14:05 LeandreBl

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?

Snaipe avatar Jun 17 '20 16:06 Snaipe

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

LeandreBl avatar Jun 17 '20 16:06 LeandreBl

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.

Snaipe avatar Jun 30 '20 10:06 Snaipe

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.

LeandreBl avatar Jun 30 '20 17:06 LeandreBl