Skip to content

Commit 7c1bc5f

Browse files
committed
Teach the kernel KUBSAN runtime about alignment_assumption
This checks the alignment of a given pointer is sufficient for the requested alignment asked for. This fixes the build with a recent llvm/clang. Sponsored by: DARPA, AFRL
1 parent 2134e85 commit 7c1bc5f

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

sys/kern/kern_ubsan.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,12 @@ struct CFloatCastOverflowData {
244244
struct CTypeDescriptor *mToType;
245245
};
246246

247+
struct CAlignmentAssumptionData {
248+
struct CSourceLocation mLocation;
249+
struct CSourceLocation mAssumptionLocation;
250+
struct CTypeDescriptor *mType;
251+
};
252+
247253
/* Local utility functions */
248254
static void Report(bool isFatal, const char *pFormat, ...) __printflike(2, 3);
249255
static bool isAlreadyReported(struct CSourceLocation *pLocation);
@@ -276,6 +282,8 @@ intptr_t __ubsan_vptr_type_cache[128];
276282
/* Public symbols used in the instrumentation of the code generation part */
277283
void __ubsan_handle_add_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
278284
void __ubsan_handle_add_overflow_abort(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS);
285+
void __ubsan_handle_alignment_assumption(struct CAlignmentAssumptionData *pData, unsigned long ulPointer, unsigned long ulAlignment, unsigned long ulOffset);
286+
void __ubsan_handle_alignment_assumption_abort(struct CAlignmentAssumptionData *pData, unsigned long ulPointer, unsigned long ulAlignment, unsigned long ulOffset);
279287
void __ubsan_handle_builtin_unreachable(struct CUnreachableData *pData);
280288
void __ubsan_handle_cfi_bad_type(struct CCFICheckFailData *pData, unsigned long ulVtable, bool bValidVtable, bool FromUnrecoverableHandler, unsigned long ProgramCounter, unsigned long FramePointer);
281289
void __ubsan_handle_cfi_check_fail(struct CCFICheckFailData *pData, unsigned long ulValue, unsigned long ulValidVtable);
@@ -338,6 +346,7 @@ static void HandleMissingReturn(bool isFatal, struct CUnreachableData *pData);
338346
static void HandleNonnullArg(bool isFatal, struct CNonNullArgData *pData);
339347
static void HandleNonnullReturn(bool isFatal, struct CNonNullReturnData *pData, struct CSourceLocation *pLocationPointer);
340348
static void HandlePointerOverflow(bool isFatal, struct CPointerOverflowData *pData, unsigned long ulBase, unsigned long ulResult);
349+
static void HandleAlignmentAssumption(bool isFatal, struct CAlignmentAssumptionData *pData, unsigned long ulPointer, unsigned long ulAlignment, unsigned long ulOffset);
341350

342351
static void
343352
HandleOverflow(bool isFatal, struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS, const char *szOperation)
@@ -690,6 +699,34 @@ HandlePointerOverflow(bool isFatal, struct CPointerOverflowData *pData, unsigned
690699
szLocation, ulBase, ulResult);
691700
}
692701

702+
static void
703+
HandleAlignmentAssumption(bool isFatal, struct CAlignmentAssumptionData *pData, unsigned long ulPointer, unsigned long ulAlignment, unsigned long ulOffset)
704+
{
705+
char szLocation[LOCATION_MAXLEN];
706+
char szAssumptionLocation[LOCATION_MAXLEN];
707+
unsigned long ulRealPointer;
708+
709+
ASSERT(pData);
710+
711+
if (isAlreadyReported(&pData->mLocation))
712+
return;
713+
714+
DeserializeLocation(szLocation, LOCATION_MAXLEN, &pData->mLocation);
715+
716+
ulRealPointer = ulPointer - ulOffset;
717+
718+
if (pData->mAssumptionLocation.mFilename != NULL) {
719+
DeserializeLocation(szAssumptionLocation, LOCATION_MAXLEN,
720+
&pData->mAssumptionLocation);
721+
Report(isFatal, "UBSan: Undefined Behavior in %s, alignment assumption of %#lx for pointer %#lx (offset %#lx), asumption made in %s\n",
722+
szLocation, ulAlignment, ulRealPointer, ulOffset,
723+
szAssumptionLocation);
724+
} else {
725+
Report(isFatal, "UBSan: Undefined Behavior in %s, alignment assumption of %#lx for pointer %#lx (offset %#lx)\n",
726+
szLocation, ulAlignment, ulRealPointer, ulOffset);
727+
}
728+
}
729+
693730
/* Definions of public symbols emitted by the instrumentation code */
694731
void
695732
__ubsan_handle_add_overflow(struct COverflowData *pData, unsigned long ulLHS, unsigned long ulRHS)
@@ -709,6 +746,24 @@ __ubsan_handle_add_overflow_abort(struct COverflowData *pData, unsigned long ulL
709746
HandleOverflow(true, pData, ulLHS, ulRHS, PLUS_STRING);
710747
}
711748

749+
void
750+
__ubsan_handle_alignment_assumption(struct CAlignmentAssumptionData *pData, unsigned long ulPointer, unsigned long ulAlignment, unsigned long ulOffset)
751+
{
752+
753+
ASSERT(pData);
754+
755+
HandleAlignmentAssumption(false, pData, ulPointer, ulAlignment, ulOffset);
756+
}
757+
758+
void
759+
__ubsan_handle_alignment_assumption_abort(struct CAlignmentAssumptionData *pData, unsigned long ulPointer, unsigned long ulAlignment, unsigned long ulOffset)
760+
{
761+
762+
ASSERT(pData);
763+
764+
HandleAlignmentAssumption(true, pData, ulPointer, ulAlignment, ulOffset);
765+
}
766+
712767
void
713768
__ubsan_handle_builtin_unreachable(struct CUnreachableData *pData)
714769
{

0 commit comments

Comments
 (0)