Skip to content

[fix](be) Avoid UB from unaligned __int128 dereference#63703

Open
jacktengg wants to merge 1 commit into
apache:masterfrom
jacktengg:wt-fix-qa-int128
Open

[fix](be) Avoid UB from unaligned __int128 dereference#63703
jacktengg wants to merge 1 commit into
apache:masterfrom
jacktengg:wt-fix-qa-int128

Conversation

@jacktengg
Copy link
Copy Markdown
Contributor

Issue Number: close #xxx

Problem Summary: Several BE call sites obtained a byte pointer from StringRef::data / Slice::data / a generic const void* (e.g. ORC pushdown literal value, JSONB serde, runtime filter literal builder, meta_tool column dump) and dereferenced it as __int128* / int128_t* / DecimalV2Value* / Decimal<int128_t>*.

Because those buffers carry no 16-byte alignment guarantee, the load is undefined behavior. On alignment-strict targets (some aarch64 / SPARC builds) and under UBSan -fsanitize=alignment the read can SIGBUS, abort, or - with SSE codegen for __int128 - fault on a movdqa instruction.

Sites fixed:

  • be/src/core/data_type_serde/data_type_number_serde.cpp (LARGEINT JSONB)
  • be/src/format/orc/vorc_reader.cpp (TYPE_DECIMALV2 / TYPE_DECIMAL128I literal conversion for ORC predicate push-down)
  • be/src/tools/meta_tool.cpp (LARGEINT and DECIMAL128I dump)
  • be/src/exprs/vexpr.h create_texpr_literal_node<>: TYPE_LARGEINT, TYPE_DECIMALV2 and TYPE_DECIMAL128I literal construction

All these sites now load the 16-byte value through the unaligned_load<T> helper from util/unaligned.h into a local __int128 / DecimalV2Value / Decimal<int128_t> before use. Modern compilers reduce the helper's memcpy to a load, so there is no measurable performance impact, but the semantics become well-defined regardless of the producer's alignment.

Note: be/src/runtime/fold_constant_executor.cpp also contains unaligned __int128 reads for TYPE_LARGEINT and TYPE_DECIMALV2 in _get_result, but that branch is unreachable under the current Nereids planner (which always sets is_nereids = true and uses be_exec_version >= 4, taking the protobuf serde path). It is left untouched here to keep the diff focused; the dead branch can be cleaned up separately.

What problem does this PR solve?

Issue Number: close #xxx

Related PR: #xxx

Problem Summary:

Release note

None

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (add detailed scripts or steps below)
    • No need to test or manual test. Explain why:
      • This is a refactor/code format and no logic has been changed.
      • Previous test can cover this change.
      • No code files have been changed.
      • Other reason
  • Behavior changed:

    • No.
    • Yes.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

Issue Number: close #xxx

Problem Summary: Several BE call sites obtained a byte pointer from
StringRef::data / Slice::data / a generic const void* (e.g. ORC
pushdown literal value, JSONB serde, runtime filter literal builder,
meta_tool column dump) and dereferenced it as `__int128*` / `int128_t*`
/ `DecimalV2Value*` / `Decimal<int128_t>*`.

Because those buffers carry no 16-byte alignment guarantee, the load is
undefined behavior. On alignment-strict targets (some aarch64 / SPARC
builds) and under UBSan -fsanitize=alignment the read can SIGBUS, abort,
or - with SSE codegen for __int128 - fault on a movdqa instruction.

Sites fixed:
- be/src/core/data_type_serde/data_type_number_serde.cpp (LARGEINT JSONB)
- be/src/format/orc/vorc_reader.cpp (TYPE_DECIMALV2 / TYPE_DECIMAL128I
  literal conversion for ORC predicate push-down)
- be/src/tools/meta_tool.cpp (LARGEINT and DECIMAL128I dump)
- be/src/exprs/vexpr.h create_texpr_literal_node<>: TYPE_LARGEINT,
  TYPE_DECIMALV2 and TYPE_DECIMAL128I literal construction

All these sites now load the 16-byte value through the
`unaligned_load<T>` helper from `util/unaligned.h` into a local
__int128 / DecimalV2Value / Decimal<int128_t> before use. Modern
compilers reduce the helper's memcpy to a load, so there is no
measurable performance impact, but the semantics become well-defined
regardless of the producer's alignment.

Note: be/src/runtime/fold_constant_executor.cpp also contains unaligned
__int128 reads for TYPE_LARGEINT and TYPE_DECIMALV2 in `_get_result`,
but that branch is unreachable under the current Nereids planner (which
always sets `is_nereids = true` and uses `be_exec_version >= 4`, taking
the protobuf serde path). It is left untouched here to keep the diff
focused; the dead branch can be cleaned up separately.
@hello-stephen
Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@jacktengg
Copy link
Copy Markdown
Contributor Author

/review

@jacktengg
Copy link
Copy Markdown
Contributor Author

run buildall

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review opinion: no blocking issues found.

Critical checkpoint conclusions:

  • Goal: The PR fixes undefined behavior from reading 16-byte integer/decimal payloads through potentially unaligned byte pointers in JSONB serialization, vexpr literal construction, ORC predicate literal conversion, and meta_tool display. The changed code uses the existing unaligned_load<T> helper, which is appropriate for these trivially-copyable value types.
  • Scope/focus: The code change is small and focused on the affected dereferences; no unrelated behavior changes were found in the GitHub PR diff.
  • Concurrency: The touched code does not introduce shared mutable state, locks, or new thread/bthread lifecycle concerns.
  • Lifecycle/static initialization: No new global/static lifecycle dependency was introduced.
  • Configuration: No configuration items were added.
  • Compatibility: No storage format, RPC, thrift/protobuf schema, or function-symbol compatibility change was introduced; values are loaded differently but serialized/formatted as before.
  • Parallel paths: The PR updates the directly targeted 16-byte load sites. I also checked for remaining similar __int128/DecimalV2Value reinterpret dereferences; the known FoldConstantExecutor::_get_result legacy path remains, but based on the current Nereids caller it is gated away by be_exec_version >= 4 && is_nereids and is called out in the PR description.
  • Conditional checks: No new special runtime condition was added.
  • Tests: A BE unit test deliberately passes misaligned buffers through create_texpr_literal_node for LARGEINT, DECIMALV2, and DECIMAL128I, and it is picked up by the BE test recursive glob. The regression test follows Doris regression standards (order_qt, drop-before-use, hardcoded table name, generated .out). One non-blocking caveat: the SQL regression mostly exercises normal column/runtime paths and does not itself guarantee unaligned storage for every fixed call site, so the BE unit test is the strongest direct proof of the unaligned-buffer contract.
  • Test results: The added .out is deterministic and consistent with the queries.
  • Observability: No new observability is needed for this low-level UB fix.
  • Transactions/persistence/data writes: No transaction, persistence, version visibility, delete bitmap, or data-write semantics are changed.
  • FE/BE variables: No new FE-BE variable passing is involved.
  • Performance: The replacement is a small memcpy-based unaligned load that compilers generally lower efficiently; no meaningful hot-path regression was found.
  • User focus: No additional user-provided review focus was present.

Residual risk: I did not run the full BE unit/regression suite in this review environment; this conclusion is based on static review of the PR diff and surrounding code.

@hello-stephen
Copy link
Copy Markdown
Contributor

TPC-H: Total hot run time: 31960 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit d978d0ba8fd5b605e2bad30494c5213c1e38125f, data reload: false

------ Round 1 ----------------------------------
orders	Doris	NULL	NULL	0	0	0	NULL	0	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	17668	4055	4012	4012
q2	q3	10809	1395	804	804
q4	4688	480	347	347
q5	7586	2312	2150	2150
q6	244	175	135	135
q7	956	773	648	648
q8	9502	1921	1636	1636
q9	5261	5026	4978	4978
q10	6402	2222	1901	1901
q11	443	275	250	250
q12	627	434	290	290
q13	18099	3376	2739	2739
q14	271	260	246	246
q15	q16	826	768	705	705
q17	992	962	907	907
q18	7127	5822	5619	5619
q19	1344	1344	1239	1239
q20	598	424	290	290
q21	6378	2841	2741	2741
q22	454	373	323	323
Total cold run time: 100275 ms
Total hot run time: 31960 ms

----- Round 2, with runtime_filter_mode=off -----
orders	Doris	NULL	NULL	150000000	42	6422171781	NULL	22778155	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	4897	4732	4835	4732
q2	q3	4973	5258	4621	4621
q4	2127	2226	1462	1462
q5	5096	4709	4756	4709
q6	237	175	127	127
q7	1900	1781	1601	1601
q8	2509	2176	2179	2176
q9	7761	7442	7528	7442
q10	4748	4679	4222	4222
q11	543	391	357	357
q12	741	741	543	543
q13	3061	3437	2789	2789
q14	270	306	283	283
q15	q16	722	702	621	621
q17	1304	1271	1264	1264
q18	7459	6953	6826	6826
q19	1096	1105	1123	1105
q20	2248	2247	1923	1923
q21	5400	4666	4566	4566
q22	532	477	402	402
Total cold run time: 57624 ms
Total hot run time: 51771 ms

@hello-stephen
Copy link
Copy Markdown
Contributor

TPC-DS: Total hot run time: 171975 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit d978d0ba8fd5b605e2bad30494c5213c1e38125f, data reload: false

query5	4327	651	528	528
query6	356	236	195	195
query7	4249	573	303	303
query8	334	230	220	220
query9	8813	4063	4063	4063
query10	483	359	295	295
query11	5810	2564	2203	2203
query12	192	129	126	126
query13	1291	585	456	456
query14	6132	5490	5163	5163
query14_1	4535	4830	4525	4525
query15	212	209	184	184
query16	1019	470	415	415
query17	965	718	590	590
query18	2441	480	352	352
query19	214	198	159	159
query20	132	132	130	130
query21	226	134	118	118
query22	13675	13625	13364	13364
query23	17366	16630	16273	16273
query23_1	16282	16394	16342	16342
query24	7465	1816	1282	1282
query24_1	1295	1289	1319	1289
query25	556	493	421	421
query26	1292	325	180	180
query27	2741	604	339	339
query28	4497	1998	1983	1983
query29	1024	662	531	531
query30	312	236	203	203
query31	1140	1087	966	966
query32	97	77	77	77
query33	565	376	315	315
query34	1193	1099	651	651
query35	788	828	726	726
query36	1442	1424	1266	1266
query37	158	112	95	95
query38	3192	3156	3059	3059
query39	923	927	896	896
query39_1	908	879	863	863
query40	241	153	132	132
query41	72	69	69	69
query42	112	114	111	111
query43	336	338	293	293
query44	
query45	218	206	205	205
query46	1082	1193	726	726
query47	2409	2346	2290	2290
query48	414	403	321	321
query49	665	525	413	413
query50	1032	350	260	260
query51	4352	4370	4233	4233
query52	107	107	95	95
query53	254	292	221	221
query54	328	293	274	274
query55	98	98	88	88
query56	325	340	321	321
query57	1440	1431	1329	1329
query58	315	279	283	279
query59	1621	1641	1456	1456
query60	331	338	327	327
query61	191	187	185	185
query62	709	644	590	590
query63	254	210	207	207
query64	2487	885	743	743
query65	
query66	1731	487	354	354
query67	29811	29703	29719	29703
query68	
query69	471	353	308	308
query70	1075	979	1027	979
query71	303	276	267	267
query72	3042	2710	2381	2381
query73	817	771	445	445
query74	5117	4997	4799	4799
query75	2704	2621	2285	2285
query76	2367	1196	759	759
query77	404	417	350	350
query78	12474	12542	11838	11838
query79	1450	1009	783	783
query80	667	565	456	456
query81	450	280	240	240
query82	1359	162	116	116
query83	367	284	248	248
query84	302	142	114	114
query85	891	570	494	494
query86	389	365	327	327
query87	3441	3396	3262	3262
query88	3632	2729	2750	2729
query89	451	391	346	346
query90	1879	184	192	184
query91	182	168	142	142
query92	83	84	73	73
query93	1470	1391	909	909
query94	546	359	316	316
query95	688	495	351	351
query96	1097	798	341	341
query97	2726	2735	2619	2619
query98	238	228	230	228
query99	1179	1156	1038	1038
Total cold run time: 255113 ms
Total hot run time: 171975 ms

@jacktengg
Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen
Copy link
Copy Markdown
Contributor

TPC-H: Total hot run time: 31404 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit d978d0ba8fd5b605e2bad30494c5213c1e38125f, data reload: false

------ Round 1 ----------------------------------
orders	Doris	NULL	NULL	0	0	0	NULL	0	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	17634	4019	4040	4019
q2	q3	10785	1453	852	852
q4	4720	475	353	353
q5	8274	2322	2098	2098
q6	335	174	135	135
q7	1010	808	637	637
q8	9362	1662	1615	1615
q9	7029	4965	4955	4955
q10	6439	2239	1981	1981
q11	432	275	242	242
q12	703	412	293	293
q13	18272	3358	2804	2804
q14	267	252	250	250
q15	q16	834	772	708	708
q17	1019	951	998	951
q18	6822	5685	5512	5512
q19	1170	1314	1050	1050
q20	496	391	262	262
q21	5861	2694	2376	2376
q22	444	353	311	311
Total cold run time: 101908 ms
Total hot run time: 31404 ms

----- Round 2, with runtime_filter_mode=off -----
orders	Doris	NULL	NULL	150000000	42	6422171781	NULL	22778155	NULL	NULL	2023-12-26 18:27:23	2023-12-26 18:42:55	NULL	utf-8	NULL	NULL	
============================================
q1	4397	4271	4282	4271
q2	q3	4527	4895	4331	4331
q4	2075	2471	1369	1369
q5	4403	4335	5031	4335
q6	255	188	144	144
q7	2019	1826	1660	1660
q8	2429	2148	2244	2148
q9	8132	8064	8033	8033
q10	4884	4771	4307	4307
q11	607	440	377	377
q12	761	755	558	558
q13	3280	3648	2997	2997
q14	311	321	280	280
q15	q16	706	728	632	632
q17	1381	1331	1374	1331
q18	7929	7386	6923	6923
q19	1136	1107	1076	1076
q20	2248	2222	1952	1952
q21	5268	4547	4428	4428
q22	547	456	407	407
Total cold run time: 57295 ms
Total hot run time: 51559 ms

@hello-stephen
Copy link
Copy Markdown
Contributor

TPC-DS: Total hot run time: 171537 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit d978d0ba8fd5b605e2bad30494c5213c1e38125f, data reload: false

query5	4311	661	520	520
query6	333	223	201	201
query7	4255	555	329	329
query8	329	236	229	229
query9	8820	4013	3996	3996
query10	464	347	296	296
query11	5749	2611	2261	2261
query12	179	128	123	123
query13	1289	601	436	436
query14	6098	5428	5104	5104
query14_1	4451	4439	4430	4430
query15	224	207	182	182
query16	1018	457	452	452
query17	1116	732	601	601
query18	2455	475	363	363
query19	209	195	156	156
query20	137	131	127	127
query21	213	135	115	115
query22	13591	13633	13405	13405
query23	17431	16497	16282	16282
query23_1	16401	16274	16292	16274
query24	7447	1776	1342	1342
query24_1	1327	1312	1327	1312
query25	564	469	415	415
query26	1310	319	174	174
query27	2706	546	342	342
query28	4465	1998	1976	1976
query29	1019	637	498	498
query30	317	235	198	198
query31	1127	1092	951	951
query32	89	78	72	72
query33	551	358	290	290
query34	1201	1178	639	639
query35	779	790	708	708
query36	1386	1427	1275	1275
query37	163	112	94	94
query38	3233	3200	3068	3068
query39	930	911	893	893
query39_1	901	879	877	877
query40	232	147	126	126
query41	66	64	63	63
query42	109	110	109	109
query43	336	341	286	286
query44	
query45	213	206	202	202
query46	1085	1224	774	774
query47	2341	2368	2223	2223
query48	428	404	301	301
query49	646	499	382	382
query50	1034	350	251	251
query51	4311	4328	4243	4243
query52	108	106	97	97
query53	263	292	213	213
query54	340	283	267	267
query55	95	91	87	87
query56	312	335	313	313
query57	1439	1438	1322	1322
query58	345	284	288	284
query59	1620	1693	1490	1490
query60	349	337	323	323
query61	185	184	183	183
query62	1051	665	591	591
query63	259	209	209	209
query64	2446	800	639	639
query65	
query66	1720	489	357	357
query67	29817	29722	28910	28910
query68	
query69	464	346	316	316
query70	1051	1025	1003	1003
query71	306	276	271	271
query72	3104	2798	2434	2434
query73	898	798	433	433
query74	5161	4973	4783	4783
query75	2718	2610	2265	2265
query76	2285	1149	749	749
query77	404	411	348	348
query78	12373	12465	11887	11887
query79	1482	1045	751	751
query80	690	562	496	496
query81	451	288	243	243
query82	1398	160	124	124
query83	365	288	260	260
query84	266	148	115	115
query85	980	649	562	562
query86	394	348	333	333
query87	3434	3384	3245	3245
query88	3585	2728	2709	2709
query89	439	398	337	337
query90	1954	192	178	178
query91	181	170	139	139
query92	80	76	74	74
query93	1433	1539	895	895
query94	546	368	328	328
query95	693	493	350	350
query96	1045	839	324	324
query97	2719	2734	2664	2664
query98	231	251	223	223
query99	1162	1141	1026	1026
Total cold run time: 254987 ms
Total hot run time: 171537 ms

@hello-stephen
Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 88.89% (8/9) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 73.83% (28076/38028)
Line Coverage 57.75% (304858/527851)
Region Coverage 54.81% (254733/464755)
Branch Coverage 56.38% (110143/195345)

@hello-stephen
Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 88.89% (8/9) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 73.78% (28058/38028)
Line Coverage 57.74% (304761/527851)
Region Coverage 54.80% (254700/464755)
Branch Coverage 56.37% (110115/195345)

@hello-stephen
Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 88.89% (8/9) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 73.73% (28037/38028)
Line Coverage 57.69% (304530/527851)
Region Coverage 54.74% (254429/464755)
Branch Coverage 56.32% (110013/195345)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants