* [PATCH 0/4] semihosting: fix various coverity issues
@ 2022-07-19 12:11 Peter Maydell
2022-07-19 12:11 ` [PATCH 1/4] semihosting: Don't return negative values on qemu_semihosting_console_write() failure Peter Maydell
` (4 more replies)
0 siblings, 5 replies; 10+ messages in thread
From: Peter Maydell @ 2022-07-19 12:11 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée
This patchset fixes a handful of bugs in the semihosting code
noticed by Coverity.
thanks
-- PMM
Peter Maydell (4):
semihosting: Don't return negative values on
qemu_semihosting_console_write() failure
semihosting: Don't copy buffer after console_write()
semihosting: Check for errors on SET_ARG()
semihosting: Fix handling of buffer in TARGET_SYS_TMPNAM
semihosting/arm-compat-semi.c | 29 ++++++++++++++++++++++++-----
semihosting/console.c | 3 ++-
semihosting/syscalls.c | 2 +-
3 files changed, 27 insertions(+), 7 deletions(-)
--
2.25.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/4] semihosting: Don't return negative values on qemu_semihosting_console_write() failure
2022-07-19 12:11 [PATCH 0/4] semihosting: fix various coverity issues Peter Maydell
@ 2022-07-19 12:11 ` Peter Maydell
2022-07-24 16:28 ` Richard Henderson
2022-07-19 12:11 ` [PATCH 2/4] semihosting: Don't copy buffer after console_write() Peter Maydell
` (3 subsequent siblings)
4 siblings, 1 reply; 10+ messages in thread
From: Peter Maydell @ 2022-07-19 12:11 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée
The documentation comment for qemu_semihosting_console_write() says
* Returns: number of bytes written -- this should only ever be short
* on some sort of i/o error.
and the callsites rely on this. However, the implementation code
path which sends console output to a chardev doesn't honour this,
and will return negative values on error. Bring it into line with
the other implementation codepaths and the documentation, so that
it returns 0 on error.
Spotted by Coverity, because console_write() passes the return value
to unlock_user(), which doesn't accept a negative length.
Resolves: Coverity CID 1490288
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
console_write() doesn't need to pass the length to unlock_user()
at all, as it happens -- see the next patch.
---
semihosting/console.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/semihosting/console.c b/semihosting/console.c
index 5b1ec0a1c39..0f976fe8cb1 100644
--- a/semihosting/console.c
+++ b/semihosting/console.c
@@ -111,7 +111,8 @@ int qemu_semihosting_console_read(CPUState *cs, void *buf, int len)
int qemu_semihosting_console_write(void *buf, int len)
{
if (console.chr) {
- return qemu_chr_write_all(console.chr, (uint8_t *)buf, len);
+ int r = qemu_chr_write_all(console.chr, (uint8_t *)buf, len);
+ return r < 0 ? 0 : r;
} else {
return fwrite(buf, 1, len, stderr);
}
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/4] semihosting: Don't copy buffer after console_write()
2022-07-19 12:11 [PATCH 0/4] semihosting: fix various coverity issues Peter Maydell
2022-07-19 12:11 ` [PATCH 1/4] semihosting: Don't return negative values on qemu_semihosting_console_write() failure Peter Maydell
@ 2022-07-19 12:11 ` Peter Maydell
2022-07-24 16:30 ` Richard Henderson
2022-07-19 12:11 ` [PATCH 3/4] semihosting: Check for errors on SET_ARG() Peter Maydell
` (2 subsequent siblings)
4 siblings, 1 reply; 10+ messages in thread
From: Peter Maydell @ 2022-07-19 12:11 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée
The console_write() semihosting function outputs guest data from a
buffer; it doesn't update that buffer. It therefore doesn't need to
pass a length value to unlock_user(), but can pass 0, meaning "do not
copy any data back to the guest memory".
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
semihosting/syscalls.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/semihosting/syscalls.c b/semihosting/syscalls.c
index 4847f66c023..508a0ad88c6 100644
--- a/semihosting/syscalls.c
+++ b/semihosting/syscalls.c
@@ -627,7 +627,7 @@ static void console_write(CPUState *cs, gdb_syscall_complete_cb complete,
}
ret = qemu_semihosting_console_write(ptr, len);
complete(cs, ret ? ret : -1, ret ? 0 : EIO);
- unlock_user(ptr, buf, ret);
+ unlock_user(ptr, buf, 0);
}
static void console_fstat(CPUState *cs, gdb_syscall_complete_cb complete,
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/4] semihosting: Check for errors on SET_ARG()
2022-07-19 12:11 [PATCH 0/4] semihosting: fix various coverity issues Peter Maydell
2022-07-19 12:11 ` [PATCH 1/4] semihosting: Don't return negative values on qemu_semihosting_console_write() failure Peter Maydell
2022-07-19 12:11 ` [PATCH 2/4] semihosting: Don't copy buffer after console_write() Peter Maydell
@ 2022-07-19 12:11 ` Peter Maydell
2022-07-24 16:35 ` Richard Henderson
2022-07-19 12:11 ` [PATCH 4/4] semihosting: Fix handling of buffer in TARGET_SYS_TMPNAM Peter Maydell
2022-07-25 12:28 ` [PATCH 0/4] semihosting: fix various coverity issues Alex Bennée
4 siblings, 1 reply; 10+ messages in thread
From: Peter Maydell @ 2022-07-19 12:11 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée
The SET_ARG() macro returns an error indication; we check this in the
TARGET_SYS_GET_CMDLINE case but not when we use it in implementing
TARGET_SYS_ELAPSED. Check for and handle the errors via the do_fault
codepath, and update the comment documenting the SET_ARG() and
GET_ARG() macros to note how they handle memory access errors.
Resolves: Coverity CID 1490287
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
semihosting/arm-compat-semi.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 1a1e2a69605..d12288fc806 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -171,6 +171,12 @@ static LayoutInfo common_semi_find_bases(CPUState *cs)
* Read the input value from the argument block; fail the semihosting
* call if the memory read fails. Eventually we could use a generic
* CPUState helper function here.
+ * Note that GET_ARG() handles memory access errors by jumping to
+ * do_fault, so must be used as the first thing done in handling a
+ * semihosting call, to avoid accidentally leaking allocated resources.
+ * SET_ARG(), since it unavoidably happens late, instead returns an
+ * error indication (0 on success, non-0 for error) which the caller
+ * should check.
*/
#define GET_ARG(n) do { \
@@ -739,10 +745,14 @@ void do_common_semihosting(CPUState *cs)
case TARGET_SYS_ELAPSED:
elapsed = get_clock() - clock_start;
if (sizeof(target_ulong) == 8) {
- SET_ARG(0, elapsed);
+ if (SET_ARG(0, elapsed)) {
+ goto do_fault;
+ }
} else {
- SET_ARG(0, (uint32_t) elapsed);
- SET_ARG(1, (uint32_t) (elapsed >> 32));
+ if (SET_ARG(0, (uint32_t) elapsed) ||
+ SET_ARG(1, (uint32_t) (elapsed >> 32))) {
+ goto do_fault;
+ }
}
common_semi_set_ret(cs, 0);
break;
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/4] semihosting: Fix handling of buffer in TARGET_SYS_TMPNAM
2022-07-19 12:11 [PATCH 0/4] semihosting: fix various coverity issues Peter Maydell
` (2 preceding siblings ...)
2022-07-19 12:11 ` [PATCH 3/4] semihosting: Check for errors on SET_ARG() Peter Maydell
@ 2022-07-19 12:11 ` Peter Maydell
2022-07-24 21:55 ` Richard Henderson
2022-07-25 12:28 ` [PATCH 0/4] semihosting: fix various coverity issues Alex Bennée
4 siblings, 1 reply; 10+ messages in thread
From: Peter Maydell @ 2022-07-19 12:11 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée
The TARGET_SYS_TMPNAM implementation has two bugs spotted by
Coverity:
* confusion about whether 'len' has the length of the string
including or excluding the terminating NUL means we
lock_user() len bytes of memory but memcpy() len + 1 bytes
* In the error-exit cases we forget to free() the buffer
that asprintf() returned to us
Resolves: Coverity CID 1490285, 1490289
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
semihosting/arm-compat-semi.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index d12288fc806..e741674238f 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -504,16 +504,25 @@ void do_common_semihosting(CPUState *cs)
GET_ARG(1);
GET_ARG(2);
len = asprintf(&s, "/tmp/qemu-%x%02x", getpid(), (int)arg1 & 0xff);
+ if (len < 0) {
+ common_semi_set_ret(cs, -1);
+ break;
+ }
+
+ /* Allow for trailing NUL */
+ len++;
/* Make sure there's enough space in the buffer */
- if (len < 0 || len >= arg2) {
+ if (len > arg2) {
+ free(s);
common_semi_set_ret(cs, -1);
break;
}
p = lock_user(VERIFY_WRITE, arg0, len, 0);
if (!p) {
+ free(s);
goto do_fault;
}
- memcpy(p, s, len + 1);
+ memcpy(p, s, len);
unlock_user(p, arg0, len);
free(s);
common_semi_set_ret(cs, 0);
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/4] semihosting: Don't return negative values on qemu_semihosting_console_write() failure
2022-07-19 12:11 ` [PATCH 1/4] semihosting: Don't return negative values on qemu_semihosting_console_write() failure Peter Maydell
@ 2022-07-24 16:28 ` Richard Henderson
0 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2022-07-24 16:28 UTC (permalink / raw)
To: Peter Maydell, qemu-devel; +Cc: Alex Bennée
On 7/19/22 17:41, Peter Maydell wrote:
> The documentation comment for qemu_semihosting_console_write() says
> * Returns: number of bytes written -- this should only ever be short
> * on some sort of i/o error.
>
> and the callsites rely on this. However, the implementation code
> path which sends console output to a chardev doesn't honour this,
> and will return negative values on error. Bring it into line with
> the other implementation codepaths and the documentation, so that
> it returns 0 on error.
>
> Spotted by Coverity, because console_write() passes the return value
> to unlock_user(), which doesn't accept a negative length.
>
> Resolves: Coverity CID 1490288
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> console_write() doesn't need to pass the length to unlock_user()
> at all, as it happens -- see the next patch.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/4] semihosting: Don't copy buffer after console_write()
2022-07-19 12:11 ` [PATCH 2/4] semihosting: Don't copy buffer after console_write() Peter Maydell
@ 2022-07-24 16:30 ` Richard Henderson
0 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2022-07-24 16:30 UTC (permalink / raw)
To: Peter Maydell, qemu-devel; +Cc: Alex Bennée
On 7/19/22 17:41, Peter Maydell wrote:
> The console_write() semihosting function outputs guest data from a
> buffer; it doesn't update that buffer. It therefore doesn't need to
> pass a length value to unlock_user(), but can pass 0, meaning "do not
> copy any data back to the guest memory".
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> semihosting/syscalls.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/4] semihosting: Check for errors on SET_ARG()
2022-07-19 12:11 ` [PATCH 3/4] semihosting: Check for errors on SET_ARG() Peter Maydell
@ 2022-07-24 16:35 ` Richard Henderson
0 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2022-07-24 16:35 UTC (permalink / raw)
To: Peter Maydell, qemu-devel; +Cc: Alex Bennée
On 7/19/22 17:41, Peter Maydell wrote:
> The SET_ARG() macro returns an error indication; we check this in the
> TARGET_SYS_GET_CMDLINE case but not when we use it in implementing
> TARGET_SYS_ELAPSED. Check for and handle the errors via the do_fault
> codepath, and update the comment documenting the SET_ARG() and
> GET_ARG() macros to note how they handle memory access errors.
>
> Resolves: Coverity CID 1490287
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 4/4] semihosting: Fix handling of buffer in TARGET_SYS_TMPNAM
2022-07-19 12:11 ` [PATCH 4/4] semihosting: Fix handling of buffer in TARGET_SYS_TMPNAM Peter Maydell
@ 2022-07-24 21:55 ` Richard Henderson
0 siblings, 0 replies; 10+ messages in thread
From: Richard Henderson @ 2022-07-24 21:55 UTC (permalink / raw)
To: Peter Maydell, qemu-devel; +Cc: Alex Bennée
On 7/19/22 17:41, Peter Maydell wrote:
> The TARGET_SYS_TMPNAM implementation has two bugs spotted by
> Coverity:
> * confusion about whether 'len' has the length of the string
> including or excluding the terminating NUL means we
> lock_user() len bytes of memory but memcpy() len + 1 bytes
> * In the error-exit cases we forget to free() the buffer
> that asprintf() returned to us
>
> Resolves: Coverity CID 1490285, 1490289
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
> semihosting/arm-compat-semi.c | 13 +++++++++++--
> 1 file changed, 11 insertions(+), 2 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/4] semihosting: fix various coverity issues
2022-07-19 12:11 [PATCH 0/4] semihosting: fix various coverity issues Peter Maydell
` (3 preceding siblings ...)
2022-07-19 12:11 ` [PATCH 4/4] semihosting: Fix handling of buffer in TARGET_SYS_TMPNAM Peter Maydell
@ 2022-07-25 12:28 ` Alex Bennée
4 siblings, 0 replies; 10+ messages in thread
From: Alex Bennée @ 2022-07-25 12:28 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel
Peter Maydell <peter.maydell@linaro.org> writes:
> This patchset fixes a handful of bugs in the semihosting code
> noticed by Coverity.
Queued to testing/next, thanks.
--
Alex Bennée
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2022-07-25 12:43 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-07-19 12:11 [PATCH 0/4] semihosting: fix various coverity issues Peter Maydell
2022-07-19 12:11 ` [PATCH 1/4] semihosting: Don't return negative values on qemu_semihosting_console_write() failure Peter Maydell
2022-07-24 16:28 ` Richard Henderson
2022-07-19 12:11 ` [PATCH 2/4] semihosting: Don't copy buffer after console_write() Peter Maydell
2022-07-24 16:30 ` Richard Henderson
2022-07-19 12:11 ` [PATCH 3/4] semihosting: Check for errors on SET_ARG() Peter Maydell
2022-07-24 16:35 ` Richard Henderson
2022-07-19 12:11 ` [PATCH 4/4] semihosting: Fix handling of buffer in TARGET_SYS_TMPNAM Peter Maydell
2022-07-24 21:55 ` Richard Henderson
2022-07-25 12:28 ` [PATCH 0/4] semihosting: fix various coverity issues Alex Bennée
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).