* [LTP] [PATCH] Fix getcwd03 testcase by zeroing target buffer for readlink() @ 2017-05-04 18:23 Helge Deller 2017-05-05 9:34 ` Cyril Hrubis 0 siblings, 1 reply; 4+ messages in thread From: Helge Deller @ 2017-05-04 18:23 UTC (permalink / raw) To: ltp 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. 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). Signed-off-by: Helge Deller <deller@gmx.de> -- testcases/kernel/syscalls/getcwd/getcwd03.c | 1 + 1 file changed, 1 insertion(+) diff --git a/testcases/kernel/syscalls/getcwd/getcwd03.c b/testcases/kernel/syscalls/getcwd/getcwd03.c index 4f8f872cf..ec1cacea9 100644 --- a/testcases/kernel/syscalls/getcwd/getcwd03.c +++ b/testcases/kernel/syscalls/getcwd/getcwd03.c @@ -74,6 +74,7 @@ static void verify_getcwd(void) } SAFE_CHDIR(".."); + memset(link, 0, sizeof(link)); SAFE_READLINK(dir_link, link, sizeof(link)); if (strcmp(link, SAFE_BASENAME(res1))) { ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [LTP] [PATCH] Fix getcwd03 testcase by zeroing target buffer for readlink() 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 0 siblings, 1 reply; 4+ messages in thread From: Cyril Hrubis @ 2017-05-05 9:34 UTC (permalink / raw) To: ltp 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'; 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. > Signed-off-by: Helge Deller <deller@gmx.de> > > -- > testcases/kernel/syscalls/getcwd/getcwd03.c | 1 + > 1 file changed, 1 insertion(+) > > > diff --git a/testcases/kernel/syscalls/getcwd/getcwd03.c b/testcases/kernel/syscalls/getcwd/getcwd03.c > index 4f8f872cf..ec1cacea9 100644 > --- a/testcases/kernel/syscalls/getcwd/getcwd03.c > +++ b/testcases/kernel/syscalls/getcwd/getcwd03.c > @@ -74,6 +74,7 @@ static void verify_getcwd(void) > } > > SAFE_CHDIR(".."); > + memset(link, 0, sizeof(link)); > SAFE_READLINK(dir_link, link, sizeof(link)); > > if (strcmp(link, SAFE_BASENAME(res1))) { > > -- > Mailing list info: https://lists.linux.it/listinfo/ltp -- Cyril Hrubis chrubis@suse.cz ^ permalink raw reply [flat|nested] 4+ messages in thread
* [LTP] [PATCH] Fix getcwd03 testcase by zeroing target buffer for readlink() 2017-05-05 9:34 ` Cyril Hrubis @ 2017-05-06 7:00 ` Helge Deller 2017-05-09 9:08 ` Cyril Hrubis 0 siblings, 1 reply; 4+ messages in thread From: Helge Deller @ 2017-05-06 7:00 UTC (permalink / raw) To: ltp * Cyril Hrubis <chrubis@suse.cz>: > 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. > 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. Helge ---------------- [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 */ 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; } return rval; ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [LTP] [PATCH] Fix getcwd03 testcase by zeroing target buffer for readlink() 2017-05-06 7:00 ` Helge Deller @ 2017-05-09 9:08 ` Cyril Hrubis 0 siblings, 0 replies; 4+ messages in thread From: Cyril Hrubis @ 2017-05-09 9:08 UTC (permalink / raw) To: ltp 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 ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-05-09 9:08 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 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 is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox