-
Notifications
You must be signed in to change notification settings - Fork 37.7k
contrib: Check symbols in the bitcoinconsensus
shared library
#25020
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
Conversation
Yes, very good idea, Concept ACK. |
print(f'{filename}: symbol {symbol.name} from unsupported version {version}') | ||
ok = False | ||
return ok | ||
|
||
def check_exported_symbols(binary) -> bool: | ||
ok: bool = True | ||
if binary.abstract.header.object_type == lief.OBJECT_TYPES.LIBRARY: | ||
return ok |
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 think one of the most important things to check for shared libraries is that they export the right symbols (to make sure their entire API is available), and only the right symbols (extra and re-exported symbols can cause conflicts).
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.
Yea, that is what I assumed this would be doing when I first looked. Otherwise I think the checks currently being added are ~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.
Exactly. It was the initial idea of this PR. When I faced with a crowd of exported symbols, I decided to make this PR focused on introducing a tool, and leave fighting with linker issues for follow ups.
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 think the PR should be renamed then? If it's not actually doing the thing in the PR title.
@@ -176,76 +176,76 @@ def check_version(max_versions, version, arch) -> bool: | |||
def check_imported_symbols(binary) -> bool: | |||
ok: bool = True | |||
|
|||
for symbol in binary.imported_symbols: | |||
for symbol in binary.concrete.imported_symbols: |
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.
2012abe: contrib: Always explicitly cast lief.Binary object
Why?
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 wonder, it's a bit ugly to have .concrete
everywhere.
print(f'{split[-1]} is not in ALLOWED_LIBRARIES!') | ||
for dylib in binary.concrete.libraries: | ||
library = dylib.name.split('/')[-1] | ||
if binary.abstract.header.object_type == lief.OBJECT_TYPES.LIBRARY and library == 'libbitcoinconsensus.0.dylib': |
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.
Let's not hardcode this name here. If we need to skip this, please define another constant for the list of libraries to skip.
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.
In general, I don't really like how these changes are mixing up the binary and library checks.
Speaking of checking exported symbols, I checked
Most are related to C++ standard library (like vector), it seems? I wonder if there's a way to avoid this. |
It appears, #24994 fixes it:
|
That's beautiful! |
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ReviewsSee the guideline for information on the review process.
If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update. ConflictsReviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first. |
GUIX hashes x86:
arm64:
|
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 change (going to be) dependant on #24994, or not? If so, maybe mark as a draft for now, and add that to the PR description?
Looks like there's still review comments outstanding, i.e here: https://github.com/bitcoin/bitcoin/pull/25020/files#r885641952 and here: https://github.com/bitcoin/bitcoin/pull/25020/files#r885637804.
@echo "Running symbol and dynamic library checks..." | ||
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS) | ||
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS) $(builddir)/.libs/$$(echo $(LIBBITCOINCONSENSUS) | sed "s/.la//")$(LIBEXT) |
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 a nicer way to do this? Would rather not re-introduce sed
.
@@ -117,7 +117,7 @@ def test_MACHO(self): | |||
''') | |||
|
|||
self.assertEqual(call_symbol_check(cc, source, executable, ['-lexpat', '-Wl,-platform_version','-Wl,macos', '-Wl,11.4', '-Wl,11.4']), | |||
(1, 'libexpat.1.dylib is not in ALLOWED_LIBRARIES!\n' + | |||
(1, f'{executable}: libexpat.1.dylib is not in ALLOWED_LIBRARIES!\n' + |
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 adding the executable name to every line is an improvement. It's already printed in the failure.
print(f'{split[-1]} is not in ALLOWED_LIBRARIES!') | ||
for dylib in binary.concrete.libraries: | ||
library = dylib.name.split('/')[-1] | ||
if binary.abstract.header.object_type == lief.OBJECT_TYPES.LIBRARY and library == 'libbitcoinconsensus.0.dylib': |
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.
In general, I don't really like how these changes are mixing up the binary and library checks.
print(f'{filename}: symbol {symbol.name} from unsupported version {version}') | ||
ok = False | ||
return ok | ||
|
||
def check_exported_symbols(binary) -> bool: | ||
ok: bool = True | ||
if binary.abstract.header.object_type == lief.OBJECT_TYPES.LIBRARY: | ||
return ok |
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 think the PR should be renamed then? If it's not actually doing the thing in the PR title.
Drafted. |
'KERNEL32.dll', # win32 base APIs | ||
'msvcrt.dll', # C standard library for MSVC | ||
'libssp-0.dll', # mingw-w64 stack smashing protection |
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.
NACK. This is accomodating a bug (in the DLL), and doing so in such a way, that it could leak into the actual 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.
This is accomodating a bug...
Which one?
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.
Non-static libssp.
Closing. |
In the light of a new shared library it looks reasonable to start checking shared library symbols.
During testing this PR, it was pointed that
libbitcoinconsensus.so
has "a ton of unnecessary symbols being exported". Fortunately, it could be fixed in #24994.Therefore, it makes sense to draft this PR until #24994 is merged.
Guix builds on
x86_64
: