On 06.10.23 01:53, Paolo Bonzini wrote:
On Thu, Oct 5, 2023 at 4:04 PM Vladimir Sementsov-Ogievskiy
<vsement...@yandex-team.ru> wrote:
+            /*
+             * Assure Coverity (and ourselves) that we are not going to OVERRUN
+             * the buffer by following ldn_he_p().
+             */
+            assert((l == 1 && len >= 1) ||
+                   (l == 2 && len >= 2) ||
+                   (l == 4 && len >= 4) ||
+                   (l == 8 && len >= 8));

I'll queue it shortly, but perhaps you can try if assert(l <= len) is enough?

Alternatively I can try applying the patch on top of the tree that we
test with, and see how things go.


I've now made 4 runs:

master:
patched = master + this patch
l_len = master + this patch, but reduce assertion to assert(l <= len)
no_assert = master + this patch, but drop assertion at all. (actully, just drop 
the modelling)

results:
+---------------+--------+-------+-----------+---------+
|               | master | l_len | no_assert | patched |
+---------------+--------+-------+-----------+---------+
| total         | 673    | 757   | 757       | 665     |
+---------------+--------+-------+-----------+---------+
| OVERRUN       | 28     | 116   | 116       | 27      |
+---------------+--------+-------+-----------+---------+
| RESOURCE_LEAK | 85     | 85    | 85        | 82      |
+---------------+--------+-------+-----------+---------+
| UNINIT        | 52     | 48    | 48        | 48      |
+---------------+--------+-------+-----------+---------+


Command to generate results:

DIR=../cov-master; rm -rf $DIR; git clean -fxd && ./configure --target-list=x86_64-softmmu 
--enable-debug --disable-docs --disable-xen --extra-cflags='-fno-lto' --cc=gcc --host-cc=gcc --cxx=g++ 
&& cov-build --dir $DIR make -j20 && cov-make-library --output-file $DIR/qemu-model 
scripts/coverity-scan/model.c && cov-analyze --dir $DIR --model-file $DIR/qemu-model

(then, change code, change DIR and rerun, and so on)


So, assert(l <= len) doesn't help :(.

Looking at first OVERRUN problem, that we have only in l_len and no_assert, in 
win_dump.c:

202     static void check_kdbg(WinDumpHeader *h, bool x64, Error **errp)
203     {
204         const char OwnerTag[] = "KDBG";
205         char read_OwnerTag[4];
206         uint64_t KdDebuggerDataBlock = WIN_DUMP_FIELD(KdDebuggerDataBlock);
207         bool try_fallback = true;
208     
209     try_again:

(1) Event cond_false:   Condition "0 /* !(sizeof (cpus.tqh_first) <= 8) */", 
taking false branch.
(2) Event loop_end:     Reached end of loop.
(3) Event overrun-buffer-val:   Overrunning array "read_OwnerTag" of 4 bytes by 
passing it to a function which accesses it at byte offset 7.

210         if (cpu_memory_rw_debug(first_cpu,
211                 KdDebuggerDataBlock + KDBG_OWNER_TAG_OFFSET,
212                 (uint8_t *)&read_OwnerTag, sizeof(read_OwnerTag), 0)) {
213             error_setg(errp, "win-dump: failed to read OwnerTag");
214             return;
215         }

So, the problem is that on the code path Coverity knows exact bound (like 4), 
but unsure about len variable.


              val = ldn_he_p(buf, l);
              result |= memory_region_dispatch_write(mr, addr1, val,
                                                     size_memop(l), attrs);
@@ -2784,6 +2793,15 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr 
addr,
              l = memory_access_size(mr, l, addr1);
              result |= memory_region_dispatch_read(mr, addr1, &val,
                                                    size_memop(l), attrs);
+
+            /*
+             * Assure Coverity (and ourselves) that we are not going to OVERRUN
+             * the buffer by following stn_he_p().
+             */
+            assert((l == 1 && len >= 1) ||
+                   (l == 2 && len >= 2) ||
+                   (l == 4 && len >= 4) ||
+                   (l == 8 && len >= 8));
              stn_he_p(buf, l, val);
          } else {
              /* RAM case */
--
2.34.1



--
Best regards,
Vladimir


Reply via email to