From: Cyril Hrubis <chrubis@suse.cz>
To: ltp@lists.linux.it
Subject: [LTP] [PATCH] Fix getcwd03 testcase by zeroing target buffer for readlink()
Date: Tue, 9 May 2017 11:08:10 +0200 [thread overview]
Message-ID: <20170509090810.GA4150@rei.suse.de> (raw)
In-Reply-To: <20170506070042.GA30720@ls3530.fritz.box>
Hi!
> > > According to the man(2) page of readlink(), a null byte is not appended to the
> > > target buffer. So applications need to make sure that the target buffer is
> > > zero-initialized, otherwise random bytes at the end of the returned string may
> > > exist.
> >
> > Good catch.
> >
> > > This patch zero-initializes the on-stack char array "link" and thus fixes the
> > > testcase failure of getcwd03 on the hppa/parisc architecture (and maybe others).
> >
> > Can we use the return value form the readlink instead?
> >
> > r = SAFE_READLINK(.., buf, sizeof(buf)-1);
> > buf[r] = '\0';
>
> Yes, that's possible.
> But we have in total three testcase which exhibit the same problem:
>
> testcases/kernel/syscalls/openat/openat03.c: SAFE_READLINK(cleanup, path, tmp, PATH_MAX);
> testcases/kernel/syscalls/getcwd/getcwd03.c: SAFE_READLINK(dir_link, link, sizeof(link));
> testcases/kernel/syscalls/open/open14.c: SAFE_READLINK(cleanup, path, tmp, PATH_MAX);
>
> All of those use a temporary un-initialized buffer on the stack, so all
> would need this fix. On the hppa architecture I found those testcases
> failing randomly.
Ok.
> > The SAFE_READLINK() does catch the case where readlink() returns -1 and
> > passing size decreased by one should handle the corner case where the
> > path is truncated and return value is the size of the buffer we passed
> > to the readlink() call.
>
> This still doesn't zero-terminate the buffer (which is on stack).
>
> Instead I'd propose the patch below. It always zero-terminates the
> buffer and as such we would handle newly added testcases in future which
> will probably miss this readlink behaviour too.
Fixing the problem in SAFE_READLIN() is a good idea, comments below.
> ----------------
>
> [PATCH] SAFE_READLINK() should return zero-terminated target buffer
>
> According to the man(2) page of readlink(), a null byte is not appended
> to the target buffer. So applications need to make sure that the target
> buffer is zero-initialized, otherwise random bytes at the end of the
> returned string may exist.
>
> Currently all users of SAFE_READLINK() get it wrong. This include the
> openat03, getcwd03 and open14 testcases which pass a temporary,
> un-initialized on-stack buffer to readlink().
>
> This patch fixes SAFE_READLINK to always return a zero-terminated string
> and thus fixes the the failure of getcwd03 on the hppa/parisc
> architecture (and probably others).
>
> Signed-off-by: Helge Deller <deller@gmx.de>
>
> diff --git a/lib/safe_macros.c b/lib/safe_macros.c
> index bffc5a17a..1267b0098 100644
> --- a/lib/safe_macros.c
> +++ b/lib/safe_macros.c
> @@ -408,9 +408,17 @@ ssize_t safe_readlink(const char *file, const int lineno,
> rval = readlink(path, buf, bufsize);
>
> if (rval == -1) {
> + buf[0] = 0; /* clear buffer on error */
Clearing the buffer here is not really needed since the tst_brkm() will
abort the test anyway.
> tst_brkm(TBROK | TERRNO, cleanup_fn,
> "%s:%d: readlink(%s,%p,%zu) failed",
> file, lineno, path, buf, bufsize);
> + } else {
> + /* readlink does not append a null byte to the buffer.
> + * Add it now. */
> + if ((size_t) rval < bufsize)
> + buf[rval] = 0;
> + else
> + buf[bufsize-1] = 0;
This looks good.
> }
>
> return rval;
--
Cyril Hrubis
chrubis@suse.cz
prev parent reply other threads:[~2017-05-09 9:08 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-04 18:23 [LTP] [PATCH] Fix getcwd03 testcase by zeroing target buffer for readlink() Helge Deller
2017-05-05 9:34 ` Cyril Hrubis
2017-05-06 7:00 ` Helge Deller
2017-05-09 9:08 ` Cyril Hrubis [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170509090810.GA4150@rei.suse.de \
--to=chrubis@suse.cz \
--cc=ltp@lists.linux.it \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox