File 1910-gh-Add-ossf-compiler-flags-scanner.patch of Package erlang
From fc9509e53c23dcad310d7230883a099aeeb7917a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lukas=20Backstr=C3=B6m?= <lukas@erlang.org>
Date: Wed, 6 Nov 2024 10:30:59 +0100
Subject: [PATCH 10/10] gh: Add ossf-compiler-flags-scanner
---
.github/scripts/ossf-sarif-generator.es | 106 ++++++++++++++++++
.../ossf-compiler-flags-scanner.yaml | 81 +++++++++++++
2 files changed, 187 insertions(+)
create mode 100755 .github/scripts/ossf-sarif-generator.es
create mode 100644 .github/workflows/ossf-compiler-flags-scanner.yaml
diff --git a/.github/scripts/ossf-sarif-generator.es b/.github/scripts/ossf-sarif-generator.es
new file mode 100755
index 0000000000..1c352e73f0
--- /dev/null
+++ b/.github/scripts/ossf-sarif-generator.es
@@ -0,0 +1,106 @@
+#!/usr/bin/env escript
+
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2024. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+
+%% This script takes a json string as argument and checks that all the compiler flags defined by the OSSF
+%% are used.
+
+main([CompilerFlagsJson]) ->
+ io:format(standard_error,"~p",[os:env()]),
+ CFLAGS = proplists:get_value(cflags, erlang:system_info(compile_info)) ++ " " ++ os:getenv("SKIPPED_OSSF_CFLAGS"),
+ LDFLAGS = proplists:get_value(ldflags, erlang:system_info(compile_info)) ++ " " ++ os:getenv("SKIPPED_OSSF_LDFLAGS"),
+ {gnuc, {Vsn, _, _} } = erlang:system_info(c_compiler_used),
+ #{ ~"options" := #{ ~"recommended" := Opts } } = json:decode(unicode:characters_to_binary(CompilerFlagsJson)),
+ io:format(standard_error, ~s'CFLAGS="~ts"~nLDFLAGS="~ts"~n',[CFLAGS, LDFLAGS]),
+ Missing = [Opt || Opt <- Opts, check_option(Opt, string:split(CFLAGS, " ", all), string:split(LDFLAGS, " ", all), Vsn)],
+ io:format("~ts~n",[sarif(Missing)]),
+ ok.
+check_option(#{ ~"requires" := #{ ~"gcc" := GccVsn }, ~"opt" := Opt }, CFLAGS, _LDFLAGS, CurrentGccVsn) ->
+ io:format(standard_error, "Looking for ~ts...",[Opt]),
+ case binary_to_integer(hd(string:split(GccVsn, "."))) > CurrentGccVsn of
+ true -> io:format(standard_error, "skipped!~n",[]), false;
+ false ->
+ check_for_flags(Opt, CFLAGS)
+ end;
+check_option(#{ ~"requires" := #{ ~"binutils" := _ }, ~"opt" := Opt }, _CFLAGS, LDFLAGS, _CurrentGccVsn) ->
+ io:format(standard_error, "Looking for ~ts...",[Opt]),
+ check_for_flags(Opt, LDFLAGS);
+check_option(#{ ~"requires" := #{ ~"libstdc++" := _ }, ~"opt" := Opt }, _CFLAGS, LDFLAGS, _CurrentGccVsn) ->
+ io:format(standard_error, "Looking for ~ts...",[Opt]),
+ check_for_flags(Opt, LDFLAGS);
+check_option(#{ ~"requires" := Tool, ~"opt" := Opt }, _CFLAGS, _LDFLAGS, _CurrentGccVsn) ->
+ io:format(standard_error, "~ts not implemented yet using ~p!~n",[Opt, Tool]),
+ true.
+
+check_for_flags(Flag, Flags) ->
+ case lists:any(fun(O) -> lists:search(fun(A) -> string:equal(string:trim(O), string:trim(A)) end, Flags) =:= false end, string:split(Flag, " ", all) ) of
+ true -> io:format(standard_error, "missing!~n",[]), true;
+ false -> io:format(standard_error, "found!~n",[]), false
+ end.
+
+sarif(Missing) ->
+ Zip = lists:zip(lists:seq(1,length(Missing)), Missing),
+ json:encode(
+ #{ ~"version" => ~"2.1.0",
+ ~"$schema" => ~"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/sarif-2.1/schema/sarif-schema-2.1.0.json",
+ ~"runs" =>
+ [ #{
+ ~"tool" =>
+ #{ ~"driver" =>
+ #{ ~"informationUri" => ~"https://github.com/erlang/otp/.github/workflow/ossf-scanner",
+ ~"name" => ~"ossf-scanner",
+ ~"rules" =>
+ [ #{ ~"id" => base64:encode(erlang:md5(Opt)),
+ ~"name" => ~"MissingCompilerFlag",
+ ~"shortDescription" =>
+ #{ ~"text" => <<"Missing CFLAGS ", Opt/binary>> },
+ ~"helpUri" => ~"https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++",
+ ~"fullDescription" =>
+ #{
+ ~"text" => <<Desc/binary,"\nA OSSF C/C++ compiler hardening flag is missing from the tests. "
+ "Please check https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++ for details.">>
+ }
+ }
+ || {_Id, #{ ~"desc" := Desc, ~"opt" := Opt }} <- Zip],
+ ~"version" => ~"1.0"
+ }
+ },
+ ~"artifacts" =>
+ [ #{
+ ~"location" => #{
+ ~"uri" => ~".github/docker/Dockerfile.64-bit"
+ },
+ ~"length" => -1
+ }
+ ],
+ ~"results" =>
+ [ #{
+ ~"ruleId" => base64:encode(erlang:md5(Opt)),
+ ~"ruleIndex" => Id,
+ ~"level" => ~"warning",
+ ~"message" => #{ ~"text" => <<"Missing CFLAGS ", Opt/binary>> },
+ ~"locations" =>
+ [ #{ ~"physicalLocation" =>
+ #{ ~"artifactLocation" =>
+ #{ ~"uri" => ~".github/docker/Dockerfile.64-bit" }
+ }
+ } ]
+ } || {Id, #{ ~"opt" := Opt }} <- Zip]
+ } ]
+ }).
\ No newline at end of file
diff --git a/.github/workflows/ossf-compiler-flags-scanner.yaml b/.github/workflows/ossf-compiler-flags-scanner.yaml
new file mode 100644
index 0000000000..655a721536
--- /dev/null
+++ b/.github/workflows/ossf-compiler-flags-scanner.yaml
@@ -0,0 +1,81 @@
+## %CopyrightBegin%
+##
+## Copyright Ericsson AB 2024. All Rights Reserved.
+##
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+##
+## %CopyrightEnd%
+
+## This workflow continually scan the master branch to make sure that
+## the correct compiler flags are used when testing Erlang/OTP on github.
+
+name: Open Source Security Foundation
+
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: 0 1 * * *
+
+permissions:
+ # Required to upload SARIF file to CodeQL.
+ # See: https://github.com/github/codeql-action/issues/2117
+ actions: read
+ # Require writing security events to upload SARIF file to security tab
+ security-events: write
+ # Only need to read contents
+ contents: read
+
+jobs:
+ schedule-scan:
+ runs-on: ubuntu-latest
+ if: github.repository == 'erlang/otp'
+ steps:
+ - uses: actions/checkout@v4.2.1
+ - name: Create initial pre-release tar
+ run: .github/scripts/init-pre-release.sh otp_src.tar.gz
+ - uses: actions/checkout@v4.2.1
+ with:
+ repository: ossf/wg-best-practices-os-developers
+ sparse-checkout: docs/Compiler-Hardening-Guides/compiler-options-scraper
+ path: ossf
+
+ - name: Setup compiler options scraper
+ run: |
+ pip3 install -r ossf/docs/Compiler-Hardening-Guides/compiler-options-scraper/requirements.txt
+ python3 ossf/docs/Compiler-Hardening-Guides/compiler-options-scraper/main.py
+ cat compiler-options.json
+
+ - uses: ./.github/actions/build-base-image
+ with:
+ BASE_BRANCH: master
+ BUILD_IMAGE: true
+
+ - name: Run compiler flag comparison
+ run: |
+ docker run -v `pwd`/.github/scripts:/github --entrypoint "" otp \
+ bash -c "/github/ossf-sarif-generator.es '$(cat compiler-options.json)'" > results.sarif
+
+ - name: "Upload artifact"
+ if: ${{ !cancelled() }}
+ uses: actions/upload-artifact@v4 # v4.4.3
+ with:
+ name: SARIF file
+ path: results.sarif
+
+ # Upload the results to GitHub's code scanning dashboard.
+ - name: "Upload to code-scanning"
+ if: ${{ !cancelled() }}
+ uses: github/codeql-action/upload-sarif@v3
+ with:
+ sarif_file: results.sarif
+
--
2.43.0