@@ -66,15 +66,16 @@ extern "C" void *__libc_stack_end;
66
66
void *__libc_stack_end = 0 ;
67
67
#endif
68
68
69
- #if SANITIZER_LINUX && (defined(__aarch64__) || defined(__loongarch_lp64)) && \
70
- !SANITIZER_GO
71
- # define INIT_LONGJMP_XOR_KEY 1
72
- #else
73
- # define INIT_LONGJMP_XOR_KEY 0
74
- #endif
69
+ # if SANITIZER_LINUX && \
70
+ (defined(__aarch64__) || defined(__loongarch_lp64)) && !SANITIZER_GO && \
71
+ !SANITIZER_ANDROID
72
+ # define INIT_LONGJMP_XOR_KEY 1
73
+ # else
74
+ # define INIT_LONGJMP_XOR_KEY 0
75
+ # endif
75
76
76
- #if INIT_LONGJMP_XOR_KEY
77
- #include " interception/interception.h"
77
+ # if INIT_LONGJMP_XOR_KEY
78
+ # include " interception/interception.h"
78
79
// Must be declared outside of other namespaces.
79
80
DECLARE_REAL (int , _setjmp, void *env)
80
81
#endif
@@ -415,7 +416,7 @@ void InitializePlatform() {
415
416
// is not compiled with -pie.
416
417
#if !SANITIZER_GO
417
418
{
418
- # if SANITIZER_LINUX && (defined(__aarch64__) || defined(__loongarch_lp64))
419
+ # if INIT_LONGJMP_XOR_KEY
419
420
// Initialize the xor key used in {sig}{set,long}jump.
420
421
InitializeLongjmpXorKey ();
421
422
# endif
@@ -484,10 +485,56 @@ int ExtractRecvmsgFDs(void *msgp, int *fds, int nfd) {
484
485
return res;
485
486
}
486
487
488
+ # if SANITIZER_NETBSD
489
+ # ifdef __x86_64__
490
+ # define LONG_JMP_SP_ENV_SLOT 6
491
+ # else
492
+ # error unsupported
493
+ # endif
494
+ # elif defined(__powerpc__)
495
+ # define LONG_JMP_SP_ENV_SLOT 0
496
+ # elif SANITIZER_FREEBSD
497
+ # ifdef __aarch64__
498
+ # define LONG_JMP_SP_ENV_SLOT 1
499
+ # else
500
+ # define LONG_JMP_SP_ENV_SLOT 2
501
+ # endif
502
+ # elif SANITIZER_LINUX && !SANITIZER_ANDROID
503
+ # ifdef __aarch64__
504
+ # define LONG_JMP_SP_ENV_SLOT 13
505
+ # elif defined(__loongarch__)
506
+ # define LONG_JMP_SP_ENV_SLOT 1
507
+ # elif defined(__mips64)
508
+ # define LONG_JMP_SP_ENV_SLOT 1
509
+ # elif SANITIZER_RISCV64
510
+ # define LONG_JMP_SP_ENV_SLOT 13
511
+ # elif defined(__s390x__)
512
+ # define LONG_JMP_SP_ENV_SLOT 9
513
+ # else
514
+ # define LONG_JMP_SP_ENV_SLOT 6
515
+ # endif
516
+ # elif SANITIZER_ANDROID
517
+ // https://android.googlesource.com/platform/bionic/+/refs/heads/android16-release/libc/arch-arm64/bionic/setjmp.S
518
+ // https://android.googlesource.com/platform/bionic/+/refs/heads/android16-release/libc/arch-x86_64/bionic/setjmp.S
519
+ // https://android.googlesource.com/platform/bionic/+/refs/heads/android16-release/libc/arch-riscv64/bionic/setjmp.S
520
+ # if defined(__aarch64__) || SANITIZER_RISCV64
521
+ # define LONG_JMP_SP_ENV_SLOT 3
522
+ # define LONG_JMP_COOKIE_ENV_SLOT 0
523
+ # elif defined(__x86_64__)
524
+ # define LONG_JMP_SP_ENV_SLOT 6
525
+ # define LONG_JMP_COOKIE_ENV_SLOT 8
526
+ # else
527
+ # error unsupported
528
+ # endif
529
+ # endif
530
+
487
531
// Reverse operation of libc stack pointer mangling
488
- static uptr UnmangleLongJmpSp (uptr mangled_sp) {
489
- #if defined(__x86_64__)
490
- # if SANITIZER_LINUX
532
+ uptr ExtractLongJmpSp (uptr *env) {
533
+ uptr mangled_sp = env[LONG_JMP_SP_ENV_SLOT];
534
+ # if SANITIZER_ANDROID
535
+ return mangled_sp ^ (env[LONG_JMP_COOKIE_ENV_SLOT] & ~1ULL );
536
+ # elif defined(__x86_64__)
537
+ # if SANITIZER_LINUX
491
538
// Reverse of:
492
539
// xor %fs:0x30, %rsi
493
540
// rol $0x11, %rsi
@@ -497,25 +544,25 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) {
497
544
: " =r" (sp)
498
545
: " 0" (mangled_sp));
499
546
return sp;
500
- # else
547
+ # else
501
548
return mangled_sp;
502
- # endif
503
- #elif defined(__aarch64__)
504
- # if SANITIZER_LINUX
549
+ # endif
550
+ # elif defined(__aarch64__)
551
+ # if SANITIZER_LINUX
505
552
return mangled_sp ^ longjmp_xor_key;
506
- # else
553
+ # else
507
554
return mangled_sp;
508
- # endif
509
- #elif defined(__loongarch_lp64)
555
+ # endif
556
+ # elif defined(__loongarch_lp64)
510
557
return mangled_sp ^ longjmp_xor_key;
511
- #elif defined(__powerpc64__)
558
+ # elif defined(__powerpc64__)
512
559
// Reverse of:
513
560
// ld r4, -28696(r13)
514
561
// xor r4, r3, r4
515
562
uptr xor_key;
516
563
asm (" ld %0, -28696(%%r13)" : " =r" (xor_key));
517
564
return mangled_sp ^ xor_key;
518
- #elif defined(__mips__)
565
+ # elif defined(__mips__)
519
566
return mangled_sp;
520
567
# elif SANITIZER_RISCV64
521
568
return mangled_sp;
@@ -528,42 +575,7 @@ static uptr UnmangleLongJmpSp(uptr mangled_sp) {
528
575
# endif
529
576
}
530
577
531
- #if SANITIZER_NETBSD
532
- # ifdef __x86_64__
533
- # define LONG_JMP_SP_ENV_SLOT 6
534
- # else
535
- # error unsupported
536
- # endif
537
- #elif defined(__powerpc__)
538
- # define LONG_JMP_SP_ENV_SLOT 0
539
- #elif SANITIZER_FREEBSD
540
- # ifdef __aarch64__
541
- # define LONG_JMP_SP_ENV_SLOT 1
542
- # else
543
- # define LONG_JMP_SP_ENV_SLOT 2
544
- # endif
545
- #elif SANITIZER_LINUX
546
- # ifdef __aarch64__
547
- # define LONG_JMP_SP_ENV_SLOT 13
548
- # elif defined(__loongarch__)
549
- # define LONG_JMP_SP_ENV_SLOT 1
550
- # elif defined(__mips64)
551
- # define LONG_JMP_SP_ENV_SLOT 1
552
- # elif SANITIZER_RISCV64
553
- # define LONG_JMP_SP_ENV_SLOT 13
554
- # elif defined(__s390x__)
555
- # define LONG_JMP_SP_ENV_SLOT 9
556
- # else
557
- # define LONG_JMP_SP_ENV_SLOT 6
558
- # endif
559
- #endif
560
-
561
- uptr ExtractLongJmpSp (uptr *env) {
562
- uptr mangled_sp = env[LONG_JMP_SP_ENV_SLOT];
563
- return UnmangleLongJmpSp (mangled_sp);
564
- }
565
-
566
- #if INIT_LONGJMP_XOR_KEY
578
+ # if INIT_LONGJMP_XOR_KEY
567
579
// GLIBC mangles the function pointers in jmp_buf (used in {set,long}*jmp
568
580
// functions) by XORing them with a random key. For AArch64 it is a global
569
581
// variable rather than a TCB one (as for x86_64/powerpc). We obtain the key by
@@ -575,17 +587,17 @@ static void InitializeLongjmpXorKey() {
575
587
576
588
// 2. Retrieve vanilla/mangled SP.
577
589
uptr sp;
578
- #ifdef __loongarch__
590
+ # ifdef __loongarch__
579
591
asm (" move %0, $sp" : " =r" (sp));
580
- #else
592
+ # else
581
593
asm (" mov %0, sp" : " =r" (sp));
582
- #endif
594
+ # endif
583
595
uptr mangled_sp = ((uptr *)&env)[LONG_JMP_SP_ENV_SLOT];
584
596
585
597
// 3. xor SPs to obtain key.
586
598
longjmp_xor_key = mangled_sp ^ sp;
587
599
}
588
- #endif
600
+ # endif
589
601
590
602
extern " C" void __tsan_tls_initialization () {}
591
603
@@ -616,43 +628,51 @@ int call_pthread_cancel_with_cleanup(int (*fn)(void *arg),
616
628
pthread_cleanup_pop (0 );
617
629
return res;
618
630
}
619
- #endif // !SANITIZER_GO
631
+ # endif // !SANITIZER_GO
620
632
621
- #if !SANITIZER_GO
622
- void ReplaceSystemMalloc () { }
623
- #endif
633
+ # if !SANITIZER_GO
634
+ void ReplaceSystemMalloc () {}
635
+ # endif
624
636
625
- #if !SANITIZER_GO
626
- #if SANITIZER_ANDROID
637
+ # if !SANITIZER_GO
638
+ # if SANITIZER_ANDROID
627
639
// On Android, one thread can call intercepted functions after
628
640
// DestroyThreadState(), so add a fake thread state for "dead" threads.
629
641
static ThreadState *dead_thread_state = nullptr ;
630
642
631
643
ThreadState *cur_thread () {
632
- ThreadState* thr = reinterpret_cast <ThreadState*>(*get_android_tls_ptr ());
644
+ ThreadState * thr = reinterpret_cast <ThreadState *>(*get_android_tls_ptr ());
633
645
if (thr == nullptr ) {
634
646
__sanitizer_sigset_t emptyset;
635
647
internal_sigfillset (&emptyset);
636
648
__sanitizer_sigset_t oldset;
637
649
CHECK_EQ (0 , internal_sigprocmask (SIG_SETMASK, &emptyset, &oldset));
638
- thr = reinterpret_cast <ThreadState*>(*get_android_tls_ptr ());
650
+ thr = reinterpret_cast <ThreadState *>(*get_android_tls_ptr ());
639
651
if (thr == nullptr ) {
640
- thr = reinterpret_cast <ThreadState*>(MmapOrDie ( sizeof (ThreadState),
641
- " ThreadState" ));
652
+ thr = reinterpret_cast <ThreadState *>(
653
+ MmapOrDie ( sizeof (ThreadState), " ThreadState" ));
642
654
*get_android_tls_ptr () = reinterpret_cast <uptr>(thr);
643
655
if (dead_thread_state == nullptr ) {
644
- dead_thread_state = reinterpret_cast <ThreadState*>(
656
+ dead_thread_state = reinterpret_cast <ThreadState *>(
645
657
MmapOrDie (sizeof (ThreadState), " ThreadState" ));
646
658
dead_thread_state->fast_state .SetIgnoreBit ();
647
659
dead_thread_state->ignore_interceptors = 1 ;
648
660
dead_thread_state->is_dead = true ;
649
- *const_cast <u32 *>(&dead_thread_state->tid ) = -1 ;
661
+ *const_cast <u32 *>(&dead_thread_state->tid ) = -1 ;
650
662
CHECK_EQ (0 , internal_mprotect (dead_thread_state, sizeof (ThreadState),
651
663
PROT_READ));
652
664
}
653
665
}
654
666
CHECK_EQ (0 , internal_sigprocmask (SIG_SETMASK, &oldset, nullptr ));
655
667
}
668
+
669
+ // This is a temporary workaround.
670
+ // Somewhere wrote get_android_tls_ptr unexpected.
671
+ uptr addr = reinterpret_cast <uptr>(thr);
672
+ if (addr % 2 != 0 ) {
673
+ return reinterpret_cast <ThreadState *>(addr & ~1ULL );
674
+ }
675
+
656
676
return thr;
657
677
}
658
678
@@ -665,15 +685,15 @@ void cur_thread_finalize() {
665
685
internal_sigfillset (&emptyset);
666
686
__sanitizer_sigset_t oldset;
667
687
CHECK_EQ (0 , internal_sigprocmask (SIG_SETMASK, &emptyset, &oldset));
668
- ThreadState* thr = reinterpret_cast <ThreadState*>(*get_android_tls_ptr ());
688
+ ThreadState * thr = reinterpret_cast <ThreadState *>(*get_android_tls_ptr ());
669
689
if (thr != dead_thread_state) {
670
690
*get_android_tls_ptr () = reinterpret_cast <uptr>(dead_thread_state);
671
691
UnmapOrDie (thr, sizeof (ThreadState));
672
692
}
673
693
CHECK_EQ (0 , internal_sigprocmask (SIG_SETMASK, &oldset, nullptr ));
674
694
}
675
- #endif // SANITIZER_ANDROID
676
- #endif // if !SANITIZER_GO
695
+ # endif // SANITIZER_ANDROID
696
+ # endif // if !SANITIZER_GO
677
697
678
698
} // namespace __tsan
679
699
0 commit comments