Skip to content

Commit 2db8948

Browse files
authored
Merge branch 'main' into fix/163090
2 parents ab24f85 + 856555b commit 2db8948

File tree

36 files changed

+743
-371
lines changed

36 files changed

+743
-371
lines changed

clang/docs/PointerAuthentication.rst

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,36 @@ The result value is never zero and always within range for both the
592592

593593
This can be used in constant expressions.
594594

595+
``ptrauth_type_discriminator``
596+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
597+
598+
.. code-block:: c
599+
600+
ptrauth_type_discriminator(type)
601+
602+
Compute the constant discriminator derived from the given type, as is computed
603+
for automatically type diversified schemas.
604+
605+
``type`` must be a type. The result has the type ``ptrauth_extra_data_t``.
606+
607+
This can be used in constant expressions.
608+
609+
``ptrauth_function_pointer_type_discriminator``
610+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
611+
612+
.. code-block:: c
613+
614+
ptrauth_function_pointer_type_discriminator(function_type)
615+
616+
Compute the constant discriminator derived from the provided function type, for
617+
use in contexts where the default function authentication schema. If function
618+
pointer type diversity is enabled, this is equivalent to
619+
`ptrauth_type_discriminator(function_type)`, if it is not enabled this is `0`.
620+
621+
``function_type`` must be a function type. The result has the type ``ptrauth_extra_data_t``.
622+
623+
This can be used in constant expressions.
624+
595625
``ptrauth_strip``
596626
^^^^^^^^^^^^^^^^^
597627

clang/lib/CIR/CodeGen/CIRGenStmt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ mlir::LogicalResult CIRGenFunction::emitLabel(const clang::LabelDecl &d) {
536536
mlir::Block *currBlock = builder.getBlock();
537537
mlir::Block *labelBlock = currBlock;
538538

539-
if (!currBlock->empty()) {
539+
if (!currBlock->empty() || currBlock->isEntryBlock()) {
540540
{
541541
mlir::OpBuilder::InsertionGuard guard(builder);
542542
labelBlock = builder.createBlock(builder.getBlock()->getParent());

clang/lib/Headers/ptrauth.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,18 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
241241
#define ptrauth_type_discriminator(__type) \
242242
__builtin_ptrauth_type_discriminator(__type)
243243

244+
/* Compute the constant discriminator used by Clang to sign pointers with the
245+
given C function pointer type.
246+
247+
A call to this function is an integer constant expression. */
248+
#if __has_feature(ptrauth_function_pointer_type_discrimination)
249+
#define ptrauth_function_pointer_type_discriminator(__type) \
250+
__builtin_ptrauth_type_discriminator(__type)
251+
#else
252+
#define ptrauth_function_pointer_type_discriminator(__type) \
253+
((ptrauth_extra_data_t)0)
254+
#endif
255+
244256
/* Compute a signature for the given pair of pointer-sized values.
245257
The order of the arguments is significant.
246258
@@ -372,6 +384,8 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
372384
})
373385

374386
#define ptrauth_type_discriminator(__type) ((ptrauth_extra_data_t)0)
387+
#define ptrauth_function_pointer_type_discriminator(__type) \
388+
((ptrauth_extra_data_t)0)
375389

376390
#define ptrauth_sign_generic_data(__value, __data) \
377391
({ \

clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ bool tryToFindPtrOrigin(
2626
const Expr *E, bool StopAtFirstRefCountedObj,
2727
std::function<bool(const clang::CXXRecordDecl *)> isSafePtr,
2828
std::function<bool(const clang::QualType)> isSafePtrType,
29+
std::function<bool(const clang::Decl *)> isSafeGlobalDecl,
2930
std::function<bool(const clang::Expr *, bool)> callback) {
3031
while (E) {
3132
if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
@@ -34,6 +35,8 @@ bool tryToFindPtrOrigin(
3435
auto IsImmortal = safeGetName(VD) == "NSApp";
3536
if (VD->hasGlobalStorage() && (IsImmortal || QT.isConstQualified()))
3637
return callback(E, true);
38+
if (VD->hasGlobalStorage() && isSafeGlobalDecl(VD))
39+
return callback(E, true);
3740
}
3841
}
3942
if (auto *tempExpr = dyn_cast<MaterializeTemporaryExpr>(E)) {
@@ -71,9 +74,11 @@ bool tryToFindPtrOrigin(
7174
}
7275
if (auto *Expr = dyn_cast<ConditionalOperator>(E)) {
7376
return tryToFindPtrOrigin(Expr->getTrueExpr(), StopAtFirstRefCountedObj,
74-
isSafePtr, isSafePtrType, callback) &&
77+
isSafePtr, isSafePtrType, isSafeGlobalDecl,
78+
callback) &&
7579
tryToFindPtrOrigin(Expr->getFalseExpr(), StopAtFirstRefCountedObj,
76-
isSafePtr, isSafePtrType, callback);
80+
isSafePtr, isSafePtrType, isSafeGlobalDecl,
81+
callback);
7782
}
7883
if (auto *cast = dyn_cast<CastExpr>(E)) {
7984
if (StopAtFirstRefCountedObj) {

clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ bool tryToFindPtrOrigin(
5656
const clang::Expr *E, bool StopAtFirstRefCountedObj,
5757
std::function<bool(const clang::CXXRecordDecl *)> isSafePtr,
5858
std::function<bool(const clang::QualType)> isSafePtrType,
59+
std::function<bool(const clang::Decl *)> isSafeGlobalDecl,
5960
std::function<bool(const clang::Expr *, bool)> callback);
6061

6162
/// For \p E referring to a ref-countable/-counted pointer/reference we return

clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ namespace {
2929
class RawPtrRefCallArgsChecker
3030
: public Checker<check::ASTDecl<TranslationUnitDecl>> {
3131
BugType Bug;
32-
mutable BugReporter *BR;
3332

3433
TrivialFunctionAnalysis TFA;
3534
EnsureFunctionAnalysis EFA;
3635

3736
protected:
37+
mutable BugReporter *BR;
3838
mutable std::optional<RetainTypeChecker> RTC;
3939

4040
public:
@@ -46,6 +46,7 @@ class RawPtrRefCallArgsChecker
4646
virtual bool isSafePtr(const CXXRecordDecl *Record) const = 0;
4747
virtual bool isSafePtrType(const QualType type) const = 0;
4848
virtual bool isSafeExpr(const Expr *) const { return false; }
49+
virtual bool isSafeDecl(const Decl *) const { return false; }
4950
virtual const char *ptrKind() const = 0;
5051

5152
void checkASTDecl(const TranslationUnitDecl *TUD, AnalysisManager &MGR,
@@ -214,6 +215,7 @@ class RawPtrRefCallArgsChecker
214215
Arg, /*StopAtFirstRefCountedObj=*/true,
215216
[&](const clang::CXXRecordDecl *Record) { return isSafePtr(Record); },
216217
[&](const clang::QualType T) { return isSafePtrType(T); },
218+
[&](const clang::Decl *D) { return isSafeDecl(D); },
217219
[&](const clang::Expr *ArgOrigin, bool IsSafe) {
218220
if (IsSafe)
219221
return true;
@@ -479,6 +481,11 @@ class UnretainedCallArgsChecker final : public RawPtrRefCallArgsChecker {
479481
isa<ObjCMessageExpr>(E);
480482
}
481483

484+
bool isSafeDecl(const Decl *D) const final {
485+
// Treat NS/CF globals in system header as immortal.
486+
return BR->getSourceManager().isInSystemHeader(D->getLocation());
487+
}
488+
482489
const char *ptrKind() const final { return "unretained"; }
483490
};
484491

clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,10 @@ bool isGuardedScopeEmbeddedInGuardianScope(const VarDecl *Guarded,
166166
class RawPtrRefLocalVarsChecker
167167
: public Checker<check::ASTDecl<TranslationUnitDecl>> {
168168
BugType Bug;
169-
mutable BugReporter *BR;
170169
EnsureFunctionAnalysis EFA;
171170

172171
protected:
172+
mutable BugReporter *BR;
173173
mutable std::optional<RetainTypeChecker> RTC;
174174

175175
public:
@@ -180,6 +180,7 @@ class RawPtrRefLocalVarsChecker
180180
virtual bool isSafePtr(const CXXRecordDecl *) const = 0;
181181
virtual bool isSafePtrType(const QualType) const = 0;
182182
virtual bool isSafeExpr(const Expr *) const { return false; }
183+
virtual bool isSafeDecl(const Decl *) const { return false; }
183184
virtual const char *ptrKind() const = 0;
184185

185186
void checkASTDecl(const TranslationUnitDecl *TUD, AnalysisManager &MGR,
@@ -288,6 +289,7 @@ class RawPtrRefLocalVarsChecker
288289
return isSafePtr(Record);
289290
},
290291
[&](const clang::QualType Type) { return isSafePtrType(Type); },
292+
[&](const clang::Decl *D) { return isSafeDecl(D); },
291293
[&](const clang::Expr *InitArgOrigin, bool IsSafe) {
292294
if (!InitArgOrigin || IsSafe)
293295
return true;
@@ -443,6 +445,10 @@ class UnretainedLocalVarsChecker final : public RawPtrRefLocalVarsChecker {
443445
return ento::cocoa::isCocoaObjectRef(E->getType()) &&
444446
isa<ObjCMessageExpr>(E);
445447
}
448+
bool isSafeDecl(const Decl *D) const final {
449+
// Treat NS/CF globals in system header as immortal.
450+
return BR->getSourceManager().isInSystemHeader(D->getLocation());
451+
}
446452
const char *ptrKind() const final { return "unretained"; }
447453
};
448454

clang/test/Analysis/Checkers/WebKit/mock-system-header.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,17 @@ void os_log_msg(os_log_t oslog, os_log_type_t type, const char *msg, ...);
3434

3535
typedef const struct __attribute__((objc_bridge(NSString))) __CFString * CFStringRef;
3636

37+
extern CFStringRef const kCFURLTagNamesKey;
38+
3739
#ifdef __OBJC__
3840
@class NSString;
3941
@interface SystemObject {
4042
NSString *ns_string;
4143
CFStringRef cf_string;
4244
}
4345
@end
46+
47+
typedef NSString *NSNotificationName;
48+
extern "C" NSNotificationName NSApplicationDidBecomeActiveNotification;
49+
4450
#endif

clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UnretainedLocalVarsChecker -verify %s
22

33
#import "objc-mock-types.h"
4+
#import "mock-system-header.h"
45

56
void someFunction();
7+
extern "C" CFStringRef LocalGlobalCFString;
8+
extern "C" NSString *LocalGlobalNSString;
69

710
namespace raw_ptr {
811
void foo() {
@@ -547,6 +550,29 @@ void foo() {
547550

548551
} // autoreleased
549552

553+
namespace ns_global {
554+
555+
void consumeCFString(CFStringRef);
556+
void consumeNSString(NSString *);
557+
558+
void cf() {
559+
auto *str = kCFURLTagNamesKey;
560+
consumeCFString(str);
561+
auto *localStr = LocalGlobalCFString;
562+
// expected-warning@-1{{Local variable 'localStr' is unretained and unsafe [alpha.webkit.UnretainedLocalVarsChecker]}}
563+
consumeCFString(localStr);
564+
}
565+
566+
void ns() {
567+
auto *str = NSApplicationDidBecomeActiveNotification;
568+
consumeNSString(str);
569+
auto *localStr = LocalGlobalNSString;
570+
// expected-warning@-1{{Local variable 'localStr' is unretained and unsafe [alpha.webkit.UnretainedLocalVarsChecker]}}
571+
consumeNSString(localStr);
572+
}
573+
574+
}
575+
550576
bool doMoreWorkOpaque(OtherObj*);
551577
SomeObj* provide();
552578

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UnretainedCallArgsChecker -verify %s
2+
3+
#import "mock-types.h"
4+
#import "mock-system-header.h"
5+
6+
void consumeCFString(CFStringRef);
7+
extern "C" CFStringRef LocalGlobalCFString;
8+
void consumeNSString(NSString *);
9+
extern "C" NSString *LocalGlobalNSString;
10+
11+
void foo() {
12+
consumeCFString(kCFURLTagNamesKey);
13+
consumeCFString(LocalGlobalCFString);
14+
// expected-warning@-1{{Call argument is unretained and unsafe}}
15+
consumeNSString(NSApplicationDidBecomeActiveNotification);
16+
consumeNSString(LocalGlobalNSString);
17+
// expected-warning@-1{{Call argument is unretained and unsafe}}
18+
}

0 commit comments

Comments
 (0)