Fix text sanitizer buffer overflow (#21698)
Improve UTF-8 sanitizer: handle truncated sequences and ensure proper hex encoding of invalid bytes
Stelios Fragkakis committed
Feb 3, 2026 at 18:27 UTC
2ccc3bbfa95f88600f12f32b4f118267fd17352c
1 file changed
+15
-8
src/libnetdata/sanitizers/utf8-sanitizer.c
+15
-8
@@ -43,9 +43,10 @@ size_t text_sanitize(unsigned char *dst, const unsigned char *src, size_t dst_si
43
if(utf8_character_bytes == 1)
44
valid_sequence = false;
45
else {
46
- // make sure all the characters are valid
46
+ // make sure all the continuation bytes are valid
47
+ // also check for premature string termination (truncated UTF-8)
48
for(size_t i = 1; i < utf8_character_bytes; i++) {
48
- if(!IS_UTF8_BYTE(src[i]) || IS_UTF8_STARTBYTE(src[i])) {
49
+ if(src[i] == '\0' || !IS_UTF8_BYTE(src[i]) || IS_UTF8_STARTBYTE(src[i])) {
50
valid_sequence = false;
51
break;
52
}
@@ -59,14 +60,20 @@ size_t text_sanitize(unsigned char *dst, const unsigned char *src, size_t dst_si
60
*d++ = *src++;
61
}
62
else {
62
- *d++ = hex_digits_lower[(*src & 0xF0) >> 4];
63
- if(d <= end) *d++ = hex_digits_lower[(*src & 0x0F)];
64
-
63
+ // invalid or truncated UTF-8 sequence - hex encode it
64
+ // each byte becomes 2 hex chars, so check we have room for at least 2
65
+ if(d + 1 < end) {
66
+ *d++ = hex_digits_lower[(*src & 0xF0) >> 4];
67
+ *d++ = hex_digits_lower[(*src & 0x0F)];
68
+ }
69
src++;
70
67
- while(IS_UTF8_BYTE(*src) && !IS_UTF8_STARTBYTE(*src) && d <= end) {
68
- *d++ = hex_digits_lower[(*src & 0xF0) >> 4];
69
- if(d <= end) *d++ = hex_digits_lower[(*src & 0x0F)];
71
+ // hex encode any continuation bytes
72
+ while(IS_UTF8_BYTE(*src) && !IS_UTF8_STARTBYTE(*src)) {
73
+ if(d + 1 < end) {
74
+ *d++ = hex_digits_lower[(*src & 0xF0) >> 4];
75
+ *d++ = hex_digits_lower[(*src & 0x0F)];
76
+ }
77
src++;
78
}
79
}