Skip to content

Commit

Permalink
gh: Add ossf-compiler-flags-scanner
Browse files Browse the repository at this point in the history
  • Loading branch information
garazdawi committed Nov 7, 2024
1 parent 82af61d commit 63b7182
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 0 deletions.
88 changes: 88 additions & 0 deletions .github/scripts/ossf-sarif-generator.es
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/env escript

%% 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]
} ]
}).
63 changes: 63 additions & 0 deletions .github/workflows/ossf-compiler-flags-scanner.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
## 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/[email protected]
- name: Create initial pre-release tar
run: .github/scripts/init-pre-release.sh otp_src.tar.gz
- uses: actions/[email protected]
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

0 comments on commit 63b7182

Please sign in to comment.