Em sáb., 18 de jul. de 2020 às 14:21, Tom Lane <t...@sss.pgh.pa.us> escreveu:

> Ranier Vilela <ranier...@gmail.com> writes:
> > Can you take a look?
> > Per Coverity.
> > There is something wrong with the definition of QUEUE_PAGESIZE on async.c
>
> No, there's just something wrong with Coverity's analysis.
> I've grown a bit disillusioned with that tool; of late it's
> been giving many more false positives than useful reports.
>
For other projects, it has helped me, but for Postgres it has really been a
challenge.

>
> > 3..sizeof(AsyncQueueControl) is 8080, according to Coverity (Windows 64
> > bits)
>
> ITYM AsyncQueueEntry?
>
Yes, my bad. Its AsyncQueueEntry size on Windows 64 bits.

>
> > 4. (Line 1508)    qe.length = QUEUE_PAGESIZE - offset;
> > 5. offset is zero
> > 6. qe.length is 8192
> > /* Now copy qe into the shared buffer page */
> > memcpy(NotifyCtl->shared->page_buffer[slotno] + offset,
> >   &qe,
> >   qe.length);
> > CID 1428952 (#1 of 1): Out-of-bounds access (OVERRUN)  at line 1515, with
> > memcpy call.
> > 9. overrun-buffer-arg: Overrunning struct type AsyncQueueEntry of 8080
> > bytes by passing it to a function which accesses it at byte offset 8191
> > using argument qe.length (which evaluates to 8192).
>
> I suppose what Coverity is on about is the possibility that we might
> increase qe.length to more than sizeof(AsyncQueueEntry).  However,
> given the logic:
>
>         if (offset + qe.length <= QUEUE_PAGESIZE)
>             ...
>         else
>             qe.length = QUEUE_PAGESIZE - offset;
>
Here, the offset is zero. Maybe qe.length > QUEUE_PAGESIZE?
"7. Condition offset + qe.length <= 8192, taking false branch."


>
> that assignment must be *reducing* qe.length, so there can be no overrun
> unless asyncQueueNotificationToEntry() had prepared an oversize value to
> begin with.  Which is impossible given the assertions in that function,
> but maybe Coverity can't work that out?

Coverity analysed the DEBUG version, what includes assertions.


> (But then why isn't it
> complaining about asyncQueueNotificationToEntry itself?)
>
 I still couldn't say.

>
> I'd be willing to add a relevant assertion to
> asyncQueueNotificationToEntry, along the lines of
>
>         /* The terminators are already included in
> AsyncQueueEntryEmptySize */
>         entryLength = AsyncQueueEntryEmptySize + payloadlen + channellen;
>         entryLength = QUEUEALIGN(entryLength);
> +       Assert(entryLength <= sizeof(AsyncQueueEntry));
>         qe->length = entryLength;
>         qe->dboid = MyDatabaseId;
>         qe->xid = GetCurrentTransactionId();
>
> if it'd shut up Coverity on this point; but I have no easy way
> to find that out.
>
I'm not sure that assertion interferes with the analysis.


>
> > Question:
> > 1. NotifyCtl->shared->page_buffer[slotno] is really struct type
> > AsyncQueueEntry?
>
> No, it's a page.  But it contains AsyncQueueEntry(s).
>
I understand.

It could be, differences in the sizes of the types. Since on Linux, there
may be no alerts.
But as it was compiled on Windows, the AsyncQueueEntry structure, have a
smaller size than in Linux, being smaller than BLCKSZ?

regards,
Ranier Vilela

Reply via email to