@cryptotaxi247 / netdata-1 / commits / 9ff1b5bda

Fix UB of unaligned loads/stores and signed shifts. (#16628)

* Ignore build/ dir. This directory is the default dir for many LSPs and for IDES using cmake. "Reserve" it by ignoring it in .gitignore. * Fix format specifier. * Use unsigned literals when shifting. * Do not sanitize shifts in libjudy. * Fix unaligned loads/stores of dbengine's CRCs * Fix unaligned load when partitioning metrics. * Use unsigned literals when shifting.

vkalintiris committed Dec 19, 2023 at 11:19 UTC 9ff1b5bdaed1bc314ccd245ba080c326597a89be
11 files changed +27 -15
.gitignore
+3
@@ -256,3 +256,6 @@ database/engine/journalfile_v2_virtmemb.ksy
256 libnetdata/gorilla/gorilla_benchmark
257 libnetdata/gorilla/gorilla_fuzzer
258 libnetdata/gorilla/fuzz-*.log
259 +
260 +# ignore build/ directory (default dir for many IDEs/LSPs)
261 +build/
collectors/xenstat.plugin/xenstat_plugin.c
+1 -4
@@ -1032,10 +1032,7 @@ int main(int argc, char **argv) {
1032 if(unlikely(netdata_exit)) break;
1033
1034 if(unlikely(debug && iteration))
1035 - fprintf(stderr, "xenstat.plugin: iteration %zu, dt %llu usec\n"
1036 - , iteration
1037 - , dt
1038 - );
1035 + fprintf(stderr, "xenstat.plugin: iteration %zu, dt %lu usec\n", iteration, dt);
1036
1037 if(likely(xhandle)) {
1038 if(unlikely(debug)) fprintf(stderr, "xenstat.plugin: calling xenstat_collect()\n");
database/engine/metric.c
+5 -2
@@ -106,8 +106,11 @@ static inline void mrg_stats_size_judyhs_removed_uuid(MRG *mrg, size_t partition
106
107 static inline size_t uuid_partition(MRG *mrg __maybe_unused, uuid_t *uuid) {
108 uint8_t *u = (uint8_t *)uuid;
109 - size_t *n = (size_t *)&u[UUID_SZ - sizeof(size_t)];
110 - return *n % mrg->partitions;
109 +
110 + size_t n;
111 + memcpy(&n, &u[UUID_SZ - sizeof(size_t)], sizeof(size_t));
112 +
113 + return n % mrg->partitions;
114 }
115
116 static inline time_t mrg_metric_get_first_time_s_smart(MRG *mrg __maybe_unused, METRIC *metric) {
database/engine/rrdenginelib.h
+4 -2
@@ -67,12 +67,14 @@ static inline unsigned long ulong_compare_and_swap(volatile unsigned long *ptr,
67
68 static inline int crc32cmp(void *crcp, uLong crc)
69 {
70 - return (*(uint32_t *)crcp != crc);
70 + uint32_t loaded_crc;
71 + memcpy(&loaded_crc, crcp, sizeof(loaded_crc));
72 + return (loaded_crc != crc);
73 }
74
75 static inline void crc32set(void *crcp, uLong crc)
76 {
75 - *(uint32_t *)crcp = crc;
77 + memcpy(crcp, &crc, sizeof(crc));
78 }
79
80 int check_file_properties(uv_file file, uint64_t *file_size, size_t min_size);
libnetdata/libjudy/src/JudyL/JudyLCascade.c
+1
@@ -311,6 +311,7 @@ static int j__udyStageJBBtoJBB(
311 //
312 // NOTE: Caller must release the Leaf2 that was passed in.
313
314 +__attribute__((no_sanitize("shift")))
315 FUNCTION static Pjlb_t j__udyJLL2toJLB1(
316 uint16_t * Pjll, // array of 16-bit indexes.
317 #ifdef JUDYL
libnetdata/libjudy/src/JudyL/JudyLDecascade.c
+2
@@ -345,6 +345,7 @@ FUNCTION int j__udyBranchUToBranchB(
345 // allocation and free, in order to allow the caller to continue with a LeafB1
346 // if allocation fails.
347
348 +__attribute__((no_sanitize("shift")))
349 FUNCTION int j__udyLeafB1ToLeaf1(
350 Pjp_t Pjp, // points to LeafB1 to shrink.
351 Pvoid_t Pjpm) // for global accounting.
@@ -431,6 +432,7 @@ FUNCTION int j__udyLeafB1ToLeaf1(
432 // TBD: In this and all following functions, the caller should already be able
433 // to compute the Pop1 return value, so why return it?
434
435 +__attribute__((no_sanitize("shift")))
436 FUNCTION Word_t j__udyLeaf1ToLeaf2(
437 uint16_t * PLeaf2, // destination uint16_t * Index portion of leaf.
438 #ifdef JUDYL
libnetdata/libjudy/src/JudyL/JudyLDel.c
+1
@@ -147,6 +147,7 @@ extern Word_t j__udyLLeaf7ToLeafW(Pjlw_t, Pjv_t, Pjp_t, Word_t, Pvoid_t);
147
148 DBGCODE(uint8_t parentJPtype;) // parent branch JP type.
149
150 +__attribute__((no_sanitize("shift")))
151 FUNCTION static int j__udyDelWalk(
152 Pjp_t Pjp, // current JP under which to delete.
153 Word_t Index, // to delete.
libnetdata/libjudy/src/JudyL/JudyLGet.c
+2
@@ -44,6 +44,8 @@
44 // See the manual entry for details. Note support for "shortcut" entries to
45 // trees known to start with a JPM.
46
47 +__attribute__((no_sanitize("shift")))
48 +
49 #ifdef JUDY1
50
51 #ifdef JUDYGETINLINE
libnetdata/libjudy/src/JudyL/JudyLIns.c
+1
@@ -152,6 +152,7 @@ extern int j__udyLInsertBranch(Pjp_t Pjp, Word_t Index, Word_t Btype, Pjpm_t);
152 // Return -1 for error (details in JPM), 0 for Index already inserted, 1 for
153 // new Index inserted.
154
155 +__attribute__((no_sanitize("shift")))
156 FUNCTION static int j__udyInsWalk(
157 Pjp_t Pjp, // current JP to descend.
158 Word_t Index, // to insert.
libnetdata/storage_number/storage_number.h
+6 -6
@@ -116,10 +116,10 @@ storage_number pack_storage_number(NETDATA_DOUBLE value, SN_FLAGS flags) __attri
116 static inline NETDATA_DOUBLE unpack_storage_number(storage_number value) __attribute__((const));
117
118 // sign div/mul <--- multiplier / divider ---> 10/100 RESET EXISTS VALUE
119 -#define STORAGE_NUMBER_POSITIVE_MAX_RAW (storage_number)( (0 << 31) | (1 << 30) | (1 << 29) | (1 << 28) | (1 << 27) | (1 << 26) | (0 << 25) | (1 << 24) | 0x00ffffff )
120 -#define STORAGE_NUMBER_POSITIVE_MIN_RAW (storage_number)( (0 << 31) | (0 << 30) | (1 << 29) | (1 << 28) | (1 << 27) | (0 << 26) | (0 << 25) | (1 << 24) | 0x00000001 )
121 -#define STORAGE_NUMBER_NEGATIVE_MAX_RAW (storage_number)( (1 << 31) | (0 << 30) | (1 << 29) | (1 << 28) | (1 << 27) | (0 << 26) | (0 << 25) | (1 << 24) | 0x00000001 )
122 -#define STORAGE_NUMBER_NEGATIVE_MIN_RAW (storage_number)( (1 << 31) | (1 << 30) | (1 << 29) | (1 << 28) | (1 << 27) | (1 << 26) | (0 << 25) | (1 << 24) | 0x00ffffff )
119 +#define STORAGE_NUMBER_POSITIVE_MAX_RAW (storage_number)( (0U << 31) | (1U << 30) | (1U << 29) | (1U << 28) | (1U << 27) | (1U << 26) | (0U << 25) | (1U << 24) | 0x00ffffff )
120 +#define STORAGE_NUMBER_POSITIVE_MIN_RAW (storage_number)( (0U << 31) | (0U << 30) | (1U << 29) | (1U << 28) | (1U << 27) | (0U << 26) | (0U << 25) | (1U << 24) | 0x00000001 )
121 +#define STORAGE_NUMBER_NEGATIVE_MAX_RAW (storage_number)( (1U << 31) | (0U << 30) | (1U << 29) | (1U << 28) | (1U << 27) | (0U << 26) | (0U << 25) | (1U << 24) | 0x00000001 )
122 +#define STORAGE_NUMBER_NEGATIVE_MIN_RAW (storage_number)( (1U << 31) | (1U << 30) | (1U << 29) | (1U << 28) | (1U << 27) | (1U << 26) | (0U << 25) | (1U << 24) | 0x00ffffff )
123
124 // accepted accuracy loss
125 #define ACCURACY_LOSS_ACCEPTED_PERCENT 0.0001
@@ -155,10 +155,10 @@ static inline NETDATA_DOUBLE unpack_storage_number(storage_number value) {
155 // bit 25 SN_FLAG_NOT_ANOMALOUS
156
157 // bit 30, 29, 28 = (multiplier or divider) 0-7 (8 total)
158 - int mul = (int)((value & ((1<<29)|(1<<28)|(1<<27))) >> 27);
158 + int mul = (int)((value & ((1U<<29)|(1U<<28)|(1U<<27))) >> 27);
159
160 // bit 24 to bit 1 = the value, so remove all other bits
161 - value ^= value & ((1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<26)|(1<<25)|(1<<24));
161 + value ^= value & ((1U <<31)|(1U <<30)|(1U <<29)|(1U <<28)|(1U <<27)|(1U <<26)|(1U <<25)|(1U<<24));
162
163 NETDATA_DOUBLE n = value;
164
streaming/compression.h
+1 -1
@@ -13,7 +13,7 @@
13
14 typedef uint32_t rrdpush_signature_t;
15 #define RRDPUSH_COMPRESSION_SIGNATURE ((rrdpush_signature_t)('z' | 0x80) | (0x80 << 8) | (0x80 << 16) | ('\n' << 24))
16 -#define RRDPUSH_COMPRESSION_SIGNATURE_MASK ((rrdpush_signature_t)0xff | (0x80 << 8) | (0x80 << 16) | (0xff << 24))
16 +#define RRDPUSH_COMPRESSION_SIGNATURE_MASK ((rrdpush_signature_t) 0xffU | (0x80U << 8) | (0x80U << 16) | (0xffU << 24))
17 #define RRDPUSH_COMPRESSION_SIGNATURE_SIZE sizeof(rrdpush_signature_t)
18
19 static inline rrdpush_signature_t rrdpush_compress_encode_signature(size_t compressed_data_size) {