From: Akira Hatanaka Date: Tue, 6 Nov 2018 06:26:17 +0000 (+0000) Subject: os_log: Add a new privacy annotation "sensitive". X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=273f2bbc3c908c659aecf42124201a753156746a;p=clang os_log: Add a new privacy annotation "sensitive". This is a stricter privacy annotation than "private", which will be used for data that shouldn’t be logged to disk. For backward compatibility, the "private" bit is set too. rdar://problem/36755912 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@346210 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/FormatString.h b/include/clang/AST/FormatString.h index 598d341ac8..39eb6258a6 100644 --- a/include/clang/AST/FormatString.h +++ b/include/clang/AST/FormatString.h @@ -475,13 +475,15 @@ class PrintfSpecifier : public analyze_format_string::FormatSpecifier { OptionalFlag HasObjCTechnicalTerm; // '[tt]' OptionalFlag IsPrivate; // '{private}' OptionalFlag IsPublic; // '{public}' + OptionalFlag IsSensitive; // '{sensitive}' OptionalAmount Precision; public: PrintfSpecifier() : FormatSpecifier(/* isPrintf = */ true), HasThousandsGrouping("'"), IsLeftJustified("-"), HasPlusPrefix("+"), HasSpacePrefix(" "), HasAlternativeForm("#"), HasLeadingZeroes("0"), - HasObjCTechnicalTerm("tt"), IsPrivate("private"), IsPublic("public") {} + HasObjCTechnicalTerm("tt"), IsPrivate("private"), IsPublic("public"), + IsSensitive("sensitive") {} static PrintfSpecifier Parse(const char *beg, const char *end); @@ -512,6 +514,9 @@ public: } void setIsPrivate(const char *position) { IsPrivate.setPosition(position); } void setIsPublic(const char *position) { IsPublic.setPosition(position); } + void setIsSensitive(const char *position) { + IsSensitive.setPosition(position); + } void setUsesPositionalArg() { UsesPositionalArg = true; } // Methods for querying the format specifier. @@ -551,6 +556,7 @@ public: const OptionalFlag &hasObjCTechnicalTerm() const { return HasObjCTechnicalTerm; } const OptionalFlag &isPrivate() const { return IsPrivate; } const OptionalFlag &isPublic() const { return IsPublic; } + const OptionalFlag &isSensitive() const { return IsSensitive; } bool usesPositionalArg() const { return UsesPositionalArg; } /// Changes the specifier and length according to a QualType, retaining any diff --git a/include/clang/AST/OSLog.h b/include/clang/AST/OSLog.h index 41e5c5a9ce..c8895156d0 100644 --- a/include/clang/AST/OSLog.h +++ b/include/clang/AST/OSLog.h @@ -60,7 +60,10 @@ public: IsPrivate = 0x1, // The item is marked "public" in the format string. - IsPublic = 0x2 + IsPublic = 0x2, + + // The item is marked "sensitive" in the format string. + IsSensitive = 0x4 | IsPrivate }; private: @@ -73,7 +76,8 @@ private: public: OSLogBufferItem(Kind kind, const Expr *expr, CharUnits size, unsigned flags) : TheKind(kind), TheExpr(expr), Size(size), Flags(flags) { - assert(((Flags == 0) || (Flags == IsPrivate) || (Flags == IsPublic)) && + assert(((Flags == 0) || (Flags == IsPrivate) || (Flags == IsPublic) || + (Flags == IsSensitive)) && "unexpected privacy flag"); } diff --git a/lib/AST/OSLog.cpp b/lib/AST/OSLog.cpp index 9124fd58a0..d70aa60518 100644 --- a/lib/AST/OSLog.cpp +++ b/lib/AST/OSLog.cpp @@ -120,7 +120,9 @@ public: ArgsData.back().FieldWidth = Args[FS.getFieldWidth().getArgIndex()]; } - if (FS.isPrivate()) + if (FS.isSensitive()) + ArgsData.back().Flags |= OSLogBufferItem::IsSensitive; + else if (FS.isPrivate()) ArgsData.back().Flags |= OSLogBufferItem::IsPrivate; else if (FS.isPublic()) ArgsData.back().Flags |= OSLogBufferItem::IsPublic; diff --git a/lib/AST/PrintfFormatString.cpp b/lib/AST/PrintfFormatString.cpp index 71c28de99c..a92375b452 100644 --- a/lib/AST/PrintfFormatString.cpp +++ b/lib/AST/PrintfFormatString.cpp @@ -127,7 +127,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, do { StringRef Str(I, E - I); - std::string Match = "^[[:space:]]*(private|public)[[:space:]]*(,|})"; + std::string Match = "^[[:space:]]*(private|public|sensitive)" + "[[:space:]]*(,|})"; llvm::Regex R(Match); SmallVector Matches; @@ -138,7 +139,11 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, // Set the privacy flag if the privacy annotation in the // comma-delimited segment is at least as strict as the privacy // annotations in previous comma-delimited segments. - if (MatchedStr.equals("private")) + if (MatchedStr.equals("sensitive")) + PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsSensitive; + else if (PrivacyFlags != + clang::analyze_os_log::OSLogBufferItem::IsSensitive && + MatchedStr.equals("private")) PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsPrivate; else if (PrivacyFlags == 0 && MatchedStr.equals("public")) PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsPublic; @@ -168,6 +173,9 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, case clang::analyze_os_log::OSLogBufferItem::IsPublic: FS.setIsPublic(MatchedStr.data()); break; + case clang::analyze_os_log::OSLogBufferItem::IsSensitive: + FS.setIsSensitive(MatchedStr.data()); + break; default: llvm_unreachable("Unexpected privacy flag value"); } diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c index 829f725617..40d7ca32d7 100644 --- a/test/CodeGen/builtins.c +++ b/test/CodeGen/builtins.c @@ -443,10 +443,17 @@ void test_builtin_os_log(void *buf, int i, const char *data) { // CHECK: call void @__os_log_helper_1_3_1_8_33( __builtin_os_log_format(buf, "%{ xyz, private }s", "abc"); + // CHECK: call void @__os_log_helper_1_3_1_8_37( + __builtin_os_log_format(buf, "%{ xyz, sensitive }s", "abc"); + // The strictest privacy annotation in the string wins. // CHECK: call void @__os_log_helper_1_3_1_8_33( __builtin_os_log_format(buf, "%{ private, public, private, public}s", "abc"); + + // CHECK: call void @__os_log_helper_1_3_1_8_37( + __builtin_os_log_format(buf, "%{ private, sensitive, private, public}s", + "abc"); } // CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_3_4_4_0_8_34_4_17_8_49