Author: flovent Date: 2025-12-17T09:56:38-08:00 New Revision: b5dd6cc7464279f9bdb7ce4cc2cec162df7aad6d
URL: https://github.com/llvm/llvm-project/commit/b5dd6cc7464279f9bdb7ce4cc2cec162df7aad6d DIFF: https://github.com/llvm/llvm-project/commit/b5dd6cc7464279f9bdb7ce4cc2cec162df7aad6d.diff LOG: [clang][BufferUsage] Fix crash when parsing invalid format string (#170496) `clang::analyze_format_string::ParsePrintfString` also returns `true` when we get an invalid or erroneous format string, so `UnsafeArg` will not be set, but `hasUnsafeFormatOrSArg`'s caller assumes `UnsafeArg` will be valid when it returns true, which leads to crash. Closes #169629 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Analysis/UnsafeBufferUsage.cpp clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 076cc1778018f..8e2e45b8ef385 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -537,6 +537,7 @@ Bug Fixes in This Version - Fixed false-positive shadow diagnostics for lambdas in explicit object member functions. (#GH163731) - Fix an assertion failure when a ``target_clones`` attribute is only on the forward declaration of a multiversioned function. (#GH165517) (#GH129483) +- Fix a crash caused by invalid format string in printf-like functions with ``-Wunsafe-buffer-usage-in-libc-call`` option enabled. (#GH170496) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp index 0b9e908517412..7ef20726d0ab9 100644 --- a/clang/lib/Analysis/UnsafeBufferUsage.cpp +++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp @@ -834,6 +834,7 @@ static bool hasUnsafeFormatOrSArg(const CallExpr *Call, const Expr *&UnsafeArg, unsigned FmtArgIdx; const Expr *&UnsafeArg; ASTContext &Ctx; + bool UnsafeArgSet; // Returns an `Expr` representing the precision if specified, null // otherwise. @@ -874,7 +875,8 @@ static bool hasUnsafeFormatOrSArg(const CallExpr *Call, const Expr *&UnsafeArg, public: StringFormatStringHandler(const CallExpr *Call, unsigned FmtArgIdx, const Expr *&UnsafeArg, ASTContext &Ctx) - : Call(Call), FmtArgIdx(FmtArgIdx), UnsafeArg(UnsafeArg), Ctx(Ctx) {} + : Call(Call), FmtArgIdx(FmtArgIdx), UnsafeArg(UnsafeArg), Ctx(Ctx), + UnsafeArgSet(false) {} bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier, @@ -912,8 +914,11 @@ static bool hasUnsafeFormatOrSArg(const CallExpr *Call, const Expr *&UnsafeArg, return true; // Handle unsafe case: UnsafeArg = Call->getArg(ArgIdx); // output + UnsafeArgSet = true; return false; // returning false stops parsing immediately } + + bool isUnsafeArgSet() { return UnsafeArgSet; } }; const Expr *Fmt = Call->getArg(FmtArgIdx); @@ -924,15 +929,17 @@ static bool hasUnsafeFormatOrSArg(const CallExpr *Call, const Expr *&UnsafeArg, StringFormatStringHandler Handler(Call, FmtArgIdx, UnsafeArg, Ctx); return analyze_format_string::ParsePrintfString( - Handler, FmtStr.begin(), FmtStr.end(), Ctx.getLangOpts(), - Ctx.getTargetInfo(), isKprintf); + Handler, FmtStr.begin(), FmtStr.end(), Ctx.getLangOpts(), + Ctx.getTargetInfo(), isKprintf) && + Handler.isUnsafeArgSet(); } if (auto FmtStr = SL->tryEvaluateString(Ctx)) { StringFormatStringHandler Handler(Call, FmtArgIdx, UnsafeArg, Ctx); return analyze_format_string::ParsePrintfString( - Handler, FmtStr->data(), FmtStr->data() + FmtStr->size(), - Ctx.getLangOpts(), Ctx.getTargetInfo(), isKprintf); + Handler, FmtStr->data(), FmtStr->data() + FmtStr->size(), + Ctx.getLangOpts(), Ctx.getTargetInfo(), isKprintf) && + Handler.isUnsafeArgSet(); } } // If format is not a string literal, we cannot analyze the format string. diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp index b23b4acd0d1c7..4f1af79609223 100644 --- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp +++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp @@ -250,3 +250,8 @@ void test(StrBuff& str) LibC.strcpy(buff); LibC.memcpy(buff, buff, 64); } + +void dontCrashForInvalidFormatString() { + snprintf((char*)0, 0, "%"); + snprintf((char*)0, 0, "\0"); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
