Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[analyzer] UnixAPIMisuseChecker Get O_CREAT from preprocessor #81855

Merged
merged 3 commits into from
Feb 20, 2024

Conversation

alejandro-alvarez-sonarsource
Copy link
Contributor

Now calling open with the O_CREAT flag and no mode parameter will raise an issue in any system that defines O_CREAT.

The value for this flag is obtained after the full source code has been parsed, leveraging checkASTDecl.
Hence, any #define or #undefine of O_CREAT following an open may alter the results. Nevertheless, since redefining reserved identifiers is UB, this is probably ok.

Now calling `open` with the `O_CREAT` flag and no mode parameter will
raise an issue in any system that defines `O_CREAT`.

The value for this flag is obtained after the full source code
has been parsed, leveraging `checkASTDecl`.
Hence, any `#define` or `#undefine` of `O_CREAT` following an
`open` may alter the results. Nevertheless, since redefining
reserved identifiers is UB, this is probably ok.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:static analyzer labels Feb 15, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Feb 15, 2024

@llvm/pr-subscribers-clang-static-analyzer-1

@llvm/pr-subscribers-clang

Author: Alejandro Álvarez Ayllón (alejandro-alvarez-sonarsource)

Changes

Now calling open with the O_CREAT flag and no mode parameter will raise an issue in any system that defines O_CREAT.

The value for this flag is obtained after the full source code has been parsed, leveraging checkASTDecl.
Hence, any #define or #undefine of O_CREAT following an open may alter the results. Nevertheless, since redefining reserved identifiers is UB, this is probably ok.


Patch is 86.15 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/81855.diff

3 Files Affected:

  • (modified) clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp (+24-18)
  • (modified) clang/test/Analysis/Inputs/expected-plists/unix-fns.c.plist (+339-339)
  • (modified) clang/test/Analysis/unix-fns.c (+2)
diff --git a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
index b05ce610067cfa..19f1ca2dc824c9 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
@@ -18,6 +18,7 @@
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
@@ -39,13 +40,18 @@ enum class OpenVariant {
 
 namespace {
 
-class UnixAPIMisuseChecker : public Checker< check::PreStmt<CallExpr> > {
+class UnixAPIMisuseChecker
+    : public Checker<check::PreStmt<CallExpr>,
+                     check::ASTDecl<TranslationUnitDecl>> {
   const BugType BT_open{this, "Improper use of 'open'", categories::UnixAPI};
   const BugType BT_pthreadOnce{this, "Improper use of 'pthread_once'",
                                categories::UnixAPI};
   mutable std::optional<uint64_t> Val_O_CREAT;
 
 public:
+  void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager &Mgr,
+                    BugReporter &BR) const;
+
   void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
 
   void CheckOpen(CheckerContext &C, const CallExpr *CE) const;
@@ -55,11 +61,8 @@ class UnixAPIMisuseChecker : public Checker< check::PreStmt<CallExpr> > {
   void CheckOpenVariant(CheckerContext &C,
                         const CallExpr *CE, OpenVariant Variant) const;
 
-  void ReportOpenBug(CheckerContext &C,
-                     ProgramStateRef State,
-                     const char *Msg,
+  void ReportOpenBug(CheckerContext &C, ProgramStateRef State, const char *Msg,
                      SourceRange SR) const;
-
 };
 
 class UnixAPIPortabilityChecker : public Checker< check::PreStmt<CallExpr> > {
@@ -90,7 +93,21 @@ class UnixAPIPortabilityChecker : public Checker< check::PreStmt<CallExpr> > {
                             const char *fn) const;
 };
 
-} //end anonymous namespace
+} // end anonymous namespace
+
+void UnixAPIMisuseChecker::checkASTDecl(const TranslationUnitDecl *TU,
+                                        AnalysisManager &Mgr,
+                                        BugReporter &) const {
+  // The definition of O_CREAT is platform specific.
+  // Try to get the macro value from the preprocessor.
+  Val_O_CREAT = tryExpandAsInteger("O_CREAT", Mgr.getPreprocessor());
+  // If we failed, fall-back to known values.
+  if (!Val_O_CREAT) {
+    if (TU->getASTContext().getTargetInfo().getTriple().getVendor() ==
+        llvm::Triple::Apple)
+      Val_O_CREAT = 0x0200;
+  }
+}
 
 //===----------------------------------------------------------------------===//
 // "open" (man 2 open)
@@ -204,19 +221,8 @@ void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext &C,
     return;
   }
 
-  // The definition of O_CREAT is platform specific.  We need a better way
-  // of querying this information from the checking environment.
   if (!Val_O_CREAT) {
-    if (C.getASTContext().getTargetInfo().getTriple().getVendor()
-                                                      == llvm::Triple::Apple)
-      Val_O_CREAT = 0x0200;
-    else {
-      // FIXME: We need a more general way of getting the O_CREAT value.
-      // We could possibly grovel through the preprocessor state, but
-      // that would require passing the Preprocessor object to the ExprEngine.
-      // See also: MallocChecker.cpp / M_ZERO.
-      return;
-    }
+    return;
   }
 
   // Now check if oflags has O_CREAT set.
diff --git a/clang/test/Analysis/Inputs/expected-plists/unix-fns.c.plist b/clang/test/Analysis/Inputs/expected-plists/unix-fns.c.plist
index 2594f3b6d097d5..d7913cbc338fd0 100644
--- a/clang/test/Analysis/Inputs/expected-plists/unix-fns.c.plist
+++ b/clang/test/Analysis/Inputs/expected-plists/unix-fns.c.plist
@@ -16,12 +16,12 @@
         <key>start</key>
          <array>
           <dict>
-           <key>line</key><integer>82</integer>
+           <key>line</key><integer>84</integer>
            <key>col</key><integer>3</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>82</integer>
+           <key>line</key><integer>84</integer>
            <key>col</key><integer>5</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -29,12 +29,12 @@
         <key>end</key>
          <array>
           <dict>
-           <key>line</key><integer>84</integer>
+           <key>line</key><integer>86</integer>
            <key>col</key><integer>3</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>84</integer>
+           <key>line</key><integer>86</integer>
            <key>col</key><integer>4</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -50,12 +50,12 @@
         <key>start</key>
          <array>
           <dict>
-           <key>line</key><integer>84</integer>
+           <key>line</key><integer>86</integer>
            <key>col</key><integer>3</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>84</integer>
+           <key>line</key><integer>86</integer>
            <key>col</key><integer>4</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -63,12 +63,12 @@
         <key>end</key>
          <array>
           <dict>
-           <key>line</key><integer>84</integer>
+           <key>line</key><integer>86</integer>
            <key>col</key><integer>7</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>84</integer>
+           <key>line</key><integer>86</integer>
            <key>col</key><integer>7</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -80,7 +80,7 @@
      <key>kind</key><string>event</string>
      <key>location</key>
      <dict>
-      <key>line</key><integer>84</integer>
+      <key>line</key><integer>86</integer>
       <key>col</key><integer>7</integer>
       <key>file</key><integer>0</integer>
      </dict>
@@ -88,12 +88,12 @@
      <array>
        <array>
         <dict>
-         <key>line</key><integer>84</integer>
+         <key>line</key><integer>86</integer>
          <key>col</key><integer>7</integer>
          <key>file</key><integer>0</integer>
         </dict>
         <dict>
-         <key>line</key><integer>84</integer>
+         <key>line</key><integer>86</integer>
          <key>col</key><integer>9</integer>
          <key>file</key><integer>0</integer>
         </dict>
@@ -113,12 +113,12 @@
         <key>start</key>
          <array>
           <dict>
-           <key>line</key><integer>84</integer>
+           <key>line</key><integer>86</integer>
            <key>col</key><integer>7</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>84</integer>
+           <key>line</key><integer>86</integer>
            <key>col</key><integer>7</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -126,12 +126,12 @@
         <key>end</key>
          <array>
           <dict>
-           <key>line</key><integer>87</integer>
+           <key>line</key><integer>89</integer>
            <key>col</key><integer>3</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>87</integer>
+           <key>line</key><integer>89</integer>
            <key>col</key><integer>4</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -147,12 +147,12 @@
         <key>start</key>
          <array>
           <dict>
-           <key>line</key><integer>87</integer>
+           <key>line</key><integer>89</integer>
            <key>col</key><integer>3</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>87</integer>
+           <key>line</key><integer>89</integer>
            <key>col</key><integer>4</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -160,12 +160,12 @@
         <key>end</key>
          <array>
           <dict>
-           <key>line</key><integer>87</integer>
+           <key>line</key><integer>89</integer>
            <key>col</key><integer>8</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>87</integer>
+           <key>line</key><integer>89</integer>
            <key>col</key><integer>11</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -177,7 +177,7 @@
      <key>kind</key><string>event</string>
      <key>location</key>
      <dict>
-      <key>line</key><integer>87</integer>
+      <key>line</key><integer>89</integer>
       <key>col</key><integer>8</integer>
       <key>file</key><integer>0</integer>
      </dict>
@@ -185,12 +185,12 @@
      <array>
        <array>
         <dict>
-         <key>line</key><integer>87</integer>
+         <key>line</key><integer>89</integer>
          <key>col</key><integer>19</integer>
          <key>file</key><integer>0</integer>
         </dict>
         <dict>
-         <key>line</key><integer>87</integer>
+         <key>line</key><integer>89</integer>
          <key>col</key><integer>25</integer>
          <key>file</key><integer>0</integer>
         </dict>
@@ -214,7 +214,7 @@
   <key>issue_hash_function_offset</key><string>6</string>
   <key>location</key>
   <dict>
-   <key>line</key><integer>87</integer>
+   <key>line</key><integer>89</integer>
    <key>col</key><integer>8</integer>
    <key>file</key><integer>0</integer>
   </dict>
@@ -222,11 +222,11 @@
   <dict>
    <key>0</key>
    <array>
-    <integer>81</integer>
-    <integer>82</integer>
     <integer>83</integer>
     <integer>84</integer>
-    <integer>87</integer>
+    <integer>85</integer>
+    <integer>86</integer>
+    <integer>89</integer>
    </array>
   </dict>
   </dict>
@@ -241,12 +241,12 @@
         <key>start</key>
          <array>
           <dict>
-           <key>line</key><integer>93</integer>
+           <key>line</key><integer>95</integer>
            <key>col</key><integer>3</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>93</integer>
+           <key>line</key><integer>95</integer>
            <key>col</key><integer>5</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -254,12 +254,12 @@
         <key>end</key>
          <array>
           <dict>
-           <key>line</key><integer>95</integer>
+           <key>line</key><integer>97</integer>
            <key>col</key><integer>3</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>95</integer>
+           <key>line</key><integer>97</integer>
            <key>col</key><integer>4</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -275,12 +275,12 @@
         <key>start</key>
          <array>
           <dict>
-           <key>line</key><integer>95</integer>
+           <key>line</key><integer>97</integer>
            <key>col</key><integer>3</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>95</integer>
+           <key>line</key><integer>97</integer>
            <key>col</key><integer>4</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -288,12 +288,12 @@
         <key>end</key>
          <array>
           <dict>
-           <key>line</key><integer>95</integer>
+           <key>line</key><integer>97</integer>
            <key>col</key><integer>7</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>95</integer>
+           <key>line</key><integer>97</integer>
            <key>col</key><integer>7</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -305,7 +305,7 @@
      <key>kind</key><string>event</string>
      <key>location</key>
      <dict>
-      <key>line</key><integer>95</integer>
+      <key>line</key><integer>97</integer>
       <key>col</key><integer>7</integer>
       <key>file</key><integer>0</integer>
      </dict>
@@ -313,12 +313,12 @@
      <array>
        <array>
         <dict>
-         <key>line</key><integer>95</integer>
+         <key>line</key><integer>97</integer>
          <key>col</key><integer>7</integer>
          <key>file</key><integer>0</integer>
         </dict>
         <dict>
-         <key>line</key><integer>95</integer>
+         <key>line</key><integer>97</integer>
          <key>col</key><integer>9</integer>
          <key>file</key><integer>0</integer>
         </dict>
@@ -338,12 +338,12 @@
         <key>start</key>
          <array>
           <dict>
-           <key>line</key><integer>95</integer>
+           <key>line</key><integer>97</integer>
            <key>col</key><integer>7</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>95</integer>
+           <key>line</key><integer>97</integer>
            <key>col</key><integer>7</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -351,12 +351,12 @@
         <key>end</key>
          <array>
           <dict>
-           <key>line</key><integer>98</integer>
+           <key>line</key><integer>100</integer>
            <key>col</key><integer>3</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>98</integer>
+           <key>line</key><integer>100</integer>
            <key>col</key><integer>4</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -372,12 +372,12 @@
         <key>start</key>
          <array>
           <dict>
-           <key>line</key><integer>98</integer>
+           <key>line</key><integer>100</integer>
            <key>col</key><integer>3</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>98</integer>
+           <key>line</key><integer>100</integer>
            <key>col</key><integer>4</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -385,12 +385,12 @@
         <key>end</key>
          <array>
           <dict>
-           <key>line</key><integer>98</integer>
+           <key>line</key><integer>100</integer>
            <key>col</key><integer>8</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>98</integer>
+           <key>line</key><integer>100</integer>
            <key>col</key><integer>13</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -402,7 +402,7 @@
      <key>kind</key><string>event</string>
      <key>location</key>
      <dict>
-      <key>line</key><integer>98</integer>
+      <key>line</key><integer>100</integer>
       <key>col</key><integer>8</integer>
       <key>file</key><integer>0</integer>
      </dict>
@@ -410,12 +410,12 @@
      <array>
        <array>
         <dict>
-         <key>line</key><integer>98</integer>
+         <key>line</key><integer>100</integer>
          <key>col</key><integer>44</integer>
          <key>file</key><integer>0</integer>
         </dict>
         <dict>
-         <key>line</key><integer>98</integer>
+         <key>line</key><integer>100</integer>
          <key>col</key><integer>50</integer>
          <key>file</key><integer>0</integer>
         </dict>
@@ -439,7 +439,7 @@
   <key>issue_hash_function_offset</key><string>6</string>
   <key>location</key>
   <dict>
-   <key>line</key><integer>98</integer>
+   <key>line</key><integer>100</integer>
    <key>col</key><integer>8</integer>
    <key>file</key><integer>0</integer>
   </dict>
@@ -447,11 +447,11 @@
   <dict>
    <key>0</key>
    <array>
-    <integer>92</integer>
-    <integer>93</integer>
     <integer>94</integer>
     <integer>95</integer>
-    <integer>98</integer>
+    <integer>96</integer>
+    <integer>97</integer>
+    <integer>100</integer>
    </array>
   </dict>
   </dict>
@@ -466,12 +466,12 @@
         <key>start</key>
          <array>
           <dict>
-           <key>line</key><integer>104</integer>
+           <key>line</key><integer>106</integer>
            <key>col</key><integer>3</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>104</integer>
+           <key>line</key><integer>106</integer>
            <key>col</key><integer>17</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -479,12 +479,12 @@
         <key>end</key>
          <array>
           <dict>
-           <key>line</key><integer>105</integer>
+           <key>line</key><integer>107</integer>
            <key>col</key><integer>8</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>105</integer>
+           <key>line</key><integer>107</integer>
            <key>col</key><integer>9</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -500,12 +500,12 @@
         <key>start</key>
          <array>
           <dict>
-           <key>line</key><integer>105</integer>
+           <key>line</key><integer>107</integer>
            <key>col</key><integer>8</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>105</integer>
+           <key>line</key><integer>107</integer>
            <key>col</key><integer>9</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -513,12 +513,12 @@
         <key>end</key>
          <array>
           <dict>
-           <key>line</key><integer>105</integer>
+           <key>line</key><integer>107</integer>
            <key>col</key><integer>52</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
-           <key>line</key><integer>105</integer>
+           <key>line</key><integer>107</integer>
            <key>col</key><integer>64</integer>
            <key>file</key><integer>0</integer>
           </dict>
@@ -530,7 +530,7 @@
      <key>kind</key><string>event</string>
      <key>location</key>
      <dict>
-      <key>line</key><integer>105</integer>
+      <key>line</key><integer>107</integer>
       <key>col</key><integer>52</integer>
       <key>file</key><integer>0</integer>
      </dict>
@@ -538,12 +538,12 @@
      <array>
        <array>
         <dict>
-         <key>line</key><integer>105</integer>
+         <key>line</key><integer>107</integer>
          <key>col</key><integer>66</integer>
          <key>file</key><integer>0</integer>
         </dict>
         <dict>
-         <key>line</key><integer>105</integer>
+         <key>line</key><integer>107</integer>
          <key>col</key><integer>72</integer>
          <key>file</key><integer>0</integer>
         </dict>
@@ -567,7 +567,7 @@
   <key>issue_hash_function_offset</key><string>2</string>
   <key>location</key>
   <dict>
-   <key>line</key><integer>105</integer>
+   <key>line</key><integer>107</integer>
    <key>col</key><integer>52</integer>
    <key>file</key><integer>0</integer>
   </dict>
@@ -575,9 +575,9 @@
   <dict>
    <key>0</key>
    <array>
-    <integer>103</integer>
-    <integer>104</integer>
     <integer>105</integer>
+    <integer>106</integer>
+    <integer>107</integer>
    </array>
   </dict>
   </dict>
@@ -592,12 +592,12 @@
         <key>start</key>
          <array>
           <dict>
-           <key>line</key><integer>115</integer>
+           <key>line</key><integer>117</integer>
            <key>col</key><integer>3</integer>
            <key>file</key><integer>0</integer>
           </dict>
           <dict>
...
[truncated]

Copy link
Collaborator

@balazske balazske left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code change looks good, but I could not verify the new test. Probably it is not tested if it works with a non-usual O_CREAT value (that is parsed by the checker).

@alejandro-alvarez-sonarsource
Copy link
Contributor Author

Thanks! I have added a new test file where the values are those of FreeRTOS

Copy link
Collaborator

@balazske balazske left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not find problems now. The failed checks looks to be different problem.

@steakhal steakhal merged commit 37c19f9 into llvm:main Feb 20, 2024
3 of 4 checks passed
@alejandro-alvarez-sonarsource alejandro-alvarez-sonarsource deleted the aa/open_o_creat branch February 21, 2024 13:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:static analyzer clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants