-
Notifications
You must be signed in to change notification settings - Fork 136
Integrating LIEF parser for SHARED builds #2534
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
Integrating LIEF parser for SHARED builds #2534
Conversation
- Add LIEF version 0.13.0 as git submodule - Configure CMake to build LIEF from source - Update inject_hash implementation to use LIEF - Remove pre-built LIEF binaries - Add initial C++ implementation and tests This change improves portability and maintainability by using LIEF as a submodule instead of pre-built binaries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
@@ -0,0 +1,37 @@ | |||
#include <LIEF/LIEF.hpp> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: 'LIEF/LIEF.hpp' file not found [clang-diagnostic-error]
#include <LIEF/LIEF.hpp>
^
- Add GitHub Actions workflow for Ubuntu and macOS - Add test script with detailed logging - Handle OS-specific library names - Add environment verification - Disable fail-fast to test both environments
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## inject-hash-cpp-experiment #2534 +/- ##
==============================================================
- Coverage 78.90% 78.76% -0.14%
==============================================================
Files 640 642 +2
Lines 109766 110242 +476
Branches 15526 15603 +77
==============================================================
+ Hits 86612 86834 +222
- Misses 22457 22711 +254
Partials 697 697 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
- Adds flag to fetch C/C++ libraries
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this file used right now? I understand that it might come up in later implementations, but we can leave until then to pull this in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed it!
tests/ci/run_inject_hash_cpp.sh
Outdated
# Test inject_hash_cpp basic functionality | ||
echo "Testing inject_hash_cpp basic functionality..." | ||
./util/fipstools/inject_hash_cpp/inject_hash_cpp --version || echo "Version check failed" | ||
./util/fipstools/inject_hash_cpp/inject_hash_cpp --help || echo "Help check failed" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't seem to be used, could we remove this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed it!
CMakeLists.txt
Outdated
@@ -1,5 +1,31 @@ | |||
cmake_minimum_required(VERSION 3.5..3.31) | |||
|
|||
|
|||
#################### |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment/text here is redundant.
tests/ci/run_inject_hash_cpp.sh
Outdated
echo "Building full project..." | ||
ninja | ||
|
||
# Test actual FIPS injection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant comment here as well.
tests/ci/run_inject_hash_cpp.sh
Outdated
-DCMAKE_BUILD_TYPE=RelWithDebInfo \ | ||
-DFIPS=1 \ | ||
-DFIPS_SHARED=1 \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also be testing the shared build with ubuntu. And we should use -DCMAKE_BUILD_TYPE=Release
since that's what we validate for FIPS :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static *
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tried handling static files, which require creating an archive file parser (left it for some other PR)
tests/ci/run_inject_hash_cpp.sh
Outdated
|
||
# First try to build just inject_hash_cpp | ||
echo "Building inject_hash_cpp..." | ||
ninja inject_hash_cpp |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think inject_hash_cpp
is necessarily used here. Calling ninja
with the build flags you've set up should be sufficient enough.
We could also probably drop the ninja
call on L49 below in favor of this line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
std::cout << "\nReceived arguments:" << std::endl; | ||
for (int i = 1; i < argc; i++) { | ||
std::cout << " Arg " << i << ": " << argv[i] << std::endl; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably useful for debugging, but we should drop it since we don't want debugging prints in most production code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the inject_hash.cpp currently is just a test file, added some test functionalities and std:cout to see if the file was actually called.
tests/ci/run_inject_hash_cpp.sh
Outdated
# Test actual FIPS injection | ||
echo "Testing FIPS injection..." | ||
if [[ "$OSTYPE" == "darwin"* ]]; then | ||
./util/fipstools/inject_hash_cpp/inject_hash_cpp -o ./crypto/libcrypto.dylib -in-object ./crypto/libcrypto.dylib -apple |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-o ./crypto/libcrypto.dylib
and -apple
don't seem to actually be used here. Same for below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Modified according to the CMake compiler flags
for (int i = 1; i < argc - 1; i++) { | ||
if (strcmp(argv[i], "-in-object") == 0) { | ||
binary_path = argv[i + 1]; | ||
break; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's probably a more graceful way to handle this. Could you look into pulling in the argument parsing functions in tool/internal.h
?
ParseKeyValueArguments
should help you parse what you need in a cleaner and more easily extendable fashion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just kept this for testing purpose. will keep this in mind while making the final file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
} | ||
std::vector<uint8_t> calculate_hash(HMAC_size(&ctx)); | ||
|
||
unsigned int calculate_hash_len; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: variable 'calculate_hash_len' is not initialized [cppcoreguidelines-init-variables]
unsigned int calculate_hash_len; | |
unsigned int calculate_hash_len = 0; |
a29cda3
to
a11e97a
Compare
tests/ci/run_inject_hash_cpp.sh
Outdated
mkdir -p build | ||
cd build | ||
|
||
# Configure based on build type and OS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing is actually building aws-lc, this is only running CMake to configure the build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missed adding the ninja command.
tests/ci/run_inject_hash_cpp.sh
Outdated
cmake -GNinja \ | ||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \ | ||
-DFIPS=1 \ | ||
-DFIPS_SHARED=1 \ | ||
-DBUILD_SHARED_LIBS=1 \ | ||
-DUSE_CPP_INJECT_HASH=ON \ | ||
-DCMAKE_OSX_SYSROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk \ | ||
.. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are existing helper functions defined in common_posix_setup.sh
to help simplify this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
included in the recent commit.
set_target_properties(inject_hash_cpp PROPERTIES | ||
CXX_STANDARD 17 | ||
CXX_STANDARD_REQUIRED ON | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why 17?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had kept it since LIEF requires this version of C++. However, we don't have to bother about the version while building aws-lc, hence deleted the properties from CMake.
chmod +x tests/ci/run_inject_hash_cpp.sh | ||
./tests/ci/run_inject_hash_cpp.sh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not check the bash script in with the correct file permissions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
…or inject_hash.cpp and made .sh locally executable
9f4fa5d
to
62d0cb0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
|
||
if (is_archive) { | ||
// Create temporary directory | ||
std::string temp_dir = std::filesystem::temp_directory_path().string() + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: variable 'temp_dir' is not initialized [cppcoreguidelines-init-variables]
std::string temp_dir = std::filesystem::temp_directory_path().string() + | |
y = 0 |
} | ||
|
||
// There should be only one object file | ||
std::string object_file; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: variable 'object_file' is not initialized [cppcoreguidelines-init-variables]
util/fipstools/inject_hash_cpp/inject_hash.cpp:57:
- le;
+ le = 0;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
} | ||
|
||
// Find extracted file | ||
std::string extracted_file; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: variable 'extracted_file' is not initialized [cppcoreguidelines-init-variables]
util/fipstools/inject_hash_cpp/inject_hash.cpp:62:
- le;
+ le = 0;
381be2b
to
62d0cb0
Compare
Keywords to look for verify that everything is building correctly: |
crypto/fipsmodule/CMakeLists.txt
Outdated
DEPENDS bcm_hashunset inject_hash | ||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} | ||
) | ||
#ignoring static builds for now |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be helpful to document the reason in the comments, but we can do that in the next PR.
CMakeLists.txt
Outdated
# Configure LIEF build options first | ||
set(LIEF_PYTHON_API OFF CACHE BOOL "") | ||
set(LIEF_EXAMPLES OFF CACHE BOOL "") | ||
set(LIEF_TESTS OFF CACHE BOOL "") | ||
set(LIEF_DOC OFF CACHE BOOL "") | ||
set(LIEF_INSTALL ON CACHE BOOL "") | ||
set(LIEF_STATIC ON CACHE BOOL "") | ||
set(LIEF_ELF ON CACHE BOOL "Enable ELF format") | ||
set(LIEF_PE ON CACHE BOOL "Enable PE format") | ||
set(LIEF_MACHO ON CACHE BOOL "Enable MACHO format") | ||
set(LIEF_DEX OFF CACHE BOOL "Disable DEX format") | ||
set(LIEF_VDEX OFF CACHE BOOL "Disable VDEX format") | ||
set(LIEF_ART OFF CACHE BOOL "Disable ART format") | ||
set(LIEF_OAT OFF CACHE BOOL "Disable OAT format") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is much more useful if your comment explains what these options are and why you chose these specific values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check LIEF_BUILD_OPTIONS at : https://lief.re/doc/latest/installation.html#cmake-integration
CMakeLists.txt
Outdated
# Add LIEF subdirectory | ||
add_subdirectory(third_party/lief) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not necessary to comment every line, especially when they are self explanatory like this.
# Add LIEF subdirectory | |
add_subdirectory(third_party/lief) | |
add_subdirectory(third_party/lief) |
CMakeLists.txt
Outdated
# Make LIEF headers available | ||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/third_party/lief/include) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes the LIEF headers available to every target, can you scope this down to just the inject hash tool?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LIEF headers are scoped to inject_hash_cpp using the util/fipstools/inject_hash_cpp/CMakeLists.txt. I added it in the global CMake, to make the LIEF available throughout, but it surely can be removed and it is better directed in it's desired scope.
crypto/CMakeLists.txt
Outdated
if(USE_CPP_INJECT_HASH) | ||
# Add dependency on C++ implementation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation looks off for the if and else block, more superfluous comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
amdended!
crypto/CMakeLists.txt
Outdated
COMMAND ${CMAKE_BINARY_DIR}/util/fipstools/inject_hash_cpp/inject_hash_cpp | ||
-o $<TARGET_FILE:crypto> | ||
-in-object $<TARGET_FILE:crypto> | ||
${INJECT_HASH_APPLE_FLAG} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are you using this flag for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these flags currently aren't of much usage, but was trying maintain similarity with the flag format used by the inject_hash.go script. Currently these flags are just printed as a part of testing the integration of the C++ script, however while creating a proper parsing and hashing script, these flags would be required to have the input path of the binary, output path and if it is suited for apple or linux.
tests/ci/run_inject_hash_cpp.sh
Outdated
|
||
# Test actual FIPS injection | ||
echo "TESTING INJECT_HASH.CPP WITH EDGE CASES..." | ||
./util/fipstools/inject_hash_cpp/inject_hash_cpp || echo "--Expected failure with no args--" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this fail the build if this isn't an error? Also I prefer moving more of this test logic into actual test files like our tools.
tests/ci/run_inject_hash_cpp.sh
Outdated
# Test with actual library | ||
if [[ "$OSTYPE" == "darwin"* ]]; then | ||
./util/fipstools/inject_hash_cpp/inject_hash_cpp \ | ||
-o ./crypto/libcrypto.dylib \ | ||
-in-object ./crypto/libcrypto.dylib \ | ||
-apple | ||
else | ||
./util/fipstools/inject_hash_cpp/inject_hash_cpp \ | ||
-o ./crypto/libcrypto.so \ | ||
-in-object ./crypto/libcrypto.so | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this run (with the correct paths) automatically during the normal FIPS build?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was added to the test script just to show contrast between "expected failure" cases and a normal case.
|
||
// Validate arguments | ||
if (!input_file || !output_file) { | ||
std::cerr << "❌ Missing required arguments" << std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is more helpful to say which ones are missing to help future customers/developers debug the issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
modified.
else if (strcmp(argv[i], "-apple") == 0) { | ||
is_apple = true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to handle Apple in a special way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesen't serve any purpose right now, was just setting foundations for the future builds.
// Parse command line arguments | ||
const char* input_file = nullptr; | ||
const char* output_file = nullptr; | ||
bool is_apple = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to re-use any of our existing argument parsing from our tools?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also brought this up in #2534 (comment). The answer seemed to imply that this would part of a larger future refactor/PR?
…s and removing redundant compilation flags
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
} | ||
|
||
// Get the input and output file paths | ||
std::string input_file, output_file; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: variable 'input_file' is not initialized [cppcoreguidelines-init-variables]
std::string input_file, output_file; | |
s = 0 |
} | ||
|
||
// Get the input and output file paths | ||
std::string input_file, output_file; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: variable 'output_file' is not initialized [cppcoreguidelines-init-variables]
util/fipstools/inject_hash_cpp/inject_hash.cpp:38:
- ;
+ = 0;
CMakeLists.txt
Outdated
# enabling installation of LIEF | ||
set(LIEF_INSTALL ON CACHE BOOL "") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to install LIEF?
crypto/CMakeLists.txt
Outdated
# Add dependency on C++ implementation | ||
add_dependencies(crypto inject_hash_cpp) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think this needs a comment?
crypto/fipsmodule/CMakeLists.txt
Outdated
|
||
#ignoring static builds for now as archive files require a seperate parser to extract .o files from it. The lief parser does not support archive files. | ||
go_executable(inject_hash | ||
boringssl.googlesource.com/boringssl/util/fipstools/inject_hash) | ||
add_custom_command( | ||
OUTPUT bcm.o | ||
COMMAND ./inject_hash -o bcm.o -in-archive $<TARGET_FILE:bcm_hashunset> | ||
DEPENDS bcm_hashunset inject_hash | ||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} | ||
) | ||
# endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Besides the comment did anything change here? If not we shouldn't change any of the whitespace because it makes tracking actual changes in git history harder.
tests/ci/run_inject_hash_cpp.sh
Outdated
if [[ "$OSTYPE" == "darwin"* ]]; then | ||
# macOS only supports shared builds | ||
run_build \ | ||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \ | ||
-DFIPS=1 \ | ||
-DBUILD_SHARED_LIBS=1 \ | ||
-DUSE_CPP_INJECT_HASH=ON | ||
else | ||
run_build \ | ||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \ | ||
-DFIPS=1 \ | ||
-DBUILD_SHARED_LIBS=1 \ | ||
-DUSE_CPP_INJECT_HASH=ON | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any difference between the if and else block?
a23de3c
into
aws:inject-hash-cpp-experiment
Title: Add CI workflow for C++ inject_hash implementation
Description:
This PR adds CI workflow and testing infrastructure for the C++ inject_hash implementation.
Changes:
Testing: