Skip to content
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

libpkg: track lib32 and Linuxulator shlibs #2387

Merged
merged 6 commits into from
Dec 21, 2024
Merged

Conversation

ifreund
Copy link
Contributor

@ifreund ifreund commented Dec 11, 2024

When scanning ELF files to generate the shlibs_provided/required lists, pkg now generates entries for lib32 and Linux compat shlibs rather than ignoring all non-native shlibs.

The following format is used for shlibs_provided/required entries:

libfoo.so.1.0.0          - native (no change to status quo)
libfoo.so.1.0.0:32       - compat 32
libfoo.so.1.0.0:Linux    - compat Linux
libfoo.so.1.0.0:Linux:32 - compat Linux 32

This is only done if targeting FreeBSD for now.

I've marked this as a draft because it depends on the unmerged #2386 and because I would like to add more tests before it is merged.

References: #2331

@ifreund ifreund marked this pull request as draft December 11, 2024 15:09
@ifreund
Copy link
Contributor Author

ifreund commented Dec 11, 2024

Note: this is not yet sufficient to fully close #2331 as lib32 and Linuxulator shlibs are not yet backed up if BACKUP_LIBRARIES is set.

@ifreund
Copy link
Contributor Author

ifreund commented Dec 11, 2024

Hmm, this PR causes the backup_lib test to fail on Debian for some reason. I will investigate tomorrow.

@ifreund
Copy link
Contributor Author

ifreund commented Dec 11, 2024

I've realized another blocker to resolve before merging this PR: We need to scan /usr/lib32 and build a list of base system-provided 32bit shlibs if pkgbase is not in use. (Just like we scan /lib and /usr/lib for native shlibs since #2386).

@ifreund
Copy link
Contributor Author

ifreund commented Dec 12, 2024

The backup_lib test is failing on Debian because pkg fails to determine that libempty.so is a linux shlib despite it being compiled for the Debian host system using the Debian toolchain. Manually examining a libempty.so produced the same way as in the test on Debian make it clear why pkg's OS detection fails, the NT_GNU_ABI_TAG style note in the ELF notes section is not present:

build@build:/tmp$ readelf -n libempty.so.1 

Displaying notes found in: .note.gnu.build-id
  Owner                Data size 	Description
  GNU                  0x00000014	NT_GNU_BUILD_ID (unique build ID bitstring)
    Build ID: d4398ec29c5fe1c5204bd739c77505f78c15c98e
build@build:/tmp$ 

Furthermore, the OS set in the elf header is very generic, so it wouldn't make sense for pkg to fall back on checking that:

build@build:/tmp$ readelf -h libempty.so.1
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          64 (bytes into file)
  Start of section headers:          13384 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         8
  Size of section headers:           64 (bytes)
  Number of section headers:         23
  Section header string table index: 22

This will also be an issue for detecting Linuxulator shlibs on FreeBSD though we don't have tests for that yet. I will investigate if there is a reliable way to detect ELF files compiled for Linux though I'm a bit worried that there is no universal solution here due to the fragmentation of the Linux ecosystem.

Sponsored by:	The FreeBSD Foundation
Sponsored by:	The FreeBSD Foundation
When scanning ELF files to generate the shlibs_provided/required lists,
pkg now generates entries for lib32 and Linux compat shlibs rather than
ignoring all non-native shlibs.

The following format is used for shlibs_provided/required entries:

libfoo.so.1.0.0          - native (no change to status quo)
libfoo.so.1.0.0:32       - compat 32
libfoo.so.1.0.0:Linux    - compat Linux
libfoo.so.1.0.0:Linux:32 - compat Linux 32

This is only done if targeting FreeBSD for now.

References:	freebsd#2331
Sponsored by:	The FreeBSD Foundation
Since pkg now tracks 32-bit compat shlib dependencies, we must take the
32-bit compat shlibs provided by the base system into account if not
targeting a pkgbase system.

Sponsored by:	The FreeBSD Foundation
If the target ABI is either Linux or FreeBSD and the target OS of
a shared library ELF file cannot be determined, assume that it is a
Linux ELF file.

It is unfortunately impossible to reliably determine whether a shared
library targets Linux.

See the new comment in pkg_elf.c for further details.

Sponsored by:	The FreeBSD Foundation
@ifreund
Copy link
Contributor Author

ifreund commented Dec 18, 2024

From my research, it seems to be impossible to reliably determine if an ELF shared library is targeting Linux.

It is possible to reliably determine that an executable targets Linux by checking DT_INTERP or NT_GNU_ABI_TAG but DT_INTERP is specifc to executables and NT_GNU_ABI_TAG is only required for executables.

The EI_OSABI value in the ELF header is not consistently set to ELFOSABI_LINUX, it usually seems to be left set to ELFOSABI_NONE aka "UNIX System V ABI."

I see 2 obvious paths we could take:

  1. Assume shared libraries for which we cannot determine an OS are Linux shlibs.
  2. Require that the user of pkg (i.e. the ports system) use brandelf(1) or similar to ensure all Linux ELF files have the necessary metadata.

I implemented option 1. in my latest commit to this branch but would be happy to take a different approach if someone has a better idea.

@ifreund ifreund marked this pull request as ready for review December 18, 2024 19:51
@bapt
Copy link
Member

bapt commented Dec 19, 2024

I don't think we can do better that implementing 1 for now.
but what I think we should do it add an option to enable/disable it for now, so we issue a release with out tracking the linux libs first and then we can make some experimental repos with the tracking activated.

If we are happy with the result, then we can enable it and remove the option to disable it.

TBH I don't know a case where 1 would be wrong.

This feature needs larger scale testing before being enabled by default
to avoid unnecessary disruption. This option is intended to be removed
in the future if/when the feature is enabled by default.

Sponsored by:	The FreeBSD Foundation
@ifreund
Copy link
Contributor Author

ifreund commented Dec 19, 2024

@bapt that seems reasonable to me, I added a TRACK_LINUX_COMPAT_SHLIBS option that defaults to FALSE.

@bapt bapt merged commit 1e333d8 into freebsd:main Dec 21, 2024
11 of 12 checks passed
@ifreund ifreund deleted the shlib-32-linux branch December 22, 2024 21:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants