Skip to content

Commit 46ab07f

Browse files
committed
Clean up assorted failures under clang's -fsanitize=undefined checks.
Most of these are cases where we could call memcpy() or other libc functions with a NULL pointer and a zero count, which is forbidden by POSIX even though every production version of libc allows it. We've fixed such things before in a piecemeal way, but apparently never made an effort to try to get them all. I don't claim that this patch does so either, but it gets every failure I observe in check-world, using clang 12.0.1 on current RHEL8. numeric.c has a different issue that the sanitizer doesn't like: "ln(-1.0)" will compute log10(0) and then try to assign the resulting -Inf to an integer variable. We don't actually use the result in such a case, so there's no live bug. Back-patch to all supported branches, with the idea that we might start running a buildfarm member that tests this case. This includes back-patching c1132aa (Check the size in COPY_POINTER_FIELD), which previously silenced some of these issues in copyfuncs.c. Discussion: https://postgr.es/m/CALNJ-vT9r0DSsAOw9OXVJFxLENoVS_68kJ5x0p44atoYH+H4dg@mail.gmail.com
1 parent 62ce0c7 commit 46ab07f

File tree

9 files changed

+31
-15
lines changed

9 files changed

+31
-15
lines changed

contrib/pgcrypto/px.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ combo_init(PX_Combo *cx, const uint8 *key, unsigned klen,
198198
ivbuf = palloc0(ivs);
199199
if (ivlen > ivs)
200200
memcpy(ivbuf, iv, ivs);
201-
else
201+
else if (ivlen > 0)
202202
memcpy(ivbuf, iv, ivlen);
203203
}
204204

src/backend/access/heap/heapam.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ initscan(HeapScanDesc scan, ScanKey key, bool keep_startblock)
328328
/*
329329
* copy the scan key, if appropriate
330330
*/
331-
if (key != NULL)
331+
if (key != NULL && scan->rs_base.rs_nkeys > 0)
332332
memcpy(scan->rs_base.rs_key, key, scan->rs_base.rs_nkeys * sizeof(ScanKeyData));
333333

334334
/*

src/backend/access/heap/heapam_visibility.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,8 +1564,8 @@ HeapTupleHeaderIsOnlyLocked(HeapTupleHeader tuple)
15641564
static bool
15651565
TransactionIdInArray(TransactionId xid, TransactionId *xip, Size num)
15661566
{
1567-
return bsearch(&xid, xip, num,
1568-
sizeof(TransactionId), xidComparator) != NULL;
1567+
return num > 0 &&
1568+
bsearch(&xid, xip, num, sizeof(TransactionId), xidComparator) != NULL;
15691569
}
15701570

15711571
/*

src/backend/access/transam/clog.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,9 @@ TransactionIdSetPageStatus(TransactionId xid, int nsubxids,
297297
if (all_xact_same_page && xid == MyProc->xid &&
298298
nsubxids <= THRESHOLD_SUBTRANS_CLOG_OPT &&
299299
nsubxids == MyProc->subxidStatus.count &&
300-
memcmp(subxids, MyProc->subxids.xids,
301-
nsubxids * sizeof(TransactionId)) == 0)
300+
(nsubxids == 0 ||
301+
memcmp(subxids, MyProc->subxids.xids,
302+
nsubxids * sizeof(TransactionId)) == 0))
302303
{
303304
/*
304305
* If we can immediately acquire XactSLRULock, we update the status of

src/backend/access/transam/xact.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5353,8 +5353,9 @@ SerializeTransactionState(Size maxsize, char *start_address)
53535353
{
53545354
if (FullTransactionIdIsValid(s->fullTransactionId))
53555355
workspace[i++] = XidFromFullTransactionId(s->fullTransactionId);
5356-
memcpy(&workspace[i], s->childXids,
5357-
s->nChildXids * sizeof(TransactionId));
5356+
if (s->nChildXids > 0)
5357+
memcpy(&workspace[i], s->childXids,
5358+
s->nChildXids * sizeof(TransactionId));
53585359
i += s->nChildXids;
53595360
}
53605361
Assert(i == nxids);

src/backend/storage/ipc/shm_mq.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -773,8 +773,11 @@ shm_mq_receive(shm_mq_handle *mqh, Size *nbytesp, void **datap, bool nowait)
773773

774774
/* Copy as much as we can. */
775775
Assert(mqh->mqh_partial_bytes + rb <= nbytes);
776-
memcpy(&mqh->mqh_buffer[mqh->mqh_partial_bytes], rawdata, rb);
777-
mqh->mqh_partial_bytes += rb;
776+
if (rb > 0)
777+
{
778+
memcpy(&mqh->mqh_buffer[mqh->mqh_partial_bytes], rawdata, rb);
779+
mqh->mqh_partial_bytes += rb;
780+
}
778781

779782
/*
780783
* Update count of bytes that can be consumed, accounting for

src/backend/utils/adt/numeric.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10048,12 +10048,20 @@ exp_var(const NumericVar *arg, NumericVar *result, int rscale)
1004810048
*
1004910049
* Essentially, we're approximating log10(abs(ln(var))). This is used to
1005010050
* determine the appropriate rscale when computing natural logarithms.
10051+
*
10052+
* Note: many callers call this before range-checking the input. Therefore,
10053+
* we must be robust against values that are invalid to apply ln() to.
10054+
* We don't wish to throw an error here, so just return zero in such cases.
1005110055
*/
1005210056
static int
1005310057
estimate_ln_dweight(const NumericVar *var)
1005410058
{
1005510059
int ln_dweight;
1005610060

10061+
/* Caller should fail on ln(negative), but for the moment return zero */
10062+
if (var->sign != NUMERIC_POS)
10063+
return 0;
10064+
1005710065
if (cmp_var(var, &const_zero_point_nine) >= 0 &&
1005810066
cmp_var(var, &const_one_point_one) <= 0)
1005910067
{

src/backend/utils/time/snapmgr.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -536,12 +536,14 @@ SetTransactionSnapshot(Snapshot sourcesnap, VirtualTransactionId *sourcevxid,
536536
CurrentSnapshot->xmax = sourcesnap->xmax;
537537
CurrentSnapshot->xcnt = sourcesnap->xcnt;
538538
Assert(sourcesnap->xcnt <= GetMaxSnapshotXidCount());
539-
memcpy(CurrentSnapshot->xip, sourcesnap->xip,
540-
sourcesnap->xcnt * sizeof(TransactionId));
539+
if (sourcesnap->xcnt > 0)
540+
memcpy(CurrentSnapshot->xip, sourcesnap->xip,
541+
sourcesnap->xcnt * sizeof(TransactionId));
541542
CurrentSnapshot->subxcnt = sourcesnap->subxcnt;
542543
Assert(sourcesnap->subxcnt <= GetMaxSnapshotSubxidCount());
543-
memcpy(CurrentSnapshot->subxip, sourcesnap->subxip,
544-
sourcesnap->subxcnt * sizeof(TransactionId));
544+
if (sourcesnap->subxcnt > 0)
545+
memcpy(CurrentSnapshot->subxip, sourcesnap->subxip,
546+
sourcesnap->subxcnt * sizeof(TransactionId));
545547
CurrentSnapshot->suboverflowed = sourcesnap->suboverflowed;
546548
CurrentSnapshot->takenDuringRecovery = sourcesnap->takenDuringRecovery;
547549
/* NB: curcid should NOT be copied, it's a local matter */

src/fe_utils/print.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -966,7 +966,8 @@ print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager)
966966

967967
more_col_wrapping = col_count;
968968
curr_nl_line = 0;
969-
memset(header_done, false, col_count * sizeof(bool));
969+
if (col_count > 0)
970+
memset(header_done, false, col_count * sizeof(bool));
970971
while (more_col_wrapping)
971972
{
972973
if (opt_border == 2)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy