[LTP] [PATCH] syscalls/renameat202: initialize str with zero

Eryu Guan eguan@redhat.com
Thu Feb 18 13:52:13 CET 2016


On Thu, Feb 18, 2016 at 12:47:22PM +0100, Cyril Hrubis wrote:
> Hi!
> > In renameat2_verify(), str is allocated on stack with size 8 (sizeof
> > content) and filled with random data. Then file content (7 bytes) is
> > read into str and the last byte in str is left unchanged with garbage,
> > and test fails if that last byte is not zero.
> 
> Good catch.
> 
> > Fix it by initializing the str with zeros, make sure str is null
> > terminated as long as correct data has been read in.
> 
> Looking at the code it may be easier to use write() to write the string
> including the null byte in the setup. But either one is fine.
> 
> > Also remove the "str[strlen(content)] == '\0'" check, which is not
> > necessary, because strcmp will catch the failure anyway.
> 
> This has been added there on purpose so that we are sure the test
> wouldn't segfault in case that the str is not null terminated which is
> unlikely but still possible. And it's still possible even when you zero
> the str buffer since the read may overwrite whole str and passing
> non-null terminated buffer to strcmp() is still undefined operation.

Makes sense, I'll add it back in v2.

> 
> Maybe it would be much better to try to read a buffer larger than the
> expected content, check that the value from read was size of the data
> and then do memcmp() with explicit size.

Agreed, do memcmp only if read(2) returned the expected size.

> 
> BTW: The size of the str should be increased anyway since the read gets
>      strlen(content) + 10 as a size parameter which is larger than
>      sizeof(str). We should just change it to some arbitrary large value
>      like 128.

Agreed.

> 
> > Also improve the failure message to print more useful debug message.
> > 
> > Signed-off-by: Eryu Guan <eguan@redhat.com>
> > ---
> >  testcases/kernel/syscalls/renameat2/renameat202.c | 17 +++++++++--------
> >  1 file changed, 9 insertions(+), 8 deletions(-)
> > 
> > diff --git a/testcases/kernel/syscalls/renameat2/renameat202.c b/testcases/kernel/syscalls/renameat2/renameat202.c
> > index 3761391..9e2d12e 100644
> > --- a/testcases/kernel/syscalls/renameat2/renameat202.c
> > +++ b/testcases/kernel/syscalls/renameat2/renameat202.c
> > @@ -118,7 +118,7 @@ static void cleanup(void)
> >  
> >  static void renameat2_verify(void)
> >  {
> > -	char str[sizeof(content)];
> > +	char str[sizeof(content)] = { 0 };
> >  	struct stat st;
> >  	char *emptyfile;
> >  	char *contentfile;
> > @@ -152,11 +152,12 @@ static void renameat2_verify(void)
> >  		tst_brkm(TERRNO | TFAIL, cleanup, "close fd failed");
> >  	fd = 0;
> >  
> > -	if (str[strlen(content)] == '\0' && !strcmp(content, str)
> > -		&& !st.st_size)
> > -		tst_resm(TPASS,
> > -			"renameat2() swapped the content of the two files");
> > -	else
> > -		tst_resm(TFAIL,
> > -			"renameat2() didn't swap the content of the two files");
> > +	if (strcmp(content, str)) {
> > +		tst_resm(TFAIL, "file content changed after renameat2()");
> > +		tst_resm(TFAIL, "expect \"%s\", got \"%s\"", content, str);
> 
> This adds two FAIL statements in the output for one failure. Either
> print the message in one tst_resm() statement or change the second one
> to TINFO.

I used TINFO at first, but thought TFAIL might be more clearer. I'll
change it back.

> 
> > +	} else if (st.st_size) {
> > +		tst_resm(TFAIL, "emptyfile has non-zero file size");
> 
> You should do return in the previous if() so that you don't have to do
> the else if () spagetthi code here.
> 
> And if you do return here the TPASS message does not have to be in the
> else block as well.

Fair enough.

Thanks for the review!

Eryu

> 
> > +	} else {
> > +		tst_resm(TPASS, "renameat2() test passed");
> > +	}
> >  }
> 
> -- 
> Cyril Hrubis
> chrubis@suse.cz


More information about the Ltp mailing list