From 75feba5476e3ca37a56c1319e952024f0b0950c1 Mon Sep 17 00:00:00 2001 From: Robert Yang Date: Tue, 6 Nov 2018 16:52:59 -0500 Subject: [PATCH] New aport ldpath Utility to add or remove paths from musl dynamic linker config file --- main/ldpath/APKBUILD | 23 +++++ main/ldpath/ldpath.sh | 168 +++++++++++++++++++++++++++++++++++++ main/ldpath/ldpath_test.sh | 73 ++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100644 main/ldpath/APKBUILD create mode 100644 main/ldpath/ldpath.sh create mode 100644 main/ldpath/ldpath_test.sh diff --git a/main/ldpath/APKBUILD b/main/ldpath/APKBUILD new file mode 100644 index 000000000..3b56195fc --- /dev/null +++ b/main/ldpath/APKBUILD @@ -0,0 +1,23 @@ +pkgname=ldpath +pkgver=0.1 +pkgrel=0 +pkgdesc="Utility to add or remove paths from musl dynamic linker config file" +url="https://postmarketos.org/" +arch="noarch" +license="MIT" +source=" + ldpath.sh + ldpath_test.sh + " + +check() { + sh ldpath_test.sh +} + +package() { + install -Dm755 "$srcdir/ldpath.sh" \ + "$pkgdir/usr/bin/ldpath" +} + +sha512sums="0bf8a3bcbb314f54653921d1757b35dc582997a4c058033a390c8b8a520f44541ba1791775ef5a63706da1b8cb86018bb9c7c7effce1c4ea65a2d33896e583ff ldpath.sh +e9ac37e88bc8fb6def9d550a58da0cc8c62dc14c49d6119e95560ff7d4c36eeb6dbbbce8006de6a170f6833b3ca54c80a2f173f67fefad4bf0927dc0a3d692b7 ldpath_test.sh" diff --git a/main/ldpath/ldpath.sh b/main/ldpath/ldpath.sh new file mode 100644 index 000000000..0ca94f42c --- /dev/null +++ b/main/ldpath/ldpath.sh @@ -0,0 +1,168 @@ +#!/bin/sh +# +# Add or remove paths from musl dynamic linker +# path file (/etc/ld-musl-$ARCH.path) +# +# usage example: +# $ ldpath.sh add /usr/lib/libdrm-grate + +default_ld_paths() { + echo "/lib:/usr/local/lib:/usr/lib" +} + +############################################### +# Processor arch in the convention used by the +# musl dynamic linker. +# See musl source code: ldso/dynlink.c +# Arguments: +# kernel machine hardware name (uname -m) +# Returns: +# musl ldso processor arch +############################################### +kernel_arch_to_ldso_arch() { + local karch=$1 + local ld_arch="" + case "$karch" in + armv7l) + ld_arch=armhf + ;; + *) + ld_arch="$karch" + ;; + esac + echo "$ld_arch" +} + +default_ld_musl_file() { + local ld_arch + ld_arch=$(kernel_arch_to_ldso_arch "$(uname -m)") + echo "/etc/ld-musl-${ld_arch}.path" +} + +############################################### +# Prepend a path to dynamic linker path file +# Arguments: +# Shared library directory +# ld musl path file +############################################### +add_path() { + local ld_library_path=$1 + local ld_musl_file=$2 + + # Don't allow duplicates + if [ -f "$ld_musl_file" ]; then + if grep -q "$ld_library_path" "$ld_musl_file"; then + return 0 + fi + fi + + if [ -f "$ld_musl_file" ]; then + echo "${ld_library_path}:$(cat "$ld_musl_file")" > \ + "$ld_musl_file" + else + echo "${ld_library_path}:$(default_ld_paths)" > "$ld_musl_file" + fi +} + +############################################### +# Remove a path from dynamic linker path file +# Arguments: +# Shared library directory +# ld musl path file +############################################### +remove_path() { + local ld_library_path=$1 + local ld_musl_file=$2 + local conf + + if [ ! -f "$ld_musl_file" ]; then + return 0 + fi + + # Don't remove default paths + if default_ld_paths | grep -q "$ld_library_path"; then + return 0 + fi + + conf=$(awk -v ld_path="$ld_library_path" '{n=split($0, array, ":")} END { + for (i in array) { + if (array[i]!=ld_path) { + printf array[i] + if (i "$ld_musl_file" +} + +print_usage() { + local ld_arch + ld_arch=$(kernel_arch_to_ldso_arch "$(uname -m)") + echo "usage: $(basename "$1") [-h] [-f FILE] {add,remove} LD_LIBRARY_PATH" + echo "" + echo "Add or remove LD_LIBRARY_PATH in $(default_ld_musl_file)" + echo "" + echo "optional arguments:" + echo " -h, --help show this help message and exit" + echo " -f, --file override ld musl path file" +} + +parse_args() { + local have_file_arg="" + while [ "${1:-}" != "" ]; do + case $1 in + add|remove) + ldpath_func="$1" + ldpath_arg="$2" + shift + shift + ;; + -f|--file) + have_file_arg="1" + ld_musl_file="$2" + shift + shift + ;; + -h|--help) + shift + return 0 + ;; + *) + echo "Invalid argument: $1" + shift + return 0 + ;; + esac + done + + if [ -z "$ldpath_func" ] || [ -z "$ldpath_arg" ]; then + return 0 + fi + + if [ "$have_file_arg" = "1" ] && + [ -z "$ld_musl_file" ]; then + return 0 + fi + + return 1 +} + +main() { + if [ -z "$ld_musl_file" ]; then + ld_musl_file=$(default_ld_musl_file) + fi + + if [ "$ldpath_func" = "add" ]; then + add_path "$ldpath_arg" "$ld_musl_file" + elif [ "$ldpath_func" = "remove" ]; then + remove_path "$ldpath_arg" "$ld_musl_file" + fi +} + +if parse_args "$@"; then + print_usage "$0" + return 1 +fi + +main "$0" diff --git a/main/ldpath/ldpath_test.sh b/main/ldpath/ldpath_test.sh new file mode 100644 index 000000000..8e384547c --- /dev/null +++ b/main/ldpath/ldpath_test.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +testdir=$(mktemp -d) +ld_musl_file="${testdir}/ld-musl-test.path" + +lib_path="/usr/lib/foo" +lib_path2="/usr/lib/bar" + +# Create ldso config file and add a path to it. +sh ldpath.sh -f "$ld_musl_file" add "$lib_path" + +if ! grep -q "$lib_path" "$ld_musl_file"; then + echo "ERROR: Did not find $lib_path in newly created config file." + exit 1 +fi + +# Add another path to config file. +sh ldpath.sh -f "$ld_musl_file" add "$lib_path2" +if ! grep -q "$lib_path2" "$ld_musl_file"; then + echo "ERROR: Did not find $lib_path2 in config file." + exit 1 +fi + +# Check that first path is still present +if ! grep -q "$lib_path" "$ld_musl_file"; then + echo "ERROR: Did not find $lib_path in config file." + exit 1 +fi + +# Remove the first path +sh ldpath.sh -f "$ld_musl_file" remove "$lib_path" +if grep -q "$lib_path" "$ld_musl_file"; then + echo "ERROR: $lib_path was not removed from config file." + exit 1 +fi + +# Check that second path is still present +if ! grep -q "$lib_path2" "$ld_musl_file"; then + echo "ERROR: $lib_path2 should not have been removed." + exit 1 +fi + +# Remove the second path +sh ldpath.sh -f "$ld_musl_file" remove "$lib_path2" +if grep -q "$lib_path2" "$ld_musl_file"; then + echo "ERROR: $lib_path2 was not removed from config file." + exit 1 +fi + +# Don't allow removal of default paths +_default_paths="/lib /usr/local/lib /usr/lib" +for _path in $_default_paths +do + sh ldpath.sh -f "$ld_musl_file" remove "$_path" + if ! grep -q "$_path" "$ld_musl_file"; then + echo "ERROR: Default path $_path should not have been removed." + exit 1 + fi +done + +# Don't allow duplicates +sh ldpath.sh -f "$ld_musl_file" add "$lib_path" +sh ldpath.sh -f "$ld_musl_file" add "$lib_path" +_count=$(grep -o "$lib_path" "$ld_musl_file" | wc -l) +if [ "$_count" -ne 1 ]; then + echo "ERROR: Multiple entries of $lib_path." + exit 1 +fi + +# Cleanup +rm -r "$testdir" + +exit 0