From ffd85476ae649faf55b3bf37195989870d709b66 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 4 Jan 2020 17:46:07 +0000 Subject: [PATCH] scst: Suppress a false positive Coverity memory corruption complaint This patch suppresses the following Coverity complaint: CID 119689 (#1 of 1): Out-of-bounds access (OVERRUN) overrun-buffer-arg: Overrunning struct type scst_event of 64 bytes by passing it to a function which accesses it at byte offset 3135 using argument 64UL + payload_len (which evaluates to 3136). [Note: The source code implementation of the function has been overridden by a builtin model.] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8760 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_event.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/scst/src/scst_event.c b/scst/src/scst_event.c index 7e7a7b52b..99fd3fd60 100644 --- a/scst/src/scst_event.c +++ b/scst/src/scst_event.c @@ -567,10 +567,10 @@ out: /* * scst_event_mutex supposed to be held. Caller supposed to free returned - * out_event_entry using kfree(). This function returnes event_entry, not + * out_event_entry using kfree(). This function returns event_entry, not * plain event, because this entry can then be queued in some list. */ -static int scst_event_get_event_from_user(void __user *arg, +static int scst_event_get_event_from_user(struct scst_event_user __user *arg, struct scst_event_entry **out_event_entry) { int res, rc, event_entry_len; @@ -579,7 +579,7 @@ static int scst_event_get_event_from_user(void __user *arg, TRACE_ENTRY(); - res = get_user(payload_len, (uint32_t __user *)arg); + res = get_user(payload_len, &arg->max_event_size); if (res != 0) { PRINT_ERROR("Failed to get payload len: %d", res); goto out; @@ -606,14 +606,22 @@ static int scst_event_get_event_from_user(void __user *arg, TRACE_MEM("Allocated event entry %p", event_entry); - rc = copy_from_user(&event_entry->event, arg, - sizeof(event_entry->event) + payload_len); + rc = copy_from_user((u8 *)event_entry + + offsetof(typeof(*event_entry), event), arg, + event_entry_len); if (rc != 0) { PRINT_ERROR("Failed to copy %d user's bytes", rc); res = -EFAULT; goto out_free; } + /* payload_len has been recopied, so recheck it. */ + if (event_entry->event.payload_len != event_entry_len) { + PRINT_ERROR("Payload len changed while being read"); + res = -EINVAL; + goto out_free; + } + event_entry->event.issuer_name[sizeof(event_entry->event.issuer_name)-1] = '\0'; TRACE_DBG("user event: event_code %d, issuer_name %s",