]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Switch to CodeQL to detect prohibited function use
authorRichard Yao <richard.yao@alumni.stonybrook.edu>
Fri, 26 Jan 2024 22:11:33 +0000 (17:11 -0500)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 29 Jan 2024 22:53:29 +0000 (14:53 -0800)
The LLVM/Clang developers pointed out that using the CPP to detect use
of functions that our QA policies prohibit risks invoking undefined
behavior. To resolve this, we configure CodeQL to detect forbidden
function usage.

Note that cpp in the context of CodeQL refers to C/C++, rather than the
C PreProcessor, which C++ also uses. It really should have been written
cxx, but that ship sailed a long time ago. This misuse of the term cpp
is retained in the CodeQL configuration for consistency with upstream
CodeQL.

As a side benefit, verbose make no longer is a wall of text showing a
bunch of CPP macros, which can make debugging slightly easier.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Richard Yao <richard.yao@alumni.stonybrook.edu>
Closes #15819
Closes #14134

.github/codeql-cpp.yml [new file with mode: 0644]
.github/codeql-python.yml [new file with mode: 0644]
.github/codeql/custom-queries/cpp/deprecatedFunctionUsage.ql [new file with mode: 0644]
.github/codeql/custom-queries/cpp/qlpack.yml [new file with mode: 0644]
.github/workflows/codeql.yml
config/Rules.am

diff --git a/.github/codeql-cpp.yml b/.github/codeql-cpp.yml
new file mode 100644 (file)
index 0000000..88b8c60
--- /dev/null
@@ -0,0 +1,4 @@
+name: "Custom CodeQL Analysis"
+
+queries:
+  - uses: ./.github/codeql/custom-queries/cpp/deprecatedFunctionUsage.ql
diff --git a/.github/codeql-python.yml b/.github/codeql-python.yml
new file mode 100644 (file)
index 0000000..93cb4a4
--- /dev/null
@@ -0,0 +1,4 @@
+name: "Custom CodeQL Analysis"
+
+paths-ignore:
+  - tests
diff --git a/.github/codeql/custom-queries/cpp/deprecatedFunctionUsage.ql b/.github/codeql/custom-queries/cpp/deprecatedFunctionUsage.ql
new file mode 100644 (file)
index 0000000..eb4b7bd
--- /dev/null
@@ -0,0 +1,59 @@
+/**
+ * @name Deprecated function usage detection
+ * @description Detects functions whose usage is banned from the OpenZFS
+ *              codebase due to QA concerns.
+ * @kind problem
+ * @severity error
+ * @id cpp/deprecated-function-usage
+*/
+
+import cpp
+
+predicate isDeprecatedFunction(Function f) {
+  f.getName() = "strtok" or
+  f.getName() = "__xpg_basename" or
+  f.getName() = "basename" or
+  f.getName() = "dirname" or
+  f.getName() = "bcopy" or
+  f.getName() = "bcmp" or
+  f.getName() = "bzero" or
+  f.getName() = "asctime" or
+  f.getName() = "asctime_r" or
+  f.getName() = "gmtime" or
+  f.getName() = "localtime" or
+  f.getName() = "strncpy"
+
+}
+
+string getReplacementMessage(Function f) {
+  if f.getName() = "strtok" then
+    result = "Use strtok_r(3) instead!"
+  else if f.getName() = "__xpg_basename" then
+    result = "basename(3) is underspecified. Use zfs_basename() instead!"
+  else if f.getName() = "basename" then
+    result = "basename(3) is underspecified. Use zfs_basename() instead!"
+  else if f.getName() = "dirname" then
+    result = "dirname(3) is underspecified. Use zfs_dirnamelen() instead!"
+  else if f.getName() = "bcopy" then
+    result = "bcopy(3) is deprecated. Use memcpy(3)/memmove(3) instead!"
+  else if f.getName() = "bcmp" then
+    result = "bcmp(3) is deprecated. Use memcmp(3) instead!"
+  else if f.getName() = "bzero" then
+    result = "bzero(3) is deprecated. Use memset(3) instead!"
+  else if f.getName() = "asctime" then
+    result = "Use strftime(3) instead!"
+  else if f.getName() = "asctime_r" then
+    result = "Use strftime(3) instead!"
+  else if f.getName() = "gmtime" then
+    result = "gmtime(3) isn't thread-safe. Use gmtime_r(3) instead!"
+  else if f.getName() = "localtime" then
+    result = "localtime(3) isn't thread-safe. Use localtime_r(3) instead!"
+  else
+    result = "strncpy(3) is deprecated. Use strlcpy(3) instead!"
+}
+
+from FunctionCall fc, Function f
+where
+  fc.getTarget() = f and
+  isDeprecatedFunction(f)
+select fc, getReplacementMessage(f)
diff --git a/.github/codeql/custom-queries/cpp/qlpack.yml b/.github/codeql/custom-queries/cpp/qlpack.yml
new file mode 100644 (file)
index 0000000..cbe0f1c
--- /dev/null
@@ -0,0 +1,4 @@
+name: openzfs-cpp-queries
+version: 0.0.0
+libraryPathDependencies: codeql-cpp
+suites: openzfs-cpp-suite
index 037f8aca0eaa1f48b7bddb2aa40f1c385db5b7cd..7ccfc1492564005c97fcff203061312996fcbaf0 100644 (file)
@@ -29,6 +29,7 @@ jobs:
     - name: Initialize CodeQL
       uses: github/codeql-action/init@v2
       with:
+        config-file: .github/codeql-${{ matrix.language }}.yml
         languages: ${{ matrix.language }}
 
     - name: Autobuild
index 7c266964f3f3cc0864a330a22e3962373f993f43..2e463ae6083a4932e3e20550eed24d0d367bcac9 100644 (file)
@@ -42,21 +42,6 @@ AM_CPPFLAGS += $(DEBUG_CPPFLAGS)
 AM_CPPFLAGS += $(CODE_COVERAGE_CPPFLAGS)
 AM_CPPFLAGS += -DTEXT_DOMAIN=\"zfs-@ac_system_l@-user\"
 
-AM_CPPFLAGS_NOCHECK  = -D"strtok(...)=strtok(__VA_ARGS__) __attribute__((deprecated(\"Use strtok_r(3) instead!\")))"
-AM_CPPFLAGS_NOCHECK += -D"__xpg_basename(...)=__xpg_basename(__VA_ARGS__) __attribute__((deprecated(\"basename(3) is underspecified. Use zfs_basename() instead!\")))"
-AM_CPPFLAGS_NOCHECK += -D"basename(...)=basename(__VA_ARGS__) __attribute__((deprecated(\"basename(3) is underspecified. Use zfs_basename() instead!\")))"
-AM_CPPFLAGS_NOCHECK += -D"dirname(...)=dirname(__VA_ARGS__) __attribute__((deprecated(\"dirname(3) is underspecified. Use zfs_dirnamelen() instead!\")))"
-AM_CPPFLAGS_NOCHECK += -D"bcopy(...)=__attribute__((deprecated(\"bcopy(3) is deprecated. Use memcpy(3)/memmove(3) instead!\"))) bcopy(__VA_ARGS__)"
-AM_CPPFLAGS_NOCHECK += -D"bcmp(...)=__attribute__((deprecated(\"bcmp(3) is deprecated. Use memcmp(3) instead!\"))) bcmp(__VA_ARGS__)"
-AM_CPPFLAGS_NOCHECK += -D"bzero(...)=__attribute__((deprecated(\"bzero(3) is deprecated. Use memset(3) instead!\"))) bzero(__VA_ARGS__)"
-AM_CPPFLAGS_NOCHECK += -D"asctime(...)=__attribute__((deprecated(\"Use strftime(3) instead!\"))) asctime(__VA_ARGS__)"
-AM_CPPFLAGS_NOCHECK += -D"asctime_r(...)=__attribute__((deprecated(\"Use strftime(3) instead!\"))) asctime_r(__VA_ARGS__)"
-AM_CPPFLAGS_NOCHECK += -D"gmtime(...)=__attribute__((deprecated(\"gmtime(3) isn't thread-safe. Use gmtime_r(3) instead!\"))) gmtime(__VA_ARGS__)"
-AM_CPPFLAGS_NOCHECK += -D"localtime(...)=__attribute__((deprecated(\"localtime(3) isn't thread-safe. Use localtime_r(3) instead!\"))) localtime(__VA_ARGS__)"
-AM_CPPFLAGS_NOCHECK += -D"strncpy(...)=__attribute__((deprecated(\"strncpy(3) is deprecated. Use strlcpy(3) instead!\"))) strncpy(__VA_ARGS__)"
-
-AM_CPPFLAGS += $(AM_CPPFLAGS_NOCHECK)
-
 if ASAN_ENABLED
 AM_CPPFLAGS += -DZFS_ASAN_ENABLED
 endif