https://github.com/vasu-the-sharma updated https://github.com/llvm/llvm-project/pull/164548
>From 856ac3b4110d79e57bfef9fed52c00a989683083 Mon Sep 17 00:00:00 2001 From: Vasu Sharma <[email protected]> Date: Wed, 22 Oct 2025 10:04:59 +0530 Subject: [PATCH 1/2] add null and aligment checks for aggregates --- clang/lib/CodeGen/CGExprAgg.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index eee397f1f3d19..de6d80a273dbd 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -2249,6 +2249,21 @@ void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, QualType Ty, bool isVolatile) { assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex"); + if (SanOpts.hasOneOf(SanitizerKind::Null | SanitizerKind::Alignment)) { + Address SrcAddr = Src.getAddress(); + Address DestAddr = Dest.getAddress(); + + // Check source pointer for null and alignment violations + EmitTypeCheck(TCK_Load, SourceLocation(), + SrcAddr.emitRawPointer(*this), Ty, SrcAddr.getAlignment(), + SanitizerSet()); + + // Check destination pointer for null and alignment violations + EmitTypeCheck(TCK_Store, SourceLocation(), + DestAddr.emitRawPointer(*this), Ty, DestAddr.getAlignment(), + SanitizerSet()); + } + Address DestPtr = Dest.getAddress(); Address SrcPtr = Src.getAddress(); >From 4b7ff1ed2976e27b82b0ce660d47749add49f817 Mon Sep 17 00:00:00 2001 From: Vasu Sharma <[email protected]> Date: Wed, 22 Oct 2025 16:15:22 +0530 Subject: [PATCH 2/2] Add null and alignment checks for aggregate copy operation --- clang/lib/CodeGen/CGExprAgg.cpp | 3 + .../Misc/Posix/aggregate_null_alignment.cpp | 79 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 compiler-rt/test/ubsan/TestCases/Misc/Posix/aggregate_null_alignment.cpp diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index de6d80a273dbd..2e5456233c711 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -2249,6 +2249,9 @@ void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, QualType Ty, bool isVolatile) { assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex"); + // Sanitizer checks to verify source and destination pointers are + // non-null and properly aligned before copying. + // Without these checks, undefined behavior from invalid pointers goes undetected. if (SanOpts.hasOneOf(SanitizerKind::Null | SanitizerKind::Alignment)) { Address SrcAddr = Src.getAddress(); Address DestAddr = Dest.getAddress(); diff --git a/compiler-rt/test/ubsan/TestCases/Misc/Posix/aggregate_null_alignment.cpp b/compiler-rt/test/ubsan/TestCases/Misc/Posix/aggregate_null_alignment.cpp new file mode 100644 index 0000000000000..de62c3d5a4df7 --- /dev/null +++ b/compiler-rt/test/ubsan/TestCases/Misc/Posix/aggregate_null_alignment.cpp @@ -0,0 +1,79 @@ +// RUN: %clangxx -fsanitize=alignment,null -O0 %s -o %t && %run %t +// RUN: %clangxx -fsanitize=alignment,null -O0 -DTEST_NULL_SRC %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-SRC +// RUN: %clangxx -fsanitize=alignment,null -O0 -DTEST_NULL_DEST %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-DEST +// RUN: %clangxx -fsanitize=alignment,null -O0 -DTEST_MISALIGN_SRC %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-ALIGN-SRC +// RUN: %clangxx -fsanitize=alignment,null -O0 -DTEST_MISALIGN_DEST %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-ALIGN-DEST + +// Tests for null pointer and alignment checks in aggregate copy operations. +// This validates the sanitizer checks added to EmitAggregateCopy for both +// source and destination pointers with null and alignment violations. + +#include <stdlib.h> +#include <string.h> + +struct alignas(16) AlignedStruct { + int a; + int b; + int c; + int d; +}; + +struct NormalStruct { + int x; + int y; + int z; +}; + +void test_null_src() { + AlignedStruct dest; + AlignedStruct *src = nullptr; + // CHECK-NULL-SRC: runtime error: load of null pointer of type 'AlignedStruct' + dest = *src; +} + +void test_null_dest() { + AlignedStruct src = {1, 2, 3, 4}; + AlignedStruct *dest = nullptr; + // CHECK-NULL-DEST: runtime error: store to null pointer of type 'AlignedStruct' + *dest = src; +} + +void test_misaligned_src() { + char buffer[sizeof(AlignedStruct) + 16]; + // Create a misaligned pointer (not 16-byte aligned) + AlignedStruct *src = (AlignedStruct *)(buffer + 1); + AlignedStruct dest; + // CHECK-ALIGN-SRC: runtime error: load of misaligned address {{0x[0-9a-f]+}} for type 'AlignedStruct', which requires 16 byte alignment + dest = *src; +} + +void test_misaligned_dest() { + AlignedStruct src = {1, 2, 3, 4}; + char buffer[sizeof(AlignedStruct) + 16]; + // Create a misaligned pointer (not 16-byte aligned) + AlignedStruct *dest = (AlignedStruct *)(buffer + 1); + // CHECK-ALIGN-DEST: runtime error: store to misaligned address {{0x[0-9a-f]+}} for type 'AlignedStruct', which requires 16 byte alignment + *dest = src; +} + +void test_normal_copy() { + // This should work fine - properly aligned, non-null pointers + AlignedStruct src = {1, 2, 3, 4}; + AlignedStruct dest; + dest = src; +} + +int main() { +#ifdef TEST_NULL_SRC + test_null_src(); +#elif defined(TEST_NULL_DEST) + test_null_dest(); +#elif defined(TEST_MISALIGN_SRC) + test_misaligned_src(); +#elif defined(TEST_MISALIGN_DEST) + test_misaligned_dest(); +#else + test_normal_copy(); +#endif + return 0; +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
