diff options
70 files changed, 3824 insertions, 2224 deletions
diff --git a/.depend b/.depend deleted file mode 100644 index 5371c1c..0000000 --- a/.depend +++ /dev/null @@ -1,5 +0,0 @@ -scanelf.o: scanelf.c paxinc.h porting.h elf.h paxelf.h -pspax.o: pspax.c paxinc.h porting.h elf.h paxelf.h -dumpelf.o: dumpelf.c paxinc.h porting.h elf.h paxelf.h -paxelf.o: paxelf.c paxinc.h porting.h elf.h paxelf.h -paxinc.o: paxinc.c paxinc.h porting.h elf.h paxelf.h diff --git a/.github/workflows/build-test-ci.yml b/.github/workflows/build-test-ci.yml new file mode 100644 index 0000000..e4e5857 --- /dev/null +++ b/.github/workflows/build-test-ci.yml @@ -0,0 +1,80 @@ +# GitHub actions workflow. +# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions + +name: Build+Test CI + +on: [pull_request, push] + +jobs: + make: + strategy: + matrix: + os: [ubuntu-latest] + cc: [gcc, clang] + bb: [meson, muon] + sanitizer: [none, address, undefined] + fail-fast: false + runs-on: ${{ matrix.os }} + env: + CC: ${{ matrix.cc }} + BB: ${{ matrix.bb }} + SANITIZER: ${{ matrix.sanitizer }} + steps: + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y python3-pyelftools python3-pip \ + libcap-dev libseccomp-dev ninja-build \ + pkg-config + case "$BB" in + meson) + sudo pip3 install meson + ;; + muon) + wget https://muon.build/releases/edge/muon-edge-amd64-linux-static -O muon + chmod +x muon + sudo install -Dm755 muon /usr/local/bin/muon + ;; + esac + - uses: actions/checkout@v4 + - run: | + export PKG_CONFIG_PATH="/usr/lib/$(uname -m)-linux-gnu/pkgconfig/" + case "$BB" in + muon) + alias ninja="muon samu" + ;; + esac + + "$BB" setup -Duse_libcap=enabled \ + -Duse_seccomp=true \ + -Dbuild_manpages=disabled \ + -Dtests=true \ + -Duse_fuzzing=true \ + -Db_sanitize="${SANITIZER}" \ + build + ninja -C build + ( cd build && "$BB" test -v ; ) + + build-macos: + strategy: + matrix: + os: [macos-latest] + cc: [clang] + runs-on: ${{ matrix.os }} + env: + CC: ${{ matrix.cc }} + steps: + - name: Install dependencies + run: brew install meson ninja + - uses: actions/checkout@v4 + - run: | + meson -Duse_libcap=disabled \ + -Duse_seccomp=false \ + -Dbuild_manpages=disabled \ + -Dtests=true \ + -Duse_fuzzing=false \ + build + ninja -C build + # The unittests generally assume a Linux ELF host, so don't bother making + # sure they pass on macOS. Run them out of morbid curiosity I guess. + ninja -kC build test ||: diff --git a/.github/workflows/ci-alpine-linux.yml b/.github/workflows/ci-alpine-linux.yml new file mode 100644 index 0000000..575e959 --- /dev/null +++ b/.github/workflows/ci-alpine-linux.yml @@ -0,0 +1,34 @@ +name: ci_alpine_linux + +on: [push, pull_request] + +jobs: + + alpine: + name: Alpine Linux + runs-on: ubuntu-latest + container: alpine:latest + strategy: + fail-fast: false + matrix: + compiler: + - gcc + - clang + env: + CC: ${{ matrix.compiler }} + steps: + - run: >- + apk --no-cache add \ + build-base \ + clang \ + meson \ + pkgconf \ + py3-elftools \ + libcap \ + libcap-dev \ + libseccomp \ + libseccomp-dev + - uses: actions/checkout@v4 + - run: meson setup -Dtests=false -Duse_fuzzing=false builddir/ + - run: meson compile -C builddir + - run: meson test --verbose -C builddir diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml new file mode 100644 index 0000000..605d2bb --- /dev/null +++ b/.github/workflows/codespell.yml @@ -0,0 +1,13 @@ +# GitHub actions workflow. +# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions + +name: Codespell + +on: [push, pull_request] + +jobs: + codespell: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: codespell-project/actions-codespell@v2 diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml new file mode 100644 index 0000000..1cd6c55 --- /dev/null +++ b/.github/workflows/coverity.yml @@ -0,0 +1,19 @@ +# GitHub actions workflow. +# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions + +# https://scan.coverity.com/projects/gentoo-pax-utils +name: Coverity Scan + +on: + push: + branches: [master] + +jobs: + coverity: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: vapier/coverity-scan-action@v1 + with: + email: vapier@gentoo.org + token: ${{ secrets.COVERITY_SCAN_TOKEN }} diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml new file mode 100644 index 0000000..7b7dcaf --- /dev/null +++ b/.github/workflows/python.yml @@ -0,0 +1,28 @@ +# GitHub actions workflow. +# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions + +name: Python + +on: [push, pull_request] + +jobs: + python: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + # NB: v1.4.0 covers Python 3.8. + - uses: ricardochaves/python-lint@v1.4.0 + with: + python-root-list: lddtree.py pylint + use-pylint: true + use-pycodestyle: false + use-flake8: false + use-black: true + use-mypy: true + use-isort: true + extra-pylint-options: "" + extra-pycodestyle-options: "" + extra-flake8-options: "" + extra-black-options: "" + extra-mypy-options: "" + extra-isort-options: "" @@ -20,25 +20,30 @@ core .gdb_history .gdbinit -aclocal.m4 -autom4te.cache -build -config.cache -config.h -config.h.in -config.log -config.status -configure -autotools -libtool -Makefile.in -stamp-h1 +/aclocal.m4 +/autom4te.cache +/autotools +/build +/config.cache +/config.h +/config.h.in +/config.log +/config.status +/configure +/INSTALL +/libtool +/Makefile.in +/stamp-h1 /dumpelf /lddtree +/paxelf +/paxldso +/paxmacho /pspax /scanelf /scanmacho +/seccomp-bpf /symtree /man/*.1 diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index b58abfa..0000000 --- a/.pylintrc +++ /dev/null @@ -1,34 +0,0 @@ -[MESSAGES CONTROL] -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifier separated by comma (,) or put this option -# multiple times (only on the command line, not in the configuration file where -# it should appear only once). -disable= - too-many-lines, - too-many-branches, - too-many-statements, - too-few-public-methods, - too-many-instance-attributes, - too-many-public-methods, - too-many-locals, - too-many-arguments, - locally-enabled, - locally-disabled, - fixme, - invalid-name, - -[REPORTS] -reports=no - -[FORMAT] -max-line-length=80 -indent-string=' ' - -[SIMILARITIES] -min-similarity-lines=20 - -[VARIABLES] -dummy-variables-rgx=_ - -[DESIGN] -max-parents=10 diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f8b90cf..0000000 --- a/.travis.yml +++ /dev/null @@ -1,33 +0,0 @@ -# Travis build integration. -# https://docs.travis-ci.com/ - -language: c -# Order here matters for implicit matrix generation and coverity scan. -# See travis/main.sh for details. -compiler: - - gcc - - clang - -sudo: false - -# Order here matters; see compiler comment above. -os: - - linux - - osx - -# Travis currently uses Ubuntu 12.04 (Precise) which is too old: it does -# not include pyelftools. Disable until they update. -env: - global: - - USE_PYTHON=no - - secure: "ePjz/xsdTlf0lhdZtANITiAk2lBAA9wwzB5PK/9aR5i1eBfjgXQgIJLY1y7Lqa4WU8TnSF2mwzd0pYgb320lQMC5rP7aEMAqxVZeG9WmFjet2G5vQ48tDhEJzzDhOpfvQyPehiWqLL6RUhNjE8+kpdK74P7oUFJVIuoQkUn2EuW9eUD9hV6z6tS60C0F4COdE/6DPnBySmqvjm9r9Sdfz1flCI2FXoV7MrrqrwLIx3OMtHmqmM9vGF1d2rGXRADVEGL+ldx9KvdfTLddXhWkCuHZil9YMvQLu0+gTK/g3V02Gh1/xrKmTa6v2RDqimCYDGKdHn0An+tQShYqk2JqJfzvPeysGS8lWfQePaEnHnf6niQN6h4078Ru5jH3D6AFjInrdPEOS3UZsbrJ//7hhUdiHONeQZcVcCVk7bvaJoanjjI9hJaPQXc72u81uyjlXaTOEj/znOAV92WyTaR62cT5r0GR+R7Jp214YR1IyAIB63zQVw2QCNi6W2HpyUEo3d2fOdJdaPwPQL52GxD/i3h4uGh1orYdRL4s/tdqwvYHklE2AGrEAboq2pIkmVirWH9+3+vRTnZ+fyoXD6dqDa0QvkN0pxEwmFy0IvbvTUA+0k6iplDVY21hqoid2OUpus+LjdXT2QALsY9OfMvMPdUaoFSTzWFm1jwZBPqlZN0=" - -# Note: OS X deps are maintained in .travis.sh until Travis supports it here. -addons: - apt: - packages: - - autoconf-archive - - gnulib - - xmlto - -script: ./travis/main.sh @@ -14,5 +14,5 @@ REPORTING BUGS -------------- e-mail us: -solar@gentoo.org vapier@gentoo.org +toolchain@gentoo.org diff --git a/Makefile b/Makefile deleted file mode 100644 index c906311..0000000 --- a/Makefile +++ /dev/null @@ -1,190 +0,0 @@ -# Copyright 2003-2006 Ned Ludd <solar@linbsd.net> -# Distributed under the terms of the GNU General Public License v2 -#################################################################### - -check_compiler = \ - $(shell if $(CC) $(WUNKNOWN) $(1) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \ - then echo "$(1)"; else echo "$(2)"; fi) -check_compiler_many = $(foreach flag,$(1),$(call check_compiler,$(flag))) - -#################################################################### -# Avoid CC overhead when installing -ifneq ($(MAKECMDGOALS),install) -WUNKNOWN := $(call check_compiler,-Werror=unknown-warning-option) -_WFLAGS := \ - -Wdeclaration-after-statement \ - -Wextra \ - -Wsequence-point \ - -Wstrict-overflow \ - -Wmisleading-indentation -WFLAGS := -Wall -Wunused -Wimplicit -Wshadow -Wformat=2 \ - -Wmissing-declarations -Wmissing-prototypes -Wwrite-strings \ - -Wbad-function-cast -Wnested-externs -Wcomment -Winline \ - -Wchar-subscripts -Wcast-align -Wno-format-nonliteral \ - $(call check_compiler_many,$(_WFLAGS)) -endif - -CFLAGS ?= -O2 -pipe -override CPPFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -LDFLAGS += -LIBS := -DESTDIR = -PREFIX = $(DESTDIR)/usr -DATADIR = $(PREFIX)/share -MANDIR = $(DATADIR)/man -DOCDIR = $(DATADIR)/doc -PKGDOCDIR = $(DOCDIR)/pax-utils -STRIP := strip -MKDIR := mkdir -p -INS_EXE := install -m755 -INS_DATA := install -m644 - -PKG_CONFIG ?= pkg-config - -ifeq ($(USE_CAP),yes) -LIBCAPS_CFLAGS := $(shell $(PKG_CONFIG) --cflags libcap) -LIBCAPS_LIBS := $(shell $(PKG_CONFIG) --libs libcap) -CPPFLAGS-pspax.c += $(LIBCAPS_CFLAGS) -DWANT_SYSCAP -LIBS-pspax += $(LIBCAPS_LIBS) -endif - -ifeq ($(USE_DEBUG),yes) -override CPPFLAGS += -DEBUG -endif - -ifeq ($(USE_SECCOMP),yes) -LIBSECCOMP_CFLAGS := $(shell $(PKG_CONFIG) --cflags libseccomp) -LIBSECCOMP_LIBS := $(shell $(PKG_CONFIG) --libs libseccomp) -override CPPFLAGS += $(LIBSECCOMP_CFLAGS) -DWANT_SECCOMP -LIBS += $(LIBSECCOMP_LIBS) -endif - -ifdef PV -override CPPFLAGS += -DVERSION=\"$(PV)\" -else -VCSID := $(shell git describe --tags HEAD) -endif -override CPPFLAGS += -DVCSID='"$(VCSID)"' - -#################################################################### -ELF_TARGETS = scanelf dumpelf $(shell echo | $(CC) -dM -E - | grep -q __svr4__ || echo pspax) -ELF_OBJS = paxelf.o paxldso.o -MACH_TARGETS = scanmacho -MACH_OBJS = paxmacho.o -COMMON_OBJS = paxinc.o security.o xfuncs.o -TARGETS = $(ELF_TARGETS) $(MACH_TARGETS) -SCRIPTS_SH = lddtree symtree -SCRIPTS_PY = lddtree -OBJS = $(ELF_OBJS) $(MACH_OBJS) $(COMMON_OBJS) $(TARGETS:%=%.o) -MPAGES = $(TARGETS:%=man/%.1) -SOURCES = $(OBJS:%.o=%.c) - -all: $(OBJS) $(TARGETS) - @: - -DEBUG_FLAGS = \ - -nopie \ - -fsanitize=address \ - -fsanitize=leak \ - -fsanitize=undefined -debug: clean - $(MAKE) CFLAGS="$(CFLAGS) -g3 -ggdb $(call check_compiler_many,$(DEBUG_FLAGS))" all - @-chpax -permsx $(ELF_TARGETS) - @-paxctl -permsx $(ELF_TARGETS) - -analyze: clean - scan-build $(MAKE) all - -fuzz: clean - $(MAKE) AFL_HARDEN=1 CC=afl-gcc all - @rm -rf findings - @printf '\nNow run:\n%s\n' \ - "afl-fuzz -t 100 -i tests/fuzz/small/ -o findings/ ./scanelf -s '*' -axetrnibSDIYZB @@" - -compile.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(CPPFLAGS-$<) -o $@ -c $< - -ifeq ($(V),) -Q := @ -else -Q := -endif -%.o: %.c -ifeq ($(V),) - @echo $(compile.c) -endif - $(Q)$(compile.c) $(WFLAGS) - -$(ELF_TARGETS): %: $(ELF_OBJS) $(COMMON_OBJS) %.o - $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LIBS) $(LIBS-$@) - -$(MACH_TARGETS): %: $(MACH_OBJS) $(COMMON_OBJS) %.o - $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LIBS) $(LIBS-$@) - -%.so: %.c - $(CC) -shared -fPIC -o $@ $< - -depend: - $(CC) $(CFLAGS) -MM $(SOURCES) > .depend - -clean: - -rm -f $(OBJS) $(TARGETS) - -distclean: clean - -rm -f *~ core *.o - -cd man && $(MAKE) clean -strip: all - $(STRIP) $(TARGETS) -strip-more: - $(STRIP) --strip-unneeded $(TARGETS) - -install: all - $(MKDIR) $(PREFIX)/bin/ $(MANDIR)/man1/ $(PKGDOCDIR)/ - for sh in $(SCRIPTS_SH) ; do $(INS_EXE) $$sh.sh $(PREFIX)/bin/$$sh || exit $$? ; done -ifneq ($(USE_PYTHON),no) - for py in $(SCRIPTS_PY) ; do $(INS_EXE) $$py.py $(PREFIX)/bin/$$py || exit $$? ; done -endif - $(INS_EXE) $(TARGETS) $(PREFIX)/bin/ - $(INS_DATA) README.md BUGS TODO $(PKGDOCDIR)/ - $(INS_DATA) $(MPAGES) $(MANDIR)/man1/ - -PN = pax-utils -P = $(PN)-$(PV) -dist: - ./make-tarball.sh $(DISTCHECK) $(PV) -distcheck: - $(MAKE) dist DISTCHECK=--check - --include .depend - -check test: - $(MAKE) -C tests - -.PHONY: all check clean dist install test - -# -# All logic related to autotools is below here -# -GEN_MARK_START = \# @@@ GEN START @@@ \# -GEN_MARK_END = \# @@@ GEN END @@@ \# -EXTRA_DIST = $(shell git ls-files | grep -v ^travis/) -autotools-update: - $(MAKE) -C man -j - sed -i.tmp '/^$(GEN_MARK_START)$$/,/^$(GEN_MARK_END)$$/d' Makefile.am - @rm -f Makefile.am.tmp - ( \ - echo "$(GEN_MARK_START)"; \ - printf 'dist_man_MANS +='; \ - printf ' \\\n\t%s' `printf '%s\n' man/*.1 | LC_ALL=C sort`; \ - echo; \ - printf 'EXTRA_DIST +='; \ - printf ' \\\n\t%s' $(EXTRA_DIST); \ - echo; \ - echo "$(GEN_MARK_END)"; \ - ) >> Makefile.am -autotools: -ifeq ($(SKIP_AUTOTOOLS_UPDATE),) - $(MAKE) autotools-update -endif - ./autogen.sh --from=make - -.PHONY: autotools autotools-update _autotools-update diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 79e5ed1..0000000 --- a/Makefile.am +++ /dev/null @@ -1,111 +0,0 @@ -ACLOCAL_AMFLAGS = -I autotools/m4 - -SUBDIRS = autotools/gnulib - -AM_CPPFLAGS = \ - -I$(top_builddir)/autotools/gnulib \ - -I$(top_srcdir)/autotools/gnulib - -noinst_LTLIBRARIES = libpaxutils.la -libpaxutils_la_LDFLAGS = -no-undefined -libpaxutils_la_SOURCES = \ - paxelf.c \ - paxinc.c \ - paxldso.c \ - paxmacho.c \ - security.c \ - xfuncs.c -LDADD = libpaxutils.la $(top_builddir)/autotools/gnulib/libgnu.a $(LIB_EACCESS) - -bin_SCRIPTS = lddtree symtree -bin_PROGRAMS = scanelf dumpelf pspax scanmacho -CLEANFILES = $(bin_SCRIPTS) - -if USE_PYTHON -lddtree: lddtree.py -else -lddtree: lddtree.sh -endif - cp $< $@ - -symtree: symtree.sh - cp $< $@ - -TMAKE = \ - $(MAKE) -C $(abs_top_srcdir)/tests \ - AUTOTOOLS=true \ - abs_top_builddir="$(abs_top_builddir)" \ - abs_top_srcdir="$(abs_top_srcdir)" -check-hook: - $(TMAKE) check -check: check-hook - -# Start off with base values which we append below -dist_man_MANS = -EXTRA_DIST = autotools/m4/gnulib-cache.m4 - -# @@@ GEN START @@@ # -dist_man_MANS += \ - man/dumpelf.1 \ - man/pspax.1 \ - man/scanelf.1 \ - man/scanmacho.1 -EXTRA_DIST += \ - .depend \ - .gitignore \ - .travis.yml \ - BUGS \ - COPYING \ - Makefile \ - Makefile.am \ - README.md \ - TODO \ - autogen.sh \ - configure.ac \ - dumpelf.c \ - elf.h \ - lddtree.py \ - lddtree.sh \ - macho.h \ - make-tarball.sh \ - man/Makefile \ - man/custom.xsl \ - man/dumpelf.docbook \ - man/fragment/date \ - man/fragment/reftail \ - man/fragment/version \ - man/pax-utils.docbook \ - man/pspax.docbook \ - man/scanelf.docbook \ - man/scanmacho.docbook \ - paxelf.c \ - paxelf.h \ - paxinc.c \ - paxinc.h \ - paxldso.c \ - paxldso.h \ - paxmacho.c \ - paxmacho.h \ - porting.h \ - pspax.c \ - scanelf.c \ - scanmacho.c \ - security.c \ - security.h \ - symtree.sh \ - tests/Makefile \ - tests/lddtree/Makefile \ - tests/lddtree/dotest.cmp \ - tests/lddtree/dotest.py \ - tests/lddtree/dotest.sfx \ - tests/lddtree/dotest.sh \ - tests/lib.sh \ - tests/scanelf/Makefile \ - tests/scanelf/dotest \ - tests/scanelf/scanelf.simple.good \ - tests/source/Makefile \ - tests/source/dotest \ - tests/source/space \ - xfuncs.c \ - xfuncs.h -# @@@ GEN END @@@ # @@ -5,11 +5,11 @@ | HOMEPAGE | https://wiki.gentoo.org/wiki/Hardened/PaX_Utilities | | GIT | git clone git://anongit.gentoo.org/proj/pax-utils.git | | VIEWVCS | https://gitweb.gentoo.org/proj/pax-utils.git/ | -| STATUS | [![Build Status](https://travis-ci.org/gentoo/pax-utils.svg?branch=master)](https://travis-ci.org/gentoo/pax-utils) [![Coverity Status](https://scan.coverity.com/projects/9213/badge.svg)](https://scan.coverity.com/projects/gentoo-pax-utils) | +| STATUS | [![Build Status](https://github.com/gentoo/pax-utils/actions/workflows/build-test-ci.yml/badge.svg)](https://github.com/gentoo/pax-utils/actions/workflows/build-test-ci.yml) [![Coverity Status](https://scan.coverity.com/projects/9213/badge.svg)](https://scan.coverity.com/projects/gentoo-pax-utils) | -pax-utils is a small set of utilities for peforming Q/A (mostly security) +pax-utils is a small set of utilities for performing Q/A (mostly security) checks on systems (most notably, `scanelf`). It is focused on the ELF -format, but does include a Mach-O helper too for OS X systems. +format, but does include a Mach-O helper too for macOS systems. While heavily integrated into Gentoo's build system, it can be used on any distro as it is a generic toolset. @@ -18,22 +18,15 @@ Originally focused only on [PaX](https://pax.grsecurity.net/), it has been expanded to be generally security focused. It still has a good number of PaX helpers for people interested in that. -## Building +## Building and installing +pax-utils uses a bog-standard meson-based build system. See `meson_options.txt` +for configuration options. -Just run `make`. This should work on any recent POSIX compliant system. - -Note: To rebuild the man-pages, you will need xmlto and the docbook-xml-dtd - packages installed on your system. - -## Installation - -`make install` - -You don't need PaX to use the pax-utils. Infact the only thing they +You don't need PaX to use the pax-utils. In fact the only thing they really have in common is that pax-utils was initially written to aid in deploying PaX systems so it includes support for PT_PAX_FLAGS and the deprecated but still in use EI_PAX flags. For more information about PaX -see the homepage at http://pax.grsecurity.net/ +see the homepage at https://pax.grsecurity.net/ ## Links @@ -42,32 +35,33 @@ If you include pax-utils in your distro, feel free to send an update for this. ##### Gentoo * https://wiki.gentoo.org/wiki/Hardened/PaX_Utilities * https://gitweb.gentoo.org/proj/pax-utils.git/ - * Maintainer: Mike Frysinger <vapier@gentoo.org>, Ned Ludd <solar@gentoo.org> + * Maintainer: Mike Frysinger <vapier@gentoo.org>, Toolchain Project <toolchain@gentoo.org> + * Original author: Ned Ludd <solar@gentoo.org> ##### openSUSE * https://build.opensuse.org/package/show?package=pax-utils&project=openSUSE%3AFactory * Maintainer: ludwig.nussel@suse.de ##### Ubuntu - * http://packages.ubuntu.com/edgy/devel/pax-utils + * https://packages.ubuntu.com/hirsute/pax-utils * Maintainer: john.r.moser@gmail.com ##### Debian - * http://packages.debian.org/unstable/misc/pax-utils - * http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=388200 + * https://packages.debian.org/unstable/misc/pax-utils + * https://bugs.debian.org/388200 * Maintainer: rdenis@simphalempin.com ##### FreeBSD - * http://portsmon.freebsd.org/portoverview.py?category=sysutils&portname=pax-utils - * http://www.freshports.org/sysutils/pax-utils/ + * https://portsmon.freebsd.org/portoverview.py?category=sysutils&portname=pax-utils + * https://www.freshports.org/sysutils/pax-utils/ * http://archive.netbsd.se/?ml=freebsd-cvs-all&a=2006-08&m=2311441 * Maintainer: sbz@FreeBSD.org ##### OpenEmedded - * http://www.openembedded.org/filebrowser/org.openembedded.dev/packages/pax-utils + * https://www.openembedded.org/filebrowser/org.openembedded.dev/packages/pax-utils ##### Crux - * http://magog.se/crux/pax-utils/Pkgfile + * https://magog.se/crux/pax-utils/Pkgfile * Maintainer: mattias@hedenskog.se ##### Fedora @@ -22,7 +22,7 @@ no hits as all of our symbol comparisons ignore the versioning info. allow digging into ARM_ATTRIBUTES (.ARM.attributes) sections - need info on the section layout - figure out how to integrate cleanly (target-independent driller) - http://sourceware.org/binutils/docs/as/GNU-Object-Attributes.html + https://sourceware.org/binutils/docs/as/GNU-Object-Attributes.html scanelf should look at the dynamic table for rpath/needed/soname entries instead of requiring section headers and looking up by section names. need to implement diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index 42e8a8c..0000000 --- a/autogen.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/bash -e - -. "${0%/*}"/travis/lib.sh - -m4dir="autotools/m4" - -v rm -rf autotools -if [[ $1 != "--from=make" ]] ; then - v ${MAKE:-make} autotools-update -fi - -# reload the gnulib code if possible -PATH=/usr/local/src/gnu/gnulib:${PATH} -mods=" - alloca - euidaccess - faccessat - fdopendir - fstatat - futimens - getline - getopt-posix - mkdirat - openat - progname - readlinkat - renameat - stat-time - stpcpy - strcasestr-simple - strncat - symlinkat - sys_stat - unlinkat - utimensat - vasprintf-posix -" -v --fold="gnulib-tool" gnulib-tool \ - --source-base=autotools/gnulib --m4-base=autotools/m4 \ - --import \ - ${mods} - -# not everyone has sys-devel/autoconf-archive installed -v tar xf travis/autotools.tar.xz -has() { [[ " ${*:2} " == *" $1 "* ]] ; } -import_ax() { - local macro content m4 lm4s=() - content=$(sed -e '/^[[:space:]]*#/d' -e 's:\<dnl\>.*::' "$@") - for macro in $(echo "${content}" | grep -o '\<AX[A-Z_]*\>' | sort -u) ; do - for m4 in $(grep -rl "\[${macro}\]" /usr/share/aclocal/) ; do - has ${m4} "${m4s[@]}" || lm4s+=( ${m4} ) - done - done - if [[ ${#lm4s[@]} -gt 0 ]] ; then - cp -v `printf '%s\n' ${lm4s[@]} | sort -u` autotools/m4/ - m4s+=( "${lm4s[@]}" ) - fi -} -m4s=() -import_ax configure.ac -curr=1 -new=0 -while [[ ${curr} -ne ${new} ]] ; do - curr=${#m4s[@]} - import_ax autotools/m4/ax_*.m4 - new=${#m4s[@]} -done - -export AUTOMAKE="automake --foreign" -v autoreconf -i -f - -if [[ -x ./test.sh ]] ; then - exec ./test.sh "$@" -fi diff --git a/configure.ac b/configure.ac deleted file mode 100644 index a22e11a..0000000 --- a/configure.ac +++ /dev/null @@ -1,71 +0,0 @@ -AC_PREREQ([2.65]) -AC_INIT([pax-utils], [git]) -AC_CONFIG_AUX_DIR([autotools]) -AM_INIT_AUTOMAKE([1.11 dist-xz no-dist-gzip silent-rules -Wall]) -AM_SILENT_RULES([yes]) # AM_INIT_AUTOMAKE([silent-rules]) is broken atm -AC_CONFIG_HEADER([config.h]) -AC_CONFIG_MACRO_DIR([autotools/m4]) - -AC_PROG_CC_C99 -AM_PROG_CC_C_O -AM_PROG_AR -AC_USE_SYSTEM_EXTENSIONS -LT_INIT -PKG_PROG_PKG_CONFIG - -gl_EARLY -gl_INIT - -AC_ARG_WITH([caps], [AS_HELP_STRING([--with-caps], [build with capabilities])]) -AS_IF([test "x$with_caps" = "xyes"], [ - PKG_CHECK_MODULES(LIBCAP, libcap) - CPPFLAGS="$CPPFLAGS $LIBCAP_CFLAGS -DWANT_SYSCAP" - LIBS="$LIBS $LIBCAP_LIBS" -]) - -AC_ARG_WITH([debug], [AS_HELP_STRING([--with-debug], [enable debug code])]) -AS_IF([test "x$with_debug" = "xyes"], [ - CPPFLAGS="$CPPFLAGS -DEBUG" -]) - -AC_ARG_WITH([python], [AS_HELP_STRING([--with-python], [use lddtree.py])]) -AM_CONDITIONAL([USE_PYTHON], [test "x$with_python" = "xyes"]) - -AC_ARG_WITH([seccomp], [AS_HELP_STRING([--with-seccomp], [build with seccomp])]) -AS_IF([test "x$with_seccomp" = "xyes"], [ - PKG_CHECK_MODULES(LIBSECCOMP, libseccomp) - CPPFLAGS="$CPPFLAGS $LIBSECCOMP_CFLAGS -DWANT_SECCOMP" - LIBS="$LIBS $LIBSECCOMP_LIBS" -]) - -AX_CFLAGS_WARN_ALL -AC_DEFUN([PT_CHECK_CFLAG],[AX_CHECK_COMPILER_FLAGS([$1],[CFLAGS="$CFLAGS $1"])]) -m4_foreach_w([flag], [ - -Wunused - -Wimplicit - -Wshadow - -Wformat=2 - -Wmissing-declarations - -Wno-missing-prototypes - -Wwrite-strings - -Wbad-function-cast - -Wnested-externs - -Wcomment - -Winline - -Wchar-subscripts - -Wcast-align - -Wno-format-nonliteral - -Wsequence-point - -Wold-style-definition - -Wextra -], [ - AX_CHECK_COMPILE_FLAG(flag, AS_VAR_APPEND([CFLAGS], " flag")) -]) - -AC_CHECK_HEADERS([linux/securebits.h]) - -AC_CONFIG_FILES([ - Makefile - autotools/gnulib/Makefile -]) -AC_OUTPUT @@ -1,9 +1,9 @@ /* - * Copyright 2005-2012 Gentoo Foundation + * Copyright 2005-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2005-2012 Ned Ludd - <solar@gentoo.org> - * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org> + * Copyright 2005-2024 Mike Frysinger - <vapier@gentoo.org> */ const char argv0[] = "dumpelf"; @@ -11,18 +11,15 @@ const char argv0[] = "dumpelf"; #include "paxinc.h" /* prototypes */ -static void dumpelf(const char *filename, size_t file_cnt); -static void dump_ehdr(elfobj *elf, const void *ehdr); -static void dump_phdr(elfobj *elf, const void *phdr, size_t phdr_cnt); -static void dump_shdr(elfobj *elf, const void *shdr, size_t shdr_cnt, const char *section_name); -static void dump_dyn(elfobj *elf, const void *dyn, size_t dyn_cnt); +static void dump_ehdr(const elfobj *elf, const void *ehdr); +static void dump_phdr(const elfobj *elf, const void *phdr, size_t phdr_cnt); +static void dump_shdr(const elfobj *elf, const void *shdr, size_t shdr_cnt, const char *section_name); +static void dump_dyn(const elfobj *elf, const void *dyn, size_t dyn_cnt); #if 0 -static void dump_sym(elfobj *elf, const void *sym); -static void dump_rel(elfobj *elf, const void *rel); -static void dump_rela(elfobj *elf, const void *rela); +static void dump_sym(const elfobj *elf, const void *sym); +static void dump_rel(const elfobj *elf, const void *rel); +static void dump_rela(const elfobj *elf, const void *rela); #endif -static void usage(int status); -static void parseargs(int argc, char *argv[]); /* variables to control behavior */ static char be_verbose = 0; @@ -31,15 +28,10 @@ static char be_verbose = 0; static const void *phdr_dynamic_void; /* dump all internal elf info */ -static void dumpelf(const char *filename, size_t file_cnt) +static void dumpelf(const elfobj *elf, size_t file_cnt) { - elfobj *elf; size_t i, b; - /* verify this is real ELF */ - if ((elf = readelf(filename)) == NULL) - return; - phdr_dynamic_void = NULL; printf("#include <elf.h>\n"); @@ -48,9 +40,9 @@ static void dumpelf(const char *filename, size_t file_cnt) "\n" "/*\n" " * ELF dump of '%s'\n" - " * %ji (0x%jX) bytes\n" + " * %" PRIi64 " (0x%" PRIX64 ") bytes\n" " */\n\n", - filename, elf->len, elf->len); + elf->filename, (int64_t)elf->len, (uint64_t)elf->len); /* setup the struct to namespace this elf */ #define MAKE_STRUCT(B) \ @@ -122,7 +114,7 @@ static void dumpelf(const char *filename, size_t file_cnt) break_out_shdr: printf("},\n"); - /* finish the namespace struct and start the abitrary ones */ + /* finish the namespace struct and start the arbitrary ones */ printf("\n.dyns = dumpedelf_dyn_%zu,\n", file_cnt); printf("};\n"); @@ -148,12 +140,23 @@ static void dumpelf(const char *filename, size_t file_cnt) printf(" /* no dynamic tags ! */ "); } printf("};\n"); +} + +static void dumpelf_file(const char *filename, size_t file_cnt) +{ + elfobj *elf = readelf(filename); + + /* verify this is real ELF */ + if (elf == NULL) + return; + + dumpelf(elf, file_cnt); /* get out of here */ unreadelf(elf); } -static void dump_ehdr(elfobj *elf, const void *ehdr_void) +static void dump_ehdr(const elfobj *elf, const void *ehdr_void) { #define DUMP_EHDR(B) \ if (elf->elf_class == ELFCLASS ## B) { \ @@ -203,7 +206,7 @@ static void dump_ehdr(elfobj *elf, const void *ehdr_void) DUMP_EHDR(64) } -static void dump_notes(elfobj *elf, size_t B, const void *memory, const void *memory_end) +static void dump_notes(const elfobj *elf, size_t B, const void *memory, const void *memory_end) { /* While normally we'd worry about Elf32_Nhdr vs Elf64_Nhdr, in the ELF * world, the two structs are exactly the same. So avoid ugly CPP. @@ -294,7 +297,7 @@ static const char *dump_p_flags(uint32_t type, uint32_t flags) return buf + 3; } -static void dump_phdr(elfobj *elf, const void *phdr_void, size_t phdr_cnt) +static void dump_phdr(const elfobj *elf, const void *phdr_void, size_t phdr_cnt) { #define DUMP_PHDR(B) \ if (elf->elf_class == ELFCLASS ## B) { \ @@ -351,7 +354,7 @@ static const char *timestamp(uint64_t stamp) return buf; } -static void dump_shdr(elfobj *elf, const void *shdr_void, size_t shdr_cnt, const char *section_name) +static void dump_shdr(const elfobj *elf, const void *shdr_void, size_t shdr_cnt, const char *section_name) { size_t i; @@ -460,6 +463,7 @@ static void dump_shdr(elfobj *elf, const void *shdr_void, size_t shdr_cnt, const ++lib; \ } \ printf("\t */\n"); \ + break; \ } \ default: { \ if (be_verbose <= 1) \ @@ -482,7 +486,7 @@ static void dump_shdr(elfobj *elf, const void *shdr_void, size_t shdr_cnt, const DUMP_SHDR(64) } -static void dump_dyn(elfobj *elf, const void *dyn_void, size_t dyn_cnt) +static void dump_dyn(const elfobj *elf, const void *dyn_void, size_t dyn_cnt) { #define DUMP_DYN(B) \ if (elf->elf_class == ELFCLASS ## B) { \ @@ -503,7 +507,6 @@ static void dump_dyn(elfobj *elf, const void *dyn_void, size_t dyn_cnt) /* usage / invocation handling functions */ #define PARSE_FLAGS "vhV" -#define a_argument required_argument static struct option const long_opts[] = { {"verbose", no_argument, NULL, 'v'}, {"help", no_argument, NULL, 'h'}, @@ -520,21 +523,16 @@ static const char * const opts_help[] = { /* display usage and exit */ static void usage(int status) { - size_t i; - printf("* Dump internal ELF structure\n\n" - "Usage: %s <file1> [file2 fileN ...]\n\n", argv0); - printf("Options:\n"); - for (i = 0; long_opts[i].name; ++i) - if (long_opts[i].has_arg == no_argument) - printf(" -%c, --%-13s* %s\n", long_opts[i].val, - long_opts[i].name, opts_help[i]); - else - printf(" -%c, --%-6s <arg> * %s\n", long_opts[i].val, - long_opts[i].name, opts_help[i]); - exit(status); + pax_usage( + "Dump internal ELF structure", + "<file1> [file2 fileN ...]", + PARSE_FLAGS, + long_opts, + opts_help, + status); } -/* parse command line arguments and preform needed actions */ +/* parse command line arguments and perform needed actions */ static void parseargs(int argc, char *argv[]) { int flag; @@ -569,10 +567,30 @@ static void parseargs(int argc, char *argv[]) size_t file_cnt = 0; while (optind < argc) - dumpelf(argv[optind++], file_cnt++); + dumpelf_file(argv[optind++], file_cnt++); } } +#if PAX_UTILS_LIBFUZZ +int LLVMFuzzerInitialize(int *argc, char ***argv) +{ + (void)argc; + (void)argv; + (void)parseargs; + security_init(false); + return 0; +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + elfobj *elf = readelf_buffer("libFuzzer", data, size); + if (elf == NULL) + return 0; + dumpelf(elf, 0); + unreadelf(elf); + return 0; +} +#else int main(int argc, char *argv[]) { security_init(false); @@ -581,3 +599,4 @@ int main(int argc, char *argv[]) parseargs(argc, argv); return EXIT_SUCCESS; } +#endif @@ -1,5 +1,5 @@ /* This file defines standard ELF types, structures, and macros. - Copyright (C) 1995-2015 Free Software Foundation, Inc. + Copyright (C) 1995-2023 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -14,7 +14,7 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + <https://www.gnu.org/licenses/>. */ #ifndef _ELF_H #define _ELF_H 1 @@ -168,106 +168,203 @@ typedef struct /* Legal values for e_machine (architecture). */ -#define EM_NONE 0 /* No machine */ -#define EM_M32 1 /* AT&T WE 32100 */ -#define EM_SPARC 2 /* SUN SPARC */ -#define EM_386 3 /* Intel 80386 */ -#define EM_68K 4 /* Motorola m68k family */ -#define EM_88K 5 /* Motorola m88k family */ -#define EM_860 7 /* Intel 80860 */ -#define EM_MIPS 8 /* MIPS R3000 big-endian */ -#define EM_S370 9 /* IBM System/370 */ -#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ - -#define EM_PARISC 15 /* HPPA */ -#define EM_VPP500 17 /* Fujitsu VPP500 */ -#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ -#define EM_960 19 /* Intel 80960 */ -#define EM_PPC 20 /* PowerPC */ -#define EM_PPC64 21 /* PowerPC 64-bit */ -#define EM_S390 22 /* IBM S390 */ - -#define EM_V800 36 /* NEC V800 series */ -#define EM_FR20 37 /* Fujitsu FR20 */ -#define EM_RH32 38 /* TRW RH-32 */ -#define EM_RCE 39 /* Motorola RCE */ -#define EM_ARM 40 /* ARM */ -#define EM_FAKE_ALPHA 41 /* Digital Alpha */ -#define EM_SH 42 /* Hitachi SH */ -#define EM_SPARCV9 43 /* SPARC v9 64-bit */ -#define EM_TRICORE 44 /* Siemens Tricore */ -#define EM_ARC 45 /* Argonaut RISC Core */ -#define EM_H8_300 46 /* Hitachi H8/300 */ -#define EM_H8_300H 47 /* Hitachi H8/300H */ -#define EM_H8S 48 /* Hitachi H8S */ -#define EM_H8_500 49 /* Hitachi H8/500 */ -#define EM_IA_64 50 /* Intel Merced */ -#define EM_MIPS_X 51 /* Stanford MIPS-X */ -#define EM_COLDFIRE 52 /* Motorola Coldfire */ -#define EM_68HC12 53 /* Motorola M68HC12 */ -#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ -#define EM_PCP 55 /* Siemens PCP */ -#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ -#define EM_NDR1 57 /* Denso NDR1 microprocessor */ -#define EM_STARCORE 58 /* Motorola Start*Core processor */ -#define EM_ME16 59 /* Toyota ME16 processor */ -#define EM_ST100 60 /* STMicroelectronic ST100 processor */ -#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ -#define EM_X86_64 62 /* AMD x86-64 architecture */ -#define EM_PDSP 63 /* Sony DSP Processor */ - -#define EM_FX66 66 /* Siemens FX66 microcontroller */ -#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ -#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ -#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ -#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ -#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ -#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ -#define EM_SVX 73 /* Silicon Graphics SVx */ -#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ -#define EM_VAX 75 /* Digital VAX */ -#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ -#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ -#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ -#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ -#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ -#define EM_HUANY 81 /* Harvard University machine-independent object files */ -#define EM_PRISM 82 /* SiTera Prism */ -#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ -#define EM_FR30 84 /* Fujitsu FR30 */ -#define EM_D10V 85 /* Mitsubishi D10V */ -#define EM_D30V 86 /* Mitsubishi D30V */ -#define EM_V850 87 /* NEC v850 */ -#define EM_M32R 88 /* Mitsubishi M32R */ -#define EM_MN10300 89 /* Matsushita MN10300 */ -#define EM_MN10200 90 /* Matsushita MN10200 */ -#define EM_PJ 91 /* picoJava */ -#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ -#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ -#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ -#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor */ -#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose Proc */ -#define EM_NS32K 97 /* National Semiconductor 32000 series */ -#define EM_TPC 98 /* Tenor Network TPC processor */ -#define EM_SNP1K 99 /* Trebia SNP 1000 processor */ -#define EM_ST200 100 /* STMicroelectronics ST200 microcontroller */ -#define EM_IP2K 101 /* Ubicom IP2xxx microcontroller family */ -#define EM_MAX 102 /* MAX Processor */ -#define EM_CR 103 /* NatSemi CompactRISC microprocessor */ -#define EM_F2MC16 104 /* Fujitsu F2MC16 */ -#define EM_MSP430 105 /* TI embedded microcontroller msp430 */ -#define EM_BLACKFIN 106 /* Analog Devices Blackfin (DSP) processor */ -#define EM_SE_C33 107 /* S1C33 Family of Seiko Epson processors */ -#define EM_SEP 108 /* Sharp embedded microprocessor */ -#define EM_ARCA 109 /* Arca RISC Microprocessor */ -#define EM_UNICORE 110 /* Microprocessor series from PKU-Unity Ltd. */ - /* and MPRC of Peking University */ -#define EM_ALTERA_NIOS2 113 /* Altera Nios II */ -#define EM_AARCH64 183 /* ARM AARCH64 */ -#define EM_TILEPRO 188 /* Tilera TILEPro */ -#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */ -#define EM_TILEGX 191 /* Tilera TILE-Gx */ -#define EM_NUM 192 +#define EM_NONE 0 /* No machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SUN SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola m68k family */ +#define EM_88K 5 /* Motorola m88k family */ +#define EM_IAMCU 6 /* Intel MCU */ +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 big-endian */ +#define EM_S370 9 /* IBM System/370 */ +#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ + /* reserved 11-14 */ +#define EM_PARISC 15 /* HPPA */ + /* reserved 16 */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* PowerPC 64-bit */ +#define EM_S390 22 /* IBM S390 */ +#define EM_SPU 23 /* IBM SPU/SPC */ + /* reserved 24-35 */ +#define EM_V800 36 /* NEC V800 series */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH-32 */ +#define EM_RCE 39 /* Motorola RCE */ +#define EM_ARM 40 /* ARM */ +#define EM_FAKE_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_TRICORE 44 /* Siemens Tricore */ +#define EM_ARC 45 /* Argonaut RISC Core */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel Merced */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola Coldfire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator */ +#define EM_PCP 55 /* Siemens PCP */ +#define EM_NCPU 56 /* Sony nCPU embedded RISC */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor */ +#define EM_STARCORE 58 /* Motorola Start*Core processor */ +#define EM_ME16 59 /* Toyota ME16 processor */ +#define EM_ST100 60 /* STMicroelectronic ST100 processor */ +#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam */ +#define EM_X86_64 62 /* AMD x86-64 architecture */ +#define EM_PDSP 63 /* Sony DSP Processor */ +#define EM_PDP10 64 /* Digital PDP-10 */ +#define EM_PDP11 65 /* Digital PDP-11 */ +#define EM_FX66 66 /* Siemens FX66 microcontroller */ +#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ +#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ +#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ +#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ +#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ +#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ +#define EM_SVX 73 /* Silicon Graphics SVx */ +#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ +#define EM_VAX 75 /* Digital VAX */ +#define EM_CRIS 76 /* Axis Communications 32-bit emb.proc */ +#define EM_JAVELIN 77 /* Infineon Technologies 32-bit emb.proc */ +#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ +#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ +#define EM_MMIX 80 /* Donald Knuth's educational 64-bit proc */ +#define EM_HUANY 81 /* Harvard University machine-independent object files */ +#define EM_PRISM 82 /* SiTera Prism */ +#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ +#define EM_FR30 84 /* Fujitsu FR30 */ +#define EM_D10V 85 /* Mitsubishi D10V */ +#define EM_D30V 86 /* Mitsubishi D30V */ +#define EM_V850 87 /* NEC v850 */ +#define EM_M32R 88 /* Mitsubishi M32R */ +#define EM_MN10300 89 /* Matsushita MN10300 */ +#define EM_MN10200 90 /* Matsushita MN10200 */ +#define EM_PJ 91 /* picoJava */ +#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ +#define EM_ARC_COMPACT 93 /* ARC International ARCompact */ +#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ +#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore */ +#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose Proc */ +#define EM_NS32K 97 /* National Semi. 32000 */ +#define EM_TPC 98 /* Tenor Network TPC */ +#define EM_SNP1K 99 /* Trebia SNP 1000 */ +#define EM_ST200 100 /* STMicroelectronics ST200 */ +#define EM_IP2K 101 /* Ubicom IP2xxx */ +#define EM_MAX 102 /* MAX processor */ +#define EM_CR 103 /* National Semi. CompactRISC */ +#define EM_F2MC16 104 /* Fujitsu F2MC16 */ +#define EM_MSP430 105 /* Texas Instruments msp430 */ +#define EM_BLACKFIN 106 /* Analog Devices Blackfin DSP */ +#define EM_SE_C33 107 /* Seiko Epson S1C33 family */ +#define EM_SEP 108 /* Sharp embedded microprocessor */ +#define EM_ARCA 109 /* Arca RISC */ +#define EM_UNICORE 110 /* PKU-Unity & MPRC Peking Uni. mc series */ +#define EM_EXCESS 111 /* eXcess configurable cpu */ +#define EM_DXP 112 /* Icera Semi. Deep Execution Processor */ +#define EM_ALTERA_NIOS2 113 /* Altera Nios II */ +#define EM_CRX 114 /* National Semi. CompactRISC CRX */ +#define EM_XGATE 115 /* Motorola XGATE */ +#define EM_C166 116 /* Infineon C16x/XC16x */ +#define EM_M16C 117 /* Renesas M16C */ +#define EM_DSPIC30F 118 /* Microchip Technology dsPIC30F */ +#define EM_CE 119 /* Freescale Communication Engine RISC */ +#define EM_M32C 120 /* Renesas M32C */ + /* reserved 121-130 */ +#define EM_TSK3000 131 /* Altium TSK3000 */ +#define EM_RS08 132 /* Freescale RS08 */ +#define EM_SHARC 133 /* Analog Devices SHARC family */ +#define EM_ECOG2 134 /* Cyan Technology eCOG2 */ +#define EM_SCORE7 135 /* Sunplus S+core7 RISC */ +#define EM_DSP24 136 /* New Japan Radio (NJR) 24-bit DSP */ +#define EM_VIDEOCORE3 137 /* Broadcom VideoCore III */ +#define EM_LATTICEMICO32 138 /* RISC for Lattice FPGA */ +#define EM_SE_C17 139 /* Seiko Epson C17 */ +#define EM_TI_C6000 140 /* Texas Instruments TMS320C6000 DSP */ +#define EM_TI_C2000 141 /* Texas Instruments TMS320C2000 DSP */ +#define EM_TI_C5500 142 /* Texas Instruments TMS320C55x DSP */ +#define EM_TI_ARP32 143 /* Texas Instruments App. Specific RISC */ +#define EM_TI_PRU 144 /* Texas Instruments Prog. Realtime Unit */ + /* reserved 145-159 */ +#define EM_MMDSP_PLUS 160 /* STMicroelectronics 64bit VLIW DSP */ +#define EM_CYPRESS_M8C 161 /* Cypress M8C */ +#define EM_R32C 162 /* Renesas R32C */ +#define EM_TRIMEDIA 163 /* NXP Semi. TriMedia */ +#define EM_QDSP6 164 /* QUALCOMM DSP6 */ +#define EM_8051 165 /* Intel 8051 and variants */ +#define EM_STXP7X 166 /* STMicroelectronics STxP7x */ +#define EM_NDS32 167 /* Andes Tech. compact code emb. RISC */ +#define EM_ECOG1X 168 /* Cyan Technology eCOG1X */ +#define EM_MAXQ30 169 /* Dallas Semi. MAXQ30 mc */ +#define EM_XIMO16 170 /* New Japan Radio (NJR) 16-bit DSP */ +#define EM_MANIK 171 /* M2000 Reconfigurable RISC */ +#define EM_CRAYNV2 172 /* Cray NV2 vector architecture */ +#define EM_RX 173 /* Renesas RX */ +#define EM_METAG 174 /* Imagination Tech. META */ +#define EM_MCST_ELBRUS 175 /* MCST Elbrus */ +#define EM_ECOG16 176 /* Cyan Technology eCOG16 */ +#define EM_CR16 177 /* National Semi. CompactRISC CR16 */ +#define EM_ETPU 178 /* Freescale Extended Time Processing Unit */ +#define EM_SLE9X 179 /* Infineon Tech. SLE9X */ +#define EM_L10M 180 /* Intel L10M */ +#define EM_K10M 181 /* Intel K10M */ + /* reserved 182 */ +#define EM_AARCH64 183 /* ARM AARCH64 */ + /* reserved 184 */ +#define EM_AVR32 185 /* Amtel 32-bit microprocessor */ +#define EM_STM8 186 /* STMicroelectronics STM8 */ +#define EM_TILE64 187 /* Tilera TILE64 */ +#define EM_TILEPRO 188 /* Tilera TILEPro */ +#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */ +#define EM_CUDA 190 /* NVIDIA CUDA */ +#define EM_TILEGX 191 /* Tilera TILE-Gx */ +#define EM_CLOUDSHIELD 192 /* CloudShield */ +#define EM_COREA_1ST 193 /* KIPO-KAIST Core-A 1st gen. */ +#define EM_COREA_2ND 194 /* KIPO-KAIST Core-A 2nd gen. */ +#define EM_ARCV2 195 /* Synopsys ARCv2 ISA. */ +#define EM_OPEN8 196 /* Open8 RISC */ +#define EM_RL78 197 /* Renesas RL78 */ +#define EM_VIDEOCORE5 198 /* Broadcom VideoCore V */ +#define EM_78KOR 199 /* Renesas 78KOR */ +#define EM_56800EX 200 /* Freescale 56800EX DSC */ +#define EM_BA1 201 /* Beyond BA1 */ +#define EM_BA2 202 /* Beyond BA2 */ +#define EM_XCORE 203 /* XMOS xCORE */ +#define EM_MCHP_PIC 204 /* Microchip 8-bit PIC(r) */ +#define EM_INTELGT 205 /* Intel Graphics Technology */ + /* reserved 206-209 */ +#define EM_KM32 210 /* KM211 KM32 */ +#define EM_KMX32 211 /* KM211 KMX32 */ +#define EM_EMX16 212 /* KM211 KMX16 */ +#define EM_EMX8 213 /* KM211 KMX8 */ +#define EM_KVARC 214 /* KM211 KVARC */ +#define EM_CDP 215 /* Paneve CDP */ +#define EM_COGE 216 /* Cognitive Smart Memory Processor */ +#define EM_COOL 217 /* Bluechip CoolEngine */ +#define EM_NORC 218 /* Nanoradio Optimized RISC */ +#define EM_CSR_KALIMBA 219 /* CSR Kalimba */ +#define EM_Z80 220 /* Zilog Z80 */ +#define EM_VISIUM 221 /* Controls and Data Services VISIUMcore */ +#define EM_FT32 222 /* FTDI Chip FT32 */ +#define EM_MOXIE 223 /* Moxie processor */ +#define EM_AMDGPU 224 /* AMD GPU */ + /* reserved 225-242 */ +#define EM_RISCV 243 /* RISC-V */ + +#define EM_BPF 247 /* Linux BPF -- in-kernel virtual machine */ +#define EM_CSKY 252 /* C-SKY */ +#define EM_LOONGARCH 258 /* LoongArch */ + +#define EM_NUM 259 + +/* Old spellings/synonyms. */ + +#define EM_ARC_A5 EM_ARC_COMPACT /* If it is necessary to assign new unofficial EM_* values, please pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the @@ -346,8 +443,9 @@ typedef struct #define SHT_FINI_ARRAY 15 /* Array of destructors */ #define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ #define SHT_GROUP 17 /* Section group */ -#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ -#define SHT_NUM 19 /* Number of defined types. */ +#define SHT_SYMTAB_SHNDX 18 /* Extended section indices */ +#define SHT_RELR 19 /* RELR relative relocations */ +#define SHT_NUM 20 /* Number of defined types. */ #define SHT_LOOS 0x60000000 /* Start OS-specific. */ #define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ #define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ @@ -380,13 +478,40 @@ typedef struct required */ #define SHF_GROUP (1 << 9) /* Section is member of a group. */ #define SHF_TLS (1 << 10) /* Section hold thread-local data. */ +#define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */ #define SHF_MASKOS 0x0ff00000 /* OS-specific. */ #define SHF_MASKPROC 0xf0000000 /* Processor-specific */ +#define SHF_GNU_RETAIN (1 << 21) /* Not to be GCed by linker. */ #define SHF_ORDERED (1 << 30) /* Special ordering requirement (Solaris). */ -#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless +#define SHF_EXCLUDE (1U << 31) /* Section is excluded unless referenced or allocated (Solaris).*/ +/* Section compression header. Used when SHF_COMPRESSED is set. */ + +typedef struct +{ + Elf32_Word ch_type; /* Compression format. */ + Elf32_Word ch_size; /* Uncompressed data size. */ + Elf32_Word ch_addralign; /* Uncompressed data alignment. */ +} Elf32_Chdr; + +typedef struct +{ + Elf64_Word ch_type; /* Compression format. */ + Elf64_Word ch_reserved; + Elf64_Xword ch_size; /* Uncompressed data size. */ + Elf64_Xword ch_addralign; /* Uncompressed data alignment. */ +} Elf64_Chdr; + +/* Legal values for ch_type (compression algorithm). */ +#define ELFCOMPRESS_ZLIB 1 /* ZLIB/DEFLATE algorithm. */ +#define ELFCOMPRESS_ZSTD 2 /* Zstandard algorithm. */ +#define ELFCOMPRESS_LOOS 0x60000000 /* Start of OS-specific. */ +#define ELFCOMPRESS_HIOS 0x6fffffff /* End of OS-specific. */ +#define ELFCOMPRESS_LOPROC 0x70000000 /* Start of processor-specific. */ +#define ELFCOMPRESS_HIPROC 0x7fffffff /* End of processor-specific. */ + /* Section group handling. */ #define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ @@ -434,7 +559,7 @@ typedef struct /* Possible bitmasks for si_flags. */ #define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ -#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ +#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-through symbol for translator */ #define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ #define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy loaded */ @@ -540,6 +665,11 @@ typedef struct Elf64_Sxword r_addend; /* Addend */ } Elf64_Rela; +/* RELR relocation table entry */ + +typedef Elf32_Word Elf32_Relr; +typedef Elf64_Xword Elf64_Relr; + /* How to extract and insert information held in the r_info field. */ #define ELF32_R_SYM(val) ((val) >> 8) @@ -597,6 +727,8 @@ typedef struct #define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ #define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ #define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ +#define PT_GNU_PROPERTY 0x6474e553 /* GNU property */ +#define PT_GNU_SFRAME 0x6474e554 /* SFrame segment. */ #define PT_LOSUNW 0x6ffffffa #define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ #define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ @@ -616,6 +748,8 @@ typedef struct /* Legal values for note segment descriptor types for core files. */ #define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ +#define NT_PRFPREG 2 /* Contains copy of fpregset + struct. */ #define NT_FPREGSET 2 /* Contains copy of fpregset struct */ #define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ #define NT_PRXREG 4 /* Contains copy of prxregset struct */ @@ -639,9 +773,30 @@ typedef struct #define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ #define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ #define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ +#define NT_PPC_TAR 0x103 /* Target Address Register */ +#define NT_PPC_PPR 0x104 /* Program Priority Register */ +#define NT_PPC_DSCR 0x105 /* Data Stream Control Register */ +#define NT_PPC_EBB 0x106 /* Event Based Branch Registers */ +#define NT_PPC_PMU 0x107 /* Performance Monitor Registers */ +#define NT_PPC_TM_CGPR 0x108 /* TM checkpointed GPR Registers */ +#define NT_PPC_TM_CFPR 0x109 /* TM checkpointed FPR Registers */ +#define NT_PPC_TM_CVMX 0x10a /* TM checkpointed VMX Registers */ +#define NT_PPC_TM_CVSX 0x10b /* TM checkpointed VSX Registers */ +#define NT_PPC_TM_SPR 0x10c /* TM Special Purpose Registers */ +#define NT_PPC_TM_CTAR 0x10d /* TM checkpointed Target Address + Register */ +#define NT_PPC_TM_CPPR 0x10e /* TM checkpointed Program Priority + Register */ +#define NT_PPC_TM_CDSCR 0x10f /* TM checkpointed Data Stream Control + Register */ +#define NT_PPC_PKEY 0x110 /* Memory Protection Keys + registers. */ +#define NT_PPC_DEXCR 0x111 /* PowerPC DEXCR registers. */ +#define NT_PPC_HASHKEYR 0x112 /* PowerPC HASHKEYR register. */ #define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ #define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ #define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */ +#define NT_X86_SHSTK 0x204 /* x86 SHSTK state */ #define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */ #define NT_S390_TIMER 0x301 /* s390 timer register */ #define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */ @@ -651,10 +806,48 @@ typedef struct #define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */ #define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */ #define NT_S390_TDB 0x308 /* s390 transaction diagnostic block */ +#define NT_S390_VXRS_LOW 0x309 /* s390 vector registers 0-15 + upper half. */ +#define NT_S390_VXRS_HIGH 0x30a /* s390 vector registers 16-31. */ +#define NT_S390_GS_CB 0x30b /* s390 guarded storage registers. */ +#define NT_S390_GS_BC 0x30c /* s390 guarded storage + broadcast control block. */ +#define NT_S390_RI_CB 0x30d /* s390 runtime instrumentation. */ +#define NT_S390_PV_CPU_DATA 0x30e /* s390 protvirt cpu dump data. */ #define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */ #define NT_ARM_TLS 0x401 /* ARM TLS register */ #define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */ #define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */ +#define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */ +#define NT_ARM_SVE 0x405 /* ARM Scalable Vector Extension + registers */ +#define NT_ARM_PAC_MASK 0x406 /* ARM pointer authentication + code masks. */ +#define NT_ARM_PACA_KEYS 0x407 /* ARM pointer authentication + address keys. */ +#define NT_ARM_PACG_KEYS 0x408 /* ARM pointer authentication + generic key. */ +#define NT_ARM_TAGGED_ADDR_CTRL 0x409 /* AArch64 tagged address + control. */ +#define NT_ARM_PAC_ENABLED_KEYS 0x40a /* AArch64 pointer authentication + enabled keys. */ +#define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note. */ +#define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers. */ +#define NT_MIPS_FP_MODE 0x801 /* MIPS floating-point mode. */ +#define NT_MIPS_MSA 0x802 /* MIPS SIMD registers. */ +#define NT_RISCV_CSR 0x900 /* RISC-V Control and Status Registers */ +#define NT_RISCV_VECTOR 0x901 /* RISC-V vector registers */ +#define NT_LOONGARCH_CPUCFG 0xa00 /* LoongArch CPU config registers. */ +#define NT_LOONGARCH_CSR 0xa01 /* LoongArch control and + status registers. */ +#define NT_LOONGARCH_LSX 0xa02 /* LoongArch Loongson SIMD + Extension registers. */ +#define NT_LOONGARCH_LASX 0xa03 /* LoongArch Loongson Advanced + SIMD Extension registers. */ +#define NT_LOONGARCH_LBT 0xa04 /* LoongArch Loongson Binary + Translation registers. */ +#define NT_LOONGARCH_HW_BREAK 0xa05 /* LoongArch hardware breakpoint registers */ +#define NT_LOONGARCH_HW_WATCH 0xa06 /* LoongArch hardware watchpoint registers */ /* Legal values for the note segment descriptor types for object files. */ @@ -719,7 +912,11 @@ typedef struct #define DT_ENCODING 32 /* Start of encoded range */ #define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ #define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ -#define DT_NUM 34 /* Number used */ +#define DT_SYMTAB_SHNDX 34 /* Address of SYMTAB_SHNDX section */ +#define DT_RELRSZ 35 /* Total size of RELR relative relocations */ +#define DT_RELR 36 /* Address of RELR relative relocations */ +#define DT_RELRENT 37 /* Size of one RELR relative relocaction */ +#define DT_NUM 38 /* Number used */ #define DT_LOOS 0x6000000d /* Start of OS-specific */ #define DT_HIOS 0x6ffff000 /* End of OS-specific */ #define DT_LOPROC 0x70000000 /* Start of processor-specific */ @@ -827,6 +1024,11 @@ typedef struct #define DF_1_SYMINTPOSE 0x00800000 /* Object has individual interposers. */ #define DF_1_GLOBAUDIT 0x01000000 /* Global auditing required. */ #define DF_1_SINGLETON 0x02000000 /* Singleton symbols are used. */ +#define DF_1_STUB 0x04000000 +#define DF_1_PIE 0x08000000 +#define DF_1_KMOD 0x10000000 +#define DF_1_WEAKFILTER 0x20000000 +#define DF_1_NOCOMMON 0x40000000 /* Flags for the feature selection in DT_FEATURE_1. */ #define DTF_1_PARINIT 0x00000001 @@ -871,7 +1073,8 @@ typedef struct /* Legal values for vd_flags (version information flags). */ #define VER_FLG_BASE 0x1 /* Version definition of file itself */ -#define VER_FLG_WEAK 0x2 /* Weak version identifier */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier. Also + used by vna_flags below. */ /* Versym symbol index values. */ #define VER_NDX_LOCAL 0 /* Symbol is local. */ @@ -879,7 +1082,7 @@ typedef struct #define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ #define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ -/* Auxialiary version information. */ +/* Auxiliary version information. */ typedef struct { @@ -949,10 +1152,6 @@ typedef struct } Elf64_Vernaux; -/* Legal values for vna_flags. */ -#define VER_FLG_WEAK 0x2 /* Weak version identifier */ - - /* Auxiliary vector. */ /* This vector is normally only used by the program interpreter. The @@ -1032,6 +1231,9 @@ typedef struct #define AT_HWCAP2 26 /* More machine-dependent hints about processor capabilities. */ +#define AT_RSEQ_FEATURE_SIZE 27 /* rseq supported feature size. */ +#define AT_RSEQ_ALIGN 28 /* rseq allocation alignment. */ + #define AT_EXECFN 31 /* Filename of executable. */ /* Pointer to the global system page used for system calls and other @@ -1046,6 +1248,20 @@ typedef struct #define AT_L2_CACHESHAPE 36 #define AT_L3_CACHESHAPE 37 +/* Shapes of the caches, with more room to describe them. + *GEOMETRY are comprised of cache line size in bytes in the bottom 16 bits + and the cache associativity in the next 16 bits. */ +#define AT_L1I_CACHESIZE 40 +#define AT_L1I_CACHEGEOMETRY 41 +#define AT_L1D_CACHESIZE 42 +#define AT_L1D_CACHEGEOMETRY 43 +#define AT_L2_CACHESIZE 44 +#define AT_L2_CACHEGEOMETRY 45 +#define AT_L3_CACHESIZE 46 +#define AT_L3_CACHEGEOMETRY 47 + +#define AT_MINSIGSTKSZ 51 /* Stack needed for signal delivery */ + /* Note section contents. Each entry in the note section begins with a header of a fixed form. */ @@ -1071,6 +1287,8 @@ typedef struct /* Note entries for GNU systems have this name. */ #define ELF_NOTE_GNU "GNU" +/* Note entries for freedesktop.org have this name. */ +#define ELF_NOTE_FDO "FDO" /* Defined types of notes for Solaris. */ @@ -1111,6 +1329,84 @@ typedef struct /* Version note generated by GNU gold containing a version string. */ #define NT_GNU_GOLD_VERSION 4 +/* Program property. */ +#define NT_GNU_PROPERTY_TYPE_0 5 + +/* Packaging metadata as defined on + https://systemd.io/COREDUMP_PACKAGE_METADATA/ */ +#define NT_FDO_PACKAGING_METADATA 0xcafe1a7e + +/* Note section name of program property. */ +#define NOTE_GNU_PROPERTY_SECTION_NAME ".note.gnu.property" + +/* Values used in GNU .note.gnu.property notes (NT_GNU_PROPERTY_TYPE_0). */ + +/* Stack size. */ +#define GNU_PROPERTY_STACK_SIZE 1 +/* No copy relocation on protected data symbol. */ +#define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2 + +/* A 4-byte unsigned integer property: A bit is set if it is set in all + relocatable inputs. */ +#define GNU_PROPERTY_UINT32_AND_LO 0xb0000000 +#define GNU_PROPERTY_UINT32_AND_HI 0xb0007fff + +/* A 4-byte unsigned integer property: A bit is set if it is set in any + relocatable inputs. */ +#define GNU_PROPERTY_UINT32_OR_LO 0xb0008000 +#define GNU_PROPERTY_UINT32_OR_HI 0xb000ffff + +/* The needed properties by the object file. */ +#define GNU_PROPERTY_1_NEEDED GNU_PROPERTY_UINT32_OR_LO + +/* Set if the object file requires canonical function pointers and + cannot be used with copy relocation. */ +#define GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS (1U << 0) + +/* Processor-specific semantics, lo */ +#define GNU_PROPERTY_LOPROC 0xc0000000 +/* Processor-specific semantics, hi */ +#define GNU_PROPERTY_HIPROC 0xdfffffff +/* Application-specific semantics, lo */ +#define GNU_PROPERTY_LOUSER 0xe0000000 +/* Application-specific semantics, hi */ +#define GNU_PROPERTY_HIUSER 0xffffffff + +/* AArch64 specific GNU properties. */ +#define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 + +#define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1U << 0) +#define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1U << 1) + +/* The x86 instruction sets indicated by the corresponding bits are + used in program. Their support in the hardware is optional. */ +#define GNU_PROPERTY_X86_ISA_1_USED 0xc0010002 +/* The x86 instruction sets indicated by the corresponding bits are + used in program and they must be supported by the hardware. */ +#define GNU_PROPERTY_X86_ISA_1_NEEDED 0xc0008002 +/* X86 processor-specific features used in program. */ +#define GNU_PROPERTY_X86_FEATURE_1_AND 0xc0000002 + +/* GNU_PROPERTY_X86_ISA_1_BASELINE: CMOV, CX8 (cmpxchg8b), FPU (fld), + MMX, OSFXSR (fxsave), SCE (syscall), SSE and SSE2. */ +#define GNU_PROPERTY_X86_ISA_1_BASELINE (1U << 0) +/* GNU_PROPERTY_X86_ISA_1_V2: GNU_PROPERTY_X86_ISA_1_BASELINE, + CMPXCHG16B (cmpxchg16b), LAHF-SAHF (lahf), POPCNT (popcnt), SSE3, + SSSE3, SSE4.1 and SSE4.2. */ +#define GNU_PROPERTY_X86_ISA_1_V2 (1U << 1) +/* GNU_PROPERTY_X86_ISA_1_V3: GNU_PROPERTY_X86_ISA_1_V2, AVX, AVX2, BMI1, + BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE. */ +#define GNU_PROPERTY_X86_ISA_1_V3 (1U << 2) +/* GNU_PROPERTY_X86_ISA_1_V4: GNU_PROPERTY_X86_ISA_1_V3, AVX512F, + AVX512BW, AVX512CD, AVX512DQ and AVX512VL. */ +#define GNU_PROPERTY_X86_ISA_1_V4 (1U << 3) + +/* This indicates that all executable sections are compatible with + IBT. */ +#define GNU_PROPERTY_X86_FEATURE_1_IBT (1U << 0) +/* This indicates that all executable sections are compatible with + SHSTK. */ +#define GNU_PROPERTY_X86_FEATURE_1_SHSTK (1U << 1) /* Move records. */ typedef struct @@ -1257,8 +1553,10 @@ typedef struct argument, returning the TLS offset for the symbol. */ #define R_386_IRELATIVE 42 /* Adjust indirectly by program base */ +#define R_386_GOT32X 43 /* Load from 32 bit GOT entry, + relaxable. */ /* Keep this the last entry. */ -#define R_386_NUM 43 +#define R_386_NUM 44 /* SUN SPARC specific definitions. */ @@ -1394,11 +1692,25 @@ typedef struct #define EF_MIPS_PIC 2 /* Contains PIC code. */ #define EF_MIPS_CPIC 4 /* Uses PIC calling sequence. */ #define EF_MIPS_XGOT 8 -#define EF_MIPS_64BIT_WHIRL 16 +#define EF_MIPS_UCODE 16 #define EF_MIPS_ABI2 32 #define EF_MIPS_ABI_ON32 64 +#define EF_MIPS_OPTIONS_FIRST 0x00000080 /* Process the .MIPS.options + section first by ld. */ +#define EF_MIPS_32BITMODE 0x00000100 /* Indicates code compiled for + a 64-bit machine in 32-bit + mode (regs are 32-bits + wide). */ #define EF_MIPS_FP64 512 /* Uses FP64 (12 callee-saved). */ #define EF_MIPS_NAN2008 1024 /* Uses IEEE 754-2008 NaN encoding. */ +#define EF_MIPS_ARCH_ASE 0x0f000000 /* Architectural Extensions + used by this file. */ +#define EF_MIPS_ARCH_ASE_MDMX 0x08000000 /* Use MDMX multimedia + extensions. */ +#define EF_MIPS_ARCH_ASE_M16 0x04000000 /* Use MIPS-16 ISA + extensions. */ +#define EF_MIPS_ARCH_ASE_MICROMIPS 0x02000000 /* Use MICROMIPS ISA + extensions. */ #define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level. */ /* Legal values for MIPS architecture level. */ @@ -1412,6 +1724,38 @@ typedef struct #define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */ #define EF_MIPS_ARCH_32R2 0x70000000 /* MIPS32r2 code. */ #define EF_MIPS_ARCH_64R2 0x80000000 /* MIPS64r2 code. */ +#define EF_MIPS_ARCH_32R6 0x90000000 /* MIPS32r6 code. */ +#define EF_MIPS_ARCH_64R6 0xa0000000 /* MIPS64r6 code. */ +#define EF_MIPS_ABI 0x0000F000 /* The ABI of the file. Also + see EF_MIPS_ABI2 above. */ +#define EF_MIPS_ABI_O32 0x00001000 /* The original o32 abi. */ +#define EF_MIPS_ABI_O64 0x00002000 /* O32 extended to work on + 64 bit architectures. */ +#define EF_MIPS_ABI_EABI32 0x00003000 /* EABI in 32 bit mode. */ +#define EF_MIPS_ABI_EABI64 0x00004000 /* EABI in 64 bit mode. */ +#define EF_MIPS_MACH 0x00FF0000 +#define EF_MIPS_MACH_3900 0x00810000 +#define EF_MIPS_MACH_4010 0x00820000 +#define EF_MIPS_MACH_4100 0x00830000 +#define EF_MIPS_MACH_ALLEGREX 0x00840000 +#define EF_MIPS_MACH_4650 0x00850000 +#define EF_MIPS_MACH_4120 0x00870000 +#define EF_MIPS_MACH_4111 0x00880000 +#define EF_MIPS_MACH_SB1 0x008a0000 +#define EF_MIPS_MACH_OCTEON 0x008b0000 +#define EF_MIPS_MACH_XLR 0x008c0000 +#define EF_MIPS_MACH_OCTEON2 0x008d0000 +#define EF_MIPS_MACH_OCTEON3 0x008e0000 +#define EF_MIPS_MACH_5400 0x00910000 +#define EF_MIPS_MACH_5900 0x00920000 +#define EF_MIPS_MACH_IAMR2 0x00930000 +#define EF_MIPS_MACH_5500 0x00980000 +#define EF_MIPS_MACH_9000 0x00990000 +#define EF_MIPS_MACH_LS2E 0x00A00000 +#define EF_MIPS_MACH_LS2F 0x00A10000 +#define EF_MIPS_MACH_GS464 0x00A20000 +#define EF_MIPS_MACH_GS464E 0x00A30000 +#define EF_MIPS_MACH_GS264E 0x00A40000 /* The following are unofficial names and should not be used. */ @@ -1472,6 +1816,8 @@ typedef struct #define SHT_MIPS_EH_REGION 0x70000027 #define SHT_MIPS_XLATE_OLD 0x70000028 #define SHT_MIPS_PDR_EXCEPTION 0x70000029 +#define SHT_MIPS_ABIFLAGS 0x7000002a +#define SHT_MIPS_XHASH 0x7000002b /* Legal values for sh_flags field of Elf32_Shdr. */ @@ -1639,10 +1985,68 @@ typedef struct #define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */ #define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */ #define R_MIPS_GLOB_DAT 51 +#define R_MIPS_PC21_S2 60 +#define R_MIPS_PC26_S2 61 +#define R_MIPS_PC18_S3 62 +#define R_MIPS_PC19_S2 63 +#define R_MIPS_PCHI16 64 +#define R_MIPS_PCLO16 65 +#define R_MIPS16_26 100 +#define R_MIPS16_GPREL 101 +#define R_MIPS16_GOT16 102 +#define R_MIPS16_CALL16 103 +#define R_MIPS16_HI16 104 +#define R_MIPS16_LO16 105 +#define R_MIPS16_TLS_GD 106 +#define R_MIPS16_TLS_LDM 107 +#define R_MIPS16_TLS_DTPREL_HI16 108 +#define R_MIPS16_TLS_DTPREL_LO16 109 +#define R_MIPS16_TLS_GOTTPREL 110 +#define R_MIPS16_TLS_TPREL_HI16 111 +#define R_MIPS16_TLS_TPREL_LO16 112 +#define R_MIPS16_PC16_S1 113 #define R_MIPS_COPY 126 #define R_MIPS_JUMP_SLOT 127 +#define R_MIPS_RELATIVE 128 +#define R_MICROMIPS_26_S1 133 +#define R_MICROMIPS_HI16 134 +#define R_MICROMIPS_LO16 135 +#define R_MICROMIPS_GPREL16 136 +#define R_MICROMIPS_LITERAL 137 +#define R_MICROMIPS_GOT16 138 +#define R_MICROMIPS_PC7_S1 139 +#define R_MICROMIPS_PC10_S1 140 +#define R_MICROMIPS_PC16_S1 141 +#define R_MICROMIPS_CALL16 142 +#define R_MICROMIPS_GOT_DISP 145 +#define R_MICROMIPS_GOT_PAGE 146 +#define R_MICROMIPS_GOT_OFST 147 +#define R_MICROMIPS_GOT_HI16 148 +#define R_MICROMIPS_GOT_LO16 149 +#define R_MICROMIPS_SUB 150 +#define R_MICROMIPS_HIGHER 151 +#define R_MICROMIPS_HIGHEST 152 +#define R_MICROMIPS_CALL_HI16 153 +#define R_MICROMIPS_CALL_LO16 154 +#define R_MICROMIPS_SCN_DISP 155 +#define R_MICROMIPS_JALR 156 +#define R_MICROMIPS_HI0_LO16 157 +#define R_MICROMIPS_TLS_GD 162 +#define R_MICROMIPS_TLS_LDM 163 +#define R_MICROMIPS_TLS_DTPREL_HI16 164 +#define R_MICROMIPS_TLS_DTPREL_LO16 165 +#define R_MICROMIPS_TLS_GOTTPREL 166 +#define R_MICROMIPS_TLS_TPREL_HI16 169 +#define R_MICROMIPS_TLS_TPREL_LO16 170 +#define R_MICROMIPS_GPREL7_S2 172 +#define R_MICROMIPS_PC23_S2 173 +#define R_MIPS_PC32 248 +#define R_MIPS_EH 249 +#define R_MIPS_GNU_REL16_S2 250 +#define R_MIPS_GNU_VTINHERIT 253 +#define R_MIPS_GNU_VTENTRY 254 /* Keep this the last entry. */ -#define R_MIPS_NUM 128 +#define R_MIPS_NUM 255 /* Legal values for p_type field of Elf32_Phdr. */ @@ -1715,7 +2119,13 @@ typedef struct PLT is writable. For a non-writable PLT, this is omitted or has a zero value. */ #define DT_MIPS_RWPLT 0x70000034 -#define DT_MIPS_NUM 0x35 +/* An alternative description of the classic MIPS RLD_MAP that is usable + in a PIE as it stores a relative offset from the address of the tag + rather than an absolute address. */ +#define DT_MIPS_RLD_MAP_REL 0x70000035 +/* GNU-style hash table with xlat. */ +#define DT_MIPS_XHASH 0x70000036 +#define DT_MIPS_NUM 0x37 /* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ @@ -1886,9 +2296,9 @@ enum #define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ #define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ -/* Additional section indeces. */ +/* Additional section indices. */ -#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared +#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tentatively declared symbols in ANSI C. */ #define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ @@ -2207,6 +2617,8 @@ enum #define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ #define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ #define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ +#define R_PPC_TLSGD 95 /* none (sym+add)@tlsgd */ +#define R_PPC_TLSLD 96 /* none (sym+add)@tlsld */ /* The remaining relocs are from the Embedded ELF ABI, and are not in the SVR4 ELF ABI. */ @@ -2250,7 +2662,11 @@ enum /* PowerPC specific values for the Dyn d_tag field. */ #define DT_PPC_GOT (DT_LOPROC + 0) -#define DT_PPC_NUM 1 +#define DT_PPC_OPT (DT_LOPROC + 1) +#define DT_PPC_NUM 2 + +/* PowerPC specific values for the DT_PPC_OPT Dyn entry. */ +#define PPC_OPT_TLS 1 /* PowerPC64 relocations defined by the ABIs */ #define R_PPC64_NONE R_PPC_NONE @@ -2396,9 +2812,10 @@ enum #define DT_PPC64_OPT (DT_LOPROC + 3) #define DT_PPC64_NUM 4 -/* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry. */ +/* PowerPC64 specific bits in the DT_PPC64_OPT Dyn entry. */ #define PPC64_OPT_TLS 1 #define PPC64_OPT_MULTI_TOC 2 +#define PPC64_OPT_LOCALENTRY 4 /* PowerPC64 specific values for the Elf64_Sym st_other field. */ #define STO_PPC64_LOCAL_BIT 5 @@ -2610,6 +3027,18 @@ enum #define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */ #define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */ +/* MTE memory tag segment type. */ +#define PT_AARCH64_MEMTAG_MTE (PT_LOPROC + 2) + +/* AArch64 specific values for the Dyn d_tag field. */ +#define DT_AARCH64_BTI_PLT (DT_LOPROC + 1) +#define DT_AARCH64_PAC_PLT (DT_LOPROC + 3) +#define DT_AARCH64_VARIANT_PCS (DT_LOPROC + 5) +#define DT_AARCH64_NUM 6 + +/* AArch64 specific values for the st_other field. */ +#define STO_AARCH64_VARIANT_PCS 0x80 + /* ARM relocs. */ #define R_ARM_NONE 0 /* No reloc */ @@ -2778,6 +3207,81 @@ enum /* Keep this the last entry. */ #define R_ARM_NUM 256 +/* C-SKY */ +#define R_CKCORE_NONE 0 /* no reloc */ +#define R_CKCORE_ADDR32 1 /* direct 32 bit (S + A) */ +#define R_CKCORE_PCRELIMM8BY4 2 /* disp ((S + A - P) >> 2) & 0xff */ +#define R_CKCORE_PCRELIMM11BY2 3 /* disp ((S + A - P) >> 1) & 0x7ff */ +#define R_CKCORE_PCREL32 5 /* 32-bit rel (S + A - P) */ +#define R_CKCORE_PCRELJSR_IMM11BY2 6 /* disp ((S + A - P) >>1) & 0x7ff */ +#define R_CKCORE_RELATIVE 9 /* 32 bit adjust program base(B + A)*/ +#define R_CKCORE_COPY 10 /* 32 bit adjust by program base */ +#define R_CKCORE_GLOB_DAT 11 /* off between got and sym (S) */ +#define R_CKCORE_JUMP_SLOT 12 /* PLT entry (S) */ +#define R_CKCORE_GOTOFF 13 /* offset to GOT (S + A - GOT) */ +#define R_CKCORE_GOTPC 14 /* PC offset to GOT (GOT + A - P) */ +#define R_CKCORE_GOT32 15 /* 32 bit GOT entry (G) */ +#define R_CKCORE_PLT32 16 /* 32 bit PLT entry (G) */ +#define R_CKCORE_ADDRGOT 17 /* GOT entry in GLOB_DAT (GOT + G) */ +#define R_CKCORE_ADDRPLT 18 /* PLT entry in GLOB_DAT (GOT + G) */ +#define R_CKCORE_PCREL_IMM26BY2 19 /* ((S + A - P) >> 1) & 0x3ffffff */ +#define R_CKCORE_PCREL_IMM16BY2 20 /* disp ((S + A - P) >> 1) & 0xffff */ +#define R_CKCORE_PCREL_IMM16BY4 21 /* disp ((S + A - P) >> 2) & 0xffff */ +#define R_CKCORE_PCREL_IMM10BY2 22 /* disp ((S + A - P) >> 1) & 0x3ff */ +#define R_CKCORE_PCREL_IMM10BY4 23 /* disp ((S + A - P) >> 2) & 0x3ff */ +#define R_CKCORE_ADDR_HI16 24 /* high & low 16 bit ADDR */ + /* ((S + A) >> 16) & 0xffff */ +#define R_CKCORE_ADDR_LO16 25 /* (S + A) & 0xffff */ +#define R_CKCORE_GOTPC_HI16 26 /* high & low 16 bit GOTPC */ + /* ((GOT + A - P) >> 16) & 0xffff */ +#define R_CKCORE_GOTPC_LO16 27 /* (GOT + A - P) & 0xffff */ +#define R_CKCORE_GOTOFF_HI16 28 /* high & low 16 bit GOTOFF */ + /* ((S + A - GOT) >> 16) & 0xffff */ +#define R_CKCORE_GOTOFF_LO16 29 /* (S + A - GOT) & 0xffff */ +#define R_CKCORE_GOT12 30 /* 12 bit disp GOT entry (G) */ +#define R_CKCORE_GOT_HI16 31 /* high & low 16 bit GOT */ + /* (G >> 16) & 0xffff */ +#define R_CKCORE_GOT_LO16 32 /* (G & 0xffff) */ +#define R_CKCORE_PLT12 33 /* 12 bit disp PLT entry (G) */ +#define R_CKCORE_PLT_HI16 34 /* high & low 16 bit PLT */ + /* (G >> 16) & 0xffff */ +#define R_CKCORE_PLT_LO16 35 /* G & 0xffff */ +#define R_CKCORE_ADDRGOT_HI16 36 /* high & low 16 bit ADDRGOT */ + /* (GOT + G * 4) & 0xffff */ +#define R_CKCORE_ADDRGOT_LO16 37 /* (GOT + G * 4) & 0xffff */ +#define R_CKCORE_ADDRPLT_HI16 38 /* high & low 16 bit ADDRPLT */ + /* ((GOT + G * 4) >> 16) & 0xFFFF */ +#define R_CKCORE_ADDRPLT_LO16 39 /* (GOT+G*4) & 0xffff */ +#define R_CKCORE_PCREL_JSR_IMM26BY2 40 /* disp ((S+A-P) >>1) & x3ffffff */ +#define R_CKCORE_TOFFSET_LO16 41 /* (S+A-BTEXT) & 0xffff */ +#define R_CKCORE_DOFFSET_LO16 42 /* (S+A-BTEXT) & 0xffff */ +#define R_CKCORE_PCREL_IMM18BY2 43 /* disp ((S+A-P) >>1) & 0x3ffff */ +#define R_CKCORE_DOFFSET_IMM18 44 /* disp (S+A-BDATA) & 0x3ffff */ +#define R_CKCORE_DOFFSET_IMM18BY2 45 /* disp ((S+A-BDATA)>>1) & 0x3ffff */ +#define R_CKCORE_DOFFSET_IMM18BY4 46 /* disp ((S+A-BDATA)>>2) & 0x3ffff */ +#define R_CKCORE_GOT_IMM18BY4 48 /* disp (G >> 2) */ +#define R_CKCORE_PLT_IMM18BY4 49 /* disp (G >> 2) */ +#define R_CKCORE_PCREL_IMM7BY4 50 /* disp ((S+A-P) >>2) & 0x7f */ +#define R_CKCORE_TLS_LE32 51 /* 32 bit offset to TLS block */ +#define R_CKCORE_TLS_IE32 52 +#define R_CKCORE_TLS_GD32 53 +#define R_CKCORE_TLS_LDM32 54 +#define R_CKCORE_TLS_LDO32 55 +#define R_CKCORE_TLS_DTPMOD32 56 +#define R_CKCORE_TLS_DTPOFF32 57 +#define R_CKCORE_TLS_TPOFF32 58 + +/* C-SKY elf header definition. */ +#define EF_CSKY_ABIMASK 0XF0000000 +#define EF_CSKY_OTHER 0X0FFF0000 +#define EF_CSKY_PROCESSOR 0X0000FFFF + +#define EF_CSKY_ABIV1 0X10000000 +#define EF_CSKY_ABIV2 0X20000000 + +/* C-SKY attributes section. */ +#define SHT_CSKY_ATTRIBUTES (SHT_LOPROC + 1) + /* IA-64 specific declarations. */ /* Processor specific flags for the Ehdr e_flags field. */ @@ -3122,8 +3626,18 @@ enum #define R_X86_64_TLSDESC 36 /* TLS descriptor. */ #define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */ #define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */ + /* 39 Reserved was R_X86_64_PC32_BND */ + /* 40 Reserved was R_X86_64_PLT32_BND */ +#define R_X86_64_GOTPCRELX 41 /* Load from 32 bit signed pc relative + offset to GOT entry without REX + prefix, relaxable. */ +#define R_X86_64_REX_GOTPCRELX 42 /* Load from 32 bit signed pc relative + offset to GOT entry with REX prefix, + relaxable. */ +#define R_X86_64_NUM 43 -#define R_X86_64_NUM 39 +/* x86-64 sh_type values. */ +#define SHT_X86_64_UNWIND 0x70000001 /* Unwind information. */ /* AM33 relocations. */ @@ -3534,4 +4048,408 @@ enum #define R_TILEGX_NUM 130 +/* RISC-V ELF Flags */ +#define EF_RISCV_RVC 0x0001 +#define EF_RISCV_FLOAT_ABI 0x0006 +#define EF_RISCV_FLOAT_ABI_SOFT 0x0000 +#define EF_RISCV_FLOAT_ABI_SINGLE 0x0002 +#define EF_RISCV_FLOAT_ABI_DOUBLE 0x0004 +#define EF_RISCV_FLOAT_ABI_QUAD 0x0006 +#define EF_RISCV_RVE 0x0008 +#define EF_RISCV_TSO 0x0010 + +/* RISC-V relocations. */ +#define R_RISCV_NONE 0 +#define R_RISCV_32 1 +#define R_RISCV_64 2 +#define R_RISCV_RELATIVE 3 +#define R_RISCV_COPY 4 +#define R_RISCV_JUMP_SLOT 5 +#define R_RISCV_TLS_DTPMOD32 6 +#define R_RISCV_TLS_DTPMOD64 7 +#define R_RISCV_TLS_DTPREL32 8 +#define R_RISCV_TLS_DTPREL64 9 +#define R_RISCV_TLS_TPREL32 10 +#define R_RISCV_TLS_TPREL64 11 +#define R_RISCV_BRANCH 16 +#define R_RISCV_JAL 17 +#define R_RISCV_CALL 18 +#define R_RISCV_CALL_PLT 19 +#define R_RISCV_GOT_HI20 20 +#define R_RISCV_TLS_GOT_HI20 21 +#define R_RISCV_TLS_GD_HI20 22 +#define R_RISCV_PCREL_HI20 23 +#define R_RISCV_PCREL_LO12_I 24 +#define R_RISCV_PCREL_LO12_S 25 +#define R_RISCV_HI20 26 +#define R_RISCV_LO12_I 27 +#define R_RISCV_LO12_S 28 +#define R_RISCV_TPREL_HI20 29 +#define R_RISCV_TPREL_LO12_I 30 +#define R_RISCV_TPREL_LO12_S 31 +#define R_RISCV_TPREL_ADD 32 +#define R_RISCV_ADD8 33 +#define R_RISCV_ADD16 34 +#define R_RISCV_ADD32 35 +#define R_RISCV_ADD64 36 +#define R_RISCV_SUB8 37 +#define R_RISCV_SUB16 38 +#define R_RISCV_SUB32 39 +#define R_RISCV_SUB64 40 +#define R_RISCV_GNU_VTINHERIT 41 +#define R_RISCV_GNU_VTENTRY 42 +#define R_RISCV_ALIGN 43 +#define R_RISCV_RVC_BRANCH 44 +#define R_RISCV_RVC_JUMP 45 +#define R_RISCV_RVC_LUI 46 +#define R_RISCV_GPREL_I 47 +#define R_RISCV_GPREL_S 48 +#define R_RISCV_TPREL_I 49 +#define R_RISCV_TPREL_S 50 +#define R_RISCV_RELAX 51 +#define R_RISCV_SUB6 52 +#define R_RISCV_SET6 53 +#define R_RISCV_SET8 54 +#define R_RISCV_SET16 55 +#define R_RISCV_SET32 56 +#define R_RISCV_32_PCREL 57 +#define R_RISCV_IRELATIVE 58 +#define R_RISCV_PLT32 59 +#define R_RISCV_SET_ULEB128 60 +#define R_RISCV_SUB_ULEB128 61 + +#define R_RISCV_NUM 62 + +/* RISC-V specific values for the st_other field. */ +#define STO_RISCV_VARIANT_CC 0x80 /* Function uses variant calling + convention */ + +/* RISC-V specific values for the sh_type field. */ +#define SHT_RISCV_ATTRIBUTES (SHT_LOPROC + 3) + +/* RISC-V specific values for the p_type field. */ +#define PT_RISCV_ATTRIBUTES (PT_LOPROC + 3) + +/* RISC-V specific values for the d_tag field. */ +#define DT_RISCV_VARIANT_CC (DT_LOPROC + 1) + +/* BPF specific declarations. */ + +#define R_BPF_NONE 0 /* No reloc */ +#define R_BPF_64_64 1 +#define R_BPF_64_32 10 + +/* Imagination Meta specific relocations. */ + +#define R_METAG_HIADDR16 0 +#define R_METAG_LOADDR16 1 +#define R_METAG_ADDR32 2 /* 32bit absolute address */ +#define R_METAG_NONE 3 /* No reloc */ +#define R_METAG_RELBRANCH 4 +#define R_METAG_GETSETOFF 5 + +/* Backward compatibility */ +#define R_METAG_REG32OP1 6 +#define R_METAG_REG32OP2 7 +#define R_METAG_REG32OP3 8 +#define R_METAG_REG16OP1 9 +#define R_METAG_REG16OP2 10 +#define R_METAG_REG16OP3 11 +#define R_METAG_REG32OP4 12 + +#define R_METAG_HIOG 13 +#define R_METAG_LOOG 14 + +#define R_METAG_REL8 15 +#define R_METAG_REL16 16 + +/* GNU */ +#define R_METAG_GNU_VTINHERIT 30 +#define R_METAG_GNU_VTENTRY 31 + +/* PIC relocations */ +#define R_METAG_HI16_GOTOFF 32 +#define R_METAG_LO16_GOTOFF 33 +#define R_METAG_GETSET_GOTOFF 34 +#define R_METAG_GETSET_GOT 35 +#define R_METAG_HI16_GOTPC 36 +#define R_METAG_LO16_GOTPC 37 +#define R_METAG_HI16_PLT 38 +#define R_METAG_LO16_PLT 39 +#define R_METAG_RELBRANCH_PLT 40 +#define R_METAG_GOTOFF 41 +#define R_METAG_PLT 42 +#define R_METAG_COPY 43 +#define R_METAG_JMP_SLOT 44 +#define R_METAG_RELATIVE 45 +#define R_METAG_GLOB_DAT 46 + +/* TLS relocations */ +#define R_METAG_TLS_GD 47 +#define R_METAG_TLS_LDM 48 +#define R_METAG_TLS_LDO_HI16 49 +#define R_METAG_TLS_LDO_LO16 50 +#define R_METAG_TLS_LDO 51 +#define R_METAG_TLS_IE 52 +#define R_METAG_TLS_IENONPIC 53 +#define R_METAG_TLS_IENONPIC_HI16 54 +#define R_METAG_TLS_IENONPIC_LO16 55 +#define R_METAG_TLS_TPOFF 56 +#define R_METAG_TLS_DTPMOD 57 +#define R_METAG_TLS_DTPOFF 58 +#define R_METAG_TLS_LE 59 +#define R_METAG_TLS_LE_HI16 60 +#define R_METAG_TLS_LE_LO16 61 + +/* NDS32 relocations. */ +#define R_NDS32_NONE 0 +#define R_NDS32_32_RELA 20 +#define R_NDS32_COPY 39 +#define R_NDS32_GLOB_DAT 40 +#define R_NDS32_JMP_SLOT 41 +#define R_NDS32_RELATIVE 42 +#define R_NDS32_TLS_TPOFF 102 +#define R_NDS32_TLS_DESC 119 + +/* LoongArch ELF Flags */ +#define EF_LARCH_ABI_MODIFIER_MASK 0x07 +#define EF_LARCH_ABI_SOFT_FLOAT 0x01 +#define EF_LARCH_ABI_SINGLE_FLOAT 0x02 +#define EF_LARCH_ABI_DOUBLE_FLOAT 0x03 +#define EF_LARCH_OBJABI_V1 0x40 + +/* LoongArch specific dynamic relocations */ +#define R_LARCH_NONE 0 +#define R_LARCH_32 1 +#define R_LARCH_64 2 +#define R_LARCH_RELATIVE 3 +#define R_LARCH_COPY 4 +#define R_LARCH_JUMP_SLOT 5 +#define R_LARCH_TLS_DTPMOD32 6 +#define R_LARCH_TLS_DTPMOD64 7 +#define R_LARCH_TLS_DTPREL32 8 +#define R_LARCH_TLS_DTPREL64 9 +#define R_LARCH_TLS_TPREL32 10 +#define R_LARCH_TLS_TPREL64 11 +#define R_LARCH_IRELATIVE 12 + +/* Reserved for future relocs that the dynamic linker must understand. */ + +/* used by the static linker for relocating .text. */ +#define R_LARCH_MARK_LA 20 +#define R_LARCH_MARK_PCREL 21 +#define R_LARCH_SOP_PUSH_PCREL 22 +#define R_LARCH_SOP_PUSH_ABSOLUTE 23 +#define R_LARCH_SOP_PUSH_DUP 24 +#define R_LARCH_SOP_PUSH_GPREL 25 +#define R_LARCH_SOP_PUSH_TLS_TPREL 26 +#define R_LARCH_SOP_PUSH_TLS_GOT 27 +#define R_LARCH_SOP_PUSH_TLS_GD 28 +#define R_LARCH_SOP_PUSH_PLT_PCREL 29 +#define R_LARCH_SOP_ASSERT 30 +#define R_LARCH_SOP_NOT 31 +#define R_LARCH_SOP_SUB 32 +#define R_LARCH_SOP_SL 33 +#define R_LARCH_SOP_SR 34 +#define R_LARCH_SOP_ADD 35 +#define R_LARCH_SOP_AND 36 +#define R_LARCH_SOP_IF_ELSE 37 +#define R_LARCH_SOP_POP_32_S_10_5 38 +#define R_LARCH_SOP_POP_32_U_10_12 39 +#define R_LARCH_SOP_POP_32_S_10_12 40 +#define R_LARCH_SOP_POP_32_S_10_16 41 +#define R_LARCH_SOP_POP_32_S_10_16_S2 42 +#define R_LARCH_SOP_POP_32_S_5_20 43 +#define R_LARCH_SOP_POP_32_S_0_5_10_16_S2 44 +#define R_LARCH_SOP_POP_32_S_0_10_10_16_S2 45 +#define R_LARCH_SOP_POP_32_U 46 + +/* used by the static linker for relocating non .text. */ +#define R_LARCH_ADD8 47 +#define R_LARCH_ADD16 48 +#define R_LARCH_ADD24 49 +#define R_LARCH_ADD32 50 +#define R_LARCH_ADD64 51 +#define R_LARCH_SUB8 52 +#define R_LARCH_SUB16 53 +#define R_LARCH_SUB24 54 +#define R_LARCH_SUB32 55 +#define R_LARCH_SUB64 56 +#define R_LARCH_GNU_VTINHERIT 57 +#define R_LARCH_GNU_VTENTRY 58 + +/* reserved 59-63 */ + +#define R_LARCH_B16 64 +#define R_LARCH_B21 65 +#define R_LARCH_B26 66 +#define R_LARCH_ABS_HI20 67 +#define R_LARCH_ABS_LO12 68 +#define R_LARCH_ABS64_LO20 69 +#define R_LARCH_ABS64_HI12 70 +#define R_LARCH_PCALA_HI20 71 +#define R_LARCH_PCALA_LO12 72 +#define R_LARCH_PCALA64_LO20 73 +#define R_LARCH_PCALA64_HI12 74 +#define R_LARCH_GOT_PC_HI20 75 +#define R_LARCH_GOT_PC_LO12 76 +#define R_LARCH_GOT64_PC_LO20 77 +#define R_LARCH_GOT64_PC_HI12 78 +#define R_LARCH_GOT_HI20 79 +#define R_LARCH_GOT_LO12 80 +#define R_LARCH_GOT64_LO20 81 +#define R_LARCH_GOT64_HI12 82 +#define R_LARCH_TLS_LE_HI20 83 +#define R_LARCH_TLS_LE_LO12 84 +#define R_LARCH_TLS_LE64_LO20 85 +#define R_LARCH_TLS_LE64_HI12 86 +#define R_LARCH_TLS_IE_PC_HI20 87 +#define R_LARCH_TLS_IE_PC_LO12 88 +#define R_LARCH_TLS_IE64_PC_LO20 89 +#define R_LARCH_TLS_IE64_PC_HI12 90 +#define R_LARCH_TLS_IE_HI20 91 +#define R_LARCH_TLS_IE_LO12 92 +#define R_LARCH_TLS_IE64_LO20 93 +#define R_LARCH_TLS_IE64_HI12 94 +#define R_LARCH_TLS_LD_PC_HI20 95 +#define R_LARCH_TLS_LD_HI20 96 +#define R_LARCH_TLS_GD_PC_HI20 97 +#define R_LARCH_TLS_GD_HI20 98 +#define R_LARCH_32_PCREL 99 +#define R_LARCH_RELAX 100 +#define R_LARCH_DELETE 101 +#define R_LARCH_ALIGN 102 +#define R_LARCH_PCREL20_S2 103 +#define R_LARCH_CFA 104 +#define R_LARCH_ADD6 105 +#define R_LARCH_SUB6 106 +#define R_LARCH_ADD_ULEB128 107 +#define R_LARCH_SUB_ULEB128 108 +#define R_LARCH_64_PCREL 109 + +/* ARC specific declarations. */ + +/* Processor specific flags for the Ehdr e_flags field. */ +#define EF_ARC_MACH_MSK 0x000000ff +#define EF_ARC_OSABI_MSK 0x00000f00 +#define EF_ARC_ALL_MSK (EF_ARC_MACH_MSK | EF_ARC_OSABI_MSK) + +/* Processor specific values for the Shdr sh_type field. */ +#define SHT_ARC_ATTRIBUTES (SHT_LOPROC + 1) /* ARC attributes section. */ + +/* ARCompact/ARCv2 specific relocs. */ +#define R_ARC_NONE 0x0 +#define R_ARC_8 0x1 +#define R_ARC_16 0x2 +#define R_ARC_24 0x3 +#define R_ARC_32 0x4 + +#define R_ARC_B22_PCREL 0x6 +#define R_ARC_H30 0x7 +#define R_ARC_N8 0x8 +#define R_ARC_N16 0x9 +#define R_ARC_N24 0xA +#define R_ARC_N32 0xB +#define R_ARC_SDA 0xC +#define R_ARC_SECTOFF 0xD +#define R_ARC_S21H_PCREL 0xE +#define R_ARC_S21W_PCREL 0xF +#define R_ARC_S25H_PCREL 0x10 +#define R_ARC_S25W_PCREL 0x11 +#define R_ARC_SDA32 0x12 +#define R_ARC_SDA_LDST 0x13 +#define R_ARC_SDA_LDST1 0x14 +#define R_ARC_SDA_LDST2 0x15 +#define R_ARC_SDA16_LD 0x16 +#define R_ARC_SDA16_LD1 0x17 +#define R_ARC_SDA16_LD2 0x18 +#define R_ARC_S13_PCREL 0x19 +#define R_ARC_W 0x1A +#define R_ARC_32_ME 0x1B +#define R_ARC_N32_ME 0x1C +#define R_ARC_SECTOFF_ME 0x1D +#define R_ARC_SDA32_ME 0x1E +#define R_ARC_W_ME 0x1F +#define R_ARC_H30_ME 0x20 +#define R_ARC_SECTOFF_U8 0x21 +#define R_ARC_SECTOFF_S9 0x22 +#define R_AC_SECTOFF_U8 0x23 +#define R_AC_SECTOFF_U8_1 0x24 +#define R_AC_SECTOFF_U8_2 0x25 +#define R_AC_SECTOFF_S9 0x26 +#define R_AC_SECTOFF_S9_1 0x27 +#define R_AC_SECTOFF_S9_2 0x28 +#define R_ARC_SECTOFF_ME_1 0x29 +#define R_ARC_SECTOFF_ME_2 0x2A +#define R_ARC_SECTOFF_1 0x2B +#define R_ARC_SECTOFF_2 0x2C +#define R_ARC_SDA_12 0x2D +#define R_ARC_SDA16_ST2 0x30 +#define R_ARC_32_PCREL 0x31 +#define R_ARC_PC32 0x32 +#define R_ARC_GOTPC32 0x33 +#define R_ARC_PLT32 0x34 +#define R_ARC_COPY 0x35 +#define R_ARC_GLOB_DAT 0x36 +#define R_ARC_JMP_SLOT 0x37 +#define R_ARC_RELATIVE 0x38 +#define R_ARC_GOTOFF 0x39 +#define R_ARC_GOTPC 0x3A +#define R_ARC_GOT32 0x3B +#define R_ARC_S21W_PCREL_PLT 0x3C +#define R_ARC_S25H_PCREL_PLT 0x3D + +#define R_ARC_JLI_SECTOFF 0x3F + +#define R_ARC_TLS_DTPMOD 0x42 +#define R_ARC_TLS_DTPOFF 0x43 +#define R_ARC_TLS_TPOFF 0x44 +#define R_ARC_TLS_GD_GOT 0x45 +#define R_ARC_TLS_GD_LD 0x46 +#define R_ARC_TLS_GD_CALL 0x47 +#define R_ARC_TLS_IE_GOT 0x48 +#define R_ARC_TLS_DTPOFF_S9 0x49 +#define R_ARC_TLS_LE_S9 0x4A +#define R_ARC_TLS_LE_32 0x4B +#define R_ARC_S25W_PCREL_PLT 0x4C +#define R_ARC_S21H_PCREL_PLT 0x4D +#define R_ARC_NPS_CMEM16 0x4E + +/* OpenRISC 1000 specific relocs. */ +#define R_OR1K_NONE 0 +#define R_OR1K_32 1 +#define R_OR1K_16 2 +#define R_OR1K_8 3 +#define R_OR1K_LO_16_IN_INSN 4 +#define R_OR1K_HI_16_IN_INSN 5 +#define R_OR1K_INSN_REL_26 6 +#define R_OR1K_GNU_VTENTRY 7 +#define R_OR1K_GNU_VTINHERIT 8 +#define R_OR1K_32_PCREL 9 +#define R_OR1K_16_PCREL 10 +#define R_OR1K_8_PCREL 11 +#define R_OR1K_GOTPC_HI16 12 +#define R_OR1K_GOTPC_LO16 13 +#define R_OR1K_GOT16 14 +#define R_OR1K_PLT26 15 +#define R_OR1K_GOTOFF_HI16 16 +#define R_OR1K_GOTOFF_LO16 17 +#define R_OR1K_COPY 18 +#define R_OR1K_GLOB_DAT 19 +#define R_OR1K_JMP_SLOT 20 +#define R_OR1K_RELATIVE 21 +#define R_OR1K_TLS_GD_HI16 22 +#define R_OR1K_TLS_GD_LO16 23 +#define R_OR1K_TLS_LDM_HI16 24 +#define R_OR1K_TLS_LDM_LO16 25 +#define R_OR1K_TLS_LDO_HI16 26 +#define R_OR1K_TLS_LDO_LO16 27 +#define R_OR1K_TLS_IE_HI16 28 +#define R_OR1K_TLS_IE_LO16 29 +#define R_OR1K_TLS_LE_HI16 30 +#define R_OR1K_TLS_LE_LO16 31 +#define R_OR1K_TLS_TPOFF 32 +#define R_OR1K_TLS_DTPOFF 33 +#define R_OR1K_TLS_DTPMOD 34 + #endif /* elf.h */ @@ -1,15 +1,14 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 2012-2014 Gentoo Foundation -# Copyright 2012-2014 Mike Frysinger <vapier@gentoo.org> -# Copyright 2012-2014 The Chromium OS Authors +#!/usr/bin/env python +# PYTHON_ARGCOMPLETE_OK +# Copyright 2012-2024 Gentoo Foundation +# Copyright 2012-2024 Mike Frysinger <vapier@gentoo.org> +# Copyright 2012-2024 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license (BSD-3) -# pylint: disable=C0301 """Read the ELF dependency tree and show it This does not work like `ldd` in that we do not execute/load code (only read -files on disk), and we should the ELFs as a tree rather than a flat list. +files on disk), and we show the ELFs as a tree rather than a flat list. Paths may be globs that lddtree will take care of expanding. Useful when you want to glob a path under the ROOT path. @@ -41,764 +40,996 @@ This will place bash, lspci, and lsof into /foo/bin/. All the libraries they need will be placed into /foo/lib/ only. """ -from __future__ import print_function - import argparse -import glob import errno +import functools +import glob +import mmap import os +import re import shutil import sys +from typing import Any, cast, Dict, Iterable, List, Optional, Tuple, Union + + +assert sys.version_info >= (3, 8), f"Python 3.8+ required, but found {sys.version}" + +# Disable import errors for all 3rd party modules. +# pylint: disable=import-error +try: + import argcomplete # type: ignore +except ImportError: + argcomplete = cast(Any, None) + +from elftools.common import exceptions # type: ignore +from elftools.elf.elffile import ELFFile # type: ignore + -from elftools.elf.elffile import ELFFile -from elftools.common import exceptions +# pylint: enable=import-error -def warn(msg, prefix='warning'): - """Write |msg| to stderr with a |prefix| before it""" - print('%s: %s: %s' % (os.path.basename(sys.argv[0]), prefix, msg), file=sys.stderr) +def warn(msg: Any, prefix: Optional[str] = "warning") -> None: + """Write |msg| to stderr with a |prefix| before it""" + print(f"{os.path.basename(sys.argv[0])}: {prefix}: {msg}", file=sys.stderr) -def err(msg, status=1): - """Write |msg| to stderr and exit with |status|""" - warn(msg, prefix='error') - sys.exit(status) +def err(msg: Any, status: Optional[int] = 1) -> None: + """Write |msg| to stderr and exit with |status|""" + warn(msg, prefix="error") + sys.exit(status) -def dbg(debug, *args, **kwargs): - """Pass |args| and |kwargs| to print() when |debug| is True""" - if debug: - print(*args, **kwargs) +def dbg(debug: bool, *args, **kwargs) -> None: + """Pass |args| and |kwargs| to print() when |debug| is True""" + if debug: + print(*args, **kwargs) -def bstr(buf): - """Decode the byte string into a string""" - if isinstance(buf, str): - return buf - return buf.decode('utf-8') +def bstr(buf: Union[bytes, str]) -> str: + """Decode the byte string into a string""" + if isinstance(buf, str): + return buf + return buf.decode("utf-8") -def normpath(path): - """Normalize a path +def normpath(path: str) -> str: + """Normalize a path - Python's os.path.normpath() doesn't handle some cases: - // -> // - //..// -> // - //..//..// -> /// - """ - return os.path.normpath(path).replace('//', '/') + Python's os.path.normpath() doesn't handle some cases: + // -> // + //..// -> // + //..//..// -> /// + """ + return os.path.normpath(path).replace("//", "/") -def readlink(path, root, prefixed=False): - """Like os.readlink(), but relative to a |root| +@functools.lru_cache(maxsize=None) +def readlink(path: str, root: str, prefixed: Optional[bool] = False) -> str: + """Like os.readlink(), but relative to a |root| - This does not currently handle the pathological case: - /lib/foo.so -> ../../../../../../../foo.so - This relies on the .. entries in / to point to itself. + This does not currently handle the pathological case: + /lib/foo.so -> ../../../../../../../foo.so + This relies on the .. entries in / to point to itself. - Args: - path: The symlink to read - root: The path to use for resolving absolute symlinks - prefixed: When False, the |path| must not have |root| prefixed to it, nor - will the return value have |root| prefixed. When True, |path| - must have |root| prefixed, and the return value will have |root| - added. + Args: + path: The symlink to read + root: The path to use for resolving absolute symlinks + prefixed: When False, the |path| must not have |root| prefixed to it, nor + will the return value have |root| prefixed. When True, |path| + must have |root| prefixed, and the return value will have |root| + added. - Returns: - A fully resolved symlink path - """ - root = root.rstrip('/') - if prefixed: - path = path[len(root):] + Returns: + A fully resolved symlink path + """ + root = root.rstrip("/") + if prefixed: + path = path[len(root) :] - while os.path.islink(root + path): - path = os.path.join(os.path.dirname(path), os.readlink(root + path)) + while os.path.islink(root + path): + path = os.path.join(os.path.dirname(path), os.readlink(root + path)) - return normpath((root + path) if prefixed else path) + return normpath((root + path) if prefixed else path) -def makedirs(path): - """Like os.makedirs(), but ignore EEXIST errors""" - try: - os.makedirs(path) - except OSError as e: - if e.errno != errno.EEXIST: - raise +def dedupe(items: List[str]) -> List[str]: + """Remove all duplicates from |items| (keeping order)""" + seen: Dict[str, str] = {} + return [seen.setdefault(x, x) for x in items if x not in seen] -def dedupe(items): - """Remove all duplicates from |items| (keeping order)""" - seen = {} - return [seen.setdefault(x, x) for x in items if x not in seen] +@functools.lru_cache(maxsize=None) +def interp_supports_argv0(interp: str) -> bool: + """See whether |interp| supports the --argv0 option. + Starting with glibc-2.33, the ldso supports --argv0 to override argv[0]. + """ + with open(interp, "rb") as fp: + with mmap.mmap(fp.fileno(), 0, prot=mmap.PROT_READ) as mm: + return mm.find(b"--argv0") >= 0 -def GenerateLdsoWrapper(root, path, interp, libpaths=()): - """Generate a shell script wrapper which uses local ldso to run the ELF - Since we cannot rely on the host glibc (or other libraries), we need to - execute the local packaged ldso directly and tell it where to find our - copies of libraries. +def GenerateLdsoWrapper( + root: str, + path: str, + interp: str, + libpaths: Iterable[str] = (), + preload: Optional[str] = None, +) -> None: + """Generate a shell script wrapper which uses local ldso to run the ELF + + Since we cannot rely on the host glibc (or other libraries), we need to + execute the local packaged ldso directly and tell it where to find our + copies of libraries. + + Args: + root: The root tree to generate scripts inside of + path: The full path (inside |root|) to the program to wrap + interp: The ldso interpreter that we need to execute + libpaths: Extra lib paths to search for libraries + """ + basedir = os.path.dirname(path) + interp_dir, interp_name = os.path.split(interp) + # Add ldso interpreter dir to end of libpaths as a fallback library path. + libpaths = dedupe(list(libpaths) + [interp_dir]) + if preload: + # If preload is an absolute path, calculate it from basedir. + preload_prefix = f'${{basedir}}/{os.path.relpath("/", basedir)}' + preload = ":".join( + f"{preload_prefix}{x}" if os.path.isabs(x) else x + for x in re.split(r"[ :]", preload) + ) + + replacements = { + "interp": os.path.join(os.path.relpath(interp_dir, basedir), interp_name), + "interp_rel": os.path.relpath(path, interp_dir), + "libpaths": ":".join( + "${basedir}/" + os.path.relpath(p, basedir) for p in libpaths + ), + "argv0_arg": '--argv0 "$0"' if interp_supports_argv0(root + interp) else "", + "preload_arg": f'--preload "{preload}"' if preload else "", + } - Args: - root: The root tree to generate scripts inside of - path: The full path (inside |root|) to the program to wrap - interp: The ldso interpreter that we need to execute - libpaths: Extra lib paths to search for libraries - """ - basedir = os.path.dirname(path) - interp_dir, interp_name = os.path.split(interp) - libpaths = dedupe([interp_dir] + list(libpaths)) - replacements = { - 'interp': os.path.join(os.path.relpath(interp_dir, basedir), - interp_name), - 'libpaths': ':'.join(['${basedir}/' + os.path.relpath(p, basedir) - for p in libpaths]), - } - wrapper = """#!/bin/sh -if ! base=$(realpath "$0" 2>/dev/null); then + # Keep path relativeness of argv0 (in ${base}.elf). This allows tools to + # remove absolute paths from build outputs and enables directory independent + # cache sharing in distributed build systems. + # + # NB: LD_ARGV0_REL below is unrelated & non-standard. It's to let tools see + # the original path if they need it and when they know they'll be wrapped up + # by this script. + wrapper = """#!/bin/sh +if base=$(readlink "$0" 2>/dev/null); then + # If $0 is an abspath symlink, fully resolve the target. + case ${base} in + /*) base=$(readlink -f "$0" 2>/dev/null);; + *) base=$(dirname "$0")/${base};; + esac +else case $0 in /*) base=$0;; *) base=${PWD:-`pwd`}/$0;; esac fi basedir=${base%%/*} -exec \ - "${basedir}/%(interp)s" \ - --library-path "%(libpaths)s" \ - --inhibit-cache \ - --inhibit-rpath '' \ - "${base}.elf" \ +LD_ARGV0_REL="%(interp_rel)s" \\ +exec \\ + "${basedir}/%(interp)s" \\ + %(argv0_arg)s \\ + %(preload_arg)s \\ + --library-path "%(libpaths)s" \\ + --inhibit-cache \\ + --inhibit-rpath '' \\ + "${base}.elf" \\ "$@" """ - wrappath = root + path - os.rename(wrappath, wrappath + '.elf') - with open(wrappath, 'w') as f: - f.write(wrapper % replacements) - os.chmod(wrappath, 0o0755) - - -def ParseLdPaths(str_ldpaths, root='', path=None): - """Parse the colon-delimited list of paths and apply ldso rules to each - - Note the special handling as dictated by the ldso: - - Empty paths are equivalent to $PWD - - $ORIGIN is expanded to the path of the given file - - (TODO) $LIB and friends - - Args: - str_ldpaths: A colon-delimited string of paths - root: The path to prepend to all paths found - path: The object actively being parsed (used for $ORIGIN) - - Returns: - list of processed paths - """ - ldpaths = [] - for ldpath in str_ldpaths.split(':'): - if ldpath == '': - # The ldso treats "" paths as $PWD. - ldpath = os.getcwd() - elif '$ORIGIN' in ldpath: - ldpath = ldpath.replace('$ORIGIN', os.path.dirname(path)) - else: - ldpath = root + ldpath - ldpaths.append(normpath(ldpath)) - return dedupe(ldpaths) - - -def ParseLdSoConf(ldso_conf, root='/', debug=False, _first=True): - """Load all the paths from a given ldso config file - - This should handle comments, whitespace, and "include" statements. - - Args: - ldso_conf: The file to scan - root: The path to prepend to all paths found - debug: Enable debug output - _first: Recursive use only; is this the first ELF ? - - Returns: - list of paths found - """ - paths = [] - - dbg_pfx = '' if _first else ' ' - try: - dbg(debug, '%sParseLdSoConf(%s)' % (dbg_pfx, ldso_conf)) - with open(ldso_conf) as f: - for line in f.readlines(): - line = line.split('#', 1)[0].strip() - if not line: - continue - if line.startswith('include '): - line = line[8:] - if line[0] == '/': - line = root + line.lstrip('/') - else: - line = os.path.dirname(ldso_conf) + '/' + line - dbg(debug, '%s glob: %s' % (dbg_pfx, line)) - # ldconfig in glibc uses glob() which returns entries sorted according - # to LC_COLLATE. Further, ldconfig does not reset that but respects - # the active env settings (which might be a mistake). Python does not - # sort its results by default though, so do it ourselves. - for path in sorted(glob.glob(line)): - paths += ParseLdSoConf(path, root=root, debug=debug, _first=False) + wrappath = root + path + os.rename(wrappath, wrappath + ".elf") + with open(wrappath, "w", encoding="utf-8") as f: + f.write(wrapper % replacements) + os.chmod(wrappath, 0o0755) + + +@functools.lru_cache(maxsize=None) +def ParseLdPaths( + str_ldpaths: str, + root: str = "", + cwd: Optional[str] = None, + path: str = "", +) -> List[str]: + """Parse the colon-delimited list of paths and apply ldso rules to each + + Note the special handling as dictated by the ldso: + - Empty paths are equivalent to $PWD + - $ORIGIN is expanded to the path of the given file + - (TODO) $LIB and friends + + Args: + str_ldpaths: A colon-delimited string of paths + root: The path to prepend to all paths found + cwd: The path to resolve relative paths against (defaults to getcwd()). + path: The object actively being parsed (used for $ORIGIN) + + Returns: + list of processed paths + """ + if cwd is None: + cwd = os.getcwd() + + ldpaths = [] + for ldpath in str_ldpaths.split(":"): + # Expand placeholders first. + if "$ORIGIN" in ldpath: + ldpath = ldpath.replace("$ORIGIN", os.path.dirname(path)) + elif "${ORIGIN}" in ldpath: + ldpath = ldpath.replace("${ORIGIN}", os.path.dirname(path)) + + # Expand relative paths if needed. These don't make sense in general, + # but that doesn't stop people from using them. As such, root prefix + # doesn't make sense with it either. + if not ldpath.startswith("/"): + # NB: The ldso treats "" paths as cwd too. + ldpath = os.path.join(cwd, ldpath) else: - paths += [normpath(root + line)] - except IOError as e: - if e.errno != errno.ENOENT: - warn(e) - - if _first: - # XXX: Load paths from ldso itself. - # Remove duplicate entries to speed things up. - paths = dedupe(paths) - - return paths - - -def LoadLdpaths(root='/', prefix='', debug=False): - """Load linker paths from common locations - - This parses the ld.so.conf and LD_LIBRARY_PATH env var. - - Args: - root: The root tree to prepend to paths - prefix: The path under |root| to search - debug: Enable debug output - - Returns: - dict containing library paths to search - """ - ldpaths = { - 'conf': [], - 'env': [], - 'interp': [], - } - - # Load up $LD_LIBRARY_PATH. - ldpaths['env'] = [] - env_ldpath = os.environ.get('LD_LIBRARY_PATH') - if not env_ldpath is None: - if root != '/': - warn('ignoring LD_LIBRARY_PATH due to ROOT usage') - else: - # XXX: If this contains $ORIGIN, we probably have to parse this - # on a per-ELF basis so it can get turned into the right thing. - ldpaths['env'] = ParseLdPaths(env_ldpath, path='') - - # Load up /etc/ld.so.conf. - ldpaths['conf'] = ParseLdSoConf(root + prefix + '/etc/ld.so.conf', root=root, - debug=debug) - - return ldpaths - - -def CompatibleELFs(elf1, elf2): - """See if two ELFs are compatible - - This compares the aspects of the ELF to see if they're compatible: - bit size, endianness, machine type, and operating system. - - Args: - elf1: an ELFFile object - elf2: an ELFFile object - - Returns: - True if compatible, False otherwise - """ - osabis = frozenset([e.header['e_ident']['EI_OSABI'] for e in (elf1, elf2)]) - compat_sets = ( - frozenset('ELFOSABI_%s' % x for x in ('NONE', 'SYSV', 'GNU', 'LINUX',)), - ) - return ((len(osabis) == 1 or any(osabis.issubset(x) for x in compat_sets)) and - elf1.elfclass == elf2.elfclass and - elf1.little_endian == elf2.little_endian and - elf1.header['e_machine'] == elf2.header['e_machine']) - - -def FindLib(elf, lib, ldpaths, root='/', debug=False): - """Try to locate a |lib| that is compatible to |elf| in the given |ldpaths| - - Args: - elf: The elf which the library should be compatible with (ELF wise) - lib: The library (basename) to search for - ldpaths: A list of paths to search - root: The root path to resolve symlinks - debug: Enable debug output - - Returns: - Tuple of the full path to the desired library and the real path to it - """ - dbg(debug, ' FindLib(%s)' % lib) - - for ldpath in ldpaths: - path = os.path.join(ldpath, lib) - target = readlink(path, root, prefixed=True) - if path != target: - dbg(debug, ' checking: %s -> %s' % (path, target)) - else: - dbg(debug, ' checking:', path) + ldpath = root + ldpath + + ldpaths.append(normpath(ldpath)) + + return dedupe(ldpaths) - if os.path.exists(target): - with open(target, 'rb') as f: - try: - libelf = ELFFile(f) - if CompatibleELFs(elf, libelf): - return (target, path) - except exceptions.ELFError as e: - warn('%s: %s' % (target, e)) - return (None, None) +def ParseLdSoConf( + ldso_conf: str, + root: str = "/", + debug: bool = False, + _first: bool = True, +) -> List[str]: + """Load all the paths from a given ldso config file + + This should handle comments, whitespace, and "include" statements. + + Args: + ldso_conf: The file to scan + root: The path to prepend to all paths found + debug: Enable debug output + _first: Recursive use only; is this the first ELF ? + + Returns: + list of paths found + """ + paths = [] + + dbg_pfx = "" if _first else " " + try: + dbg(debug, f"{dbg_pfx}ParseLdSoConf({ldso_conf})") + with open(ldso_conf, encoding="utf-8") as f: + for line in f.readlines(): + line = line.split("#", 1)[0].strip() + if not line: + continue + if line.startswith("include "): + line = line[8:] + if line[0] == "/": + line = root + line.lstrip("/") + else: + line = os.path.dirname(ldso_conf) + "/" + line + dbg(debug, dbg_pfx, "glob:", line) + # ldconfig in glibc uses glob() which returns entries sorted according + # to LC_COLLATE. Further, ldconfig does not reset that but respects + # the active env settings (which might be a mistake). Python does not + # sort its results by default though, so do it ourselves. + for path in sorted(glob.glob(line)): + paths += ParseLdSoConf( + path, root=root, debug=debug, _first=False + ) + else: + paths += [normpath(root + line)] + except IOError as e: + if e.errno != errno.ENOENT: + warn(e) + + if _first: + # XXX: Load paths from ldso itself. + # Remove duplicate entries to speed things up. + paths = dedupe(paths) + + return paths + + +def LoadLdpaths( + root: str = "/", + cwd: Optional[str] = None, + prefix: str = "", + debug: bool = False, +) -> Dict[str, List[str]]: + """Load linker paths from common locations + + This parses the ld.so.conf and LD_LIBRARY_PATH env var. + + Args: + root: The root tree to prepend to paths + cwd: The path to resolve relative paths against + prefix: The path under |root| to search + debug: Enable debug output + + Returns: + dict containing library paths to search + """ + ldpaths: Dict[str, List[str]] = { + "conf": [], + "env": [], + "interp": [], + } + + # Load up $LD_LIBRARY_PATH. + ldpaths["env"] = [] + env_ldpath = os.environ.get("LD_LIBRARY_PATH") + if not env_ldpath is None: + if root != "/": + warn("ignoring LD_LIBRARY_PATH due to ROOT usage") + else: + # XXX: If this contains $ORIGIN, we probably have to parse this + # on a per-ELF basis so it can get turned into the right thing. + ldpaths["env"] = ParseLdPaths(env_ldpath, cwd=cwd, path="") + + # Load up /etc/ld.so.conf. + ldpaths["conf"] = ParseLdSoConf( + root + prefix + "/etc/ld.so.conf", root=root, debug=debug + ) + + return ldpaths + + +def CompatibleELFs(elf1: ELFFile, elf2: ELFFile) -> bool: + """See if two ELFs are compatible + + This compares the aspects of the ELF to see if they're compatible: + bit size, endianness, machine type, and operating system. + + Args: + elf1: an ELFFile object + elf2: an ELFFile object + + Returns: + True if compatible, False otherwise + """ + osabis = frozenset([e.header["e_ident"]["EI_OSABI"] for e in (elf1, elf2)]) + compat_sets = ( + frozenset(f"ELFOSABI_{x}" for x in ("NONE", "SYSV", "GNU", "LINUX")), + ) + return ( + (len(osabis) == 1 or any(osabis.issubset(x) for x in compat_sets)) + and elf1.elfclass == elf2.elfclass + and elf1.little_endian == elf2.little_endian + and elf1.header["e_machine"] == elf2.header["e_machine"] + ) + + +def FindLib( + elf: ELFFile, + lib: str, + ldpaths: List[str], + root: str = "/", + debug: bool = False, +) -> Tuple[Optional[str], Optional[str]]: + """Try to locate a |lib| that is compatible to |elf| in the given |ldpaths| + + Args: + elf: The elf which the library should be compatible with (ELF wise) + lib: The library (basename) to search for + ldpaths: A list of paths to search + root: The root path to resolve symlinks + debug: Enable debug output + + Returns: + Tuple of the full path to the desired library and the real path to it + """ + dbg(debug, f" FindLib({lib})") + + for ldpath in ldpaths: + path = os.path.join(ldpath, lib) + target = readlink(path, root, prefixed=True) + if path != target: + dbg(debug, " checking:", path, "->", target) + else: + dbg(debug, " checking:", path) + + if os.path.exists(target): + with open(target, "rb") as f: + try: + libelf = ELFFile(f) + if CompatibleELFs(elf, libelf): + return (target, path) + except exceptions.ELFError as e: + warn(f"{target}: {e}") + + return (None, None) # We abuse the _all_libs state. We probably shouldn't, but we do currently. # pylint: disable=dangerous-default-value -def ParseELF(path, root='/', prefix='', ldpaths={'conf':[], 'env':[], 'interp':[]}, - display=None, debug=False, _first=True, _all_libs={}): - """Parse the ELF dependency tree of the specified file - - Args: - path: The ELF to scan - root: The root tree to prepend to paths; this applies to interp and rpaths +def ParseELF( + path: str, + root: str = "/", + cwd: Optional[str] = None, + prefix: str = "", + ldpaths={"conf": [], "env": [], "interp": []}, + display: Optional[str] = None, + debug: bool = False, + _first: bool = True, + _all_libs={}, +) -> Dict[str, Any]: + """Parse the ELF dependency tree of the specified file + + Args: + path: The ELF to scan + root: The root tree to prepend to paths; this applies to interp and rpaths only as |path| and |ldpaths| are expected to be prefixed already - prefix: The path under |root| to search - ldpaths: dict containing library paths to search; should have the keys: - conf, env, interp - display: The path to show rather than |path| - debug: Enable debug output - _first: Recursive use only; is this the first ELF ? - _all_libs: Recursive use only; dict of all libs we've seen - - Returns: - a dict containing information about all the ELFs; e.g. - { - 'interp': '/lib64/ld-linux.so.2', - 'needed': ['libc.so.6', 'libcurl.so.4',], - 'libs': { - 'libc.so.6': { - 'path': '/lib64/libc.so.6', - 'needed': [], - }, - 'libcurl.so.4': { - 'path': '/usr/lib64/libcurl.so.4', - 'needed': ['libc.so.6', 'librt.so.1',], + cwd: The path to resolve relative paths against. + prefix: The path under |root| to search + ldpaths: dict containing library paths to search; should have the keys: + conf, env, interp + display: The path to show rather than |path| + debug: Enable debug output + _first: Recursive use only; is this the first ELF ? + _all_libs: Recursive use only; dict of all libs we've seen + + Returns: + a dict containing information about all the ELFs; e.g. + { + 'interp': '/lib64/ld-linux.so.2', + 'needed': ['libc.so.6', 'libcurl.so.4',], + 'libs': { + 'libc.so.6': { + 'path': '/lib64/libc.so.6', + 'needed': [], + }, + 'libcurl.so.4': { + 'path': '/usr/lib64/libcurl.so.4', + 'needed': ['libc.so.6', 'librt.so.1',], + }, }, - }, - } - """ - if _first: - _all_libs = {} - ldpaths = ldpaths.copy() - ret = { - 'interp': None, - 'path': path if display is None else display, - 'realpath': path, - 'needed': [], - 'rpath': [], - 'runpath': [], - 'libs': _all_libs, - } - - dbg(debug, 'ParseELF(%s)' % path) - - with open(path, 'rb') as f: - elf = ELFFile(f) - - # If this is the first ELF, extract the interpreter. + } + """ if _first: - for segment in elf.iter_segments(): - if segment.header.p_type != 'PT_INTERP': - continue - - interp = bstr(segment.get_interp_name()) - dbg(debug, ' interp =', interp) - ret['interp'] = normpath(root + interp) - real_interp = readlink(ret['interp'], root, prefixed=True) - ret['libs'][os.path.basename(interp)] = { - 'path': ret['interp'], - 'realpath': real_interp, - 'needed': [], - } - # XXX: Could read it and scan for /lib paths. - # If the interp is a symlink, lets follow it on the assumption that it - # is in this path purely for ABI reasons, and the distro is using a - # different (probably more correct) path. This can come up in some - # multilib situations like s390x where /lib64/ contains all the native - # libraries, but /lib/ld64.so.1 is the interp hardcoded in gcc, so the - # ld64.so.1 is really a symlink to ../lib64/ld64.so.1. In the multiarch - # setup, it'll be /lib/ld64.so.1 -> /lib/s390x-linux-gnu/ld64.so.1. - # That is why we use |real_interp| here instead of |interp|. - ldpaths['interp'] = [ - os.path.dirname(real_interp), - normpath(root + prefix + '/usr/' + os.path.dirname( - real_interp)[len(root) + len(prefix):]), - ] - dbg(debug, ' ldpaths[interp] =', ldpaths['interp']) - break - - # Parse the ELF's dynamic tags. - libs = [] - rpaths = [] - runpaths = [] - for segment in elf.iter_segments(): - if segment.header.p_type != 'PT_DYNAMIC': - continue - - for t in segment.iter_tags(): - if t.entry.d_tag == 'DT_RPATH': - rpaths = ParseLdPaths(bstr(t.rpath), root=root, path=path) - elif t.entry.d_tag == 'DT_RUNPATH': - runpaths = ParseLdPaths(bstr(t.runpath), root=root, path=path) - elif t.entry.d_tag == 'DT_NEEDED': - libs.append(bstr(t.needed)) - if runpaths: - # If both RPATH and RUNPATH are set, only the latter is used. - rpaths = [] + _all_libs = {} + ldpaths = ldpaths.copy() + ret: Dict[str, Any] = { + "interp": None, + "path": path if display is None else display, + "realpath": path, + "needed": [], + "rpath": [], + "runpath": [], + "libs": _all_libs, + } - # XXX: We assume there is only one PT_DYNAMIC. This is - # probably fine since the runtime ldso does the same. - break - if _first: - # Propagate the rpaths used by the main ELF since those will be - # used at runtime to locate things. - ldpaths['rpath'] = rpaths - ldpaths['runpath'] = runpaths - dbg(debug, ' ldpaths[rpath] =', rpaths) - dbg(debug, ' ldpaths[runpath] =', runpaths) - ret['rpath'] = rpaths - ret['runpath'] = runpaths - ret['needed'] = libs - - # Search for the libs this ELF uses. - all_ldpaths = None - for lib in libs: - if lib in _all_libs: - continue - if all_ldpaths is None: - all_ldpaths = rpaths + ldpaths['rpath'] + ldpaths['env'] + runpaths + ldpaths['runpath'] + ldpaths['conf'] + ldpaths['interp'] - realpath, fullpath = FindLib(elf, lib, all_ldpaths, root, debug=debug) - _all_libs[lib] = { - 'realpath': realpath, - 'path': fullpath, - 'needed': [], - } - if fullpath: + dbg(debug, f"ParseELF({path})") + + with open(path, "rb") as f: try: - lret = ParseELF(realpath, root, prefix, ldpaths, display=fullpath, - debug=debug, _first=False, _all_libs=_all_libs) - except exceptions.ELFError as e: - warn('%s: %s' % (realpath, e)) - _all_libs[lib]['needed'] = lret['needed'] + elf = ELFFile(f) + except exceptions.ELFParseError: + warn("ELFParser failed to parse", path) + raise + + # If this is the first ELF, extract the interpreter. + if _first: + for segment in elf.iter_segments(): + if segment.header.p_type != "PT_INTERP": + continue + + interp = bstr(segment.get_interp_name()) + dbg(debug, " interp =", interp) + ret["interp"] = normpath(root + interp) + real_interp = readlink(ret["interp"], root, prefixed=True) + ret["libs"][os.path.basename(interp)] = { + "path": ret["interp"], + "realpath": real_interp, + "needed": [], + } + # XXX: Could read it and scan for /lib paths. + # If the interp is a symlink, lets follow it on the assumption that it + # is in this path purely for ABI reasons, and the distro is using a + # different (probably more correct) path. This can come up in some + # multilib situations like s390x where /lib64/ contains all the native + # libraries, but /lib/ld64.so.1 is the interp hardcoded in gcc, so the + # ld64.so.1 is really a symlink to ../lib64/ld64.so.1. In the multiarch + # setup, it'll be /lib/ld64.so.1 -> /lib/s390x-linux-gnu/ld64.so.1. + # That is why we use |real_interp| here instead of |interp|. + ldpaths["interp"] = [ + os.path.dirname(real_interp), + normpath( + root + + prefix + + "/usr/" + + os.path.dirname(real_interp)[len(root) + len(prefix) :] + ), + ] + dbg(debug, " ldpaths[interp] =", ldpaths["interp"]) + break + + # Parse the ELF's dynamic tags. + libs = [] + rpaths = [] + runpaths = [] + for segment in elf.iter_segments(): + if segment.header.p_type != "PT_DYNAMIC": + continue + + for t in segment.iter_tags(): + if t.entry.d_tag == "DT_RPATH": + rpaths = ParseLdPaths(bstr(t.rpath), root=root, cwd=cwd, path=path) + elif t.entry.d_tag == "DT_RUNPATH": + runpaths = ParseLdPaths( + bstr(t.runpath), root=root, cwd=cwd, path=path + ) + elif t.entry.d_tag == "DT_NEEDED": + libs.append(bstr(t.needed)) + if runpaths: + # If both RPATH and RUNPATH are set, only the latter is used. + rpaths = [] + + # XXX: We assume there is only one PT_DYNAMIC. This is + # probably fine since the runtime ldso does the same. + break + if _first: + # Propagate the rpaths used by the main ELF since those will be + # used at runtime to locate things. + ldpaths["rpath"] = rpaths + ldpaths["runpath"] = runpaths + dbg(debug, " ldpaths[rpath] =", rpaths) + dbg(debug, " ldpaths[runpath] =", runpaths) + ret["rpath"] = rpaths + ret["runpath"] = runpaths + ret["needed"] = libs + + # Search for the libs this ELF uses. + all_ldpaths = None + for lib in libs: + if lib in _all_libs: + continue + if all_ldpaths is None: + all_ldpaths = ( + rpaths + + ldpaths["rpath"] + + ldpaths["env"] + + runpaths + + ldpaths["runpath"] + + ldpaths["conf"] + + ldpaths["interp"] + ) + realpath, fullpath = FindLib(elf, lib, all_ldpaths, root, debug=debug) + _all_libs[lib] = { + "realpath": realpath, + "path": fullpath, + "needed": [], + } + if realpath is not None: + try: + lret = ParseELF( + realpath, + root, + cwd, + prefix, + ldpaths, + display=fullpath, + debug=debug, + _first=False, + _all_libs=_all_libs, + ) + except exceptions.ELFError as e: + warn(f"{realpath}: {e}") + _all_libs[lib]["needed"] = lret["needed"] + + del elf + + return ret - del elf - return ret # pylint: enable=dangerous-default-value class _NormalizePathAction(argparse.Action): - def __call__(self, parser, namespace, values, option_string=None): - setattr(namespace, self.dest, normpath(values)) + """Argparse action to normalize paths.""" + + def __call__(self, parser, namespace, values, option_string=None): + setattr(namespace, self.dest, normpath(values)) + +def _ActionShow(options: argparse.Namespace, elf: dict): + """Show the dependency tree for this ELF""" -def _ActionShow(options, elf): - """Show the dependency tree for this ELF""" - def _show(lib, depth): - chain_libs.append(lib) - fullpath = elf['libs'][lib]['path'] + def _show(lib, depth): + chain_libs.append(lib) + fullpath = elf["libs"][lib]["path"] + if options.list: + print(fullpath or lib) + else: + indent = " " * depth + print(f"{indent}{lib}", "=>", fullpath) + + new_libs = [] + for nlib in elf["libs"][lib]["needed"]: + if nlib in chain_libs: + if not options.list: + print(f"{indent}{nlib} => !!! circular loop !!!") + continue + if options.all or not nlib in shown_libs: + shown_libs.add(nlib) + new_libs.append(nlib) + + for nlib in new_libs: + _show(nlib, depth + 1) + chain_libs.pop() + + shown_libs = set(elf["needed"]) + new_libs = elf["needed"][:] + chain_libs: List[str] = [] + interp = elf["interp"] + if interp: + lib = os.path.basename(interp) + shown_libs.add(lib) + # If we are in non-list mode, then we want to show the "duplicate" interp + # lines -- first the header (interp=>xxx), and then the DT_NEEDED line to + # show that the ELF is directly linked against the interp. + # If we're in list mode though, we only want to show the interp once. + # Unless of course we have the --all flag active, then we show everything. + if not options.all and options.list and lib in new_libs: + new_libs.remove(lib) if options.list: - print(fullpath or lib) + print(elf["path"]) + if not interp is None: + print(interp) else: - print('%s%s => %s' % (' ' * depth, lib, fullpath)) - - new_libs = [] - for lib in elf['libs'][lib]['needed']: - if lib in chain_libs: - if not options.list: - print('%s%s => !!! circular loop !!!' % (' ' * depth, lib)) - continue - if options.all or not lib in shown_libs: - shown_libs.add(lib) - new_libs.append(lib) - + print(elf["path"], f"(interpreter => {interp})") for lib in new_libs: - _show(lib, depth + 1) - chain_libs.pop() - - shown_libs = set(elf['needed']) - new_libs = elf['needed'][:] - chain_libs = [] - interp = elf['interp'] - if interp: - lib = os.path.basename(interp) - shown_libs.add(lib) - # If we are in non-list mode, then we want to show the "duplicate" interp - # lines -- first the header (interp=>xxx), and then the DT_NEEDED line to - # show that the ELF is directly linked against the interp. - # If we're in list mode though, we only want to show the interp once. - # Unless of course we have the --all flag active, then we show everything. - if not options.all and options.list and lib in new_libs: - new_libs.remove(lib) - if options.list: - print(elf['path']) - if not interp is None: - print(interp) - else: - print('%s (interpreter => %s)' % (elf['path'], interp)) - for lib in new_libs: - _show(lib, 1) - - -def _ActionCopy(options, elf): - """Copy the ELF and its dependencies to a destination tree""" - def _StripRoot(path): - return path[len(options.root) - 1:] - - def _copy(realsrc, src, striproot=True, wrapit=False, libpaths=(), - outdir=None): - if realsrc is None: - return - - if wrapit: - # Static ELFs don't need to be wrapped. - if not elf['interp']: - wrapit = False - - striproot = _StripRoot if striproot else lambda x: x - - if outdir: - subdst = os.path.join(outdir, os.path.basename(src)) - else: - subdst = striproot(src) - dst = options.dest + subdst + _show(lib, 1) - try: - # See if they're the same file. - nstat = os.stat(dst + ('.elf' if wrapit else '')) - ostat = os.stat(realsrc) - for field in ('mode', 'mtime', 'size'): - if getattr(ostat, 'st_' + field) != \ - getattr(nstat, 'st_' + field): - break - else: - return - except OSError as e: - if e.errno != errno.ENOENT: - raise - - if options.verbose: - print('%s -> %s' % (src, dst)) - - makedirs(os.path.dirname(dst)) - try: - shutil.copy2(realsrc, dst) - except IOError: - os.unlink(dst) - shutil.copy2(realsrc, dst) - - if wrapit: - if options.verbose: - print('generate wrapper %s' % (dst,)) - - if options.libdir: - interp = os.path.join(options.libdir, os.path.basename(elf['interp'])) - else: - interp = _StripRoot(elf['interp']) - GenerateLdsoWrapper(options.dest, subdst, interp, libpaths) - - # XXX: We should automatically import libgcc_s.so whenever libpthread.so - # is copied over (since we know it can be dlopen-ed by NPTL at runtime). - # Similarly, we should provide an option for automatically copying over - # the libnsl.so and libnss_*.so libraries, as well as an open ended list - # for known libs that get loaded (e.g. curl will dlopen(libresolv)). - uniq_libpaths = set() - for lib in elf['libs']: - libdata = elf['libs'][lib] - path = libdata['realpath'] - if path is None: - warn('could not locate library: %s' % lib) - continue - if not options.libdir: - uniq_libpaths.add(_StripRoot(os.path.dirname(path))) - _copy(path, libdata['path'], outdir=options.libdir) - if not options.libdir: - libpaths = list(uniq_libpaths) - if elf['runpath']: - libpaths = elf['runpath'] + libpaths - else: - libpaths = elf['rpath'] + libpaths - else: - uniq_libpaths.add(options.libdir) - libpaths = list(uniq_libpaths) - - # We don't bother to copy this as ParseElf adds the interp to the 'libs', - # so it was already copied in the libs loop above. - #_copy(elf['interp'], outdir=options.libdir) - _copy(elf['realpath'], elf['path'], striproot=options.auto_root, - wrapit=options.generate_wrappers, libpaths=libpaths, - outdir=options.bindir) - - -def GetParser(): - """Get a CLI parser.""" - parser = argparse.ArgumentParser( - description=__doc__, - formatter_class=argparse.RawDescriptionHelpFormatter) - parser.add_argument('-a', '--all', - action='store_true', default=False, - help='Show all duplicated dependencies') - parser.add_argument('-R', '--root', - default=os.environ.get('ROOT', ''), type=str, - action=_NormalizePathAction, - help='Search for all files/dependencies in ROOT') - parser.add_argument('-P', '--prefix', - default=os.environ.get( - 'EPREFIX', '@GENTOO_PORTAGE_EPREFIX@'), type=str, - action=_NormalizePathAction, - help='Specify EPREFIX for binaries (for Gentoo Prefix)') - parser.add_argument('--no-auto-root', - dest='auto_root', action='store_false', default=True, - help='Do not automatically prefix input ELFs with ROOT') - parser.add_argument('-l', '--list', - action='store_true', default=False, - help='Display output in a simple list (easy for copying)') - parser.add_argument('-x', '--debug', - action='store_true', default=False, - help='Run with debugging') - parser.add_argument('-v', '--verbose', - action='store_true', default=False, - help='Be verbose') - parser.add_argument('--skip-non-elfs', - action='store_true', default=False, - help='Skip plain (non-ELF) files instead of warning') - parser.add_argument('-V', '--version', - action='version', - version='lddtree by Mike Frysinger <vapier@gentoo.org>', - help='Show version information') - parser.add_argument('path', nargs='+') - - group = parser.add_argument_group('Copying options') - group.add_argument('--copy-to-tree', - dest='dest', default=None, type=str, - action=_NormalizePathAction, - help='Copy all files to the specified tree') - group.add_argument('--bindir', - default=None, type=str, - action=_NormalizePathAction, - help='Dir to store all ELFs specified on the command line') - group.add_argument('--libdir', - default=None, type=str, - action=_NormalizePathAction, - help='Dir to store all ELF libs') - group.add_argument('--generate-wrappers', - action='store_true', default=False, - help='Wrap executable ELFs with scripts for local ldso') - group.add_argument('--copy-non-elfs', - action='store_true', default=False, - help='Copy over plain (non-ELF) files instead of warn+ignore') - - return parser - - -def main(argv): - """The main entry point!""" - parser = GetParser() - options = parser.parse_args(argv) - paths = options.path - - if options.root != '/': - options.root += '/' - if options.prefix == '@''GENTOO_PORTAGE_EPREFIX''@': - options.prefix = '' - - if options.bindir and options.bindir[0] != '/': - parser.error('--bindir accepts absolute paths only') - if options.libdir and options.libdir[0] != '/': - parser.error('--libdir accepts absolute paths only') - - if options.skip_non_elfs and options.copy_non_elfs: - parser.error('pick one handler for non-ELFs: skip or copy') - - dbg(options.debug, 'root =', options.root) - if options.dest: - dbg(options.debug, 'dest =', options.dest) - if not paths: - err('missing ELF files to scan') - - ldpaths = LoadLdpaths(options.root, options.prefix, debug=options.debug) - dbg(options.debug, 'ldpaths[conf] =', ldpaths['conf']) - dbg(options.debug, 'ldpaths[env] =', ldpaths['env']) - - # Process all the files specified. - ret = 0 - for path in paths: - dbg(options.debug, 'argv[x] =', path) - # Only auto-prefix the path if the ELF is absolute. - # If it's a relative path, the user most likely wants - # the local path. - if options.auto_root and path.startswith('/'): - path = options.root + path.lstrip('/') - dbg(options.debug, ' +auto-root =', path) - - matched = False - for p in glob.iglob(path): - # Once we've processed the globs, resolve the symlink. This way you can - # operate on a path that is an absolute symlink itself. e.g.: - # $ ln -sf /bin/bash $PWD/root/bin/sh - # $ lddtree --root $PWD/root /bin/sh - # First we'd turn /bin/sh into $PWD/root/bin/sh, then we want to resolve - # the symlink to $PWD/root/bin/bash rather than a plain /bin/bash. - dbg(options.debug, ' globbed =', p) - if not path.startswith('/'): - realpath = os.path.realpath(path) - elif options.auto_root: - realpath = readlink(p, options.root, prefixed=True) - else: - realpath = path - if path != realpath: - dbg(options.debug, ' resolved =', realpath) - - matched = True - try: - elf = ParseELF(realpath, options.root, options.prefix, ldpaths, - display=p, debug=options.debug) - except exceptions.ELFError as e: - if options.skip_non_elfs: - continue - # XXX: Ugly. Should unify with _Action* somehow. - if options.dest is not None and options.copy_non_elfs: - if os.path.exists(p): - elf = { - 'interp': None, - 'libs': [], - 'runpath': [], - 'rpath': [], - 'path': p, - 'realpath': realpath, - } - _ActionCopy(options, elf) - continue - ret = 1 - warn('%s: %s' % (p, e)) - continue - except IOError as e: - ret = 1 - warn('%s: %s' % (p, e)) - continue +def _ActionCopy(options: argparse.Namespace, elf: dict): + """Copy the ELF and its dependencies to a destination tree""" + + def _StripRoot(path: str) -> str: + return path[len(options.root) - 1 :] - if options.dest is None: - _ActionShow(options, elf) - else: - _ActionCopy(options, elf) + def _copy( + realsrc, + src, + striproot=True, + wrapit=False, + libpaths=(), + outdir=None, + preload=None, + ): + if realsrc is None: + return - if not matched: - ret = 1 - warn('%s: did not match any paths' % (path,)) + if wrapit: + # Static ELFs don't need to be wrapped. + if not elf["interp"]: + wrapit = False - return ret + striproot = _StripRoot if striproot else lambda x: x + if outdir: + subdst = os.path.join(outdir, os.path.basename(src)) + else: + subdst = striproot(src) + dst = options.dest + subdst + + try: + # See if they're the same file. + nstat = os.stat(dst + (".elf" if wrapit else "")) + ostat = os.stat(realsrc) + for field in ("mode", "mtime", "size"): + if getattr(ostat, "st_" + field) != getattr(nstat, "st_" + field): + break + else: + return + except OSError as e: + if e.errno != errno.ENOENT: + raise + + if options.verbose: + print(src, "->", dst) + + os.makedirs(os.path.dirname(dst), exist_ok=True) + try: + shutil.copy2(realsrc, dst) + except FileNotFoundError as e: + warn(f'{elf["path"]}: {e}') + return + except IOError: + try: + os.unlink(dst) + except FileNotFoundError: + pass + shutil.copy2(realsrc, dst) + + if wrapit: + if options.verbose: + print("generate wrapper", dst) + + if options.libdir: + interp = os.path.join(options.libdir, os.path.basename(elf["interp"])) + else: + interp = _StripRoot(elf["interp"]) + GenerateLdsoWrapper(options.dest, subdst, interp, libpaths, preload) + + # XXX: We should automatically import libgcc_s.so whenever libpthread.so + # is copied over (since we know it can be dlopen-ed by NPTL at runtime). + # Similarly, we should provide an option for automatically copying over + # the libnsl.so and libnss_*.so libraries, as well as an open ended list + # for known libs that get loaded (e.g. curl will dlopen(libresolv)). + uniq_libpaths = set() + for lib in elf["libs"]: + libdata = elf["libs"][lib] + path = libdata["realpath"] + if path is None: + warn("could not locate library:", lib) + continue + if not options.libdir: + uniq_libpaths.add(_StripRoot(os.path.dirname(path))) + _copy(path, libdata["path"], outdir=options.libdir) -if __name__ == '__main__': - sys.exit(main(sys.argv[1:])) + if not options.libdir: + libpaths = list(uniq_libpaths) + if elf["runpath"]: + libpaths = elf["runpath"] + libpaths + else: + libpaths = elf["rpath"] + libpaths + else: + uniq_libpaths.add(options.libdir) + libpaths = list(uniq_libpaths) + + # We don't bother to copy this as ParseElf adds the interp to the 'libs', + # so it was already copied in the libs loop above. + # _copy(elf['interp'], outdir=options.libdir) + _copy( + elf["realpath"], + elf["path"], + striproot=options.auto_root, + wrapit=options.generate_wrappers, + libpaths=libpaths, + outdir=options.bindir, + preload=options.wrapper_preload, + ) + + +def GetParser() -> argparse.ArgumentParser: + """Get a CLI parser.""" + parser = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + parser.add_argument( + "-a", + "--all", + action="store_true", + default=False, + help="Show all duplicated dependencies", + ) + parser.add_argument( + "-l", + "--list", + action="store_true", + default=False, + help="Display output in a simple list (easy for copying)", + ) + parser.add_argument( + "-x", "--debug", action="store_true", default=False, help="Run with debugging" + ) + parser.add_argument( + "-v", "--verbose", action="store_true", default=False, help="Be verbose" + ) + parser.add_argument( + "--skip-non-elfs", + action="store_true", + default=False, + help="Skip plain (non-ELF) files instead of warning", + ) + parser.add_argument( + "--skip-missing", + action="store_true", + default=False, + help="Skip missing files instead of failing", + ) + parser.add_argument( + "-V", + "--version", + action="version", + version="lddtree by Mike Frysinger <vapier@gentoo.org>", + help="Show version information", + ) + parser.add_argument("path", nargs="+") + + group = parser.add_argument_group("Path options") + group.add_argument( + "-R", + "--root", + default=os.environ.get("ROOT", ""), + type=str, + action=_NormalizePathAction, + help="Search for all files/dependencies in ROOT", + ) + group.add_argument( + "--no-auto-root", + dest="auto_root", + action="store_false", + default=True, + help="Do not automatically prefix input ELFs with ROOT", + ) + group.add_argument( + "-C", + "--cwd", + default=os.getcwd(), + type=str, + action=_NormalizePathAction, + help="Path to resolve relative paths against", + ) + group.add_argument( + "-P", + "--prefix", + default=os.environ.get("EPREFIX", "@GENTOO_PORTAGE_EPREFIX@"), + type=str, + action=_NormalizePathAction, + help="Specify EPREFIX for binaries (for Gentoo Prefix)", + ) + + group = parser.add_argument_group("Copying options") + group.add_argument( + "--copy-to-tree", + dest="dest", + default=None, + type=str, + action=_NormalizePathAction, + help="Copy all files to the specified tree", + ) + group.add_argument( + "--bindir", + default=None, + type=str, + action=_NormalizePathAction, + help="Dir to store all ELFs specified on the command line", + ) + group.add_argument( + "--libdir", + default=None, + type=str, + action=_NormalizePathAction, + help="Dir to store all ELF libs", + ) + group.add_argument( + "--generate-wrappers", + action="store_true", + default=False, + help="Wrap executable ELFs with scripts for local ldso", + ) + group.add_argument( + "--copy-non-elfs", + action="store_true", + default=False, + help="Copy over plain (non-ELF) files instead of warn+ignore", + ) + group.add_argument( + "--wrapper-preload", + default=None, + type=str, + help="Have wrapper add --preload to the ldso invocation", + ) + + if argcomplete is not None: + argcomplete.autocomplete(parser) + return parser + + +def main(argv: List[str]) -> Optional[int]: + """The main entry point!""" + parser = GetParser() + options = parser.parse_args(argv) + paths = options.path + + if options.root != "/": + options.root += "/" + if options.prefix == "@" "GENTOO_PORTAGE_EPREFIX" "@": + options.prefix = "" + + if options.bindir and options.bindir[0] != "/": + parser.error("--bindir accepts absolute paths only") + if options.libdir and options.libdir[0] != "/": + parser.error("--libdir accepts absolute paths only") + + if options.skip_non_elfs and options.copy_non_elfs: + parser.error("pick one handler for non-ELFs: skip or copy") + + dbg(options.debug, "root =", options.root) + dbg(options.debug, "cwd =", options.cwd) + if options.dest: + dbg(options.debug, "dest =", options.dest) + if not paths: + err("missing ELF files to scan") + + ldpaths = LoadLdpaths( + options.root, cwd=options.cwd, prefix=options.prefix, debug=options.debug + ) + dbg(options.debug, "ldpaths[conf] =", ldpaths["conf"]) + dbg(options.debug, "ldpaths[env] =", ldpaths["env"]) + + # Process all the files specified. + ret = 0 + for path in paths: + dbg(options.debug, "argv[x] =", path) + # Only auto-prefix the path if the ELF is absolute. + # If it's a relative path, the user most likely wants + # the local path. + if options.auto_root and path.startswith("/"): + path = options.root + path.lstrip("/") + dbg(options.debug, " +auto-root =", path) + + matched = False + for p in glob.iglob(path): + # Once we've processed the globs, resolve the symlink. This way you can + # operate on a path that is an absolute symlink itself. e.g.: + # $ ln -sf /bin/bash $PWD/root/bin/sh + # $ lddtree --root $PWD/root /bin/sh + # First we'd turn /bin/sh into $PWD/root/bin/sh, then we want to resolve + # the symlink to $PWD/root/bin/bash rather than a plain /bin/bash. + dbg(options.debug, " globbed =", p) + if not path.startswith("/"): + realpath = os.path.realpath(path) + elif options.auto_root: + realpath = readlink(p, options.root, prefixed=True) + else: + realpath = path + if path != realpath: + dbg(options.debug, " resolved =", realpath) + + matched = True + try: + elf = ParseELF( + realpath, + options.root, + options.cwd, + options.prefix, + ldpaths, + display=p, + debug=options.debug, + ) + except exceptions.ELFError as e: + if options.skip_non_elfs: + continue + # XXX: Ugly. Should unify with _Action* somehow. + if options.dest is not None and options.copy_non_elfs: + if os.path.exists(p): + elf = { + "interp": None, + "libs": [], + "runpath": [], + "rpath": [], + "path": p, + "realpath": realpath, + } + _ActionCopy(options, elf) + continue + ret = 1 + warn(f"{p}: {e}") + continue + except IOError as e: + ret = 1 + warn(f"{p}: {e}") + continue + + if options.dest is None: + _ActionShow(options, elf) + else: + _ActionCopy(options, elf) + + if not matched: + if not options.skip_missing: + ret = 1 + warn(f"{path}: did not match any paths") + + return ret + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) @@ -1,6 +1,6 @@ #!/bin/bash -# Copyright 2007-2013 Gentoo Foundation -# Copyright 2007-2013 Mike Frysinger <vapier@gentoo.org> +# Copyright 2007-2024 Gentoo Foundation +# Copyright 2007-2024 Mike Frysinger <vapier@gentoo.org> # Distributed under the terms of the GNU General Public License v2 argv0=${0##*/} @@ -45,7 +45,7 @@ elf_specs() { sed -E 's: (LINUX|GNU)$: NONE:' } -lib_paths_fallback="${ROOT}lib* ${ROOT}usr/lib* ${ROOT}usr/local/lib*" +lib_paths_fallback="${ROOT}lib* ${ROOT}usr/lib* ${ROOT}usr/local/lib* ${ROOT}usr/X11R6/lib*" c_ldso_paths_loaded='false' find_elf() { _find_elf='' @@ -73,7 +73,7 @@ find_elf() { if [[ ${c_last_needed_by} != ${needed_by} ]] ; then c_last_needed_by=${needed_by} c_last_needed_by_rpaths=$(scanelf -qF '#F%r' "${needed_by}" | \ - sed -e 's|:| |g' -e "s:[$]ORIGIN:${needed_by%/*}:") + sed -E -e 's|:| |g' -e "s:[$](ORIGIN|\{ORIGIN\}):${needed_by%/*}:") fi check_paths "${elf}" ${c_last_needed_by_rpaths} && return 0 @@ -96,8 +96,8 @@ find_elf() { read_ldso_conf() { local line p for p ; do - # if the glob didnt match anything #360041, - # or the files arent readable, skip it + # If the glob didn't match anything #360041, + # or the files aren't readable, skip it. [[ -r ${p} ]] || continue while read line ; do case ${line} in @@ -118,7 +118,7 @@ find_elf() { check_paths "${elf}" "${c_ldso_paths[@]}" && return 0 fi - check_paths "${elf}" ${lib_paths_ldso:-${lib_paths_fallback}} && return 0 + check_paths "${elf}" ${lib_paths_fallback} && return 0 fi return 1 } @@ -154,13 +154,6 @@ show_elf() { else printf " (interpreter => ${interp:-none})" fi - if [[ -r ${interp} ]] ; then - # Extract the default lib paths out of the ldso. - lib_paths_ldso=$( - strings "${interp}" | \ - sed -nr -e "/^\/.*lib/{s|^/?|${ROOT}|;s|/$||;s|/?:/?|\n${ROOT}|g;p}" - ) - fi full_interp=${interp} interp=${interp##*/} # If we are in non-list mode, then we want to show the "duplicate" interp @@ -186,12 +179,12 @@ show_elf() { # No need for leading comma w/my_allhits as we guarantee it always # starts with one due to the way we append the value above. [[ ${my_allhits}, == *,${lib},* ]] && continue - # If the interp is being linked against directly, re-use the existing + # If the interp is being linked against directly, reuse the existing # full path rather than perform a search for it. When systems symlink # the interp to a diff location, we might locate a different path, and # displaying both doesn't make sense as it doesn't match the runtime -- # the ldso won't load another copy of ldso into memory from the search - # path, it'll re-use the existing copy that was loaded from the full + # path, it'll reuse the existing copy that was loaded from the full # hardcoded path. if [[ ${lib} == "${interp}" ]] ; then rlib=${full_interp} @@ -235,7 +228,6 @@ ${SET_X} && set -x ret=0 for elf ; do - unset lib_paths_ldso unset c_last_needed_by if ${AUTO_ROOT} && [[ ${elf} == /* ]] ; then elf="${ROOT}${elf#/}" @@ -1,5 +1,5 @@ /* - * Copyright 2008-2012 Gentoo Foundation + * Copyright 2008-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 */ @@ -9,7 +9,8 @@ #include <stdint.h> /* - * http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html + * https://nicolascormier.com/documentation/macosx-programming/MachORuntime.pdf + * https://web.archive.org/web/20090404123504/http://developer.apple.com/DOCUMENTATION/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html */ #define CPU_ARCH_ABI64 0x01000000 /* 64 bit */ @@ -72,7 +73,7 @@ struct mach_header incremental link against a base file and cannot be link edited again */ #define MH_DYLDLINK 0x4 /* the object file is input for the dynamic - linker and cannot be staticly link edited + linker and cannot be statically link edited again */ #define MH_TWOLEVEL 0x80 /* the image is using two-level namespace bindings */ @@ -106,7 +107,7 @@ struct mach_header they are not used by other code */ #define MH_NOMULTIDEFS 0x200 /* this umbrella guarantees there are no - multiple defintions of symbols in its + multiple definitions of symbols in its subimages, as a result the two-level namespace hints can always be used */ @@ -128,6 +129,7 @@ struct mach_header_64 /* cputype */ #define CPU_TYPE_POWERPC64 (CPU_TYPE_POWERPC | CPU_ARCH_ABI64) #define CPU_TYPE_X86_64 (CPU_TYPE_I386 | CPU_ARCH_ABI64) +#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64) struct load_command { @@ -257,6 +259,12 @@ struct rpath_command { union lc_str path; }; +struct uuid_command { + uint32_t cmd; + uint32_t cmdsize; + uint8_t uuid[16]; +}; + struct fat_header { uint32_t magic; diff --git a/make-seccomp-filters.sh b/make-seccomp-filters.sh new file mode 100755 index 0000000..124646a --- /dev/null +++ b/make-seccomp-filters.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -ufe +>&2 echo THIS IS A DEVELOPER SCRIPT +>&2 echo YOU DO NOT NEED TO RUN IT UNLESS YOU EDITED seccomp-bpf.c + +: "${CC:=gcc}" +: "${CCFLAGS:=$(pkg-config --cflags --libs libseccomp)}" + +generator="$(mktemp)" +trap 'rm "${generator}"' EXIT + +"${CC}" -o "${generator}" -D_GNU_SOURCE ${CCFLAGS} seccomp-bpf.c && \ + "${generator}" > seccomp-bpf.h diff --git a/make-tarball.sh b/make-tarball.sh deleted file mode 100755 index 04f778d..0000000 --- a/make-tarball.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/bash - -set -e - -if ! . /etc/init.d/functions.sh 2>/dev/null ; then - einfo() { printf ' * %b\n' "$*"; } - eerror() { einfo "$@" 1>&2; } -fi -die() { eerror "$@"; exit 1; } - -v() { printf '\t%s\n' "$*"; "$@"; } - -: ${MAKE:=make} - -CHECK=false -if [[ $1 == "--check" ]] ; then - CHECK=true - shift -fi - -if [[ $# -ne 1 ]] ; then - die "Usage: $0 <ver>" -fi - -case $1 in -snap) ver=$(date -u +%Y%m%d) ;; -git) ver="HEAD" ;; -*) - ver="v${1#v}" - if ! git describe --tags "${ver}" >&/dev/null ; then - die "Please create the tag first: git tag ${ver}" - fi - ;; -esac -p="pax-utils-${ver#v}" - -rm -rf "${p}" -mkdir "${p}" - -einfo "Checking out clean git sources ..." -git archive "${ver}" | tar xf - -C "${p}" - -pushd "${p}" >/dev/null - -einfo "Building docs ..." -echo "<releaseinfo>${ver#v}</releaseinfo>" > man/fragment/version -make -C man - -einfo "Building autotools ..." -sed -i "/^AC_INIT/s:git:${ver}:" configure.ac -sed -i "1iPV := ${ver}" Makefile -SKIP_AUTOTOOLS_UPDATE=true LC_ALL=C ${MAKE} -s autotools >/dev/null -rm -rf autom4te.cache - -popd >/dev/null - -einfo "Generating tarball ..." -tar cf - "${p}" | xz > "${p}".tar.xz -rm -r "${p}" - -if ${CHECK} ; then - -einfo "Checking tarball (simple) ..." -tar xf "${p}".tar.* -pushd "${p}" >/dev/null -v ${MAKE} -s -v ${MAKE} -s check -popd >/dev/null -rm -rf "${p}" - -einfo "Checking tarball (autotools) ..." -tar xf "${p}".tar.* -pushd "${p}" >/dev/null -v ./configure -q -v ${MAKE} -s -v ${MAKE} -s check -popd >/dev/null -rm -rf "${p}" - -fi - -echo -einfo "All ready for distribution!" -du -b "${p}".tar.* - -exit 0 diff --git a/man/Makefile b/man/Makefile deleted file mode 100644 index 6f1f185..0000000 --- a/man/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -all: man - -XMLTO_FLAGS_man = -x custom.xsl --skip-validation -man pdf txt xhtml xhtml-nochunks: - @xmlto $@ $(XMLTO_FLAGS_$@) pax-utils.docbook || echo "If this failed, you probably need to emerge ~app-text/docbook-xml-dtd-4.4 app-text/xmlto dev-tex/xmltex" - @# scanelf.1 has funky indented lists ... hack it back - @sed -i.tmp 's:^[.]TP 4:.TP 2:' scanelf.1 - @rm scanelf.1.tmp -clean distclean: - rm -f *.1 *.html - -.PHONY: all clean distclean \ - man pdf txt xhtml xhtml-nochunks diff --git a/man/custom.xsl b/man/custom.xsl index bf01b14..c1ab12d 100644 --- a/man/custom.xsl +++ b/man/custom.xsl @@ -12,8 +12,7 @@ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:text>.sp -1 </xsl:text> <xsl:text>.TP</xsl:text> <xsl:if test="not($list-indent = '')"> - <xsl:text> </xsl:text> - <xsl:value-of select="$list-indent"/> + <xsl:text> 2</xsl:text> </xsl:if> <xsl:text> </xsl:text> </xsl:if> diff --git a/man/fragment/date b/man/fragment/date deleted file mode 100644 index e69de29..0000000 --- a/man/fragment/date +++ /dev/null diff --git a/man/fragment/reftail b/man/fragment/reftail index 3acd009..c722421 100644 --- a/man/fragment/reftail +++ b/man/fragment/reftail @@ -1,6 +1,6 @@ <refsect1 id='homepage'> <title>HOMEPAGE</title> - <para><ulink>http://hardened.gentoo.org/pax-utils.xml</ulink></para> + <para><ulink>https://wiki.gentoo.org/wiki/Hardened/PaX_Utilities</ulink></para> </refsect1> <refsect1 id='report_bugs'> @@ -9,7 +9,7 @@ Please include as much information as possible (using any available debugging options) and send bug reports to the maintainers (see the <link><emphasis remap='B'>AUTHORS</emphasis></link> section). Please - use the Gentoo bugzilla at <ulink>http://bugs.gentoo.org/</ulink> if + use the Gentoo bugzilla at <ulink>https://bugs.gentoo.org/</ulink> if possible. </para> </refsect1> diff --git a/man/fragment/version b/man/fragment/version deleted file mode 100644 index 69ba922..0000000 --- a/man/fragment/version +++ /dev/null @@ -1 +0,0 @@ -<releaseinfo>git</releaseinfo> diff --git a/man/meson.build b/man/meson.build new file mode 100644 index 0000000..09ac0d5 --- /dev/null +++ b/man/meson.build @@ -0,0 +1,44 @@ +xmlto = find_program('xmlto', required : get_option('build_manpages'), disabler: true) + +docbook_conf = configuration_data() +docbook_conf.set('version', meson.project_version()) +docbook_conf.set('man_dir', meson.current_source_dir()) + +book = configure_file( + input : 'pax-utils.docbook.in', + output : 'pax-utils.docbook', + configuration : docbook_conf +) + +pages = [ + 'dumpelf.docbook', 'pspax.docbook', 'scanelf.docbook', 'scanmacho.docbook' +] + +fs = import('fs') + +out_pages = [] +generated_man_pages_exist = true +foreach page : pages + man_page_name = page.replace('.docbook', '.1') + out_pages += man_page_name + if not fs.exists(man_page_name) + generated_man_pages_exist = false + endif +endforeach + +if generated_man_pages_exist + install_man(out_pages) +else + custom_target('docbook_to_man', + command : [ + xmlto, '-x', files('custom.xsl'), '--skip-validation', + '-o', meson.current_build_dir(), 'man', book + ], + input : [ + 'pax-utils.docbook.in', 'custom.xsl', 'fragment/reftail', + ] + pages, + output : out_pages, + install : true, + install_dir : get_option('mandir') / 'man1' + ) +endif diff --git a/man/pax-utils.docbook b/man/pax-utils.docbook.in index 79e6c12..a8fd7df 100644 --- a/man/pax-utils.docbook +++ b/man/pax-utils.docbook.in @@ -2,16 +2,14 @@ <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.4//EN" "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [ - <!ENTITY date SYSTEM "fragment/date"> - <!ENTITY version SYSTEM "fragment/version"> - <!ENTITY reftail SYSTEM "fragment/reftail"> + <!ENTITY reftail SYSTEM "@man_dir@/fragment/reftail"> <!ENTITY project "pax-utils"> - <!ENTITY dumpelf SYSTEM "dumpelf.docbook"> - <!ENTITY pspax SYSTEM "pspax.docbook"> - <!ENTITY scanelf SYSTEM "scanelf.docbook"> - <!ENTITY scanmacho SYSTEM "scanmacho.docbook"> + <!ENTITY dumpelf SYSTEM "@man_dir@/dumpelf.docbook"> + <!ENTITY pspax SYSTEM "@man_dir@/pspax.docbook"> + <!ENTITY scanelf SYSTEM "@man_dir@/scanelf.docbook"> + <!ENTITY scanmacho SYSTEM "@man_dir@/scanmacho.docbook"> ]> <book id="pax-utils" lang="en"> @@ -40,8 +38,7 @@ </author> </authorgroup> - &version; - &date; + <releaseinfo>@version@</releaseinfo> </bookinfo> &dumpelf; diff --git a/man/scanelf.docbook b/man/scanelf.docbook index d9032a9..22503b2 100644 --- a/man/scanelf.docbook +++ b/man/scanelf.docbook @@ -214,6 +214,13 @@ listing ELFs. </para></listitem> </varlistentry> + <varlistentry> + <term><option>--ldcache</option> <replaceable>PATH</replaceable></term> + <listitem><para> + Use specified path instead of /etc/ld.so.cache. Generally paired with + options like -L or -n. + </para></listitem> + </varlistentry> </variablelist> </refsect1> diff --git a/meson-build-dist-man.sh b/meson-build-dist-man.sh new file mode 100755 index 0000000..699a380 --- /dev/null +++ b/meson-build-dist-man.sh @@ -0,0 +1,12 @@ +#!/bin/sh +# This script should be invoked by meson itself (via 'meson dist') +# See https://github.com/mesonbuild/meson/issues/2166 and more specifically, +# https://github.com/mesonbuild/meson/issues/2166#issuecomment-629696911. +set -eu + +cd "${MESON_DIST_ROOT}" +mkdir build +meson setup build -Dbuild_manpages=enabled +meson compile -C build +cp build/man/* man/ +rm -rf build diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..319e3de --- /dev/null +++ b/meson.build @@ -0,0 +1,174 @@ +project('pax-utils', 'c', + version : '1.3.7', + license : 'GPL-2.0-only', + default_options : [ + 'warning_level=2', + 'c_std=gnu11', + ], +) + +cc = meson.get_compiler('c') + +libcap = dependency('libcap', required : get_option('use_libcap')) +if libcap.found() + add_project_arguments('-DWANT_SYSCAP', language : 'c') +endif + +if get_option('use_seccomp') + add_project_arguments('-DWANT_SECCOMP', language : 'c') +endif + +if get_option('buildtype') in ['debug', 'debugoptimized'] + add_project_arguments('-DEBUG', language : 'c') +endif + +# generate VCSID +version_h = vcs_tag(input : 'version.h.in', output : 'pax_utils_version.h') +# tell paxinc.h to use it +add_project_arguments('-DINCLUDE_GENERATE_VERSION_H', language : 'c') +add_project_arguments('-DVERSION="' + meson.project_version() + '"', language : 'c') + +add_project_arguments('-D_GNU_SOURCE', language : 'c') +add_project_arguments('-D_FILE_OFFSET_BITS=64', language : 'c') + +# probe the platform... +probe_results = configuration_data() + +## first, we check a bunch of headers +foreach x : [ + 'endian.h', 'byteswap.h', # GNU-likes + 'sys/endian.h', # BSDs, + 'sys/isa_defs.h', # Sun/Illumios + 'machine/endian.h', # Mach + + 'linux/seccomp.h', + 'linux/securebits.h', + 'sys/prctl.h', + 'elf-hints.h', + 'glob.h', +] + if cc.has_header(x) + probe_results.set('HAVE_' + x.to_upper().underscorify(), 1) + endif +endforeach + +configure_file( + output : 'config.h', + configuration : probe_results, +) + + +# common code +common_src = [ + 'paxinc.c', + 'security.c', + 'xfuncs.c', + version_h, +] +common = static_library('common', + common_src, + install : false +) + +if cc.get_define('__svr4__') == '' + executable('pspax', + 'paxelf.c', + 'paxldso.c', + 'pspax.c', + version_h, + dependencies : [libcap], + link_with : common, + install : true + ) +endif + +executable('scanelf', + 'paxelf.c', + 'paxldso.c', + 'scanelf.c', + version_h, + dependencies : [libcap], + link_with : common, + install : true +) + +# dumpelf code (without the common code above) +dumpelf_src = [ + 'paxelf.c', + 'paxldso.c', + 'dumpelf.c', + version_h, +] + +executable('dumpelf', + dumpelf_src, + dependencies : [libcap], + link_with : common, + install : true +) + +executable('scanmacho', + 'paxmacho.c', + 'scanmacho.c', + version_h, + dependencies : [libcap], + link_with : common, + install : true +) + +lddtree_impl = get_option('lddtree_implementation') +if lddtree_impl != 'none' + if lddtree_impl == 'python' + suffix = '.py' + else + suffix = '.sh' + endif + install_data('lddtree' + suffix, + rename : 'lddtree', + install_dir : get_option('bindir') + ) +endif +install_data('symtree.sh', + rename : 'symtree', + install_dir : get_option('bindir') +) + +subdir('man') + +meson.add_dist_script('meson-build-dist-man.sh') + +do_tests = get_option('tests') +if do_tests + subdir('tests/lddtree') + subdir('tests/scanelf') + subdir('tests/source') +endif + +if do_tests and get_option('use_fuzzing') + ncc = meson.get_compiler('c', native : true) + fuzz_flags = [ + '-g3', '-ggdb', + '-fsanitize=fuzzer', '-fsanitize-coverage=edge', + '-DPAX_UTILS_LIBFUZZ=1', + ] + if ncc.get_id() != 'clang' + warning('use_fuzzing requires Clang, due to LibFuzzer. Not building fuzzers') + else + dumpelf_fuzzer = executable('dumpelf.fuzz', + common_src + dumpelf_src, + override_options : [ + 'buildtype=debug', + ], + c_args : fuzz_flags, + link_args : fuzz_flags, + install : false + ) + test('fuzz-dumpelf', dumpelf_fuzzer, + args : [ + '-close_fd_mask=3', + '-max_total_time=10', + '-print_final_stats', + ] + ) + endif +endif diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..04b51fe --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,17 @@ +option('lddtree_implementation', type : 'combo', + choices : ['python', 'sh', 'none'], value : 'python', + description : 'Which lddtree implementation to install?') +option('use_libcap', type : 'feature', value : 'auto', + description : 'Enable listing capabilities in pspax output (requires libcap)' +) +option('use_seccomp', type : 'boolean', value : true, + description : 'Enable seccomp filters at runtime (does *not* require libseccomp, but does require kernel support)' +) +option('build_manpages', type : 'feature', value : 'auto', + description : 'Build manuals via DocBook (requires xmlto)') +option('tests', type : 'boolean', value : true, + description : 'Enable testing (not guaranteed to work)' +) +option('use_fuzzing', type : 'boolean', value : true, + description : 'Also build LibFuzzer fuzzers as tests' +) @@ -1,9 +1,9 @@ /* - * Copyright 2003-2012 Gentoo Foundation + * Copyright 2003-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2005-2012 Ned Ludd - <solar@gentoo.org> - * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org> + * Copyright 2005-2024 Mike Frysinger - <vapier@gentoo.org> */ #include "paxinc.h" @@ -276,6 +276,8 @@ static pairtype elf_emtypes[] = { QUERY(EM_MICROBLAZE), QUERY(EM_TILEGX), QUERY(EM_ALPHA), + QUERY(EM_RISCV), + QUERY(EM_LOONGARCH), { 0, 0 } }; @@ -582,7 +584,7 @@ free_elf_and_return: /* check class and stuff */ if (!DO_WE_LIKE_ELF(elf->data)) { - warn("we no likey %s: {%s,%s,%s,%s}", + warn("unknown ELF settings: %s: {%s,%s,%s,%s}", filename, get_elfeitype(EI_CLASS, elf->data[EI_CLASS]), get_elfeitype(EI_DATA, elf->data[EI_DATA]), @@ -618,6 +620,11 @@ free_elf_and_return: char invalid; \ const Elf ## B ## _Ehdr *ehdr = EHDR ## B (elf->ehdr); \ Elf ## B ## _Off size; \ + /* Need enough bytes for all of ehdr. */ \ + if (elf->len < (off_t)sizeof(*ehdr)) { \ + warn("%s: Incomplete ELF header", filename); \ + goto free_elf_and_return; \ + } \ /* verify program header */ \ invalid = 0; \ if (EGET(ehdr->e_phnum) <= 0) \ @@ -1,9 +1,9 @@ /* - * Copyright 2005-2012 Gentoo Foundation + * Copyright 2005-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2005-2012 Ned Ludd - <solar@gentoo.org> - * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org> + * Copyright 2005-2024 Mike Frysinger - <vapier@gentoo.org> * * Make sure all of the common elf stuff is setup as we expect */ @@ -1,9 +1,9 @@ /* - * Copyright 2003-2012 Gentoo Foundation + * Copyright 2003-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2005-2012 Ned Ludd - <solar@gentoo.org> - * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org> + * Copyright 2005-2024 Mike Frysinger - <vapier@gentoo.org> */ /* stick common symbols here that are needed by paxinc.h */ @@ -50,14 +50,52 @@ archive_handle *ar_open(const char *filename, bool verbose) return ret; } +static uint64_t ar_read_ascii_number(const char *numstr, size_t ndigits, int base) +{ + /* Largest field ar headers have is 16 bytes. */ + char buf[17]; + char *endp; + long long ret; + + memcpy(buf, numstr, ndigits); + buf[ndigits] = '\0'; + + ret = strtoll(buf, &endp, base); + /* Numbers are padded with whitespace. */ + if (*endp != '\0' && *endp != ' ') { + warn("ar: invalid number: %s", buf); + ret = 0; + } + + /* + * Unsigned 64-bit numbers use up to 20 digits, and signed 64-bit numbers use + * up to 19 digits, but ndigits is always less than that. So we'd never handle + * a number that requires all 64-bits. If it's negative, it's because the input + * was negative e.g. "-1", and none of these fields should ever be negative. + */ + if (ret < 0) { + warn("ar: invalid number: %s", buf); + ret = 0; + } + + return ret; +} +#define read_octal_number(s, n) ar_read_ascii_number(s, n, 8) +#define read_decimal_number(s, n) ar_read_ascii_number(s, n, 10) +/* For char[] arrays rather than dynamic pointers. */ +#define read_octal_number_fixed(s) read_octal_number(s, sizeof(s)) +#define read_decimal_number_fixed(s) read_decimal_number(s, sizeof(s)) + archive_member *ar_next(archive_handle *ar) { char *s; + char *heap_s = NULL; ssize_t len = 0; static archive_member ret; if (ar->skip && lseek(ar->fd, ar->skip, SEEK_CUR) == -1) { close_and_ret: + free(heap_s); free(ar->extfn); close(ar->fd); ar->extfn = NULL; @@ -84,12 +122,13 @@ close_and_ret: goto close_and_ret; } + /* System V extended filename section. */ if (ret.buf.formatted.name[0] == '/' && ret.buf.formatted.name[1] == '/') { if (ar->extfn != NULL) { warn("%s: Duplicate GNU extended filename section", ar->filename); goto close_and_ret; } - len = atoi(ret.buf.formatted.size); + len = ar->extfn_len = read_decimal_number_fixed(ret.buf.formatted.size); ar->extfn = xmalloc(sizeof(char) * (len + 1)); if (read(ar->fd, ar->extfn, len) != len) goto close_and_ret; @@ -104,12 +143,12 @@ close_and_ret: s = ret.buf.formatted.name; if (s[0] == '#' && s[1] == '1' && s[2] == '/') { /* BSD extended filename, always in use on Darwin */ - len = atoi(s + 3); + len = read_decimal_number(s + 3, sizeof(ret.buf.formatted.name) - 3); if (len <= (ssize_t)sizeof(ret.buf.formatted.name)) { if (read(ar->fd, ret.buf.formatted.name, len) != len) goto close_and_ret; } else { - s = alloca(sizeof(char) * len + 1); + s = heap_s = xmalloc(sizeof(char) * (len + 1)); if (read(ar->fd, s, len) != len) goto close_and_ret; s[len] = '\0'; @@ -120,18 +159,25 @@ close_and_ret: warn("%s: GNU extended filename without special data section", ar->filename); goto close_and_ret; } - s = ar->extfn + atoi(s + 1); + /* NB: We NUL terminated extfn above when reading it. */ + int64_t off = read_decimal_number(s + 1, sizeof(ret.buf.formatted.name) - 1); + if (off >= ar->extfn_len) { + warn("%s: GNU extended filename has invalid offset", ar->filename); + goto close_and_ret; + } + s = ar->extfn + off; } snprintf(ret.name, sizeof(ret.name), "%s:%s", ar->filename, s); + free(heap_s); ret.name[sizeof(ret.name) - 1] = '\0'; if ((s=strchr(ret.name+strlen(ar->filename), '/')) != NULL) *s = '\0'; - ret.date = atoi(ret.buf.formatted.date); - ret.uid = atoi(ret.buf.formatted.uid); - ret.gid = atoi(ret.buf.formatted.gid); - ret.mode = strtol(ret.buf.formatted.mode, NULL, 8); - ret.size = atoi(ret.buf.formatted.size); + ret.date = read_decimal_number_fixed(ret.buf.formatted.date); + ret.uid = read_decimal_number_fixed(ret.buf.formatted.uid); + ret.gid = read_decimal_number_fixed(ret.buf.formatted.gid); + ret.mode = read_octal_number_fixed(ret.buf.formatted.mode); + ret.size = read_decimal_number_fixed(ret.buf.formatted.size); ar->skip = ret.size - len; return &ret; @@ -198,3 +244,53 @@ const char *root_rel_path(const char *path) return path; } + +void pax_usage( + const char *header, + const char *args, + const char *parse_flags, + const struct option long_opts[], + const char * const opts_help[], + int status) +{ + const char a_arg[] = "<arg>"; + size_t a_arg_len = strlen(a_arg) + 2; + size_t i; + int optlen; + + printf("* %s\n\n" + "Usage: %s [options] %s\n\n", header, argv0, args); + printf("Options: -[%s]\n", parse_flags); + + /* Prescan the --long opt length to auto-align. */ + optlen = 0; + for (i = 0; long_opts[i].name; ++i) { + int l = strlen(long_opts[i].name); + if (long_opts[i].has_arg == a_argument) + l += a_arg_len; + optlen = max(l, optlen); + } + /* Use some reasonable min width. */ + optlen = max(20, optlen); + + for (i = 0; long_opts[i].name; ++i) { + /* First output the short flag if it has one. */ + if (long_opts[i].val > '~') + printf(" "); + else + printf(" -%c, ", long_opts[i].val); + + /* Then the long flag. */ + if (long_opts[i].has_arg == no_argument) + printf("--%-*s", optlen, long_opts[i].name); + else + printf("--%s %s %*s", long_opts[i].name, a_arg, + (int)(optlen - strlen(long_opts[i].name) - a_arg_len), ""); + + /* Finally the help text. */ + printf("* %s\n", opts_help[i]); + } + + printf("\nFor more information, see the %s(1) manpage.\n", argv0); + exit(status); +} @@ -1,9 +1,9 @@ /* - * Copyright 2005-2012 Gentoo Foundation + * Copyright 2005-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2005-2012 Ned Ludd - <solar@gentoo.org> - * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org> + * Copyright 2005-2024 Mike Frysinger - <vapier@gentoo.org> * * Make sure all of the common stuff is setup as we expect */ @@ -18,6 +18,9 @@ #ifndef VERSION # define VERSION "git" #endif +#ifdef INCLUDE_GENERATE_VERSION_H +# include "pax_utils_version.h" +#endif #ifndef VCSID # define VCSID "<unknown>" #endif @@ -45,6 +48,7 @@ typedef struct { const char *filename; size_t skip; char *extfn; + off_t extfn_len; bool verbose; } archive_handle; #else @@ -108,6 +112,12 @@ const char *strfileperms(const char *fname); #define PTR_ALIGN_DOWN(base, size) ((__typeof__(base))ALIGN_DOWN((uintptr_t)(base), (size))) #define PTR_ALIGN_UP(base, size) ((__typeof__(base))ALIGN_UP ((uintptr_t)(base), (size))) +/* Support for libFuzzer: https://llvm.org/docs/LibFuzzer.html */ +#if PAX_UTILS_LIBFUZZ +int LLVMFuzzerInitialize(__unused__ int *argc, __unused__ char ***argv); +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); +#endif + /* helper functions for showing errors */ extern const char *NORM, *RED, *YELLOW; void color_init(bool disable); @@ -115,6 +125,17 @@ void color_init(bool disable); /* constant pointer to a constant buffer ... each program needs to set this */ extern const char argv0[]; +/* Display usage and exit. */ +extern void pax_usage( + const char *header, + const char *args, + const char *parse_flags, + const struct option long_opts[], + const char * const opts_help[], + int status); + +#define a_argument required_argument + /* we need the space before the last comma or we trigger a bug in gcc-2 :( */ #define warn(fmt, args...) \ fprintf(stderr, "%s%s%s: " fmt "\n", RED, argv0, NORM , ## args) @@ -1,9 +1,9 @@ /* - * Copyright 2003-2016 Gentoo Foundation + * Copyright 2003-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2003-2012 Ned Ludd - <solar@gentoo.org> - * Copyright 2004-2016 Mike Frysinger - <vapier@gentoo.org> + * Copyright 2004-2024 Mike Frysinger - <vapier@gentoo.org> */ #include "paxinc.h" @@ -14,19 +14,28 @@ #if PAX_LDSO_CACHE -static void *ldcache = NULL; +/* Memory region containing a specific cache. Will be a subset of the mmap. */ +static const void *ldcache = NULL; static size_t ldcache_size = 0; +/* Entire memory mapped cache file. */ +static void *ldcache_mmap_base = NULL; +static size_t ldcache_mmap_size = 0; + static char *ldso_cache_buf = NULL; static size_t ldso_cache_buf_size = 0; #if defined(__GLIBC__) || defined(__UCLIBC__) /* Defines can be seen in glibc's sysdeps/generic/ldconfig.h */ -#define LDSO_CACHE_MAGIC "ld.so-" -#define LDSO_CACHE_MAGIC_LEN (sizeof LDSO_CACHE_MAGIC -1) -#define LDSO_CACHE_VER "1.7.0" -#define LDSO_CACHE_VER_LEN (sizeof LDSO_CACHE_VER -1) +#define LDSO_CACHE_MAGIC_OLD "ld.so-" +#define LDSO_CACHE_MAGIC_OLD_LEN (sizeof LDSO_CACHE_MAGIC_OLD - 1) +#define LDSO_CACHE_VER_OLD "1.7.0" +#define LDSO_CACHE_VER_OLD_LEN (sizeof LDSO_CACHE_VER_OLD - 1) +#define LDSO_CACHE_MAGIC_NEW "glibc-ld.so.cache" +#define LDSO_CACHE_MAGIC_NEW_LEN (sizeof LDSO_CACHE_MAGIC_NEW - 1) +#define LDSO_CACHE_VER_NEW "1.1" +#define LDSO_CACHE_VER_NEW_LEN (sizeof LDSO_CACHE_VER_NEW - 1) #define FLAG_ANY -1 #define FLAG_TYPE_MASK 0x00ff #define FLAG_LIBC4 0x0000 @@ -48,14 +57,45 @@ static size_t ldso_cache_buf_size = 0; #define FLAG_MIPS_LIB32_NAN2008 0x0c00 #define FLAG_MIPS64_LIBN32_NAN2008 0x0d00 #define FLAG_MIPS64_LIBN64_NAN2008 0x0e00 +#define FLAG_RISCV_FLOAT_ABI_SOFT 0x0f00 +#define FLAG_RISCV_FLOAT_ABI_DOUBLE 0x1000 typedef struct { int flags; unsigned int sooffset; unsigned int liboffset; -} libentry_t; +} libentry_old_t; + +typedef struct { + const char magic[LDSO_CACHE_MAGIC_OLD_LEN]; + const char version[LDSO_CACHE_VER_OLD_LEN]; + unsigned int nlibs; + libentry_old_t libs[0]; +} header_old_t; -static bool is_compatible(elfobj *elf, libentry_t *libent) +typedef struct { + int32_t flags; + uint32_t sooffset; + uint32_t liboffset; + uint32_t osversion; + uint64_t hwcap; +} libentry_new_t; + +typedef struct { + const char magic[LDSO_CACHE_MAGIC_NEW_LEN]; + const char version[LDSO_CACHE_VER_NEW_LEN]; + uint32_t nlibs; + uint32_t len_strings; + uint8_t flags; + uint8_t _pad_flags[3]; + uint32_t extension_offset; + uint32_t _pad_ext[3]; + libentry_new_t libs[0]; +} header_new_t; + +static bool ldcache_is_new; + +static bool is_compatible(elfobj *elf, const libentry_old_t *libent) { int flags = libent->flags & FLAG_REQUIRED_MASK; @@ -136,74 +176,124 @@ static bool is_compatible(elfobj *elf, libentry_t *libent) return false; } -char *ldso_cache_lookup_lib(elfobj *elf, const char *fname) +static void ldso_cache_load(void) { - unsigned int nlib; - char *ret = NULL; - char *strs; - - typedef struct { - char magic[LDSO_CACHE_MAGIC_LEN]; - char version[LDSO_CACHE_VER_LEN]; - unsigned int nlibs; - } header_t; - header_t *header; + int fd; + const char *cachefile; + struct stat st; + const header_old_t *header_old; + const header_new_t *header_new; - libentry_t *libent; + if (ldcache_mmap_base != NULL) + return; - if (fname == NULL) - return NULL; + cachefile = root_rel_path(ldcache_path); - if (ldcache == NULL) { - int fd; - const char *cachefile = root_rel_path("/etc/ld.so.cache"); - struct stat st; + if (fstatat(root_fd, cachefile, &st, 0)) + return; - if (fstatat(root_fd, cachefile, &st, 0)) - return NULL; + fd = openat(root_fd, cachefile, O_RDONLY); + if (fd == -1) + return; - fd = openat(root_fd, cachefile, O_RDONLY); - if (fd == -1) - return NULL; + /* cache these values so we only map/unmap the cache file once */ + ldcache_mmap_size = st.st_size; + ldcache_mmap_base = mmap(0, ldcache_mmap_size, PROT_READ, MAP_SHARED, fd, 0); + close(fd); - /* cache these values so we only map/unmap the cache file once */ - ldcache_size = st.st_size; - header = ldcache = mmap(0, ldcache_size, PROT_READ, MAP_SHARED, fd, 0); - close(fd); + if (ldcache_mmap_base == MAP_FAILED) { + ldcache_mmap_base = NULL; + return; + } - if (ldcache == MAP_FAILED) { - ldcache = NULL; - return NULL; + ldcache_size = ldcache_mmap_size; + ldcache = ldcache_mmap_base; + header_old = ldcache; + header_new = ldcache; +#define memeq(mem1, mem2) (memcmp(mem1, mem2, sizeof(mem2) - 1) == 0) + if (memeq(header_new->magic, LDSO_CACHE_MAGIC_NEW) && + memeq(header_new->version, LDSO_CACHE_VER_NEW)) { + ldcache_is_new = true; + } else if (memeq(header_old->magic, LDSO_CACHE_MAGIC_OLD) && + memeq(header_old->version, LDSO_CACHE_VER_OLD)) { + /* See if the new cache format is appended after the old cache. */ + uintptr_t end = + (uintptr_t)ldcache + sizeof(header_old_t) + + (header_old->nlibs * sizeof(libentry_old_t)); + header_new = (const void *)ALIGN_UP(end, __alignof__(header_new_t)); + if (memeq(header_new->magic, LDSO_CACHE_MAGIC_NEW) && + memeq(header_new->version, LDSO_CACHE_VER_NEW)) { + ldcache_is_new = true; + ldcache_size -= ((uintptr_t)header_new - (uintptr_t)ldcache); + ldcache = header_new; + } else { + ldcache_is_new = false; } + } else { + munmap(ldcache_mmap_base, ldcache_mmap_size); + ldcache_mmap_base = NULL; + return; + } +#undef memq - if (memcmp(header->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN) || - memcmp(header->version, LDSO_CACHE_VER, LDSO_CACHE_VER_LEN)) - { - munmap(ldcache, ldcache_size); - ldcache = NULL; - return NULL; - } + ldso_cache_buf_size = 4096; + ldso_cache_buf = xrealloc(ldso_cache_buf, ldso_cache_buf_size); +} - ldso_cache_buf_size = 4096; - ldso_cache_buf = xrealloc(ldso_cache_buf, ldso_cache_buf_size); - } else - header = ldcache; +char *ldso_cache_lookup_lib(elfobj *elf, const char *fname) +{ + unsigned int nlib, nlibs; + char *ret = NULL; + const char *strs; + const libentry_old_t *libent_old; + const libentry_new_t *libent_new; - libent = ldcache + sizeof(header_t); - strs = (char *) &libent[header->nlibs]; + if (fname == NULL) + return NULL; - for (nlib = 0; nlib < header->nlibs; ++nlib) { + ldso_cache_load(); + if (ldcache == NULL) + return NULL; + + if (ldcache_is_new) { + const header_new_t *header = ldcache; + libent_old = NULL; + libent_new = &header->libs[0]; + strs = (const char *)header; + nlibs = header->nlibs; + } else { + const header_old_t *header = ldcache; + libent_old = &header->libs[0]; + libent_new = NULL; + strs = (const char *)&libent_old[header->nlibs]; + nlibs = header->nlibs; + } + + /* + * TODO: Should add memory range checking in case cache file is corrupt. + * TODO: We search the cache from start to finish, but since we know the cache + * is sorted, we really should be doing a binary search to speed it up. + */ + for (nlib = 0; nlib < nlibs; ++nlib) { const char *lib; size_t lib_len; - if (!is_compatible(elf, &libent[nlib])) + /* The first few fields are the same between new/old formats. */ + const libentry_old_t *libent; + if (ldcache_is_new) { + libent = (void *)&libent_new[nlib]; + } else { + libent = &libent_old[nlib]; + } + + if (!is_compatible(elf, libent)) continue; - if (strcmp(fname, strs + libent[nlib].sooffset) != 0) + if (strcmp(fname, strs + libent->sooffset) != 0) continue; /* Return first hit because that is how the ldso rolls */ - lib = strs + libent[nlib].liboffset; + lib = strs + libent->liboffset; lib_len = strlen(lib) + 1; if (lib_len > ldso_cache_buf_size) { ldso_cache_buf = xrealloc(ldso_cache_buf, ldso_cache_buf_size + 4096); @@ -223,8 +313,8 @@ static void ldso_cache_cleanup(void) { free(ldso_cache_buf); - if (ldcache != NULL) - munmap(ldcache, ldcache_size); + if (ldcache_mmap_base != NULL) + munmap(ldcache_mmap_base, ldcache_mmap_size); } #else @@ -267,7 +357,7 @@ int ldso_config_load(const char *fname) size_t x; const char *gpath; - /* re-use existing path buffer ... need to be creative */ + /* Reuse existing path buffer ... need to be creative. */ if (path[8] != '/') gpath = memcpy(path + 3, "/etc/", 5); else @@ -369,3 +459,56 @@ void paxldso_cleanup(void) ldso_config_cleanup(); } #endif + +const char *ldcache_path = "/etc/ld.so.cache"; + +#ifdef MAIN + +const char argv0[] = "paxldso"; + +int main(int argc, char *argv[]) +{ + elfobj *elf = readelf(argv[0]); + ldso_cache_load(); + printf("cache file memory base is %p\n", ldcache_mmap_base); + printf("cache memory base is %p\n", ldcache); + for (int i = 1; i < argc; ++i) { + const char *search = argv[i]; + const char *lib = ldso_cache_lookup_lib(elf, search); + printf("%s -> %s\n", search, lib); + } + unreadelf(elf); + + if (ldcache) { + unsigned int nlib; + const char *strs, *s; + + if (ldcache_is_new) { + const header_new_t *header = ldcache; + const libentry_new_t *libents = &header->libs[0]; + strs = (const char *)header; + printf("dumping new cache format\n"); + + for (nlib = 0; nlib < header->nlibs; ++nlib) { + const libentry_new_t *libent = &libents[nlib]; + s = strs + libent->sooffset; + printf("%p: %s\n", libent, s); + } + } else { + const header_old_t *header = ldcache; + const libentry_old_t *libents = &header->libs[0]; + strs = (const char *)&libents[header->nlibs]; + printf("dumping old cache format\n"); + + for (nlib = 0; nlib < header->nlibs; ++nlib) { + const libentry_old_t *libent = &libents[nlib]; + s = strs + libent->sooffset; + printf("%p: %s\n", libent, s); + } + } + } + + paxldso_cleanup(); +} + +#endif @@ -1,9 +1,9 @@ /* - * Copyright 2003-2016 Gentoo Foundation + * Copyright 2003-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2003-2012 Ned Ludd - <solar@gentoo.org> - * Copyright 2004-2016 Mike Frysinger - <vapier@gentoo.org> + * Copyright 2004-2024 Mike Frysinger - <vapier@gentoo.org> */ #ifndef _PAX_LDSO_H @@ -66,4 +66,7 @@ extern void paxldso_cleanup(void); # define paxldso_cleanup() #endif +/* Path to ld.so.cache. Usually overridden for tests. */ +extern const char *ldcache_path; + #endif @@ -1,10 +1,10 @@ /* - * Copyright 2003-2012 Gentoo Foundation + * Copyright 2003-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2005-2012 Ned Ludd - <solar@gentoo.org> - * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org> - * 2008-2012 Fabian Groffen - <grobian@gentoo.org> + * Copyright 2005-2024 Mike Frysinger - <vapier@gentoo.org> + * 2008-2021 Fabian Groffen - <grobian@gentoo.org> */ #include "paxinc.h" @@ -17,6 +17,7 @@ static const char STR_PPC64[] = "ppc64"; static const char STR_I386[] = "i386"; static const char STR_X86_64[] = "x86_64"; static const char STR_ARM[] = "arm"; /* iPhone */ +static const char STR_ARM64[] = "arm64"; /* Apple M1 */ static const char STR_UNKNOWN[] = "unknown"; #define QUERY(n) { #n, n } @@ -95,6 +96,7 @@ static pairtype macho_cputype[] = { QUERY(CPU_TYPE_ARM), QUERY(CPU_TYPE_POWERPC64), QUERY(CPU_TYPE_X86_64), + QUERY(CPU_TYPE_ARM64), { 0, 0 } }; const char *get_machocputype(fatobj *fobj) @@ -383,6 +385,7 @@ const char *get_machomtype(fatobj *fobj) case CPU_TYPE_ARM: return STR_ARM; case CPU_TYPE_POWERPC64: return STR_PPC64; case CPU_TYPE_X86_64: return STR_X86_64; + case CPU_TYPE_ARM64: return STR_ARM64; default: return STR_UNKNOWN; } } @@ -1,9 +1,9 @@ /* - * Copyright 2005-2012 Gentoo Foundation + * Copyright 2005-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2005-2012 Ned Ludd - <solar@gentoo.org> - * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org> + * Copyright 2005-2024 Mike Frysinger - <vapier@gentoo.org> * 2008-2012 Fabian Groffen - <grobian@gentoo.org> * * Make sure all of the common mach-o stuff is setup as we expect @@ -1,9 +1,9 @@ /* - * Copyright 2005-2012 Gentoo Foundation + * Copyright 2005-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2005-2012 Ned Ludd - <solar@gentoo.org> - * Copyright 2005-2012 Mike Frysinger - <vapier@gentoo.org> + * Copyright 2005-2024 Mike Frysinger - <vapier@gentoo.org> * * Make sure all of the common elf stuff is setup as we expect */ @@ -11,9 +11,7 @@ #ifndef _PORTING_H #define _PORTING_H -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +#include "config.h" #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(*arr)) @@ -31,43 +29,44 @@ #include <regex.h> #include <sched.h> #include <signal.h> +#include <stddef.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <time.h> -#include <unistd.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> +#include <time.h> +#include <unistd.h> #include "elf.h" -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) -# include <alloca.h> -#endif -#if defined(__linux__) +#ifdef HAVE_SYS_PRCTL_H # include <sys/prctl.h> -# if !defined(HAVE_CONFIG_H) || defined(HAVE_LINUX_SECUREBITS_H) +# ifdef HAVE_LINUX_SECCOMP_H +# include <linux/seccomp.h> +# endif +# ifdef HAVE_LINUX_SECUREBITS_H # include <linux/securebits.h> # endif #endif -#if defined(__GLIBC__) || defined(__UCLIBC__) || defined(__ANDROID__) +#if defined(HAVE_ENDIAN_H) && defined(HAVE_BYTESWAP_H) # include <byteswap.h> # include <endian.h> -#elif defined(__FreeBSD__) +#elif defined(HAVE_SYS_ENDIAN_H) # include <sys/endian.h> -#elif defined(__sun__) +#elif defined(HAVE_ISA_DEFS_H) # include <sys/isa_defs.h> -#elif defined(__MACH__) +#elif defined(HAVE_MACHINE_ENDIAN_H) # include <machine/endian.h> #endif -#if defined(__GLIBC__) || defined(__UCLIBC__) +#ifdef HAVE_GLOB_H # include <glob.h> #endif #if defined(__GLIBC__) || defined(__UCLIBC__) || defined(__NetBSD__) # define __PAX_UTILS_DEFAULT_LD_CACHE_CONFIG "/etc/ld.so.conf" -#elif defined(__FreeBSD__) || defined(__DragonFly__) +#elif defined(HAVE_ELF_HINTS_H) # include <elf-hints.h> # define __PAX_UTILS_DEFAULT_LD_CACHE_CONFIG _PATH_ELF_HINTS #else @@ -75,12 +74,12 @@ #endif #undef PAX_UTILS_CLEANUP -/* bounds checking code will fart on free(NULL) even though that - * is valid usage. So let's wrap it if need be. - */ -#ifdef __BOUNDS_CHECKING_ON -# define free(ptr) do { if (ptr) free(ptr); } while (0) -# define PAX_UTILS_CLEANUP 1 +#ifndef __SANITIZE_ADDRESS__ +# ifdef __has_feature +# if __has_feature (address_sanitizer) +# define __SANITIZE_ADDRESS__ 1 +# endif +# endif #endif /* LSAN (Leak Sanitizer) will complain about things we leak. */ #ifdef __SANITIZE_ADDRESS__ @@ -94,6 +93,11 @@ # define PAX_UTILS_CLEANUP 0 #endif +/* Support for libFuzzer: https://llvm.org/docs/LibFuzzer.html */ +#ifndef PAX_UTILS_LIBFUZZ +# define PAX_UTILS_LIBFUZZ 0 +#endif + /* Few arches can safely do unaligned accesses */ #if defined(__cris__) || \ defined(__i386__) || \ @@ -160,7 +164,6 @@ # define __PAX_UTILS_PATH_MAX PATH_MAX #endif -/* fall back case for non-Linux hosts ... so lame */ #if !defined(ELF_DATA) # if defined(BYTE_ORDER) # if BYTE_ORDER == LITTLE_ENDIAN @@ -192,7 +195,7 @@ #endif /* - * propably will never be official added to the toolchain. + * Probably will never be officially added to the toolchain. * But none the less we should try to get 0x65041580 reserved */ #ifndef PT_PAX_FLAGS @@ -40,33 +40,12 @@ static pid_t show_pid = 0; static uid_t show_uid = (uid_t)-1; static gid_t show_gid = (gid_t)-1; -static int proc_open(int pfd, const char *file) -{ - return openat(pfd, file, O_RDONLY|O_CLOEXEC); -} - -static FILE *proc_fopen(int pfd, const char *file) -{ - int fd; - FILE *fp; - - fd = proc_open(pfd, file); - if (fd == -1) - return NULL; - - fp = fdopen(fd, "re"); - if (fp == NULL) - close(fd); - - return fp; -} - static elfobj *proc_readelf(int pfd) { int fd; elfobj *elf; - fd = proc_open(pfd, "exe"); + fd = openat(pfd, "exe", O_RDONLY|O_CLOEXEC); if (fd == -1) return NULL; @@ -80,11 +59,11 @@ static const char *get_proc_name_cmdline(int pfd) FILE *fp; static char str[1024]; - fp = proc_fopen(pfd, "cmdline"); + fp = fopenat_r(pfd, "cmdline"); if (fp == NULL) return NULL; - if (fscanf(fp, "%s.1023", str) != 1) { + if (fscanf(fp, "%1023s", str) != 1) { fclose(fp); return NULL; } @@ -96,38 +75,57 @@ static const char *get_proc_name_cmdline(int pfd) static const char *get_proc_name(int pfd) { FILE *fp; - static char str[BUFSIZ]; + /* + * The stat file says process names are truncated to TASK_COMM_LEN (16) bytes. + * That includes the trailing NUL (\0) byte. This is true for userspace, but + * kernel processes seem to be unlimited. We don't care about those in this + * program though, so truncating them all the time is fine. + */ + static char str[16]; if (wide_output) return get_proc_name_cmdline(pfd); - fp = proc_fopen(pfd, "stat"); + fp = fopenat_r(pfd, "stat"); if (fp == NULL) return NULL; - if (fscanf(fp, "%*d %s.16", str) != 1) { + /* + * The format is: + * <pid> (<name>) ...more fields... + * For example: + * 1234 (bash) R ... + * + * Match the leading (, then read 15 bytes (since scanf writes, but doesn't count, + * NUL bytes, so it will write up to 16 bytes to str). Ignore the rest rather than + * look for closing ) since kernel processes can be longer. + */ + if (fscanf(fp, "%*d (%15s", str) != 1) { fclose(fp); return NULL; } if (*str) { - str[strlen(str) - 1] = '\0'; - str[16] = 0; + /* Discard trailing ) if it exists. */ + size_t len = strlen(str); + if (str[len - 1] == ')') + str[len - 1] = '\0'; } fclose(fp); - return (str+1); + return str; } static int get_proc_maps(int pfd) { FILE *fp; - static char str[BUFSIZ]; + static char *str = NULL; + static size_t len = 0; - if ((fp = proc_fopen(pfd, "maps")) == NULL) + if ((fp = fopenat_r(pfd, "maps")) == NULL) return -1; - while (fgets(str, sizeof(str), fp)) { + while (getline(&str, &len, fp) != -1) { char *p; if ((p = strchr(str, ' ')) != NULL) { if (strlen(p) < 6) @@ -158,12 +156,13 @@ static int get_proc_maps(int pfd) static int print_executable_mappings(int pfd) { FILE *fp; - static char str[BUFSIZ]; + static char *str = NULL; + static size_t len = 0; - if ((fp = proc_fopen(pfd, "maps")) == NULL) + if ((fp = fopenat_r(pfd, "maps")) == NULL) return -1; - while (fgets(str, sizeof(str), fp)) { + while (getline(&str, &len, fp) != -1) { char *p; if ((p = strchr(str, ' ')) != NULL) { if (strlen(p) < 6) @@ -189,15 +188,6 @@ static int print_executable_mappings(int pfd) return 0; } -#ifdef __BOUNDS_CHECKING_ON -# define NOTE_TO_SELF warn( \ - "This is bullshit but getpwuid() is leaking memory and I wasted a few hrs 1 day tracking it down in pspax\n" \ - "Later on I forgot I tracked it down before and saw pspax leaking memory so I tracked it down all over again (silly me)\n" \ - "Hopefully the getpwuid()/nis/nss/pam or whatever wont suck later on in the future.") -#else -# define NOTE_TO_SELF -#endif - static const struct passwd *get_proc_passwd(int pfd) { struct stat st; @@ -212,20 +202,21 @@ static const struct passwd *get_proc_passwd(int pfd) static const char *get_proc_status(int pfd, const char *name) { FILE *fp; - size_t len; - static char str[BUFSIZ]; + size_t name_len; + static char *str = NULL; + static size_t len = 0; - if ((fp = proc_fopen(pfd, "status")) == NULL) + if ((fp = fopenat_r(pfd, "status")) == NULL) return NULL; - len = strlen(name); - while (fgets(str, sizeof(str), fp)) { - if (strncasecmp(str, name, len) != 0) + name_len = strlen(name); + while (getline(&str, &len, fp) != -1) { + if (strncasecmp(str, name, name_len) != 0) continue; - if (str[len] == ':') { + if (str[name_len] == ':') { fclose(fp); str[strlen(str) - 1] = 0; - return (str + len + 2); + return (str + name_len + 2); } } fclose(fp); @@ -237,14 +228,20 @@ static const char *get_pid_attr(int pfd) { FILE *fp; char *p; - static char buf[BUFSIZ]; + static char *buf = NULL; + static size_t len = 0; - if ((fp = proc_fopen(pfd, "attr/current")) == NULL) + if ((fp = fopenat_r(pfd, "attr/current")) == NULL) return NULL; - if (fgets(buf, sizeof(buf), fp) != NULL) - if ((p = strchr(buf, '\n')) != NULL) - *p = 0; + if (getline(&buf, &len, fp) == -1) { + fclose(fp); + return NULL; + } + + if ((p = strchr(buf, '\n')) != NULL) + *p = 0; + fclose(fp); return buf; @@ -254,14 +251,20 @@ static const char *get_pid_addr(int pfd) { FILE *fp; char *p; - static char buf[BUFSIZ]; + static char *buf = NULL; + static size_t len = 0; - if ((fp = proc_fopen(pfd, "ipaddr")) == NULL) + if ((fp = fopenat_r(pfd, "ipaddr")) == NULL) return NULL; - if (fgets(buf, sizeof(buf), fp) != NULL) - if ((p = strchr(buf, '\n')) != NULL) - *p = 0; + if (getline(&buf, &len, fp) == -1) { + fclose(fp); + return NULL; + } + + if ((p = strchr(buf, '\n')) != NULL) + *p = 0; + fclose(fp); return buf; @@ -413,7 +416,7 @@ static void pspax(const char *find_name) /* this is a non-POSIX function */ caps = NULL; - WRAP_SYSCAP(capgetp(pfd, cap_d)); + WRAP_SYSCAP(cap_d = cap_get_pid(pid)); WRAP_SYSCAP(caps = cap_to_text(cap_d, &length)); if (pwd && strlen(pwd->pw_name) >= 8) @@ -445,7 +448,6 @@ static void pspax(const char *find_name) /* usage / invocation handling functions */ #define PARSE_FLAGS "aeip:u:g:nwWvCBhV" -#define a_argument required_argument static struct option const long_opts[] = { {"all", no_argument, NULL, 'a'}, {"header", no_argument, NULL, 'e'}, @@ -485,22 +487,16 @@ static const char * const opts_help[] = { /* display usage and exit */ static void usage(int status) { - int i; - printf("* List ELF/PaX information about running processes\n\n" - "Usage: %s [options]\n\n", argv0); - fputs("Options:\n", stdout); - for (i = 0; long_opts[i].name; ++i) - printf(" -%c, --%-12s* %s\n", long_opts[i].val, - long_opts[i].name, opts_help[i]); -#ifdef MANLYPAGE - for (i = 0; long_opts[i].name; ++i) - printf(".TP\n\\fB\\-%c, \\-\\-%s\\fR\n%s\n", long_opts[i].val, - long_opts[i].name, opts_help[i]); -#endif - exit(status); + pax_usage( + "List ELF/PaX information about running processes", + "", + PARSE_FLAGS, + long_opts, + opts_help, + status); } -/* parse command line arguments and preform needed actions */ +/* parse command line arguments and perform needed actions */ static void parseargs(int argc, char *argv[]) { int flag; @@ -577,6 +573,5 @@ int main(int argc, char *argv[]) pspax(name); - NOTE_TO_SELF; return EXIT_SUCCESS; } @@ -1,49 +1,46 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# Copyright 1999-2017 Gentoo Foundation +#!/usr/bin/env python +# Copyright 1999-2024 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 """Run pylint with the right settings.""" -from __future__ import print_function - import os import sys def find_all_modules(source_root): - """Locate all python modules in the tree for scanning""" - ret = [] + """Locate all python modules in the tree for scanning""" + ret = [] - for root, _dirs, files in os.walk(source_root, topdown=False): - # Add all of the .py modules in the tree. - ret += [os.path.join(root, x) for x in files if x.endswith('.py')] + for root, _dirs, files in os.walk(source_root, topdown=False): + # Add all of the .py modules in the tree. + ret += [os.path.join(root, x) for x in files if x.endswith(".py")] - # Add the main scripts that don't end in .py. - ret += [os.path.join(source_root, x) for x in ('pylint',)] + # Add the main scripts that don't end in .py. + ret += [os.path.join(source_root, x) for x in ("pylint",)] - return ret + return ret def main(argv): - """The main entry point""" - source_root = os.path.dirname(os.path.realpath(__file__)) + """The main entry point""" + source_root = os.path.dirname(os.path.realpath(__file__)) - if not argv: - argv = find_all_modules(source_root) + if not argv: + argv = find_all_modules(source_root) - pympath = source_root - pythonpath = os.environ.get('PYTHONPATH') - if pythonpath is None: - pythonpath = pympath - else: - pythonpath = pympath + ':' + pythonpath - os.environ['PYTHONPATH'] = pythonpath + pympath = source_root + pythonpath = os.environ.get("PYTHONPATH") + if pythonpath is None: + pythonpath = pympath + else: + pythonpath = pympath + ":" + pythonpath + os.environ["PYTHONPATH"] = pythonpath - pylintrc = os.path.join(source_root, '.pylintrc') - cmd = ['pylint', '--rcfile', pylintrc] - os.execvp(cmd[0], cmd + argv) + pylintrc = os.path.join(source_root, "pyproject.toml") + cmd = ["pylint", "--rcfile", pylintrc] + os.execvp(cmd[0], cmd + argv) -if __name__ == '__main__': - sys.exit(main(sys.argv[1:])) +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..d3ae4e0 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,121 @@ +# Copyright 2024 Gentoo Foundation +# Copyright 2024 Mike Frysinger <vapier@gentoo.org> +# Copyright 2024 The ChromiumOS Authors +# Distributed under the terms of the GNU General Public License v2 + +# https://packaging.python.org/en/latest/guides/writing-pyproject-toml/ + + +# https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html +[tool.black] +line-length = 88 +target-version = ["py38"] + + +# https://github.com/codespell-project/codespell?tab=readme-ov-file#using-a-config-file +[tool.codespell] +# eles: We use variable name as short for "elements". +# Ned: Author's name. +ignore-words-list = "eles,ned" + +# Imported from glibc. +skip = "elf.h" + + +# https://pycqa.github.io/isort/docs/configuration/options +[tool.isort] +py_version = "38" + +# Be compatible with `black` since it also matches what we want. +profile = "black" + +line_length = 88 +length_sort = false +force_single_line = true +lines_after_imports = 2 +from_first = false +case_sensitive = false +force_sort_within_sections = true +order_by_type = false + +# Allow importing multiple classes on a single line from these modules. +# https://google.github.io/styleguide/pyguide#s2.2-imports +single_line_exclusions = [ + "abc", + "collections.abc", + "typing", +] + + +# https://mypy.readthedocs.io/en/stable/config_file.html +[tool.mypy] +python_version = "3.8" + + +# https://pylint.pycqa.org/en/latest/user_guide/usage/run.html +[tool.pylint."MASTER"] +py-version = "3.8" + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins = [ + "pylint.extensions.bad_builtin", + "pylint.extensions.check_elif", + "pylint.extensions.docstyle", + "pylint.extensions.overlapping_exceptions", + "pylint.extensions.redefined_variable_type", +] + +# Run everything in parallel. +jobs = 0 + +# https://pylint.pycqa.org/en/latest/user_guide/messages/index.html +[tool.pylint."MESSAGES CONTROL"] +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifier separated by comma (,) or put this option +# multiple times (only on the command line, not in the configuration file where +# it should appear only once). +disable = [ + "too-many-lines", + "too-many-branches", + "too-many-statements", + "too-few-public-methods", + "too-many-instance-attributes", + "too-many-public-methods", + "too-many-locals", + "too-many-arguments", + "fixme", + "invalid-name", +] + +[tool.pylint."REPORTS"] +reports = false +score = false + +[tool.pylint."FORMAT"] +max-line-length = 100 +indent-string = " " + +[tool.pylint."BASIC"] +bad-functions = [ + "exit", + "filter", + "input", + "map", + "quit", +] + +[tool.pylint."SIMILARITIES"] +min-similarity-lines = 20 + +[tool.pylint."VARIABLES"] +dummy-variables-rgx = "_" + +[tool.pylint."DESIGN"] +max-parents = 10 + +[tool.pylint."IMPORTS"] +deprecated-modules = [ + "mox", + "optparse", +] diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..9f4869c --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,12 @@ +# Copyright 2024 Gentoo Foundation +# Copyright 2024 Mike Frysinger <vapier@gentoo.org> +# Copyright 2024 The ChromiumOS Authors +# Distributed under the terms of the GNU General Public License v2 + +# Deps needed to run tests/linters/etc... +# https://pip.pypa.io/en/stable/reference/requirements-file-format/ + +black==23.* +isort==5.* +mypy==1.* +pylint==3.0.* diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..540976b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,9 @@ +# Copyright 2024 Gentoo Foundation +# Copyright 2024 Mike Frysinger <vapier@gentoo.org> +# Copyright 2024 The ChromiumOS Authors +# Distributed under the terms of the GNU General Public License v2 + +# Deps needed to run Python scripts after installed. +# https://pip.pypa.io/en/stable/reference/requirements-file-format/ + +pyelftools @@ -1,9 +1,9 @@ /* - * Copyright 2003-2012 Gentoo Foundation + * Copyright 2003-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2003-2012 Ned Ludd - <solar@gentoo.org> - * Copyright 2004-2012 Mike Frysinger - <vapier@gentoo.org> + * Copyright 2004-2024 Mike Frysinger - <vapier@gentoo.org> */ const char argv0[] = "scanelf"; @@ -315,9 +315,9 @@ static void scanelf_file_get_symtabs(elfobj *elf, const void **sym, const void * Elf32_Word sym_idx; \ Elf32_Word chained; \ \ - if (!VALID_RANGE(elf, offset, nbuckets * 4)) \ + if (!VALID_RANGE(elf, hash_offset, nbuckets * (uint64_t)4)) \ goto corrupt_hash; \ - if (!VALID_RANGE(elf, offset, nchains * 4)) \ + if (!VALID_RANGE(elf, hash_offset, nchains * (uint64_t)4)) \ goto corrupt_hash; \ \ for (b = 0; b < nbuckets; ++b) { \ @@ -707,7 +707,8 @@ static const char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char printf("%s", elf->data + EGET(strtab->sh_offset) + EGET(sym->st_name)); \ else \ printf("(memory/data?)"); \ - printf(" [0x%lX]", (unsigned long)r_offset); \ + printf(" [r_offset=0x%lX]", (unsigned long)r_offset); \ + printf(" r_type=%lu", (unsigned long)ELF ## B ## _ST_TYPE(r_info)); \ /* now try to find the closest symbol that this rel is probably in */ \ sym = SYM ## B (elf->vdata + EGET(symtab->sh_offset)); \ func = NULL; \ @@ -730,9 +731,9 @@ static const char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char } else \ printf("(missing symbols)"); \ } else \ - printf("(optimized out)"); \ - printf(" [0x%lX]\n", (unsigned long)offset_tmp); \ - if (be_verbose && objdump) { \ + printf("(optimized out?)"); \ + printf(" [closest_prev_sym=0x%lX]\n", (unsigned long)offset_tmp); \ + if (be_verbose && objdump && func) { \ Elf ## B ## _Addr end_addr = offset_tmp + EGET(func->st_size); \ char *sysbuf; \ int ret; \ @@ -760,7 +761,7 @@ static const char *scanelf_file_textrels(elfobj *elf, char *found_textrels, char if (symtab_void && elf->phdr) SCANELF_ELF_SIZED(SHOW_TEXTRELS); if (!*found_textrels) - warnf("ELF %s has TEXTREL markings but doesnt appear to have any real TEXTREL's !?", elf->filename); + warnf("ELF %s has TEXTREL markings but doesn't appear to have any real TEXTREL's !?", elf->filename); return NULL; } @@ -1153,7 +1154,7 @@ static const char *scanelf_file_soname(elfobj *elf, char *found_soname) * STV group: STV_DEFAULT:p STV_INTERNAL:i STV_HIDDEN:h STV_PROTECTED:P * SHN group: SHN_UNDEF:u SHN_ABS:a SHN_COMMON:c {defined}:d * The "defined" value in the SHN group does not correspond to a SHN_xxx define. - * You can search for multiple symbols at once by seperating with a comma (","). + * You can search for multiple symbols at once by separating with a comma (","). * * Some examples: * ELFs with a weak function "foo": @@ -1827,10 +1828,10 @@ static void scanelf_envpath(void) /* usage / invocation handling functions */ /* Free Flags: c d j u w G H J K P Q U W */ #define PARSE_FLAGS "plRmyAXz:xetrnLibSs:k:gN:TaqvF:f:o:E:M:DIYO:ZCBhV" -#define a_argument required_argument static struct option const long_opts[] = { {"path", no_argument, NULL, 'p'}, {"ldpath", no_argument, NULL, 'l'}, + {"ldcache", a_argument, NULL, 130}, {"use-ldpath",no_argument, NULL, 129}, {"root", a_argument, NULL, 128}, {"recursive", no_argument, NULL, 'R'}, @@ -1876,6 +1877,7 @@ static struct option const long_opts[] = { static const char * const opts_help[] = { "Scan all directories in PATH environment", "Scan all directories in /etc/ld.so.conf", + "Use alternate ld.so.cache specified in <arg>", "Use ld.so.conf to show full path (use with -r/-n)", "Root directory (use with -l or -p)", "Scan directories recursively", @@ -1921,46 +1923,16 @@ static const char * const opts_help[] = { /* display usage and exit */ static void usage(int status) { - const char a_arg[] = "<arg>"; - size_t a_arg_len = strlen(a_arg) + 2; - size_t i; - int optlen; - printf("* Scan ELF binaries for stuff\n\n" - "Usage: %s [options] <dir1/file1> [dir2 dirN file2 fileN ...]\n\n", argv0); - printf("Options: -[%s]\n", PARSE_FLAGS); - - /* prescan the --long opt length to auto-align */ - optlen = 0; - for (i = 0; long_opts[i].name; ++i) { - int l = strlen(long_opts[i].name); - if (long_opts[i].has_arg == a_argument) - l += a_arg_len; - optlen = max(l, optlen); - } - - for (i = 0; long_opts[i].name; ++i) { - /* first output the short flag if it has one */ - if (long_opts[i].val > '~') - printf(" "); - else - printf(" -%c, ", long_opts[i].val); - - /* then the long flag */ - if (long_opts[i].has_arg == no_argument) - printf("--%-*s", optlen, long_opts[i].name); - else - printf("--%s %s %*s", long_opts[i].name, a_arg, - (int)(optlen - strlen(long_opts[i].name) - a_arg_len), ""); - - /* finally the help text */ - printf("* %s\n", opts_help[i]); - } - - puts("\nFor more information, see the scanelf(1) manpage"); - exit(status); + pax_usage( + "Scan ELF binaries for stuff", + "<dir1/file1> [dir2 dirN file2 fileN ...]", + PARSE_FLAGS, + long_opts, + opts_help, + status); } -/* parse command line arguments and preform needed actions */ +/* parse command line arguments and perform needed actions */ #define do_pax_state(option, flag) \ if (islower(option)) { \ flags &= ~PF_##flag; \ @@ -2119,6 +2091,7 @@ static int parseargs(int argc, char *argv[]) err("Could not open root: %s", optarg); break; case 129: load_cache_config = use_ldpath = 1; break; + case 130: ldcache_path = optarg; break; case ':': err("Option '%c' is missing parameter", optopt); case '?': diff --git a/scanmacho.c b/scanmacho.c index 71b1593..d33a440 100644 --- a/scanmacho.c +++ b/scanmacho.c @@ -1,12 +1,12 @@ /* - * Copyright 2008-2012 Gentoo Foundation + * Copyright 2008-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * based on scanelf by: * Copyright 2003-2012 Ned Ludd - <solar@gentoo.org> - * Copyright 2004-2012 Mike Frysinger - <vapier@gentoo.org> + * Copyright 2004-2024 Mike Frysinger - <vapier@gentoo.org> * for Darwin specific fun: - * 2008-2013 Fabian Groffen - <grobian@gentoo.org> + * 2008-2021 Fabian Groffen - <grobian@gentoo.org> */ const char argv0[] = "scanmacho"; @@ -37,6 +37,7 @@ static char show_rpath = 0; static char show_needed = 0; static char show_interp = 0; static char show_bind = 0; +static char show_uuid = 0; static char show_soname = 0; static char show_banner = 1; static char show_endian = 0; @@ -181,18 +182,54 @@ static char *macho_file_soname(fatobj *fobj, char *found_soname) return NULL; } +static char *macho_file_uuid(fatobj *fobj, char *found_uuid) +{ + loadcmd *lcmd; + uint32_t lc_uuid; + static char uuid_buf[32 + 4 + 1]; + + if (!show_uuid) + return NULL; + + lcmd = firstloadcmd(fobj); + lc_uuid = MGET(fobj->swapped, LC_UUID); + + do { + if (lcmd->lcmd->cmd == lc_uuid) { + struct uuid_command *ucmd = lcmd->data; + unsigned char *uuid; + uuid = (unsigned char *)(ucmd->uuid); + *found_uuid = 1; + free(lcmd); + if (be_wewy_wewy_quiet) + return NULL; + snprintf(uuid_buf, sizeof(uuid_buf), + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x", + uuid[0], uuid[1], uuid[2], uuid[3], + uuid[4], uuid[5], + uuid[6], uuid[7], + uuid[8], uuid[9], + uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]); + return uuid_buf; + } + } while (nextloadcmd(lcmd)); + + return NULL; +} + /* scan a macho file and show all the fun stuff */ #define prints(str) ({ ssize_t ret = write(fileno(stdout), str, strlen(str)); ret; }) static int scanmacho_fatobj(fatobj *fobj) { unsigned long i; char found_rpath, found_needed, found_interp, found_soname, - found_lib, found_file; + found_lib, found_file, found_uuid; static char *out_buffer = NULL; static size_t out_len; found_rpath = found_needed = found_interp = found_soname = \ - found_lib = found_file = 0; + found_lib = found_file = found_uuid = 0; if (be_verbose > 2) printf("%s: scanning file {%s,%s}\n", fobj->filename, @@ -228,6 +265,7 @@ static int scanmacho_fatobj(fatobj *fobj) case 'b': prints("FLAGS "); break; case 'Z': prints("SIZE "); break; case 'S': prints("INSTALLNAME "); break; + case 'U': prints("UUID "); break; case 'N': prints("LIB "); break; case 'a': prints("ARCH "); break; case 'O': prints("PERM "); break; @@ -293,6 +331,7 @@ static int scanmacho_fatobj(fatobj *fobj) case 'i': out = macho_file_interp(fobj, &found_interp); break; case 'b': get_machomhflags(fobj, &out_buffer, &out_len); break; case 'S': out = macho_file_soname(fobj, &found_soname); break; + case 'U': out = macho_file_uuid(fobj, &found_uuid); break; case 'a': out = get_machomtype(fobj); break; case 'Z': snprintf(ubuf, sizeof(ubuf), "%llu", (unsigned long long int)fobj->len); out = ubuf; break;; default: warnf("'%c' has no scan code?", out_format[i]); @@ -532,9 +571,8 @@ static void scanmacho_envpath(void) free(path); } -/* usage / invocation handling functions */ /* Free Flags: c d e j k l s t u w x z G H I J K L P Q T U W X Y */ -#define PARSE_FLAGS "pRmyArnibSN:gE:M:DO:ZaqvF:f:o:CBhV" -#define a_argument required_argument +/* usage / invocation handling functions */ /* Free Flags: c d e j k l s t u w x z G H I J K L P Q T W X Y */ +#define PARSE_FLAGS "pRmyArnibSUN:gE:M:DO:ZaqvF:f:o:CBhV" static struct option const long_opts[] = { {"path", no_argument, NULL, 'p'}, {"recursive", no_argument, NULL, 'R'}, @@ -546,6 +584,7 @@ static struct option const long_opts[] = { {"interp", no_argument, NULL, 'i'}, {"bind", no_argument, NULL, 'b'}, {"soname", no_argument, NULL, 'S'}, + {"uuid", no_argument, NULL, 'U'}, {"lib", a_argument, NULL, 'N'}, {"gmatch", no_argument, NULL, 'g'}, {"etype", a_argument, NULL, 'E'}, @@ -577,10 +616,11 @@ static const char * const opts_help[] = { "Print LC_LOAD_DYLINKER information (ELF: INTERP)", "Print flags from mach_header (ELF: BIND)", "Print LC_ID_DYLIB information (ELF: SONAME)", + "Print LC_UUID information", "Find a specified library", "Use strncmp to match libraries. (use with -N)", "Print only Mach-O files matching mach_header\n" - " MH_OBJECT,MH_EXECUTE ... (ELF: etype)", + " MH_OBJECT,MH_EXECUTE ... (ELF: etype)", "Print only Mach-O files matching numeric bits", "Print Endianness", "Print only Mach-O files matching octal permissions", @@ -601,23 +641,16 @@ static const char * const opts_help[] = { /* display usage and exit */ static void usage(int status) { - unsigned long i; - printf("* Scan Mach-O binaries for stuff\n\n" - "Usage: %s [options] <dir1/file1> [dir2 dirN file2 fileN ...]\n\n", argv0); - printf("Options: -[%s]\n", PARSE_FLAGS); - for (i = 0; long_opts[i].name; ++i) - if (long_opts[i].has_arg == no_argument) - printf(" -%c, --%-14s* %s\n", long_opts[i].val, - long_opts[i].name, opts_help[i]); - else - printf(" -%c, --%-7s <arg> * %s\n", long_opts[i].val, - long_opts[i].name, opts_help[i]); - - puts("\nFor more information, see the scanmacho(1) manpage"); - exit(status); + pax_usage( + "Scan Mach-O binaries for stuff", + "<dir1/file1> [dir2 dirN file2 fileN ...]", + PARSE_FLAGS, + long_opts, + opts_help, + status); } -/* parse command line arguments and preform needed actions */ +/* parse command line arguments and perform needed actions */ static int parseargs(int argc, char *argv[]) { int i; @@ -678,6 +711,7 @@ static int parseargs(int argc, char *argv[]) case 'i': show_interp = 1; break; case 'b': show_bind = 1; break; case 'S': show_soname = 1; break; + case 'U': show_uuid = 1; break; case 'q': be_quiet = 1; break; case 'v': be_verbose = (be_verbose % 20) + 1; break; case 'a': show_perms = show_endian = show_bind = 1; break; @@ -717,6 +751,7 @@ static int parseargs(int argc, char *argv[]) case 'i': show_interp = 1; break; case 'b': show_bind = 1; break; case 'S': show_soname = 1; break; + case 'U': show_uuid = 1; break; default: err("Invalid format specifier '%c' (byte %i)", out_format[i], i+1); @@ -738,6 +773,7 @@ static int parseargs(int argc, char *argv[]) if (show_interp) xstrcat(&out_format, "%i ", &fmt_len); if (show_bind) xstrcat(&out_format, "%b ", &fmt_len); if (show_soname) xstrcat(&out_format, "%S ", &fmt_len); + if (show_uuid) xstrcat(&out_format, "%U ", &fmt_len); if (find_lib) xstrcat(&out_format, "%N ", &fmt_len); if (!be_quiet) xstrcat(&out_format, "%F ", &fmt_len); } diff --git a/seccomp-bpf.c b/seccomp-bpf.c new file mode 100644 index 0000000..b56e9e4 --- /dev/null +++ b/seccomp-bpf.c @@ -0,0 +1,277 @@ +/* + * Generate the bpf rules ahead of time to speed up runtime. + * + * Copyright 2015-2024 Gentoo Foundation + * Distributed under the terms of the GNU General Public License v2 + * + * Copyright 2015-2024 Mike Frysinger - <vapier@gentoo.org> + */ + +const char argv0[] = "seccomp-bpf"; + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/types.h> + +#include <seccomp.h> + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +static const struct { + const char *name; + uint32_t arch; + const char *ifdef; +} gen_seccomp_arches[] = { +#define A(arch, ifdef) { #arch, SCMP_ARCH_##arch, ifdef } + A(AARCH64, "defined(__aarch64__)"), + A(ARM, "defined(__arm__)"), + A(MIPS, "defined(__mips__) && defined(__MIPSEB__) && (_MIPS_SIM == _ABIO32)"), + A(MIPS64, "defined(__mips__) && defined(__MIPSEB__) && (_MIPS_SIM == _ABI64)"), + A(MIPS64N32, "defined(__mips__) && defined(__MIPSEB__) && (_MIPS_SIM == _ABIN32)"), + A(MIPSEL, "defined(__mips__) && defined(__MIPSEL__) && (_MIPS_SIM == _ABIO32)"), + A(MIPSEL64, "defined(__mips__) && defined(__MIPSEL__) && (_MIPS_SIM == _ABI64)"), + A(MIPSEL64N32, "defined(__mips__) && defined(__MIPSEL__) && (_MIPS_SIM == _ABIN32)"), + A(PARISC, "defined(__hppa__) && !defined(__hppa64__)"), + A(PARISC64, "defined(__hppa__) && defined(__hppa64__)"), + A(PPC, "defined(__powerpc__) && !defined(__powerpc64__) && defined(__BIG_ENDIAN__)"), + A(PPC64, "defined(__powerpc__) && defined(__powerpc64__) && defined(__BIG_ENDIAN__)"), + A(PPC64LE, "defined(__powerpc__) && defined(__powerpc64__) && !defined(__BIG_ENDIAN__)"), + A(RISCV64, "defined(__riscv) && __riscv_xlen == 64"), + A(S390, "defined(__s390__) && !defined(__s390x__)"), + A(S390X, "defined(__s390__) && defined(__s390x__)"), + A(X86, "defined(__i386__)"), + A(X32, "defined(__x86_64__) && defined(__ILP32__)"), + A(X86_64, "defined(__x86_64__) && !defined(__ILP32__)"), +#undef A +}; + +/* Simple helper to add all of the syscalls in an array. */ +static int gen_seccomp_rules_add(scmp_filter_ctx ctx, const int syscalls[], size_t num) +{ + static uint8_t prio; + size_t i; + for (i = 0; i < num; ++i) { + if (seccomp_syscall_priority(ctx, syscalls[i], prio++) < 0) { + warn("seccomp_syscall_priority failed"); + return -1; + } + if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscalls[i], 0) < 0) { + warn("seccomp_rule_add failed"); + return -1; + } + } + return 0; +} +#define gen_seccomp_rules_add(ctx, syscalls) gen_seccomp_rules_add(ctx, syscalls, ARRAY_SIZE(syscalls)) + +static void gen_seccomp_dump(scmp_filter_ctx ctx, const char *name) +{ + unsigned char buf[32768 * 8]; + ssize_t i, len; + int fd; + + fd = memfd_create("bpf", MFD_CLOEXEC); + if (fd < 0) + err(1, "memfd_create failed"); + if (seccomp_export_bpf(ctx, fd) < 0) + err(1, "seccomp_export_bpf_mem failed"); + if (lseek(fd, 0, SEEK_SET) != 0) + err(1, "seek failed"); + len = read(fd, buf, sizeof(buf)); + if (len <= 0) + err(1, "read failed"); + + printf("static const unsigned char seccomp_bpf_blks_%s[] = {\n\t", name); + for (i = 0; i < len; ++i) + printf("%u,", buf[i]); + printf("\n};\n"); +} + +static void gen_seccomp_program(const char *name) +{ + printf( + "static const seccomp_bpf_program_t seccomp_bpf_program_%s = {\n" + " .cnt = sizeof(seccomp_bpf_blks_%s) / 8,\n" + " .bpf = seccomp_bpf_blks_%s,\n" + "};\n", name, name, name); +} + +int main(void) +{ + /* Order determines priority (first == lowest prio). */ + static const int base_syscalls[] = { + /* We write the most w/scanelf. */ + SCMP_SYS(write), + SCMP_SYS(writev), + SCMP_SYS(pwrite64), + SCMP_SYS(pwritev), + + /* Then the stat family of functions. */ + SCMP_SYS(newfstatat), + SCMP_SYS(fstat), + SCMP_SYS(fstat64), + SCMP_SYS(fstatat64), + SCMP_SYS(lstat), + SCMP_SYS(lstat64), + SCMP_SYS(stat), + SCMP_SYS(stat64), + SCMP_SYS(statx), + + /* Then the fd close func. */ + SCMP_SYS(close), + + /* Then fd open family of functions. */ + SCMP_SYS(open), + SCMP_SYS(openat), + + /* Then the memory mapping functions. */ + SCMP_SYS(mmap), + SCMP_SYS(mmap2), + SCMP_SYS(munmap), + + /* Then the directory reading functions. */ + SCMP_SYS(getdents), + SCMP_SYS(getdents64), + + /* Then the file reading functions. */ + SCMP_SYS(pread64), + SCMP_SYS(read), + SCMP_SYS(readv), + SCMP_SYS(preadv), + + /* Then the fd manipulation functions. */ + SCMP_SYS(fcntl), + SCMP_SYS(fcntl64), + + /* After this point, just sort the list alphabetically. */ + SCMP_SYS(access), + SCMP_SYS(brk), + SCMP_SYS(capget), + SCMP_SYS(chdir), + SCMP_SYS(dup), + SCMP_SYS(dup2), + SCMP_SYS(dup3), + SCMP_SYS(exit), + SCMP_SYS(exit_group), + SCMP_SYS(faccessat), +#ifndef __SNR_faccessat2 +/* faccessat2 is not yet defined in libseccomp-2.5.1 */ +# define __SNR_faccessat2 __NR_faccessat2 +#endif + SCMP_SYS(faccessat2), + SCMP_SYS(fchdir), + SCMP_SYS(getpid), + SCMP_SYS(gettid), + SCMP_SYS(ioctl), + SCMP_SYS(lseek), + SCMP_SYS(_llseek), + SCMP_SYS(mprotect), + + /* Syscalls listed because of compiler settings. */ + SCMP_SYS(futex), + + /* Syscalls listed because of sandbox. */ + SCMP_SYS(readlink), + SCMP_SYS(readlinkat), + SCMP_SYS(getcwd), + + /* Syscalls listed because of fakeroot. */ + SCMP_SYS(msgget), + SCMP_SYS(msgrcv), + SCMP_SYS(msgsnd), + SCMP_SYS(semget), + SCMP_SYS(semop), + SCMP_SYS(semtimedop), + /* + * Some targets (e.g. ppc & i386) implement the above functions + * as ipc() subcalls. #675378 + */ + SCMP_SYS(ipc), + + /* glibc-2.34+ uses it as part of mem alloc functions. */ + SCMP_SYS(getrandom), + + /* glibc-2.35+ uses it when GLIBC_TUNABLES=glibc.malloc.hugetlb=1. */ + SCMP_SYS(madvise), + }; + static const int fork_syscalls[] = { + SCMP_SYS(clone), + SCMP_SYS(execve), + SCMP_SYS(fork), + SCMP_SYS(rt_sigaction), + SCMP_SYS(rt_sigprocmask), + SCMP_SYS(unshare), + SCMP_SYS(vfork), + SCMP_SYS(wait4), + SCMP_SYS(waitid), + SCMP_SYS(waitpid), + }; + + /* TODO: Handle debug and KILL vs TRAP. */ + + scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL); + if (!ctx) + err(1, "seccomp_init failed"); + + printf("/* AUTO GENERATED FILE. To regenerate run:\n"); + printf(" * $ $EDITOR seccomp-bpf.c\n"); + printf(" * $ make seccomp-bpf.h\n"); + printf(" * See seccomp-bpf.c for details. */\n"); + printf("#undef SECCOMP_BPF_AVAILABLE\n"); + + if (seccomp_arch_remove(ctx, seccomp_arch_native()) < 0) + err(1, "seccomp_arch_remove failed"); + + for (size_t i = 0; i < ARRAY_SIZE(gen_seccomp_arches); ++i) { + uint32_t arch = gen_seccomp_arches[i].arch; + + seccomp_reset(ctx, SCMP_ACT_KILL); + + if (arch != seccomp_arch_native()) { + if (seccomp_arch_remove(ctx, seccomp_arch_native()) < 0) + err(1, "seccomp_arch_remove failed"); + if (seccomp_arch_add(ctx, arch) < 0) + err(1, "seccomp_arch_add failed"); + } + + printf("\n#if %s\n", gen_seccomp_arches[i].ifdef); + printf("/* %s */\n", gen_seccomp_arches[i].name); + printf("#define SECCOMP_BPF_AVAILABLE\n"); + + if (gen_seccomp_rules_add(ctx, base_syscalls) < 0) + err(1, "seccomp_rules_add failed"); + gen_seccomp_dump(ctx, "base"); + + if (gen_seccomp_rules_add(ctx, fork_syscalls) < 0) + err(1, "seccomp_rules_add failed"); + gen_seccomp_dump(ctx, "fork"); + + if (0) { + printf("/*\n"); + fflush(stdout); + seccomp_export_pfc(ctx, 1); + fflush(stdout); + printf("*/\n"); + } + + printf("#endif\n"); + } + + printf( + "\n" + "#ifdef SECCOMP_BPF_AVAILABLE\n" + "typedef struct {\n" + " uint16_t cnt;\n" + " const void *bpf;\n" + "} seccomp_bpf_program_t;\n"); + gen_seccomp_program("base"); + gen_seccomp_program("fork"); + printf("#endif\n"); + + seccomp_release(ctx); + + return 0; +} diff --git a/seccomp-bpf.h b/seccomp-bpf.h new file mode 100644 index 0000000..80d6d94 --- /dev/null +++ b/seccomp-bpf.h @@ -0,0 +1,229 @@ +/* AUTO GENERATED FILE. To regenerate run: + * $ $EDITOR seccomp-bpf.c + * $ make seccomp-bpf.h + * See seccomp-bpf.c for details. */ +#undef SECCOMP_BPF_AVAILABLE + +#if defined(__aarch64__) +/* AARCH64 */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 32,0,0,0,4,0,0,0,21,0,0,45,183,0,0,192,32,0,0,0,0,0,0,0,21,0,42,0,233,0,0,0,21,0,41,0,22,1,0,0,21,0,40,0,192,0,0,0,21,0,39,0,193,0,0,0,21,0,38,0,190,0,0,0,21,0,37,0,189,0,0,0,21,0,36,0,188,0,0,0,21,0,35,0,186,0,0,0,21,0,34,0,17,0,0,0,21,0,33,0,78,0,0,0,21,0,32,0,98,0,0,0,21,0,31,0,226,0,0,0,21,0,30,0,62,0,0,0,21,0,29,0,29,0,0,0,21,0,28,0,178,0,0,0,21,0,27,0,172,0,0,0,21,0,26,0,50,0,0,0,21,0,25,0,183,1,0,0,21,0,24,0,48,0,0,0,21,0,23,0,94,0,0,0,21,0,22,0,93,0,0,0,21,0,21,0,24,0,0,0,21,0,20,0,23,0,0,0,21,0,19,0,49,0,0,0,21,0,18,0,90,0,0,0,21,0,17,0,214,0,0,0,21,0,16,0,25,0,0,0,21,0,15,0,69,0,0,0,21,0,14,0,65,0,0,0,21,0,13,0,63,0,0,0,21,0,12,0,67,0,0,0,21,0,11,0,61,0,0,0,21,0,10,0,215,0,0,0,21,0,9,0,222,0,0,0,21,0,8,0,56,0,0,0,21,0,7,0,57,0,0,0,21,0,6,0,35,1,0,0,21,0,5,0,80,0,0,0,21,0,4,0,79,0,0,0,21,0,3,0,70,0,0,0,21,0,2,0,68,0,0,0,21,0,1,0,66,0,0,0,21,0,0,1,64,0,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 32,0,0,0,4,0,0,0,21,0,0,52,183,0,0,192,32,0,0,0,0,0,0,0,21,0,49,0,95,0,0,0,21,0,48,0,4,1,0,0,21,0,47,0,97,0,0,0,21,0,46,0,135,0,0,0,21,0,45,0,134,0,0,0,21,0,44,0,221,0,0,0,21,0,43,0,220,0,0,0,21,0,42,0,233,0,0,0,21,0,41,0,22,1,0,0,21,0,40,0,192,0,0,0,21,0,39,0,193,0,0,0,21,0,38,0,190,0,0,0,21,0,37,0,189,0,0,0,21,0,36,0,188,0,0,0,21,0,35,0,186,0,0,0,21,0,34,0,17,0,0,0,21,0,33,0,78,0,0,0,21,0,32,0,98,0,0,0,21,0,31,0,226,0,0,0,21,0,30,0,62,0,0,0,21,0,29,0,29,0,0,0,21,0,28,0,178,0,0,0,21,0,27,0,172,0,0,0,21,0,26,0,50,0,0,0,21,0,25,0,183,1,0,0,21,0,24,0,48,0,0,0,21,0,23,0,94,0,0,0,21,0,22,0,93,0,0,0,21,0,21,0,24,0,0,0,21,0,20,0,23,0,0,0,21,0,19,0,49,0,0,0,21,0,18,0,90,0,0,0,21,0,17,0,214,0,0,0,21,0,16,0,25,0,0,0,21,0,15,0,69,0,0,0,21,0,14,0,65,0,0,0,21,0,13,0,63,0,0,0,21,0,12,0,67,0,0,0,21,0,11,0,61,0,0,0,21,0,10,0,215,0,0,0,21,0,9,0,222,0,0,0,21,0,8,0,56,0,0,0,21,0,7,0,57,0,0,0,21,0,6,0,35,1,0,0,21,0,5,0,80,0,0,0,21,0,4,0,79,0,0,0,21,0,3,0,70,0,0,0,21,0,2,0,68,0,0,0,21,0,1,0,66,0,0,0,21,0,0,1,64,0,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +#endif + +#if defined(__arm__) +/* ARM */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 32,0,0,0,4,0,0,0,21,0,0,57,40,0,0,64,32,0,0,0,0,0,0,0,21,0,54,0,220,0,0,0,21,0,53,0,128,1,0,0,21,0,52,0,56,1,0,0,21,0,51,0,42,1,0,0,21,0,50,0,43,1,0,0,21,0,49,0,45,1,0,0,21,0,48,0,46,1,0,0,21,0,47,0,47,1,0,0,21,0,46,0,183,0,0,0,21,0,45,0,76,1,0,0,21,0,44,0,85,0,0,0,21,0,43,0,240,0,0,0,21,0,42,0,125,0,0,0,21,0,41,0,140,0,0,0,21,0,40,0,19,0,0,0,21,0,39,0,54,0,0,0,21,0,38,0,224,0,0,0,21,0,37,0,20,0,0,0,21,0,36,0,133,0,0,0,21,0,35,0,183,1,0,0,21,0,34,0,78,1,0,0,21,0,33,0,248,0,0,0,21,0,32,0,1,0,0,0,21,0,31,0,102,1,0,0,21,0,30,0,63,0,0,0,21,0,29,0,41,0,0,0,21,0,28,0,12,0,0,0,21,0,27,0,184,0,0,0,21,0,26,0,45,0,0,0,21,0,25,0,33,0,0,0,21,0,24,0,221,0,0,0,21,0,23,0,55,0,0,0,21,0,22,0,105,1,0,0,21,0,21,0,145,0,0,0,21,0,20,0,3,0,0,0,21,0,19,0,180,0,0,0,21,0,18,0,217,0,0,0,21,0,17,0,141,0,0,0,21,0,16,0,91,0,0,0,21,0,15,0,192,0,0,0,21,0,14,0,66,1,0,0,21,0,13,0,5,0,0,0,21,0,12,0,6,0,0,0,21,0,11,0,141,1,0,0,21,0,10,0,195,0,0,0,21,0,9,0,106,0,0,0,21,0,8,0,196,0,0,0,21,0,7,0,107,0,0,0,21,0,6,0,71,1,0,0,21,0,5,0,197,0,0,0,21,0,4,0,108,0,0,0,21,0,3,0,106,1,0,0,21,0,2,0,181,0,0,0,21,0,1,0,146,0,0,0,21,0,0,1,4,0,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 32,0,0,0,4,0,0,0,21,0,0,66,40,0,0,64,32,0,0,0,0,0,0,0,21,0,63,0,24,1,0,0,21,0,62,0,114,0,0,0,21,0,61,0,190,0,0,0,21,0,60,0,81,1,0,0,21,0,59,0,175,0,0,0,21,0,58,0,174,0,0,0,21,0,57,0,2,0,0,0,21,0,56,0,11,0,0,0,21,0,55,0,120,0,0,0,21,0,54,0,220,0,0,0,21,0,53,0,128,1,0,0,21,0,52,0,56,1,0,0,21,0,51,0,42,1,0,0,21,0,50,0,43,1,0,0,21,0,49,0,45,1,0,0,21,0,48,0,46,1,0,0,21,0,47,0,47,1,0,0,21,0,46,0,183,0,0,0,21,0,45,0,76,1,0,0,21,0,44,0,85,0,0,0,21,0,43,0,240,0,0,0,21,0,42,0,125,0,0,0,21,0,41,0,140,0,0,0,21,0,40,0,19,0,0,0,21,0,39,0,54,0,0,0,21,0,38,0,224,0,0,0,21,0,37,0,20,0,0,0,21,0,36,0,133,0,0,0,21,0,35,0,183,1,0,0,21,0,34,0,78,1,0,0,21,0,33,0,248,0,0,0,21,0,32,0,1,0,0,0,21,0,31,0,102,1,0,0,21,0,30,0,63,0,0,0,21,0,29,0,41,0,0,0,21,0,28,0,12,0,0,0,21,0,27,0,184,0,0,0,21,0,26,0,45,0,0,0,21,0,25,0,33,0,0,0,21,0,24,0,221,0,0,0,21,0,23,0,55,0,0,0,21,0,22,0,105,1,0,0,21,0,21,0,145,0,0,0,21,0,20,0,3,0,0,0,21,0,19,0,180,0,0,0,21,0,18,0,217,0,0,0,21,0,17,0,141,0,0,0,21,0,16,0,91,0,0,0,21,0,15,0,192,0,0,0,21,0,14,0,66,1,0,0,21,0,13,0,5,0,0,0,21,0,12,0,6,0,0,0,21,0,11,0,141,1,0,0,21,0,10,0,195,0,0,0,21,0,9,0,106,0,0,0,21,0,8,0,196,0,0,0,21,0,7,0,107,0,0,0,21,0,6,0,71,1,0,0,21,0,5,0,197,0,0,0,21,0,4,0,108,0,0,0,21,0,3,0,106,1,0,0,21,0,2,0,181,0,0,0,21,0,1,0,146,0,0,0,21,0,0,1,4,0,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +#endif + +#if defined(__mips__) && defined(__MIPSEB__) && (_MIPS_SIM == _ABIO32) +/* MIPS */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 0,32,0,0,0,0,0,4,0,21,0,57,0,0,0,8,0,32,0,0,0,0,0,0,0,21,54,0,0,0,16,122,0,21,53,0,0,0,17,1,0,21,52,0,0,0,16,21,0,21,51,0,0,0,16,107,0,21,50,0,0,0,16,202,0,21,49,0,0,0,15,245,0,21,48,0,0,0,16,142,0,21,47,0,0,0,16,29,0,21,46,0,0,0,16,44,0,21,45,0,0,0,15,179,0,21,44,0,0,0,15,214,0,21,43,0,0,0,16,126,0,21,42,0,0,0,15,180,0,21,41,0,0,0,16,37,0,21,40,0,0,0,17,87,0,21,39,0,0,0,16,204,0,21,38,0,0,0,16,150,0,21,37,0,0,0,15,161,0,21,36,0,0,0,16,231,0,21,35,0,0,0,15,223,0,21,34,0,0,0,15,201,0,21,33,0,0,0,15,172,0,21,32,0,0,0,16,108,0,21,31,0,0,0,15,205,0,21,30,0,0,0,15,193,0,21,29,0,0,0,16,124,0,21,28,0,0,0,15,215,0,21,27,0,0,0,16,234,0,21,26,0,0,0,16,49,0,21,25,0,0,0,15,163,0,21,24,0,0,0,16,104,0,21,23,0,0,0,16,123,0,21,22,0,0,0,16,45,0,21,21,0,0,0,15,251,0,21,20,0,0,0,16,114,0,21,19,0,0,0,15,250,0,21,18,0,0,0,16,192,0,21,17,0,0,0,15,165,0,21,16,0,0,0,15,166,0,21,15,0,0,0,17,14,0,21,14,0,0,0,16,117,0,21,13,0,0,0,16,10,0,21,12,0,0,0,16,118,0,21,11,0,0,0,16,11,0,21,10,0,0,0,16,197,0,21,9,0,0,0,16,119,0,21,8,0,0,0,16,12,0,21,7,0,0,0,16,235,0,21,6,0,0,0,16,105,0,21,5,0,0,0,16,50,0,21,4,0,0,0,15,164,0,21,3,0,0,0,17,41,0,21,2,0,0,0,17,47,0,21,1,0,0,0,17,48,0,21,0,1,0,0,17,49,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 0,32,0,0,0,0,0,4,0,21,0,66,0,0,0,8,0,32,0,0,0,0,0,0,0,21,63,0,0,0,15,167,0,21,62,0,0,0,16,182,0,21,61,0,0,0,16,18,0,21,60,0,0,0,16,207,0,21,59,0,0,0,16,99,0,21,58,0,0,0,16,98,0,21,57,0,0,0,15,162,0,21,56,0,0,0,15,171,0,21,55,0,0,0,16,24,0,21,54,0,0,0,16,122,0,21,53,0,0,0,17,1,0,21,52,0,0,0,16,21,0,21,51,0,0,0,16,107,0,21,50,0,0,0,16,202,0,21,49,0,0,0,15,245,0,21,48,0,0,0,16,142,0,21,47,0,0,0,16,29,0,21,46,0,0,0,16,44,0,21,45,0,0,0,15,179,0,21,44,0,0,0,15,214,0,21,43,0,0,0,16,126,0,21,42,0,0,0,15,180,0,21,41,0,0,0,16,37,0,21,40,0,0,0,17,87,0,21,39,0,0,0,16,204,0,21,38,0,0,0,16,150,0,21,37,0,0,0,15,161,0,21,36,0,0,0,16,231,0,21,35,0,0,0,15,223,0,21,34,0,0,0,15,201,0,21,33,0,0,0,15,172,0,21,32,0,0,0,16,108,0,21,31,0,0,0,15,205,0,21,30,0,0,0,15,193,0,21,29,0,0,0,16,124,0,21,28,0,0,0,15,215,0,21,27,0,0,0,16,234,0,21,26,0,0,0,16,49,0,21,25,0,0,0,15,163,0,21,24,0,0,0,16,104,0,21,23,0,0,0,16,123,0,21,22,0,0,0,16,45,0,21,21,0,0,0,15,251,0,21,20,0,0,0,16,114,0,21,19,0,0,0,15,250,0,21,18,0,0,0,16,192,0,21,17,0,0,0,15,165,0,21,16,0,0,0,15,166,0,21,15,0,0,0,17,14,0,21,14,0,0,0,16,117,0,21,13,0,0,0,16,10,0,21,12,0,0,0,16,118,0,21,11,0,0,0,16,11,0,21,10,0,0,0,16,197,0,21,9,0,0,0,16,119,0,21,8,0,0,0,16,12,0,21,7,0,0,0,16,235,0,21,6,0,0,0,16,105,0,21,5,0,0,0,16,50,0,21,4,0,0,0,15,164,0,21,3,0,0,0,17,41,0,21,2,0,0,0,17,47,0,21,1,0,0,0,17,48,0,21,0,1,0,0,17,49,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +#endif + +#if defined(__mips__) && defined(__MIPSEB__) && (_MIPS_SIM == _ABI64) +/* MIPS64 */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 0,32,0,0,0,0,0,4,0,21,0,52,128,0,0,8,0,32,0,0,0,0,0,0,0,21,49,0,0,0,19,203,0,21,48,0,0,0,19,204,0,21,47,0,0,0,19,202,0,21,46,0,0,0,19,213,0,21,45,0,0,0,20,137,0,21,44,0,0,0,19,223,0,21,43,0,0,0,20,74,0,21,42,0,0,0,19,146,0,21,41,0,0,0,19,144,0,21,40,0,0,0,19,151,0,21,39,0,0,0,20,58,0,21,38,0,0,0,19,174,0,21,37,0,0,0,19,215,0,21,36,0,0,0,21,63,0,21,35,0,0,0,20,139,0,21,34,0,0,0,20,85,0,21,33,0,0,0,19,194,0,21,32,0,0,0,20,166,0,21,31,0,0,0,19,168,0,21,30,0,0,0,19,167,0,21,29,0,0,0,19,214,0,21,28,0,0,0,20,3,0,21,27,0,0,0,19,148,0,21,26,0,0,0,19,156,0,21,25,0,0,0,19,206,0,21,24,0,0,0,20,169,0,21,23,0,0,0,19,154,0,21,22,0,0,0,19,136,0,21,21,0,0,0,19,152,0,21,20,0,0,0,20,188,0,21,19,0,0,0,19,212,0,21,18,0,0,0,19,147,0,21,17,0,0,0,19,145,0,21,16,0,0,0,20,127,0,21,15,0,0,0,19,138,0,21,14,0,0,0,19,139,0,21,13,0,0,0,20,206,0,21,12,0,0,0,19,140,0,21,11,0,0,0,19,142,0,21,10,0,0,0,19,141,0,21,9,0,0,0,20,132,0,21,8,0,0,0,20,170,0,21,7,0,0,0,19,153,0,21,6,0,0,0,19,155,0,21,5,0,0,0,19,137,0,21,4,0,0,0,19,163,0,21,3,0,0,0,20,193,0,21,2,0,0,0,20,94,0,21,1,0,0,0,19,199,0,21,0,1,0,0,19,198,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 0,32,0,0,0,0,0,4,0,21,0,60,128,0,0,8,0,32,0,0,0,0,0,0,0,21,57,0,0,0,19,203,0,21,56,0,0,0,19,204,0,21,55,0,0,0,19,202,0,21,54,0,0,0,19,213,0,21,53,0,0,0,20,137,0,21,52,0,0,0,19,223,0,21,51,0,0,0,20,74,0,21,50,0,0,0,19,146,0,21,49,0,0,0,19,144,0,21,48,0,0,0,19,151,0,21,47,0,0,0,20,58,0,21,46,0,0,0,19,174,0,21,45,0,0,0,19,215,0,21,44,0,0,0,21,63,0,21,43,0,0,0,20,139,0,21,42,0,0,0,20,85,0,21,41,0,0,0,19,194,0,21,40,0,0,0,20,166,0,21,39,0,0,0,19,168,0,21,38,0,0,0,19,167,0,21,37,0,0,0,19,214,0,21,36,0,0,0,20,3,0,21,35,0,0,0,19,148,0,21,34,0,0,0,19,156,0,21,33,0,0,0,19,206,0,21,32,0,0,0,20,169,0,21,31,0,0,0,19,154,0,21,30,0,0,0,19,136,0,21,29,0,0,0,19,152,0,21,28,0,0,0,20,188,0,21,27,0,0,0,19,212,0,21,26,0,0,0,19,147,0,21,25,0,0,0,19,145,0,21,24,0,0,0,20,127,0,21,23,0,0,0,19,138,0,21,22,0,0,0,19,139,0,21,21,0,0,0,20,206,0,21,20,0,0,0,19,140,0,21,19,0,0,0,19,142,0,21,18,0,0,0,19,141,0,21,17,0,0,0,20,132,0,21,16,0,0,0,20,170,0,21,15,0,0,0,19,153,0,21,14,0,0,0,19,155,0,21,13,0,0,0,19,137,0,21,12,0,0,0,20,117,0,21,11,0,0,0,19,195,0,21,10,0,0,0,20,142,0,21,9,0,0,0,19,150,0,21,8,0,0,0,19,149,0,21,7,0,0,0,19,192,0,21,6,0,0,0,19,193,0,21,5,0,0,0,19,191,0,21,4,0,0,0,19,163,0,21,3,0,0,0,20,193,0,21,2,0,0,0,20,94,0,21,1,0,0,0,19,199,0,21,0,1,0,0,19,198,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +#endif + +#if defined(__mips__) && defined(__MIPSEB__) && (_MIPS_SIM == _ABIN32) +/* MIPS64N32 */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 0,32,0,0,0,0,0,4,0,21,0,53,160,0,0,8,0,32,0,0,0,0,0,0,0,21,50,0,0,0,23,139,0,21,49,0,0,0,24,173,0,21,48,0,0,0,24,71,0,21,47,0,0,0,23,175,0,21,46,0,0,0,23,174,0,21,45,0,0,0,23,179,0,21,44,0,0,0,23,180,0,21,43,0,0,0,23,178,0,21,42,0,0,0,23,189,0,21,41,0,0,0,24,117,0,21,40,0,0,0,23,199,0,21,39,0,0,0,24,50,0,21,38,0,0,0,23,122,0,21,37,0,0,0,23,120,0,21,36,0,0,0,23,127,0,21,35,0,0,0,24,34,0,21,34,0,0,0,23,150,0,21,33,0,0,0,23,191,0,21,32,0,0,0,25,39,0,21,31,0,0,0,24,119,0,21,30,0,0,0,24,61,0,21,29,0,0,0,23,170,0,21,28,0,0,0,24,146,0,21,27,0,0,0,23,144,0,21,26,0,0,0,23,143,0,21,25,0,0,0,23,190,0,21,24,0,0,0,23,235,0,21,23,0,0,0,23,124,0,21,22,0,0,0,23,132,0,21,21,0,0,0,24,68,0,21,20,0,0,0,23,182,0,21,19,0,0,0,24,149,0,21,18,0,0,0,23,130,0,21,17,0,0,0,23,112,0,21,16,0,0,0,23,128,0,21,15,0,0,0,24,155,0,21,14,0,0,0,23,188,0,21,13,0,0,0,23,123,0,21,12,0,0,0,23,121,0,21,11,0,0,0,24,107,0,21,10,0,0,0,23,114,0,21,9,0,0,0,23,115,0,21,8,0,0,0,24,186,0,21,7,0,0,0,23,116,0,21,6,0,0,0,23,118,0,21,5,0,0,0,23,117,0,21,4,0,0,0,24,112,0,21,3,0,0,0,24,150,0,21,2,0,0,0,23,129,0,21,1,0,0,0,23,131,0,21,0,1,0,0,23,113,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 0,32,0,0,0,0,0,4,0,21,0,61,160,0,0,8,0,32,0,0,0,0,0,0,0,21,58,0,0,0,24,97,0,21,57,0,0,0,23,171,0,21,56,0,0,0,24,122,0,21,55,0,0,0,23,126,0,21,54,0,0,0,23,125,0,21,53,0,0,0,23,168,0,21,52,0,0,0,23,169,0,21,51,0,0,0,23,167,0,21,50,0,0,0,23,139,0,21,49,0,0,0,24,173,0,21,48,0,0,0,24,71,0,21,47,0,0,0,23,175,0,21,46,0,0,0,23,174,0,21,45,0,0,0,23,179,0,21,44,0,0,0,23,180,0,21,43,0,0,0,23,178,0,21,42,0,0,0,23,189,0,21,41,0,0,0,24,117,0,21,40,0,0,0,23,199,0,21,39,0,0,0,24,50,0,21,38,0,0,0,23,122,0,21,37,0,0,0,23,120,0,21,36,0,0,0,23,127,0,21,35,0,0,0,24,34,0,21,34,0,0,0,23,150,0,21,33,0,0,0,23,191,0,21,32,0,0,0,25,39,0,21,31,0,0,0,24,119,0,21,30,0,0,0,24,61,0,21,29,0,0,0,23,170,0,21,28,0,0,0,24,146,0,21,27,0,0,0,23,144,0,21,26,0,0,0,23,143,0,21,25,0,0,0,23,190,0,21,24,0,0,0,23,235,0,21,23,0,0,0,23,124,0,21,22,0,0,0,23,132,0,21,21,0,0,0,24,68,0,21,20,0,0,0,23,182,0,21,19,0,0,0,24,149,0,21,18,0,0,0,23,130,0,21,17,0,0,0,23,112,0,21,16,0,0,0,23,128,0,21,15,0,0,0,24,155,0,21,14,0,0,0,23,188,0,21,13,0,0,0,23,123,0,21,12,0,0,0,23,121,0,21,11,0,0,0,24,107,0,21,10,0,0,0,23,114,0,21,9,0,0,0,23,115,0,21,8,0,0,0,24,186,0,21,7,0,0,0,23,116,0,21,6,0,0,0,23,118,0,21,5,0,0,0,23,117,0,21,4,0,0,0,24,112,0,21,3,0,0,0,24,150,0,21,2,0,0,0,23,129,0,21,1,0,0,0,23,131,0,21,0,1,0,0,23,113,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +#endif + +#if defined(__mips__) && defined(__MIPSEL__) && (_MIPS_SIM == _ABIO32) +/* MIPSEL */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 32,0,0,0,4,0,0,0,21,0,0,57,8,0,0,64,32,0,0,0,0,0,0,0,21,0,54,0,122,16,0,0,21,0,53,0,1,17,0,0,21,0,52,0,21,16,0,0,21,0,51,0,107,16,0,0,21,0,50,0,202,16,0,0,21,0,49,0,245,15,0,0,21,0,48,0,142,16,0,0,21,0,47,0,29,16,0,0,21,0,46,0,44,16,0,0,21,0,45,0,179,15,0,0,21,0,44,0,214,15,0,0,21,0,43,0,126,16,0,0,21,0,42,0,180,15,0,0,21,0,41,0,37,16,0,0,21,0,40,0,87,17,0,0,21,0,39,0,204,16,0,0,21,0,38,0,150,16,0,0,21,0,37,0,161,15,0,0,21,0,36,0,231,16,0,0,21,0,35,0,223,15,0,0,21,0,34,0,201,15,0,0,21,0,33,0,172,15,0,0,21,0,32,0,108,16,0,0,21,0,31,0,205,15,0,0,21,0,30,0,193,15,0,0,21,0,29,0,124,16,0,0,21,0,28,0,215,15,0,0,21,0,27,0,234,16,0,0,21,0,26,0,49,16,0,0,21,0,25,0,163,15,0,0,21,0,24,0,104,16,0,0,21,0,23,0,123,16,0,0,21,0,22,0,45,16,0,0,21,0,21,0,251,15,0,0,21,0,20,0,114,16,0,0,21,0,19,0,250,15,0,0,21,0,18,0,192,16,0,0,21,0,17,0,165,15,0,0,21,0,16,0,166,15,0,0,21,0,15,0,14,17,0,0,21,0,14,0,117,16,0,0,21,0,13,0,10,16,0,0,21,0,12,0,118,16,0,0,21,0,11,0,11,16,0,0,21,0,10,0,197,16,0,0,21,0,9,0,119,16,0,0,21,0,8,0,12,16,0,0,21,0,7,0,235,16,0,0,21,0,6,0,105,16,0,0,21,0,5,0,50,16,0,0,21,0,4,0,164,15,0,0,21,0,3,0,41,17,0,0,21,0,2,0,47,17,0,0,21,0,1,0,48,17,0,0,21,0,0,1,49,17,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 32,0,0,0,4,0,0,0,21,0,0,66,8,0,0,64,32,0,0,0,0,0,0,0,21,0,63,0,167,15,0,0,21,0,62,0,182,16,0,0,21,0,61,0,18,16,0,0,21,0,60,0,207,16,0,0,21,0,59,0,99,16,0,0,21,0,58,0,98,16,0,0,21,0,57,0,162,15,0,0,21,0,56,0,171,15,0,0,21,0,55,0,24,16,0,0,21,0,54,0,122,16,0,0,21,0,53,0,1,17,0,0,21,0,52,0,21,16,0,0,21,0,51,0,107,16,0,0,21,0,50,0,202,16,0,0,21,0,49,0,245,15,0,0,21,0,48,0,142,16,0,0,21,0,47,0,29,16,0,0,21,0,46,0,44,16,0,0,21,0,45,0,179,15,0,0,21,0,44,0,214,15,0,0,21,0,43,0,126,16,0,0,21,0,42,0,180,15,0,0,21,0,41,0,37,16,0,0,21,0,40,0,87,17,0,0,21,0,39,0,204,16,0,0,21,0,38,0,150,16,0,0,21,0,37,0,161,15,0,0,21,0,36,0,231,16,0,0,21,0,35,0,223,15,0,0,21,0,34,0,201,15,0,0,21,0,33,0,172,15,0,0,21,0,32,0,108,16,0,0,21,0,31,0,205,15,0,0,21,0,30,0,193,15,0,0,21,0,29,0,124,16,0,0,21,0,28,0,215,15,0,0,21,0,27,0,234,16,0,0,21,0,26,0,49,16,0,0,21,0,25,0,163,15,0,0,21,0,24,0,104,16,0,0,21,0,23,0,123,16,0,0,21,0,22,0,45,16,0,0,21,0,21,0,251,15,0,0,21,0,20,0,114,16,0,0,21,0,19,0,250,15,0,0,21,0,18,0,192,16,0,0,21,0,17,0,165,15,0,0,21,0,16,0,166,15,0,0,21,0,15,0,14,17,0,0,21,0,14,0,117,16,0,0,21,0,13,0,10,16,0,0,21,0,12,0,118,16,0,0,21,0,11,0,11,16,0,0,21,0,10,0,197,16,0,0,21,0,9,0,119,16,0,0,21,0,8,0,12,16,0,0,21,0,7,0,235,16,0,0,21,0,6,0,105,16,0,0,21,0,5,0,50,16,0,0,21,0,4,0,164,15,0,0,21,0,3,0,41,17,0,0,21,0,2,0,47,17,0,0,21,0,1,0,48,17,0,0,21,0,0,1,49,17,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +#endif + +#if defined(__mips__) && defined(__MIPSEL__) && (_MIPS_SIM == _ABI64) +/* MIPSEL64 */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 32,0,0,0,4,0,0,0,21,0,0,52,8,0,0,192,32,0,0,0,0,0,0,0,21,0,49,0,163,19,0,0,21,0,48,0,193,20,0,0,21,0,47,0,94,20,0,0,21,0,46,0,199,19,0,0,21,0,45,0,198,19,0,0,21,0,44,0,203,19,0,0,21,0,43,0,204,19,0,0,21,0,42,0,202,19,0,0,21,0,41,0,213,19,0,0,21,0,40,0,137,20,0,0,21,0,39,0,223,19,0,0,21,0,38,0,74,20,0,0,21,0,37,0,146,19,0,0,21,0,36,0,144,19,0,0,21,0,35,0,151,19,0,0,21,0,34,0,58,20,0,0,21,0,33,0,174,19,0,0,21,0,32,0,215,19,0,0,21,0,31,0,63,21,0,0,21,0,30,0,139,20,0,0,21,0,29,0,85,20,0,0,21,0,28,0,194,19,0,0,21,0,27,0,166,20,0,0,21,0,26,0,168,19,0,0,21,0,25,0,167,19,0,0,21,0,24,0,214,19,0,0,21,0,23,0,3,20,0,0,21,0,22,0,148,19,0,0,21,0,21,0,156,19,0,0,21,0,20,0,206,19,0,0,21,0,19,0,169,20,0,0,21,0,18,0,154,19,0,0,21,0,17,0,136,19,0,0,21,0,16,0,152,19,0,0,21,0,15,0,188,20,0,0,21,0,14,0,212,19,0,0,21,0,13,0,147,19,0,0,21,0,12,0,145,19,0,0,21,0,11,0,127,20,0,0,21,0,10,0,138,19,0,0,21,0,9,0,139,19,0,0,21,0,8,0,206,20,0,0,21,0,7,0,140,19,0,0,21,0,6,0,142,19,0,0,21,0,5,0,141,19,0,0,21,0,4,0,132,20,0,0,21,0,3,0,170,20,0,0,21,0,2,0,153,19,0,0,21,0,1,0,155,19,0,0,21,0,0,1,137,19,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 32,0,0,0,4,0,0,0,21,0,0,60,8,0,0,192,32,0,0,0,0,0,0,0,21,0,57,0,117,20,0,0,21,0,56,0,195,19,0,0,21,0,55,0,142,20,0,0,21,0,54,0,150,19,0,0,21,0,53,0,149,19,0,0,21,0,52,0,192,19,0,0,21,0,51,0,193,19,0,0,21,0,50,0,191,19,0,0,21,0,49,0,163,19,0,0,21,0,48,0,193,20,0,0,21,0,47,0,94,20,0,0,21,0,46,0,199,19,0,0,21,0,45,0,198,19,0,0,21,0,44,0,203,19,0,0,21,0,43,0,204,19,0,0,21,0,42,0,202,19,0,0,21,0,41,0,213,19,0,0,21,0,40,0,137,20,0,0,21,0,39,0,223,19,0,0,21,0,38,0,74,20,0,0,21,0,37,0,146,19,0,0,21,0,36,0,144,19,0,0,21,0,35,0,151,19,0,0,21,0,34,0,58,20,0,0,21,0,33,0,174,19,0,0,21,0,32,0,215,19,0,0,21,0,31,0,63,21,0,0,21,0,30,0,139,20,0,0,21,0,29,0,85,20,0,0,21,0,28,0,194,19,0,0,21,0,27,0,166,20,0,0,21,0,26,0,168,19,0,0,21,0,25,0,167,19,0,0,21,0,24,0,214,19,0,0,21,0,23,0,3,20,0,0,21,0,22,0,148,19,0,0,21,0,21,0,156,19,0,0,21,0,20,0,206,19,0,0,21,0,19,0,169,20,0,0,21,0,18,0,154,19,0,0,21,0,17,0,136,19,0,0,21,0,16,0,152,19,0,0,21,0,15,0,188,20,0,0,21,0,14,0,212,19,0,0,21,0,13,0,147,19,0,0,21,0,12,0,145,19,0,0,21,0,11,0,127,20,0,0,21,0,10,0,138,19,0,0,21,0,9,0,139,19,0,0,21,0,8,0,206,20,0,0,21,0,7,0,140,19,0,0,21,0,6,0,142,19,0,0,21,0,5,0,141,19,0,0,21,0,4,0,132,20,0,0,21,0,3,0,170,20,0,0,21,0,2,0,153,19,0,0,21,0,1,0,155,19,0,0,21,0,0,1,137,19,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +#endif + +#if defined(__mips__) && defined(__MIPSEL__) && (_MIPS_SIM == _ABIN32) +/* MIPSEL64N32 */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 32,0,0,0,4,0,0,0,21,0,0,53,8,0,0,224,32,0,0,0,0,0,0,0,21,0,50,0,61,24,0,0,21,0,49,0,170,23,0,0,21,0,48,0,146,24,0,0,21,0,47,0,144,23,0,0,21,0,46,0,143,23,0,0,21,0,45,0,190,23,0,0,21,0,44,0,235,23,0,0,21,0,43,0,124,23,0,0,21,0,42,0,132,23,0,0,21,0,41,0,68,24,0,0,21,0,40,0,182,23,0,0,21,0,39,0,149,24,0,0,21,0,38,0,130,23,0,0,21,0,37,0,112,23,0,0,21,0,36,0,128,23,0,0,21,0,35,0,155,24,0,0,21,0,34,0,188,23,0,0,21,0,33,0,123,23,0,0,21,0,32,0,121,23,0,0,21,0,31,0,107,24,0,0,21,0,30,0,114,23,0,0,21,0,29,0,115,23,0,0,21,0,28,0,186,24,0,0,21,0,27,0,116,23,0,0,21,0,26,0,118,23,0,0,21,0,25,0,117,23,0,0,21,0,24,0,112,24,0,0,21,0,23,0,150,24,0,0,21,0,22,0,129,23,0,0,21,0,21,0,131,23,0,0,21,0,20,0,113,23,0,0,21,0,19,0,139,23,0,0,21,0,18,0,173,24,0,0,21,0,17,0,71,24,0,0,21,0,16,0,175,23,0,0,21,0,15,0,174,23,0,0,21,0,14,0,179,23,0,0,21,0,13,0,180,23,0,0,21,0,12,0,178,23,0,0,21,0,11,0,189,23,0,0,21,0,10,0,117,24,0,0,21,0,9,0,199,23,0,0,21,0,8,0,50,24,0,0,21,0,7,0,122,23,0,0,21,0,6,0,120,23,0,0,21,0,5,0,127,23,0,0,21,0,4,0,34,24,0,0,21,0,3,0,150,23,0,0,21,0,2,0,191,23,0,0,21,0,1,0,39,25,0,0,21,0,0,1,119,24,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 32,0,0,0,4,0,0,0,21,0,0,61,8,0,0,224,32,0,0,0,0,0,0,0,21,0,58,0,61,24,0,0,21,0,57,0,170,23,0,0,21,0,56,0,146,24,0,0,21,0,55,0,144,23,0,0,21,0,54,0,143,23,0,0,21,0,53,0,190,23,0,0,21,0,52,0,235,23,0,0,21,0,51,0,124,23,0,0,21,0,50,0,132,23,0,0,21,0,49,0,68,24,0,0,21,0,48,0,182,23,0,0,21,0,47,0,149,24,0,0,21,0,46,0,130,23,0,0,21,0,45,0,112,23,0,0,21,0,44,0,128,23,0,0,21,0,43,0,155,24,0,0,21,0,42,0,188,23,0,0,21,0,41,0,123,23,0,0,21,0,40,0,121,23,0,0,21,0,39,0,107,24,0,0,21,0,38,0,114,23,0,0,21,0,37,0,115,23,0,0,21,0,36,0,186,24,0,0,21,0,35,0,116,23,0,0,21,0,34,0,118,23,0,0,21,0,33,0,117,23,0,0,21,0,32,0,112,24,0,0,21,0,31,0,150,24,0,0,21,0,30,0,129,23,0,0,21,0,29,0,131,23,0,0,21,0,28,0,113,23,0,0,21,0,27,0,97,24,0,0,21,0,26,0,171,23,0,0,21,0,25,0,122,24,0,0,21,0,24,0,126,23,0,0,21,0,23,0,125,23,0,0,21,0,22,0,168,23,0,0,21,0,21,0,169,23,0,0,21,0,20,0,167,23,0,0,21,0,19,0,139,23,0,0,21,0,18,0,173,24,0,0,21,0,17,0,71,24,0,0,21,0,16,0,175,23,0,0,21,0,15,0,174,23,0,0,21,0,14,0,179,23,0,0,21,0,13,0,180,23,0,0,21,0,12,0,178,23,0,0,21,0,11,0,189,23,0,0,21,0,10,0,117,24,0,0,21,0,9,0,199,23,0,0,21,0,8,0,50,24,0,0,21,0,7,0,122,23,0,0,21,0,6,0,120,23,0,0,21,0,5,0,127,23,0,0,21,0,4,0,34,24,0,0,21,0,3,0,150,23,0,0,21,0,2,0,191,23,0,0,21,0,1,0,39,25,0,0,21,0,0,1,119,24,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +#endif + +#if defined(__hppa__) && !defined(__hppa64__) +/* PARISC */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 0,32,0,0,0,0,0,4,0,21,0,58,0,0,0,15,0,32,0,0,0,0,0,0,0,21,55,0,0,0,0,119,0,21,54,0,0,0,1,83,0,21,53,0,0,0,0,228,0,21,52,0,0,0,0,185,0,21,51,0,0,0,0,186,0,21,50,0,0,0,0,188,0,21,49,0,0,0,0,189,0,21,48,0,0,0,0,190,0,21,47,0,0,0,0,110,0,21,46,0,0,0,1,29,0,21,45,0,0,0,0,85,0,21,44,0,0,0,0,210,0,21,43,0,0,0,0,125,0,21,42,0,0,0,0,140,0,21,41,0,0,0,0,19,0,21,40,0,0,0,0,54,0,21,39,0,0,0,0,206,0,21,38,0,0,0,0,20,0,21,37,0,0,0,0,133,0,21,36,0,0,0,1,183,0,21,35,0,0,0,1,31,0,21,34,0,0,0,0,222,0,21,33,0,0,0,0,1,0,21,32,0,0,0,1,56,0,21,31,0,0,0,0,63,0,21,30,0,0,0,0,41,0,21,29,0,0,0,0,12,0,21,28,0,0,0,0,106,0,21,27,0,0,0,0,45,0,21,26,0,0,0,0,33,0,21,25,0,0,0,0,202,0,21,24,0,0,0,0,55,0,21,23,0,0,0,1,59,0,21,22,0,0,0,0,145,0,21,21,0,0,0,0,3,0,21,20,0,0,0,0,108,0,21,19,0,0,0,0,201,0,21,18,0,0,0,0,141,0,21,17,0,0,0,0,91,0,21,16,0,0,0,0,89,0,21,15,0,0,0,0,90,0,21,14,0,0,0,1,19,0,21,13,0,0,0,0,5,0,21,12,0,0,0,0,6,0,21,11,0,0,0,1,93,0,21,10,0,0,0,0,101,0,21,9,0,0,0,0,18,0,21,8,0,0,0,0,198,0,21,7,0,0,0,0,84,0,21,6,0,0,0,1,24,0,21,5,0,0,0,0,112,0,21,4,0,0,0,0,28,0,21,3,0,0,0,1,60,0,21,2,0,0,0,0,109,0,21,1,0,0,0,0,146,0,21,0,1,0,0,0,4,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 0,32,0,0,0,0,0,4,0,21,0,68,0,0,0,15,0,32,0,0,0,0,0,0,0,21,65,0,0,0,0,7,0,21,64,0,0,0,0,235,0,21,63,0,0,0,0,114,0,21,62,0,0,0,0,113,0,21,61,0,0,0,1,32,0,21,60,0,0,0,0,175,0,21,59,0,0,0,0,174,0,21,58,0,0,0,0,2,0,21,57,0,0,0,0,11,0,21,56,0,0,0,0,120,0,21,55,0,0,0,0,119,0,21,54,0,0,0,1,83,0,21,53,0,0,0,0,228,0,21,52,0,0,0,0,185,0,21,51,0,0,0,0,186,0,21,50,0,0,0,0,188,0,21,49,0,0,0,0,189,0,21,48,0,0,0,0,190,0,21,47,0,0,0,0,110,0,21,46,0,0,0,1,29,0,21,45,0,0,0,0,85,0,21,44,0,0,0,0,210,0,21,43,0,0,0,0,125,0,21,42,0,0,0,0,140,0,21,41,0,0,0,0,19,0,21,40,0,0,0,0,54,0,21,39,0,0,0,0,206,0,21,38,0,0,0,0,20,0,21,37,0,0,0,0,133,0,21,36,0,0,0,1,183,0,21,35,0,0,0,1,31,0,21,34,0,0,0,0,222,0,21,33,0,0,0,0,1,0,21,32,0,0,0,1,56,0,21,31,0,0,0,0,63,0,21,30,0,0,0,0,41,0,21,29,0,0,0,0,12,0,21,28,0,0,0,0,106,0,21,27,0,0,0,0,45,0,21,26,0,0,0,0,33,0,21,25,0,0,0,0,202,0,21,24,0,0,0,0,55,0,21,23,0,0,0,1,59,0,21,22,0,0,0,0,145,0,21,21,0,0,0,0,3,0,21,20,0,0,0,0,108,0,21,19,0,0,0,0,201,0,21,18,0,0,0,0,141,0,21,17,0,0,0,0,91,0,21,16,0,0,0,0,89,0,21,15,0,0,0,0,90,0,21,14,0,0,0,1,19,0,21,13,0,0,0,0,5,0,21,12,0,0,0,0,6,0,21,11,0,0,0,1,93,0,21,10,0,0,0,0,101,0,21,9,0,0,0,0,18,0,21,8,0,0,0,0,198,0,21,7,0,0,0,0,84,0,21,6,0,0,0,1,24,0,21,5,0,0,0,0,112,0,21,4,0,0,0,0,28,0,21,3,0,0,0,1,60,0,21,2,0,0,0,0,109,0,21,1,0,0,0,0,146,0,21,0,1,0,0,0,4,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +#endif + +#if defined(__hppa__) && defined(__hppa64__) +/* PARISC64 */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 0,32,0,0,0,0,0,4,0,21,0,58,128,0,0,15,0,32,0,0,0,0,0,0,0,21,55,0,0,0,0,119,0,21,54,0,0,0,1,83,0,21,53,0,0,0,0,228,0,21,52,0,0,0,0,185,0,21,51,0,0,0,0,186,0,21,50,0,0,0,0,188,0,21,49,0,0,0,0,189,0,21,48,0,0,0,0,190,0,21,47,0,0,0,0,110,0,21,46,0,0,0,1,29,0,21,45,0,0,0,0,85,0,21,44,0,0,0,0,210,0,21,43,0,0,0,0,125,0,21,42,0,0,0,0,140,0,21,41,0,0,0,0,19,0,21,40,0,0,0,0,54,0,21,39,0,0,0,0,206,0,21,38,0,0,0,0,20,0,21,37,0,0,0,0,133,0,21,36,0,0,0,1,183,0,21,35,0,0,0,1,31,0,21,34,0,0,0,0,222,0,21,33,0,0,0,0,1,0,21,32,0,0,0,1,56,0,21,31,0,0,0,0,63,0,21,30,0,0,0,0,41,0,21,29,0,0,0,0,12,0,21,28,0,0,0,0,106,0,21,27,0,0,0,0,45,0,21,26,0,0,0,0,33,0,21,25,0,0,0,0,202,0,21,24,0,0,0,0,55,0,21,23,0,0,0,1,59,0,21,22,0,0,0,0,145,0,21,21,0,0,0,0,3,0,21,20,0,0,0,0,108,0,21,19,0,0,0,0,201,0,21,18,0,0,0,0,141,0,21,17,0,0,0,0,91,0,21,16,0,0,0,0,89,0,21,15,0,0,0,0,90,0,21,14,0,0,0,1,19,0,21,13,0,0,0,0,5,0,21,12,0,0,0,0,6,0,21,11,0,0,0,1,93,0,21,10,0,0,0,0,101,0,21,9,0,0,0,0,18,0,21,8,0,0,0,0,198,0,21,7,0,0,0,0,84,0,21,6,0,0,0,1,24,0,21,5,0,0,0,0,112,0,21,4,0,0,0,0,28,0,21,3,0,0,0,1,60,0,21,2,0,0,0,0,109,0,21,1,0,0,0,0,146,0,21,0,1,0,0,0,4,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 0,32,0,0,0,0,0,4,0,21,0,68,128,0,0,15,0,32,0,0,0,0,0,0,0,21,65,0,0,0,0,7,0,21,64,0,0,0,0,235,0,21,63,0,0,0,0,114,0,21,62,0,0,0,0,113,0,21,61,0,0,0,1,32,0,21,60,0,0,0,0,175,0,21,59,0,0,0,0,174,0,21,58,0,0,0,0,2,0,21,57,0,0,0,0,11,0,21,56,0,0,0,0,120,0,21,55,0,0,0,0,119,0,21,54,0,0,0,1,83,0,21,53,0,0,0,0,228,0,21,52,0,0,0,0,185,0,21,51,0,0,0,0,186,0,21,50,0,0,0,0,188,0,21,49,0,0,0,0,189,0,21,48,0,0,0,0,190,0,21,47,0,0,0,0,110,0,21,46,0,0,0,1,29,0,21,45,0,0,0,0,85,0,21,44,0,0,0,0,210,0,21,43,0,0,0,0,125,0,21,42,0,0,0,0,140,0,21,41,0,0,0,0,19,0,21,40,0,0,0,0,54,0,21,39,0,0,0,0,206,0,21,38,0,0,0,0,20,0,21,37,0,0,0,0,133,0,21,36,0,0,0,1,183,0,21,35,0,0,0,1,31,0,21,34,0,0,0,0,222,0,21,33,0,0,0,0,1,0,21,32,0,0,0,1,56,0,21,31,0,0,0,0,63,0,21,30,0,0,0,0,41,0,21,29,0,0,0,0,12,0,21,28,0,0,0,0,106,0,21,27,0,0,0,0,45,0,21,26,0,0,0,0,33,0,21,25,0,0,0,0,202,0,21,24,0,0,0,0,55,0,21,23,0,0,0,1,59,0,21,22,0,0,0,0,145,0,21,21,0,0,0,0,3,0,21,20,0,0,0,0,108,0,21,19,0,0,0,0,201,0,21,18,0,0,0,0,141,0,21,17,0,0,0,0,91,0,21,16,0,0,0,0,89,0,21,15,0,0,0,0,90,0,21,14,0,0,0,1,19,0,21,13,0,0,0,0,5,0,21,12,0,0,0,0,6,0,21,11,0,0,0,1,93,0,21,10,0,0,0,0,101,0,21,9,0,0,0,0,18,0,21,8,0,0,0,0,198,0,21,7,0,0,0,0,84,0,21,6,0,0,0,1,24,0,21,5,0,0,0,0,112,0,21,4,0,0,0,0,28,0,21,3,0,0,0,1,60,0,21,2,0,0,0,0,109,0,21,1,0,0,0,0,146,0,21,0,1,0,0,0,4,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +#endif + +#if defined(__powerpc__) && !defined(__powerpc64__) && defined(__BIG_ENDIAN__) +/* PPC */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 0,32,0,0,0,0,0,4,0,21,0,57,0,0,0,20,0,32,0,0,0,0,0,0,0,21,54,0,0,0,0,205,0,21,53,0,0,0,1,103,0,21,52,0,0,0,0,117,0,21,51,0,0,0,0,182,0,21,50,0,0,0,1,40,0,21,49,0,0,0,0,85,0,21,48,0,0,0,0,221,0,21,47,0,0,0,0,125,0,21,46,0,0,0,0,140,0,21,45,0,0,0,0,19,0,21,44,0,0,0,0,54,0,21,43,0,0,0,0,207,0,21,42,0,0,0,0,20,0,21,41,0,0,0,0,133,0,21,40,0,0,0,1,183,0,21,39,0,0,0,1,42,0,21,38,0,0,0,0,234,0,21,37,0,0,0,0,1,0,21,36,0,0,0,1,60,0,21,35,0,0,0,0,63,0,21,34,0,0,0,0,41,0,21,33,0,0,0,0,12,0,21,32,0,0,0,0,183,0,21,31,0,0,0,0,45,0,21,30,0,0,0,0,33,0,21,29,0,0,0,0,204,0,21,28,0,0,0,0,55,0,21,27,0,0,0,1,64,0,21,26,0,0,0,0,145,0,21,25,0,0,0,0,3,0,21,24,0,0,0,0,179,0,21,23,0,0,0,0,202,0,21,22,0,0,0,0,141,0,21,21,0,0,0,0,91,0,21,20,0,0,0,0,192,0,21,19,0,0,0,0,90,0,21,18,0,0,0,1,30,0,21,17,0,0,0,0,5,0,21,16,0,0,0,0,6,0,21,15,0,0,0,1,127,0,21,14,0,0,0,0,195,0,21,13,0,0,0,0,106,0,21,12,0,0,0,0,196,0,21,11,0,0,0,0,107,0,21,10,0,0,0,1,35,0,21,9,0,0,0,0,197,0,21,8,0,0,0,0,108,0,21,7,0,0,0,1,65,0,21,6,0,0,0,0,180,0,21,5,0,0,0,0,146,0,21,4,0,0,0,0,4,0,21,3,0,0,0,1,137,0,21,2,0,0,0,1,143,0,21,1,0,0,0,1,144,0,21,0,1,0,0,1,145,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 0,32,0,0,0,0,0,4,0,21,0,67,0,0,0,20,0,32,0,0,0,0,0,0,0,21,64,0,0,0,0,7,0,21,63,0,0,0,1,16,0,21,62,0,0,0,0,114,0,21,61,0,0,0,0,189,0,21,60,0,0,0,1,26,0,21,59,0,0,0,0,174,0,21,58,0,0,0,0,173,0,21,57,0,0,0,0,2,0,21,56,0,0,0,0,11,0,21,55,0,0,0,0,120,0,21,54,0,0,0,0,205,0,21,53,0,0,0,1,103,0,21,52,0,0,0,0,117,0,21,51,0,0,0,0,182,0,21,50,0,0,0,1,40,0,21,49,0,0,0,0,85,0,21,48,0,0,0,0,221,0,21,47,0,0,0,0,125,0,21,46,0,0,0,0,140,0,21,45,0,0,0,0,19,0,21,44,0,0,0,0,54,0,21,43,0,0,0,0,207,0,21,42,0,0,0,0,20,0,21,41,0,0,0,0,133,0,21,40,0,0,0,1,183,0,21,39,0,0,0,1,42,0,21,38,0,0,0,0,234,0,21,37,0,0,0,0,1,0,21,36,0,0,0,1,60,0,21,35,0,0,0,0,63,0,21,34,0,0,0,0,41,0,21,33,0,0,0,0,12,0,21,32,0,0,0,0,183,0,21,31,0,0,0,0,45,0,21,30,0,0,0,0,33,0,21,29,0,0,0,0,204,0,21,28,0,0,0,0,55,0,21,27,0,0,0,1,64,0,21,26,0,0,0,0,145,0,21,25,0,0,0,0,3,0,21,24,0,0,0,0,179,0,21,23,0,0,0,0,202,0,21,22,0,0,0,0,141,0,21,21,0,0,0,0,91,0,21,20,0,0,0,0,192,0,21,19,0,0,0,0,90,0,21,18,0,0,0,1,30,0,21,17,0,0,0,0,5,0,21,16,0,0,0,0,6,0,21,15,0,0,0,1,127,0,21,14,0,0,0,0,195,0,21,13,0,0,0,0,106,0,21,12,0,0,0,0,196,0,21,11,0,0,0,0,107,0,21,10,0,0,0,1,35,0,21,9,0,0,0,0,197,0,21,8,0,0,0,0,108,0,21,7,0,0,0,1,65,0,21,6,0,0,0,0,180,0,21,5,0,0,0,0,146,0,21,4,0,0,0,0,4,0,21,3,0,0,0,1,137,0,21,2,0,0,0,1,143,0,21,1,0,0,0,1,144,0,21,0,1,0,0,1,145,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +#endif + +#if defined(__powerpc__) && defined(__powerpc64__) && defined(__BIG_ENDIAN__) +/* PPC64 */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 0,32,0,0,0,0,0,4,0,21,0,53,128,0,0,21,0,32,0,0,0,0,0,0,0,21,50,0,0,0,0,141,0,21,49,0,0,0,0,91,0,21,48,0,0,0,0,90,0,21,47,0,0,0,1,30,0,21,46,0,0,0,0,5,0,21,45,0,0,0,0,6,0,21,44,0,0,0,1,127,0,21,43,0,0,0,0,106,0,21,42,0,0,0,0,107,0,21,41,0,0,0,0,108,0,21,40,0,0,0,1,35,0,21,39,0,0,0,1,65,0,21,38,0,0,0,0,180,0,21,37,0,0,0,0,146,0,21,36,0,0,0,0,4,0,21,35,0,0,0,0,205,0,21,34,0,0,0,1,103,0,21,33,0,0,0,0,117,0,21,32,0,0,0,0,182,0,21,31,0,0,0,1,40,0,21,30,0,0,0,0,85,0,21,29,0,0,0,0,221,0,21,28,0,0,0,0,125,0,21,27,0,0,0,0,140,0,21,26,0,0,0,0,19,0,21,25,0,0,0,0,54,0,21,24,0,0,0,0,207,0,21,23,0,0,0,0,20,0,21,22,0,0,0,0,133,0,21,21,0,0,0,1,183,0,21,20,0,0,0,1,42,0,21,19,0,0,0,0,234,0,21,18,0,0,0,0,1,0,21,17,0,0,0,1,60,0,21,16,0,0,0,0,63,0,21,15,0,0,0,0,41,0,21,14,0,0,0,0,12,0,21,13,0,0,0,0,183,0,21,12,0,0,0,0,45,0,21,11,0,0,0,0,33,0,21,10,0,0,0,0,55,0,21,9,0,0,0,1,64,0,21,8,0,0,0,0,145,0,21,7,0,0,0,0,3,0,21,6,0,0,0,0,179,0,21,5,0,0,0,0,202,0,21,4,0,0,0,1,136,0,21,3,0,0,0,1,137,0,21,2,0,0,0,1,143,0,21,1,0,0,0,1,144,0,21,0,1,0,0,1,145,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 0,32,0,0,0,0,0,4,0,21,0,63,128,0,0,21,0,32,0,0,0,0,0,0,0,21,60,0,0,0,0,141,0,21,59,0,0,0,0,91,0,21,58,0,0,0,0,90,0,21,57,0,0,0,1,30,0,21,56,0,0,0,0,5,0,21,55,0,0,0,0,6,0,21,54,0,0,0,1,127,0,21,53,0,0,0,0,106,0,21,52,0,0,0,0,107,0,21,51,0,0,0,0,108,0,21,50,0,0,0,1,35,0,21,49,0,0,0,1,65,0,21,48,0,0,0,0,180,0,21,47,0,0,0,0,146,0,21,46,0,0,0,0,4,0,21,45,0,0,0,0,7,0,21,44,0,0,0,1,16,0,21,43,0,0,0,0,114,0,21,42,0,0,0,0,189,0,21,41,0,0,0,1,26,0,21,40,0,0,0,0,174,0,21,39,0,0,0,0,173,0,21,38,0,0,0,0,2,0,21,37,0,0,0,0,11,0,21,36,0,0,0,0,120,0,21,35,0,0,0,0,205,0,21,34,0,0,0,1,103,0,21,33,0,0,0,0,117,0,21,32,0,0,0,0,182,0,21,31,0,0,0,1,40,0,21,30,0,0,0,0,85,0,21,29,0,0,0,0,221,0,21,28,0,0,0,0,125,0,21,27,0,0,0,0,140,0,21,26,0,0,0,0,19,0,21,25,0,0,0,0,54,0,21,24,0,0,0,0,207,0,21,23,0,0,0,0,20,0,21,22,0,0,0,0,133,0,21,21,0,0,0,1,183,0,21,20,0,0,0,1,42,0,21,19,0,0,0,0,234,0,21,18,0,0,0,0,1,0,21,17,0,0,0,1,60,0,21,16,0,0,0,0,63,0,21,15,0,0,0,0,41,0,21,14,0,0,0,0,12,0,21,13,0,0,0,0,183,0,21,12,0,0,0,0,45,0,21,11,0,0,0,0,33,0,21,10,0,0,0,0,55,0,21,9,0,0,0,1,64,0,21,8,0,0,0,0,145,0,21,7,0,0,0,0,3,0,21,6,0,0,0,0,179,0,21,5,0,0,0,0,202,0,21,4,0,0,0,1,136,0,21,3,0,0,0,1,137,0,21,2,0,0,0,1,143,0,21,1,0,0,0,1,144,0,21,0,1,0,0,1,145,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +#endif + +#if defined(__powerpc__) && defined(__powerpc64__) && !defined(__BIG_ENDIAN__) +/* PPC64LE */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 32,0,0,0,4,0,0,0,21,0,0,53,21,0,0,192,32,0,0,0,0,0,0,0,21,0,50,0,205,0,0,0,21,0,49,0,103,1,0,0,21,0,48,0,117,0,0,0,21,0,47,0,182,0,0,0,21,0,46,0,40,1,0,0,21,0,45,0,85,0,0,0,21,0,44,0,221,0,0,0,21,0,43,0,125,0,0,0,21,0,42,0,140,0,0,0,21,0,41,0,19,0,0,0,21,0,40,0,54,0,0,0,21,0,39,0,207,0,0,0,21,0,38,0,20,0,0,0,21,0,37,0,133,0,0,0,21,0,36,0,183,1,0,0,21,0,35,0,42,1,0,0,21,0,34,0,234,0,0,0,21,0,33,0,1,0,0,0,21,0,32,0,60,1,0,0,21,0,31,0,63,0,0,0,21,0,30,0,41,0,0,0,21,0,29,0,12,0,0,0,21,0,28,0,183,0,0,0,21,0,27,0,45,0,0,0,21,0,26,0,33,0,0,0,21,0,25,0,55,0,0,0,21,0,24,0,64,1,0,0,21,0,23,0,145,0,0,0,21,0,22,0,3,0,0,0,21,0,21,0,179,0,0,0,21,0,20,0,202,0,0,0,21,0,19,0,141,0,0,0,21,0,18,0,91,0,0,0,21,0,17,0,90,0,0,0,21,0,16,0,30,1,0,0,21,0,15,0,5,0,0,0,21,0,14,0,6,0,0,0,21,0,13,0,127,1,0,0,21,0,12,0,106,0,0,0,21,0,11,0,107,0,0,0,21,0,10,0,108,0,0,0,21,0,9,0,35,1,0,0,21,0,8,0,65,1,0,0,21,0,7,0,180,0,0,0,21,0,6,0,146,0,0,0,21,0,5,0,4,0,0,0,21,0,4,0,136,1,0,0,21,0,3,0,137,1,0,0,21,0,2,0,143,1,0,0,21,0,1,0,144,1,0,0,21,0,0,1,145,1,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 32,0,0,0,4,0,0,0,21,0,0,63,21,0,0,192,32,0,0,0,0,0,0,0,21,0,60,0,7,0,0,0,21,0,59,0,16,1,0,0,21,0,58,0,114,0,0,0,21,0,57,0,189,0,0,0,21,0,56,0,26,1,0,0,21,0,55,0,174,0,0,0,21,0,54,0,173,0,0,0,21,0,53,0,2,0,0,0,21,0,52,0,11,0,0,0,21,0,51,0,120,0,0,0,21,0,50,0,205,0,0,0,21,0,49,0,103,1,0,0,21,0,48,0,117,0,0,0,21,0,47,0,182,0,0,0,21,0,46,0,40,1,0,0,21,0,45,0,85,0,0,0,21,0,44,0,221,0,0,0,21,0,43,0,125,0,0,0,21,0,42,0,140,0,0,0,21,0,41,0,19,0,0,0,21,0,40,0,54,0,0,0,21,0,39,0,207,0,0,0,21,0,38,0,20,0,0,0,21,0,37,0,133,0,0,0,21,0,36,0,183,1,0,0,21,0,35,0,42,1,0,0,21,0,34,0,234,0,0,0,21,0,33,0,1,0,0,0,21,0,32,0,60,1,0,0,21,0,31,0,63,0,0,0,21,0,30,0,41,0,0,0,21,0,29,0,12,0,0,0,21,0,28,0,183,0,0,0,21,0,27,0,45,0,0,0,21,0,26,0,33,0,0,0,21,0,25,0,55,0,0,0,21,0,24,0,64,1,0,0,21,0,23,0,145,0,0,0,21,0,22,0,3,0,0,0,21,0,21,0,179,0,0,0,21,0,20,0,202,0,0,0,21,0,19,0,141,0,0,0,21,0,18,0,91,0,0,0,21,0,17,0,90,0,0,0,21,0,16,0,30,1,0,0,21,0,15,0,5,0,0,0,21,0,14,0,6,0,0,0,21,0,13,0,127,1,0,0,21,0,12,0,106,0,0,0,21,0,11,0,107,0,0,0,21,0,10,0,108,0,0,0,21,0,9,0,35,1,0,0,21,0,8,0,65,1,0,0,21,0,7,0,180,0,0,0,21,0,6,0,146,0,0,0,21,0,5,0,4,0,0,0,21,0,4,0,136,1,0,0,21,0,3,0,137,1,0,0,21,0,2,0,143,1,0,0,21,0,1,0,144,1,0,0,21,0,0,1,145,1,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +#endif + +#if defined(__riscv) && __riscv_xlen == 64 +/* RISCV64 */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 32,0,0,0,4,0,0,0,21,0,0,45,243,0,0,192,32,0,0,0,0,0,0,0,21,0,42,0,233,0,0,0,21,0,41,0,22,1,0,0,21,0,40,0,192,0,0,0,21,0,39,0,193,0,0,0,21,0,38,0,190,0,0,0,21,0,37,0,189,0,0,0,21,0,36,0,188,0,0,0,21,0,35,0,186,0,0,0,21,0,34,0,17,0,0,0,21,0,33,0,78,0,0,0,21,0,32,0,98,0,0,0,21,0,31,0,226,0,0,0,21,0,30,0,62,0,0,0,21,0,29,0,29,0,0,0,21,0,28,0,178,0,0,0,21,0,27,0,172,0,0,0,21,0,26,0,50,0,0,0,21,0,25,0,183,1,0,0,21,0,24,0,48,0,0,0,21,0,23,0,94,0,0,0,21,0,22,0,93,0,0,0,21,0,21,0,24,0,0,0,21,0,20,0,23,0,0,0,21,0,19,0,49,0,0,0,21,0,18,0,90,0,0,0,21,0,17,0,214,0,0,0,21,0,16,0,25,0,0,0,21,0,15,0,69,0,0,0,21,0,14,0,65,0,0,0,21,0,13,0,63,0,0,0,21,0,12,0,67,0,0,0,21,0,11,0,61,0,0,0,21,0,10,0,215,0,0,0,21,0,9,0,222,0,0,0,21,0,8,0,56,0,0,0,21,0,7,0,57,0,0,0,21,0,6,0,35,1,0,0,21,0,5,0,80,0,0,0,21,0,4,0,79,0,0,0,21,0,3,0,70,0,0,0,21,0,2,0,68,0,0,0,21,0,1,0,66,0,0,0,21,0,0,1,64,0,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 32,0,0,0,4,0,0,0,21,0,0,52,243,0,0,192,32,0,0,0,0,0,0,0,21,0,49,0,95,0,0,0,21,0,48,0,4,1,0,0,21,0,47,0,97,0,0,0,21,0,46,0,135,0,0,0,21,0,45,0,134,0,0,0,21,0,44,0,221,0,0,0,21,0,43,0,220,0,0,0,21,0,42,0,233,0,0,0,21,0,41,0,22,1,0,0,21,0,40,0,192,0,0,0,21,0,39,0,193,0,0,0,21,0,38,0,190,0,0,0,21,0,37,0,189,0,0,0,21,0,36,0,188,0,0,0,21,0,35,0,186,0,0,0,21,0,34,0,17,0,0,0,21,0,33,0,78,0,0,0,21,0,32,0,98,0,0,0,21,0,31,0,226,0,0,0,21,0,30,0,62,0,0,0,21,0,29,0,29,0,0,0,21,0,28,0,178,0,0,0,21,0,27,0,172,0,0,0,21,0,26,0,50,0,0,0,21,0,25,0,183,1,0,0,21,0,24,0,48,0,0,0,21,0,23,0,94,0,0,0,21,0,22,0,93,0,0,0,21,0,21,0,24,0,0,0,21,0,20,0,23,0,0,0,21,0,19,0,49,0,0,0,21,0,18,0,90,0,0,0,21,0,17,0,214,0,0,0,21,0,16,0,25,0,0,0,21,0,15,0,69,0,0,0,21,0,14,0,65,0,0,0,21,0,13,0,63,0,0,0,21,0,12,0,67,0,0,0,21,0,11,0,61,0,0,0,21,0,10,0,215,0,0,0,21,0,9,0,222,0,0,0,21,0,8,0,56,0,0,0,21,0,7,0,57,0,0,0,21,0,6,0,35,1,0,0,21,0,5,0,80,0,0,0,21,0,4,0,79,0,0,0,21,0,3,0,70,0,0,0,21,0,2,0,68,0,0,0,21,0,1,0,66,0,0,0,21,0,0,1,64,0,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +#endif + +#if defined(__s390__) && !defined(__s390x__) +/* S390 */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 0,32,0,0,0,0,0,4,0,21,0,57,0,0,0,22,0,32,0,0,0,0,0,0,0,21,54,0,0,0,0,219,0,21,53,0,0,0,1,93,0,21,52,0,0,0,0,117,0,21,51,0,0,0,0,183,0,21,50,0,0,0,1,42,0,21,49,0,0,0,0,85,0,21,48,0,0,0,0,238,0,21,47,0,0,0,0,125,0,21,46,0,0,0,0,140,0,21,45,0,0,0,0,19,0,21,44,0,0,0,0,54,0,21,43,0,0,0,0,236,0,21,42,0,0,0,0,20,0,21,41,0,0,0,0,133,0,21,40,0,0,0,1,183,0,21,39,0,0,0,1,44,0,21,38,0,0,0,0,248,0,21,37,0,0,0,0,1,0,21,36,0,0,0,1,70,0,21,35,0,0,0,0,63,0,21,34,0,0,0,0,41,0,21,33,0,0,0,0,12,0,21,32,0,0,0,0,184,0,21,31,0,0,0,0,45,0,21,30,0,0,0,0,33,0,21,29,0,0,0,0,221,0,21,28,0,0,0,0,55,0,21,27,0,0,0,1,72,0,21,26,0,0,0,0,145,0,21,25,0,0,0,0,3,0,21,24,0,0,0,0,180,0,21,23,0,0,0,0,220,0,21,22,0,0,0,0,141,0,21,21,0,0,0,0,91,0,21,20,0,0,0,0,192,0,21,19,0,0,0,0,90,0,21,18,0,0,0,1,32,0,21,17,0,0,0,0,5,0,21,16,0,0,0,0,6,0,21,15,0,0,0,1,123,0,21,14,0,0,0,0,195,0,21,13,0,0,0,0,106,0,21,12,0,0,0,0,196,0,21,11,0,0,0,0,107,0,21,10,0,0,0,1,37,0,21,9,0,0,0,0,197,0,21,8,0,0,0,0,108,0,21,7,0,0,0,1,73,0,21,6,0,0,0,0,181,0,21,5,0,0,0,0,146,0,21,4,0,0,0,0,4,0,21,3,0,0,0,1,137,0,21,2,0,0,0,1,143,0,21,1,0,0,0,1,144,0,21,0,1,0,0,1,145,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 0,32,0,0,0,0,0,4,0,21,0,66,0,0,0,22,0,32,0,0,0,0,0,0,0,21,63,0,0,0,1,25,0,21,62,0,0,0,0,114,0,21,61,0,0,0,0,190,0,21,60,0,0,0,1,47,0,21,59,0,0,0,0,175,0,21,58,0,0,0,0,174,0,21,57,0,0,0,0,2,0,21,56,0,0,0,0,11,0,21,55,0,0,0,0,120,0,21,54,0,0,0,0,219,0,21,53,0,0,0,1,93,0,21,52,0,0,0,0,117,0,21,51,0,0,0,0,183,0,21,50,0,0,0,1,42,0,21,49,0,0,0,0,85,0,21,48,0,0,0,0,238,0,21,47,0,0,0,0,125,0,21,46,0,0,0,0,140,0,21,45,0,0,0,0,19,0,21,44,0,0,0,0,54,0,21,43,0,0,0,0,236,0,21,42,0,0,0,0,20,0,21,41,0,0,0,0,133,0,21,40,0,0,0,1,183,0,21,39,0,0,0,1,44,0,21,38,0,0,0,0,248,0,21,37,0,0,0,0,1,0,21,36,0,0,0,1,70,0,21,35,0,0,0,0,63,0,21,34,0,0,0,0,41,0,21,33,0,0,0,0,12,0,21,32,0,0,0,0,184,0,21,31,0,0,0,0,45,0,21,30,0,0,0,0,33,0,21,29,0,0,0,0,221,0,21,28,0,0,0,0,55,0,21,27,0,0,0,1,72,0,21,26,0,0,0,0,145,0,21,25,0,0,0,0,3,0,21,24,0,0,0,0,180,0,21,23,0,0,0,0,220,0,21,22,0,0,0,0,141,0,21,21,0,0,0,0,91,0,21,20,0,0,0,0,192,0,21,19,0,0,0,0,90,0,21,18,0,0,0,1,32,0,21,17,0,0,0,0,5,0,21,16,0,0,0,0,6,0,21,15,0,0,0,1,123,0,21,14,0,0,0,0,195,0,21,13,0,0,0,0,106,0,21,12,0,0,0,0,196,0,21,11,0,0,0,0,107,0,21,10,0,0,0,1,37,0,21,9,0,0,0,0,197,0,21,8,0,0,0,0,108,0,21,7,0,0,0,1,73,0,21,6,0,0,0,0,181,0,21,5,0,0,0,0,146,0,21,4,0,0,0,0,4,0,21,3,0,0,0,1,137,0,21,2,0,0,0,1,143,0,21,1,0,0,0,1,144,0,21,0,1,0,0,1,145,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +#endif + +#if defined(__s390__) && defined(__s390x__) +/* S390X */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 0,32,0,0,0,0,0,4,0,21,0,52,128,0,0,22,0,32,0,0,0,0,0,0,0,21,49,0,0,0,1,73,0,21,48,0,0,0,0,181,0,21,47,0,0,0,0,146,0,21,46,0,0,0,0,4,0,21,45,0,0,0,0,219,0,21,44,0,0,0,1,93,0,21,43,0,0,0,0,117,0,21,42,0,0,0,0,183,0,21,41,0,0,0,1,42,0,21,40,0,0,0,0,85,0,21,39,0,0,0,0,238,0,21,38,0,0,0,0,125,0,21,37,0,0,0,0,19,0,21,36,0,0,0,0,54,0,21,35,0,0,0,0,236,0,21,34,0,0,0,0,20,0,21,33,0,0,0,0,133,0,21,32,0,0,0,1,183,0,21,31,0,0,0,1,44,0,21,30,0,0,0,0,248,0,21,29,0,0,0,0,1,0,21,28,0,0,0,1,70,0,21,27,0,0,0,0,63,0,21,26,0,0,0,0,41,0,21,25,0,0,0,0,12,0,21,24,0,0,0,0,184,0,21,23,0,0,0,0,45,0,21,22,0,0,0,0,33,0,21,21,0,0,0,0,55,0,21,20,0,0,0,1,72,0,21,19,0,0,0,0,145,0,21,18,0,0,0,0,3,0,21,17,0,0,0,0,180,0,21,16,0,0,0,0,220,0,21,15,0,0,0,0,141,0,21,14,0,0,0,0,91,0,21,13,0,0,0,0,90,0,21,12,0,0,0,1,32,0,21,11,0,0,0,0,5,0,21,10,0,0,0,0,6,0,21,9,0,0,0,1,123,0,21,8,0,0,0,0,106,0,21,7,0,0,0,0,107,0,21,6,0,0,0,0,108,0,21,5,0,0,0,1,37,0,21,4,0,0,0,1,136,0,21,3,0,0,0,1,137,0,21,2,0,0,0,1,143,0,21,1,0,0,0,1,144,0,21,0,1,0,0,1,145,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 0,32,0,0,0,0,0,4,0,21,0,61,128,0,0,22,0,32,0,0,0,0,0,0,0,21,58,0,0,0,1,73,0,21,57,0,0,0,0,181,0,21,56,0,0,0,0,146,0,21,55,0,0,0,0,4,0,21,54,0,0,0,1,25,0,21,53,0,0,0,0,114,0,21,52,0,0,0,0,190,0,21,51,0,0,0,1,47,0,21,50,0,0,0,0,175,0,21,49,0,0,0,0,174,0,21,48,0,0,0,0,2,0,21,47,0,0,0,0,11,0,21,46,0,0,0,0,120,0,21,45,0,0,0,0,219,0,21,44,0,0,0,1,93,0,21,43,0,0,0,0,117,0,21,42,0,0,0,0,183,0,21,41,0,0,0,1,42,0,21,40,0,0,0,0,85,0,21,39,0,0,0,0,238,0,21,38,0,0,0,0,125,0,21,37,0,0,0,0,19,0,21,36,0,0,0,0,54,0,21,35,0,0,0,0,236,0,21,34,0,0,0,0,20,0,21,33,0,0,0,0,133,0,21,32,0,0,0,1,183,0,21,31,0,0,0,1,44,0,21,30,0,0,0,0,248,0,21,29,0,0,0,0,1,0,21,28,0,0,0,1,70,0,21,27,0,0,0,0,63,0,21,26,0,0,0,0,41,0,21,25,0,0,0,0,12,0,21,24,0,0,0,0,184,0,21,23,0,0,0,0,45,0,21,22,0,0,0,0,33,0,21,21,0,0,0,0,55,0,21,20,0,0,0,1,72,0,21,19,0,0,0,0,145,0,21,18,0,0,0,0,3,0,21,17,0,0,0,0,180,0,21,16,0,0,0,0,220,0,21,15,0,0,0,0,141,0,21,14,0,0,0,0,91,0,21,13,0,0,0,0,90,0,21,12,0,0,0,1,32,0,21,11,0,0,0,0,5,0,21,10,0,0,0,0,6,0,21,9,0,0,0,1,123,0,21,8,0,0,0,0,106,0,21,7,0,0,0,0,107,0,21,6,0,0,0,0,108,0,21,5,0,0,0,1,37,0,21,4,0,0,0,1,136,0,21,3,0,0,0,1,137,0,21,2,0,0,0,1,143,0,21,1,0,0,0,1,144,0,21,0,1,0,0,1,145,0,6,0,0,127,255,0,0,0,6,0,0,0,0,0,0, +}; +#endif + +#if defined(__i386__) +/* X86 */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 32,0,0,0,4,0,0,0,21,0,0,57,3,0,0,64,32,0,0,0,0,0,0,0,21,0,54,0,219,0,0,0,21,0,53,0,99,1,0,0,21,0,52,0,117,0,0,0,21,0,51,0,183,0,0,0,21,0,50,0,49,1,0,0,21,0,49,0,85,0,0,0,21,0,48,0,240,0,0,0,21,0,47,0,125,0,0,0,21,0,46,0,140,0,0,0,21,0,45,0,19,0,0,0,21,0,44,0,54,0,0,0,21,0,43,0,224,0,0,0,21,0,42,0,20,0,0,0,21,0,41,0,133,0,0,0,21,0,40,0,183,1,0,0,21,0,39,0,51,1,0,0,21,0,38,0,252,0,0,0,21,0,37,0,1,0,0,0,21,0,36,0,74,1,0,0,21,0,35,0,63,0,0,0,21,0,34,0,41,0,0,0,21,0,33,0,12,0,0,0,21,0,32,0,184,0,0,0,21,0,31,0,45,0,0,0,21,0,30,0,33,0,0,0,21,0,29,0,221,0,0,0,21,0,28,0,55,0,0,0,21,0,27,0,77,1,0,0,21,0,26,0,145,0,0,0,21,0,25,0,3,0,0,0,21,0,24,0,180,0,0,0,21,0,23,0,220,0,0,0,21,0,22,0,141,0,0,0,21,0,21,0,91,0,0,0,21,0,20,0,192,0,0,0,21,0,19,0,90,0,0,0,21,0,18,0,39,1,0,0,21,0,17,0,5,0,0,0,21,0,16,0,6,0,0,0,21,0,15,0,127,1,0,0,21,0,14,0,195,0,0,0,21,0,13,0,106,0,0,0,21,0,12,0,196,0,0,0,21,0,11,0,107,0,0,0,21,0,10,0,44,1,0,0,21,0,9,0,197,0,0,0,21,0,8,0,108,0,0,0,21,0,7,0,78,1,0,0,21,0,6,0,181,0,0,0,21,0,5,0,146,0,0,0,21,0,4,0,4,0,0,0,21,0,3,0,137,1,0,0,21,0,2,0,143,1,0,0,21,0,1,0,144,1,0,0,21,0,0,1,145,1,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 32,0,0,0,4,0,0,0,21,0,0,67,3,0,0,64,32,0,0,0,0,0,0,0,21,0,64,0,7,0,0,0,21,0,63,0,28,1,0,0,21,0,62,0,114,0,0,0,21,0,61,0,190,0,0,0,21,0,60,0,54,1,0,0,21,0,59,0,175,0,0,0,21,0,58,0,174,0,0,0,21,0,57,0,2,0,0,0,21,0,56,0,11,0,0,0,21,0,55,0,120,0,0,0,21,0,54,0,219,0,0,0,21,0,53,0,99,1,0,0,21,0,52,0,117,0,0,0,21,0,51,0,183,0,0,0,21,0,50,0,49,1,0,0,21,0,49,0,85,0,0,0,21,0,48,0,240,0,0,0,21,0,47,0,125,0,0,0,21,0,46,0,140,0,0,0,21,0,45,0,19,0,0,0,21,0,44,0,54,0,0,0,21,0,43,0,224,0,0,0,21,0,42,0,20,0,0,0,21,0,41,0,133,0,0,0,21,0,40,0,183,1,0,0,21,0,39,0,51,1,0,0,21,0,38,0,252,0,0,0,21,0,37,0,1,0,0,0,21,0,36,0,74,1,0,0,21,0,35,0,63,0,0,0,21,0,34,0,41,0,0,0,21,0,33,0,12,0,0,0,21,0,32,0,184,0,0,0,21,0,31,0,45,0,0,0,21,0,30,0,33,0,0,0,21,0,29,0,221,0,0,0,21,0,28,0,55,0,0,0,21,0,27,0,77,1,0,0,21,0,26,0,145,0,0,0,21,0,25,0,3,0,0,0,21,0,24,0,180,0,0,0,21,0,23,0,220,0,0,0,21,0,22,0,141,0,0,0,21,0,21,0,91,0,0,0,21,0,20,0,192,0,0,0,21,0,19,0,90,0,0,0,21,0,18,0,39,1,0,0,21,0,17,0,5,0,0,0,21,0,16,0,6,0,0,0,21,0,15,0,127,1,0,0,21,0,14,0,195,0,0,0,21,0,13,0,106,0,0,0,21,0,12,0,196,0,0,0,21,0,11,0,107,0,0,0,21,0,10,0,44,1,0,0,21,0,9,0,197,0,0,0,21,0,8,0,108,0,0,0,21,0,7,0,78,1,0,0,21,0,6,0,181,0,0,0,21,0,5,0,146,0,0,0,21,0,4,0,4,0,0,0,21,0,3,0,137,1,0,0,21,0,2,0,143,1,0,0,21,0,1,0,144,1,0,0,21,0,0,1,145,1,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +#endif + +#if defined(__x86_64__) && defined(__ILP32__) +/* X32 */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 32,0,0,0,4,0,0,0,21,0,0,53,62,0,0,192,32,0,0,0,0,0,0,0,53,0,0,51,0,0,0,64,21,0,49,0,28,0,0,64,21,0,48,0,62,1,0,64,21,0,47,0,220,0,0,64,21,0,46,0,65,0,0,64,21,0,45,0,64,0,0,64,21,0,44,0,69,0,0,64,21,0,43,0,70,0,0,64,21,0,42,0,68,0,0,64,21,0,41,0,79,0,0,64,21,0,40,0,11,1,0,64,21,0,39,0,89,0,0,64,21,0,38,0,202,0,0,64,21,0,37,0,10,0,0,64,21,0,36,0,8,0,0,64,21,0,35,0,2,2,0,64,21,0,34,0,186,0,0,64,21,0,33,0,39,0,0,64,21,0,32,0,81,0,0,64,21,0,31,0,183,1,0,64,21,0,30,0,13,1,0,64,21,0,29,0,231,0,0,64,21,0,28,0,60,0,0,64,21,0,27,0,36,1,0,64,21,0,26,0,33,0,0,64,21,0,25,0,32,0,0,64,21,0,24,0,80,0,0,64,21,0,23,0,125,0,0,64,21,0,22,0,12,0,0,64,21,0,21,0,21,0,0,64,21,0,20,0,72,0,0,64,21,0,19,0,22,2,0,64,21,0,18,0,3,2,0,64,21,0,17,0,0,0,0,64,21,0,16,0,17,0,0,64,21,0,15,0,217,0,0,64,21,0,14,0,78,0,0,64,21,0,13,0,11,0,0,64,21,0,12,0,9,0,0,64,21,0,11,0,1,1,0,64,21,0,10,0,2,0,0,64,21,0,9,0,3,0,0,64,21,0,8,0,76,1,0,64,21,0,7,0,4,0,0,64,21,0,6,0,6,0,0,64,21,0,5,0,5,0,0,64,21,0,4,0,6,1,0,64,21,0,3,0,23,2,0,64,21,0,2,0,18,0,0,64,21,0,1,0,4,2,0,64,21,0,0,1,1,0,0,64,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 32,0,0,0,4,0,0,0,21,0,0,62,62,0,0,192,32,0,0,0,0,0,0,0,53,0,0,60,0,0,0,64,21,0,58,0,17,2,0,64,21,0,57,0,61,0,0,64,21,0,56,0,58,0,0,64,21,0,55,0,16,1,0,64,21,0,54,0,14,0,0,64,21,0,53,0,0,2,0,64,21,0,52,0,57,0,0,64,21,0,51,0,8,2,0,64,21,0,50,0,56,0,0,64,21,0,49,0,28,0,0,64,21,0,48,0,62,1,0,64,21,0,47,0,220,0,0,64,21,0,46,0,65,0,0,64,21,0,45,0,64,0,0,64,21,0,44,0,69,0,0,64,21,0,43,0,70,0,0,64,21,0,42,0,68,0,0,64,21,0,41,0,79,0,0,64,21,0,40,0,11,1,0,64,21,0,39,0,89,0,0,64,21,0,38,0,202,0,0,64,21,0,37,0,10,0,0,64,21,0,36,0,8,0,0,64,21,0,35,0,2,2,0,64,21,0,34,0,186,0,0,64,21,0,33,0,39,0,0,64,21,0,32,0,81,0,0,64,21,0,31,0,183,1,0,64,21,0,30,0,13,1,0,64,21,0,29,0,231,0,0,64,21,0,28,0,60,0,0,64,21,0,27,0,36,1,0,64,21,0,26,0,33,0,0,64,21,0,25,0,32,0,0,64,21,0,24,0,80,0,0,64,21,0,23,0,125,0,0,64,21,0,22,0,12,0,0,64,21,0,21,0,21,0,0,64,21,0,20,0,72,0,0,64,21,0,19,0,22,2,0,64,21,0,18,0,3,2,0,64,21,0,17,0,0,0,0,64,21,0,16,0,17,0,0,64,21,0,15,0,217,0,0,64,21,0,14,0,78,0,0,64,21,0,13,0,11,0,0,64,21,0,12,0,9,0,0,64,21,0,11,0,1,1,0,64,21,0,10,0,2,0,0,64,21,0,9,0,3,0,0,64,21,0,8,0,76,1,0,64,21,0,7,0,4,0,0,64,21,0,6,0,6,0,0,64,21,0,5,0,5,0,0,64,21,0,4,0,6,1,0,64,21,0,3,0,23,2,0,64,21,0,2,0,18,0,0,64,21,0,1,0,4,2,0,64,21,0,0,1,1,0,0,64,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +#endif + +#if defined(__x86_64__) && !defined(__ILP32__) +/* X86_64 */ +#define SECCOMP_BPF_AVAILABLE +static const unsigned char seccomp_bpf_blks_base[] = { + 32,0,0,0,4,0,0,0,21,0,0,54,62,0,0,192,32,0,0,0,0,0,0,0,53,0,0,1,0,0,0,64,21,0,0,51,255,255,255,255,21,0,49,0,220,0,0,0,21,0,48,0,65,0,0,0,21,0,47,0,64,0,0,0,21,0,46,0,69,0,0,0,21,0,45,0,70,0,0,0,21,0,44,0,68,0,0,0,21,0,43,0,79,0,0,0,21,0,42,0,11,1,0,0,21,0,41,0,89,0,0,0,21,0,40,0,202,0,0,0,21,0,39,0,10,0,0,0,21,0,38,0,8,0,0,0,21,0,37,0,16,0,0,0,21,0,36,0,186,0,0,0,21,0,35,0,39,0,0,0,21,0,34,0,81,0,0,0,21,0,33,0,183,1,0,0,21,0,32,0,13,1,0,0,21,0,31,0,231,0,0,0,21,0,30,0,60,0,0,0,21,0,29,0,36,1,0,0,21,0,28,0,33,0,0,0,21,0,27,0,32,0,0,0,21,0,26,0,80,0,0,0,21,0,25,0,125,0,0,0,21,0,24,0,12,0,0,0,21,0,23,0,21,0,0,0,21,0,22,0,72,0,0,0,21,0,21,0,39,1,0,0,21,0,20,0,19,0,0,0,21,0,19,0,0,0,0,0,21,0,18,0,17,0,0,0,21,0,17,0,217,0,0,0,21,0,16,0,78,0,0,0,21,0,15,0,11,0,0,0,21,0,14,0,9,0,0,0,21,0,13,0,1,1,0,0,21,0,12,0,2,0,0,0,21,0,11,0,3,0,0,0,21,0,10,0,76,1,0,0,21,0,9,0,4,0,0,0,21,0,8,0,6,0,0,0,21,0,7,0,5,0,0,0,21,0,6,0,6,1,0,0,21,0,5,0,40,1,0,0,21,0,4,0,18,0,0,0,21,0,3,0,20,0,0,0,21,0,2,0,1,0,0,0,21,0,1,0,28,0,0,0,21,0,0,1,62,1,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +static const unsigned char seccomp_bpf_blks_fork[] = { + 32,0,0,0,4,0,0,0,21,0,0,63,62,0,0,192,32,0,0,0,0,0,0,0,53,0,0,1,0,0,0,64,21,0,0,60,255,255,255,255,21,0,58,0,220,0,0,0,21,0,57,0,65,0,0,0,21,0,56,0,64,0,0,0,21,0,55,0,69,0,0,0,21,0,54,0,70,0,0,0,21,0,53,0,68,0,0,0,21,0,52,0,79,0,0,0,21,0,51,0,11,1,0,0,21,0,50,0,89,0,0,0,21,0,49,0,202,0,0,0,21,0,48,0,10,0,0,0,21,0,47,0,8,0,0,0,21,0,46,0,16,0,0,0,21,0,45,0,186,0,0,0,21,0,44,0,39,0,0,0,21,0,43,0,81,0,0,0,21,0,42,0,183,1,0,0,21,0,41,0,13,1,0,0,21,0,40,0,231,0,0,0,21,0,39,0,60,0,0,0,21,0,38,0,36,1,0,0,21,0,37,0,33,0,0,0,21,0,36,0,32,0,0,0,21,0,35,0,80,0,0,0,21,0,34,0,125,0,0,0,21,0,33,0,12,0,0,0,21,0,32,0,21,0,0,0,21,0,31,0,72,0,0,0,21,0,30,0,39,1,0,0,21,0,29,0,19,0,0,0,21,0,28,0,0,0,0,0,21,0,27,0,17,0,0,0,21,0,26,0,217,0,0,0,21,0,25,0,78,0,0,0,21,0,24,0,11,0,0,0,21,0,23,0,9,0,0,0,21,0,22,0,1,1,0,0,21,0,21,0,2,0,0,0,21,0,20,0,3,0,0,0,21,0,19,0,76,1,0,0,21,0,18,0,4,0,0,0,21,0,17,0,6,0,0,0,21,0,16,0,5,0,0,0,21,0,15,0,6,1,0,0,21,0,14,0,40,1,0,0,21,0,13,0,18,0,0,0,21,0,12,0,20,0,0,0,21,0,11,0,1,0,0,0,21,0,10,0,247,0,0,0,21,0,9,0,61,0,0,0,21,0,8,0,58,0,0,0,21,0,7,0,16,1,0,0,21,0,6,0,14,0,0,0,21,0,5,0,13,0,0,0,21,0,4,0,57,0,0,0,21,0,3,0,59,0,0,0,21,0,2,0,56,0,0,0,21,0,1,0,28,0,0,0,21,0,0,1,62,1,0,0,6,0,0,0,0,0,255,127,6,0,0,0,0,0,0,0, +}; +#endif + +#ifdef SECCOMP_BPF_AVAILABLE +typedef struct { + uint16_t cnt; + const void *bpf; +} seccomp_bpf_program_t; +static const seccomp_bpf_program_t seccomp_bpf_program_base = { + .cnt = sizeof(seccomp_bpf_blks_base) / 8, + .bpf = seccomp_bpf_blks_base, +}; +static const seccomp_bpf_program_t seccomp_bpf_program_fork = { + .cnt = sizeof(seccomp_bpf_blks_fork) / 8, + .bpf = seccomp_bpf_blks_fork, +}; +#endif @@ -1,11 +1,12 @@ /* - * Copyright 2015 Gentoo Foundation + * Copyright 2015-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * - * Copyright 2015 Mike Frysinger - <vapier@gentoo.org> + * Copyright 2015-2024 Mike Frysinger - <vapier@gentoo.org> */ #include "paxinc.h" +#include "seccomp-bpf.h" #ifdef __linux__ @@ -26,189 +27,27 @@ #define CLONE_NEWUTS 0 #endif +#ifndef PR_SET_SECCOMP +#define PR_SET_SECCOMP 22 +#endif +#ifndef SECCOMP_MODE_FILTER +#define SECCOMP_MODE_FILTER 2 +#endif + #ifdef __SANITIZE_ADDRESS__ /* ASAN does some weird stuff. */ # define ALLOW_PIDNS 0 +# undef WANT_SECCOMP #else # define ALLOW_PIDNS 1 #endif -#ifdef WANT_SECCOMP -# include <seccomp.h> - -/* Simple helper to add all of the syscalls in an array. */ -static int pax_seccomp_rules_add(scmp_filter_ctx ctx, int syscalls[], size_t num) -{ - static uint8_t prio; - size_t i; - for (i = 0; i < num; ++i) { - if (syscalls[i] < 0) - continue; - - if (seccomp_syscall_priority(ctx, syscalls[i], prio++) < 0) { - warnp("seccomp_syscall_priority failed"); - return -1; - } - if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscalls[i], 0) < 0) { - warnp("seccomp_rule_add failed"); - return -1; - } - } - return 0; -} -#define pax_seccomp_rules_add(ctx, syscalls) pax_seccomp_rules_add(ctx, syscalls, ARRAY_SIZE(syscalls)) - -static void -pax_seccomp_sigal(__unused__ int signo, siginfo_t *info, __unused__ void *context) -{ -#ifdef si_syscall - warn("seccomp violated: syscall %i", info->si_syscall); - fflush(stderr); - warn(" syscall = %s", - seccomp_syscall_resolve_num_arch(seccomp_arch_native(), info->si_syscall)); - fflush(stderr); -#else - warn("seccomp violated: syscall unknown (no si_syscall)"); -#endif - kill(getpid(), SIGSYS); - _exit(1); -} - -static void pax_seccomp_signal_init(void) -{ - struct sigaction act; - sigemptyset(&act.sa_mask); - act.sa_sigaction = pax_seccomp_sigal, - act.sa_flags = SA_SIGINFO | SA_RESETHAND; - sigaction(SIGSYS, &act, NULL); -} - -static void pax_seccomp_init(bool allow_forking) -{ - /* Order determines priority (first == lowest prio). */ - int base_syscalls[] = { - /* We write the most w/scanelf. */ - SCMP_SYS(write), - SCMP_SYS(writev), - SCMP_SYS(pwrite64), - SCMP_SYS(pwritev), - - /* Then the stat family of functions. */ - SCMP_SYS(newfstatat), - SCMP_SYS(fstat), - SCMP_SYS(fstat64), - SCMP_SYS(fstatat64), - SCMP_SYS(lstat), - SCMP_SYS(lstat64), - SCMP_SYS(stat), - SCMP_SYS(stat64), - - /* Then the fd close func. */ - SCMP_SYS(close), - - /* Then fd open family of functions. */ - SCMP_SYS(open), - SCMP_SYS(openat), - - /* Then the memory mapping functions. */ - SCMP_SYS(mmap), - SCMP_SYS(mmap2), - SCMP_SYS(munmap), - - /* Then the directory reading functions. */ - SCMP_SYS(getdents), - SCMP_SYS(getdents64), - - /* Then the file reading functions. */ - SCMP_SYS(pread64), - SCMP_SYS(read), - SCMP_SYS(readv), - SCMP_SYS(preadv), - - /* Then the fd manipulation functions. */ - SCMP_SYS(fcntl), - SCMP_SYS(fcntl64), - - /* After this point, just sort the list alphabetically. */ - SCMP_SYS(access), - SCMP_SYS(brk), - SCMP_SYS(capget), - SCMP_SYS(chdir), - SCMP_SYS(dup), - SCMP_SYS(dup2), - SCMP_SYS(dup3), - SCMP_SYS(exit), - SCMP_SYS(exit_group), - SCMP_SYS(faccessat), - SCMP_SYS(fchdir), - SCMP_SYS(getpid), - SCMP_SYS(gettid), - SCMP_SYS(ioctl), - SCMP_SYS(lseek), - SCMP_SYS(_llseek), - SCMP_SYS(mprotect), - - /* Syscalls listed because of compiler settings. */ - SCMP_SYS(futex), - - /* Syscalls listed because of sandbox. */ - SCMP_SYS(readlink), - SCMP_SYS(readlinkat), - SCMP_SYS(getcwd), - - /* Syscalls listed because of fakeroot. */ - SCMP_SYS(msgget), - SCMP_SYS(msgrcv), - SCMP_SYS(msgsnd), - SCMP_SYS(semget), - SCMP_SYS(semop), - }; - int fork_syscalls[] = { - SCMP_SYS(clone), - SCMP_SYS(execve), - SCMP_SYS(fork), - SCMP_SYS(rt_sigaction), - SCMP_SYS(rt_sigprocmask), - SCMP_SYS(unshare), - SCMP_SYS(vfork), - SCMP_SYS(wait4), - SCMP_SYS(waitid), - SCMP_SYS(waitpid), - }; - scmp_filter_ctx ctx = seccomp_init(USE_DEBUG ? SCMP_ACT_TRAP : SCMP_ACT_KILL); - if (!ctx) { - warnp("seccomp_init failed"); - return; - } - - if (pax_seccomp_rules_add(ctx, base_syscalls) < 0) - goto done; - - if (allow_forking) - if (pax_seccomp_rules_add(ctx, fork_syscalls) < 0) - goto done; - - /* We already called prctl. */ - seccomp_attr_set(ctx, SCMP_FLTATR_CTL_NNP, 0); - - if (USE_DEBUG) - pax_seccomp_signal_init(); - -#ifndef __SANITIZE_ADDRESS__ - /* ASAN does some weird stuff. */ - if (seccomp_load(ctx) < 0) { - /* We have to assume that EINVAL == CONFIG_SECCOMP is disabled. */ - if (errno != EINVAL) - warnp("seccomp_load failed"); - } +#ifndef SECCOMP_BPF_AVAILABLE +# undef WANT_SECCOMP #endif - done: - seccomp_release(ctx); -} - -#else -# define pax_seccomp_init(allow_forking) +#if PAX_UTILS_LIBFUZZ +# undef WANT_SECCOMP #endif static int ns_unshare(int flags) @@ -259,6 +98,7 @@ void security_init_pid(void) void security_init(bool allow_forking) { + (void) allow_forking; int flags; if (!ALLOW_PIDNS) @@ -295,7 +135,19 @@ void security_init(bool allow_forking) _exit(0); } - pax_seccomp_init(allow_forking); +#ifdef WANT_SECCOMP + { + int ret; + + if (allow_forking) + ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &seccomp_bpf_program_fork); + else + ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &seccomp_bpf_program_base); + + if (ret) + warn("enabling seccomp failed"); + } +#endif } #endif @@ -1,9 +1,9 @@ /* Various security related features. * - * Copyright 2015 Gentoo Foundation + * Copyright 2015-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * - * Copyright 2015 Mike Frysinger - <vapier@gentoo.org> + * Copyright 2015-2024 Mike Frysinger - <vapier@gentoo.org> */ #ifndef _PAX_SECURITY_H @@ -22,7 +22,7 @@ void security_init(bool allow_forking); /* Disable forking; usable only when allow_forking above was true. */ void security_init_pid(void); #else -static inline void security_init(bool allow_forking) {} +static inline void security_init(bool allow_forking) { (void) allow_forking; } static inline void security_init_pid(void) {} #endif diff --git a/tests/Makefile b/tests/Makefile deleted file mode 100644 index f4b81e8..0000000 --- a/tests/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -SUBDIRS = $(patsubst %/Makefile,%,$(wildcard */Makefile)) -abs_top_srcdir = $(realpath $(PWD)/..) -abs_top_builddir = $(realpath $(PWD)/..) -# DO NOT STARE AT THE SUN -all: -%:; $(MAKE) `printf '%s_$@_ ' $(SUBDIRS)` -_words = $(subst _, ,$1) -_dir = $(firstword $(call _words,$@)) -_targ = $(lastword $(call _words,$@)) -%_:; $(MAKE) -C $(_dir) $(_targ) srcdir=$(abs_top_srcdir)/tests/$(_dir) builddir=$(abs_top_builddir)/tests/$(_dir) diff --git a/tests/lddtree/Makefile b/tests/lddtree/Makefile deleted file mode 100644 index 3a13e28..0000000 --- a/tests/lddtree/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -all: check - -%.check: - ./dotest-$(@:.check=) - -test check: sh.check -ifneq ($(USE_PYTHON),no) -test check: py.check cmp.check -endif - -clean: - -.PHONY: all check clean test diff --git a/tests/lddtree/meson.build b/tests/lddtree/meson.build new file mode 100644 index 0000000..256998e --- /dev/null +++ b/tests/lddtree/meson.build @@ -0,0 +1,10 @@ +foreach sfx : ['sh', 'py', 'cmp'] + test('lddtree-' + sfx, files('dotest-' + sfx), + workdir : meson.current_source_dir(), + env : { + 'builddir' : meson.project_build_root(), + 'srcdir' : meson.project_source_root(), + 'current_srcdir' : meson.current_source_dir(), + } + ) +endforeach diff --git a/tests/lib.sh b/tests/lib.sh index 927e503..0dab3fa 100644 --- a/tests/lib.sh +++ b/tests/lib.sh @@ -1,17 +1,8 @@ -if [[ -z ${abs_top_builddir} ]] ; then - srcdir=$(cd "${0%/*}" && pwd) - top_srcdir=$(cd "${srcdir}/../.." && pwd) - builddir=${srcdir} - top_builddir=${top_srcdir} -else - mkdir -p "${builddir}" - top_srcdir=${abs_top_srcdir} - top_builddir=${abs_top_builddir} -fi +GOOD=$'\e[32;1m' +BAD=$'\e[31;1m' +NORMAL=$'\e[m' -[ -e /etc/init.d/functions.sh ] && source /etc/init.d/functions.sh - -PATH="${top_srcdir}:${top_builddir}:${PATH}" +PATH="$(realpath "${srcdir}" "${builddir}" | tr '\n' ':'):${PATH}" unset ROOT # who knows! ret=0 diff --git a/tests/scanelf/Makefile b/tests/scanelf/Makefile deleted file mode 100644 index 62084f0..0000000 --- a/tests/scanelf/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -all: check - -test check: - ./dotest - -clean: - -.PHONY: all check clean test diff --git a/tests/scanelf/dotest b/tests/scanelf/dotest index d06f086..fdfd2a2 100755 --- a/tests/scanelf/dotest +++ b/tests/scanelf/dotest @@ -5,9 +5,9 @@ # # simple scanelf symbol checks # -scanelf -qsmain -F'%s %f' "${top_builddir}"/scanelf \ - > "${builddir}"/scanelf.simple -testit scanelf.simple{,.good} +${MESON_EXE_WRAPPER} "${builddir}/scanelf" -qsmain -F'%s %f' \ + "${builddir}"/scanelf > "${builddir}"/scanelf.simple +testit scanelf.simple tests/scanelf/scanelf.simple.good diff --git a/tests/scanelf/meson.build b/tests/scanelf/meson.build new file mode 100644 index 0000000..af632fd --- /dev/null +++ b/tests/scanelf/meson.build @@ -0,0 +1,8 @@ +test('scanelf-test', files('dotest'), + workdir : meson.current_source_dir(), + env : { + 'builddir' : meson.project_build_root(), + 'srcdir' : meson.project_source_root(), + 'current_srcdir' : meson.current_source_dir(), + } +) diff --git a/tests/source/Makefile b/tests/source/Makefile deleted file mode 100644 index 62084f0..0000000 --- a/tests/source/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -all: check - -test check: - ./dotest - -clean: - -.PHONY: all check clean test diff --git a/tests/source/dotest b/tests/source/dotest index 4cbb54a..c97e8cb 100755 --- a/tests/source/dotest +++ b/tests/source/dotest @@ -9,35 +9,6 @@ findfiles() { } # -# check for misc common typos -# -find "${top_srcdir}" \ - '(' -type d -a '(' -name .git -o -name tests ')' -prune ')' \ - -o '(' -type f -a -print0 ')' | xargs -0 \ - grep -n -I \ - -e '\<compatability\>' \ - -e '\<compatable\>' \ - -e '\<fordeground\>' \ - -e '\<depency\>' \ - -e '\<defalt\>' \ - -e '\<remaing\>' \ - -e '\<queuing\>' \ - -e '\<detatch\>' \ - -e '\<sempahore\>' \ - -e '\<reprenstative\>' \ - -e '\<overriden\>' \ - -e '\<readed\>' \ - -e '\<formated\>' \ - -e '\<algorithic\>' \ - -e '\<deamon\>' \ - -e '\<derefernce\>' \ - -e '\<lenght\>' \ - | sed -e "s:^\.\./\.\./::g" > "${builddir}"/src.typos -testit src.typos - - - -# # don't allow obsolete functions # findfiles | xargs -0 \ diff --git a/tests/source/meson.build b/tests/source/meson.build new file mode 100644 index 0000000..f435679 --- /dev/null +++ b/tests/source/meson.build @@ -0,0 +1,8 @@ +test('source tests', files('dotest'), + workdir : meson.current_source_dir(), + env : { + 'builddir' : meson.project_build_root(), + 'srcdir' : meson.project_source_root(), + 'current_srcdir' : meson.current_source_dir(), + } +) diff --git a/travis/autotools.tar.xz b/travis/autotools.tar.xz Binary files differdeleted file mode 100644 index 1c0c854..0000000 --- a/travis/autotools.tar.xz +++ /dev/null diff --git a/travis/lib.sh b/travis/lib.sh deleted file mode 100644 index 687ed41..0000000 --- a/travis/lib.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -# Common funcs for working w/Travis. - -travis_fold() { - if [[ -n ${TRAVIS_OS_NAME} ]] ; then - printf 'travis_fold:%s:%s\r\n' "$@" | sed 's: :_:g' - fi -} - -if [[ -n ${TRAVIS_OS_NAME} ]] ; then - whitebg=$(tput setab 7) - blackfg=$(tput setaf 0) - normal=$(tput sgr0) -else - whitebg= - blackbg= - normal= -fi -v() { - local fold="" - case $1 in - --fold=*) fold=${1:7}; shift;; - esac - if [[ -n ${fold} ]] ; then - travis_fold start "${fold}" - echo "\$ $*" - "$@" - travis_fold end "${fold}" - else - echo "${whitebg}${blackfg}\$ $*${normal}" - "$@" - fi -} - -ncpus=$(getconf _NPROCESSORS_ONLN) -m() { - v make -j${ncpus} "$@" -} diff --git a/travis/main.sh b/travis/main.sh deleted file mode 100755 index 50e8a2f..0000000 --- a/travis/main.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash -e - -. "${0%/*}"/lib.sh - -# We have to do this by hand rather than use the coverity addon because of -# matrix explosion: https://github.com/travis-ci/travis-ci/issues/1975 -# We also do it by hand because when we're throttled, the addon will exit -# the build immediately and skip the main script! -coverity_scan() { - local reason - [[ ${TRAVIS_JOB_NUMBER} != *.1 ]] && reason="not first build job" - [[ -n ${TRAVIS_TAG} ]] && reason="git tag" - [[ ${TRAVIS_PULL_REQUEST} == "true" ]] && reason="pull request" - if [[ -n ${reason} ]] ; then - echo "Skipping coverity scan due to: ${reason}" - return - fi - - export COVERITY_SCAN_PROJECT_NAME="${TRAVIS_REPO_SLUG}" - export COVERITY_SCAN_NOTIFICATION_EMAIL="vapier@gentoo.org" - export COVERITY_SCAN_BUILD_COMMAND="make -j${ncpus}" - export COVERITY_SCAN_BUILD_COMMAND_PREPEND="git clean -q -x -d -f; git checkout -f" - export COVERITY_SCAN_BRANCH_PATTERN="master" - - curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash || : -} - -main() { - if [[ ${TRAVIS_OS_NAME} == "osx" ]] ; then - # Note: Linux deps are maintained in .travis.yml. - v --fold="brew_update" brew update - v --fold="brew_install" brew install xmlto xz - fi - - # See if we have to bootstrap gnulib. This is the case on OS X, and on - # Linux until they whitelist the package: - # https://github.com/travis-ci/apt-package-whitelist/issues/727 - if ! gnulib-tool --version >&/dev/null ; then - if [[ ! -d ../gnulib ]] ; then - v --fold="git_clone_gnulib" \ - git clone --depth=1 https://github.com/coreutils/gnulib.git ../gnulib - else - pushd ../gnulib - v --fold="git_pull_gnulib" git pull - popd - fi - export PATH="${PATH}:${PWD}/../gnulib" - fi - - if [[ ${TRAVIS_OS_NAME} == "linux" ]] ; then - # Standard optimized build. - m - m check - - # Debug build w/ASAN and such enabled. - m debug - m check - fi - - # Autotools based build. - v ./autogen.sh - if [[ ${TRAVIS_OS_NAME} == "linux" ]] ; then - v --fold="configure" ./configure - m V=1 distcheck - else - # ELF checks don't work on OS X -- no ELFs! - v ./configure - m V=1 - fi - - # Do scans last as they like to dirty the tree and some tests - # expect a clean tree (like code style checks). - v --fold="coverity_scan" coverity_scan -} -main "$@" diff --git a/version.h.in b/version.h.in new file mode 100644 index 0000000..eac885b --- /dev/null +++ b/version.h.in @@ -0,0 +1 @@ +#define VCSID "@VCS_TAG@" @@ -1,9 +1,9 @@ /* - * Copyright 2003-2012 Gentoo Foundation + * Copyright 2003-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2003-2012 Ned Ludd - <solar@gentoo.org> - * Copyright 2004-2012 Mike Frysinger - <vapier@gentoo.org> + * Copyright 2004-2024 Mike Frysinger - <vapier@gentoo.org> */ #include "paxinc.h" @@ -1,9 +1,9 @@ /* - * Copyright 2003-2012 Gentoo Foundation + * Copyright 2003-2024 Gentoo Foundation * Distributed under the terms of the GNU General Public License v2 * * Copyright 2003-2012 Ned Ludd - <solar@gentoo.org> - * Copyright 2004-2012 Mike Frysinger - <vapier@gentoo.org> + * Copyright 2004-2024 Mike Frysinger - <vapier@gentoo.org> */ #ifndef __XFUNCS_H__ |