pthbs

Packaging Through Hashed Build Scripts
git clone https://ccx.te2000.cz/git/pthbs
Log | Files | Refs | Submodules | README

commit 81d7bfeb7a4406ac5c4bbef2c1cc31430777efd1
parent b67e94c3cab9a702cc40e7c0c25dbb869ed9b5a2
Author: ccx <ccx@te2000.cz>
Date:   Sun, 10 Mar 2024 00:24:34 +0000

applyuidgid-caps code and package

Diffstat:
Afiles/applyuidgid-caps.c | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apackages/applyuidgid-caps | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpackages/default.environment | 6++++--
Apackages/libcap | 119+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mpackages/userspace.environment | 6++++--
Atemplates/pkg/applyuidgid-caps | 25+++++++++++++++++++++++++
Atemplates/pkg/libcap | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Mtemplates/pkg/userspace.environment | 2++
8 files changed, 395 insertions(+), 4 deletions(-)

diff --git a/files/applyuidgid-caps.c b/files/applyuidgid-caps.c @@ -0,0 +1,98 @@ +/* ISC license. */ + +#include <unistd.h> +#include <grp.h> +#include <limits.h> +#include <stdlib.h> +#include <sys/prctl.h> +#include <sys/capability.h> +#include <linux/securebits.h> + +#include <skalibs/types.h> +#include <skalibs/setgroups.h> +#include <skalibs/strerr2.h> +#include <skalibs/sgetopt.h> +#include <skalibs/djbunix.h> +#include <skalibs/exec.h> + +#define USAGE "applyuidgid-caps [ -z ] [ -u uid ] [ -g gid ] [ -G gidlist ] [ -U ] iab_caps prog..." +#define dieusage() strerr_dieusage(100, USAGE) + +int main (int argc, char const *const *argv) +{ + uid_t uid = 0 ; + gid_t gid = 0 ; + gid_t gids[NGROUPS_MAX+1] ; + size_t gidn = (size_t)-1 ; + int unexport = 0 ; + PROG = "s6-applyuidgid" ; + { + subgetopt l = SUBGETOPT_ZERO ; + for (;;) + { + int opt = subgetopt_r(argc, argv, "zUu:g:G:", &l) ; + if (opt == -1) break ; + switch (opt) + { + case 'z' : unexport = 1 ; break ; + case 'u' : if (!uid0_scan(l.arg, &uid)) dieusage() ; break ; + case 'g' : if (!gid0_scan(l.arg, &gid)) dieusage() ; break ; + case 'G' : if (!gid_scanlist(gids, NGROUPS_MAX, l.arg, &gidn) && *l.arg) dieusage() ; break ; + case 'U' : + { + char const *x = getenv("UID") ; + if (!x) strerr_dienotset(100, "UID") ; + if (!uid0_scan(x, &uid)) strerr_dieinvalid(100, "UID") ; + x = getenv("GID") ; + if (!x) strerr_dienotset(100, "GID") ; + if (!gid0_scan(x, &gid)) strerr_dieinvalid(100, "GID") ; + x = getenv("GIDLIST") ; + if (!x) strerr_dienotset(100, "GIDLIST") ; + if (!gid_scanlist(gids, NGROUPS_MAX+1, x, &gidn) && *x) + strerr_dieinvalid(100, "GIDLIST") ; + break ; + } + default : dieusage() ; + } + } + argc -= l.ind ; argv += l.ind ; + } + if (argc < 2) dieusage() ; + + /* + The IAB 3-tuple of capability vectors (Inh, Amb and Bound), + captured in type cap_iab_t combine to pass capabilities + from one process to another through execve(2) system calls. + */ + + /* parse the first argument to obtain a set of capabilities */ + cap_iab_t new_iab; + new_iab = cap_iab_from_text(argv[0]); + if (new_iab == NULL) { + strerr_dieinvalid(100, "caps") ; + // strerr_dief1sys(100, "requested capabilities were not recognized"); + } + + if (prctl(PR_SET_SECUREBITS, + SECBIT_KEEP_CAPS | /* unneeded as NO_SETUID_FIXUP is superset */ + SECBIT_NO_SETUID_FIXUP | + SECBIT_NOROOT | /* disables suid and filecap privilege gain */ + SECBIT_NOROOT_LOCKED) < 1) { + strerr_dief1sys(111, "Failed to set securebits via prctl()"); + } + + /* set these capabilities for the current process */ + if (cap_iab_set_proc(new_iab) != 0) { + strerr_dief1sys(111, "Failed to set capabilities via cap_set_proc()"); + } + + if (gidn != (size_t)-1 && setgroups_and_gid(gid ? gid : getegid(), gidn, gids) < 0) + strerr_diefu1sys(111, "set supplementary group list") ; + if (gid && setgid(gid) < 0) + strerr_diefu1sys(111, "setgid") ; + if (uid && setuid(uid) < 0) + strerr_diefu1sys(111, "setuid") ; + + if (unexport) xmexec_n(argv, "UID\0GID\0GIDLIST", 16, 3) ; + else xexec(&argv[1]) ; +} diff --git a/packages/applyuidgid-caps b/packages/applyuidgid-caps @@ -0,0 +1,93 @@ +#!/usr/bin/env pthbs-build +#+musl-cross-make.65f98305f5666435bf0c6b9ccedffae2179ff1b3286752756886f760cf7771d2 +#+gnu-make.782c9e6625fd7420e2cd38b847afed19db3b3844cae8a0426a0dbf73e10d78e5 +#+busybox.e60885fe93ee85c01831673bb29f0e62a64903f4ce3094e3dc35bc8ec8887ad9 +#+skalibs.9c4a42aba2c3b6d3622a04a17fb8dbb75d51805220f45823c26fe7a73e842b5e +#+libcap.3528f93ae9873fceae62855cb7c0fa521ac2c3cfabe71bf58ba01483136bf5fd +#@sha256:1ca7801a4f247d9433de87373e243f3a38618e0e508501e4ecbb96516cbeee1d:applyuidgid-caps.c + +name=applyuidgid-caps +check_static() { + local exe || true + exe=$pthbs_destdir/'/versions'/$pthbs_package/$1 + if ! test -f $exe; then + printf '%s\n' "Error: file '$1' doesn't exist!" + exit 1 + fi + interp_info=$(readelf --string-dump=.interp "$exe") || exit $? + if test x '!=' "x$interp_info"; then + printf '%s\n' "Error: '$1' is a dynamic binary!" + exit 1 + fi +} +build_env_static() { + export LD_LIBRARY_PATH="$pthbs_build_environment/library" + export CPATH="$pthbs_build_environment/include" + export LDFLAGS="-static -L$pthbs_build_environment/library $LDFLAGS" +} +def_prefix() { + prefix=/versions/$pthbs_package +} +def_dest() { + dest=${pthbs_destdir%/}//versions/$pthbs_package +} +build_env_static +def_prefix + +gcc -D_GNU_SOURCE -static -o $name $name.c $LDFLAGS -lskarnet -lcap + +install -d "$pthbs_destdir/$prefix/command" +install -m 755 $name "$pthbs_destdir/$prefix/command" +check_static command/$name + +cd "$pthbs_destdir/versions/$pthbs_package" +find -type d -o -print | awk -F/ ' +BEGIN { + x["./command/applyuidgid-caps"]=1} + +function r1(s) { + sub("^[.]/[^/]*", ".", s) + return s +} +function s1(repl, s) { + sub("^[.]/[^/]*", "./"repl, s) + return s +} +function link(src) { + x[$0]=0 + printf "%s\t%s\n", $0, src + printf "genlinks >>%s\t%s<<\n", $0, src >>"/dev/stderr" +} +$1!="."{exit 1} + + +$2 == "command" { link($0); next } +$2 == "bin" { link(s1("command", $0)); next } + +$2 == "library.so" { link($0); next } +$2 == "library" { link($0); next } +$2 == "lib" && $NF ~ /\.l?a$/ { link(s1("library", $0)); next } +$2 == "lib" && $NF ~ /\.so(|\..*)$/ { link(s1("library.so", $0)); next } + +$2 == "share" && $3 ~ /^(info|man|doc|icons|terminfo)$/ { link(r1($0)); next } + +$2 == "man" { link($0); next } +$2 == "info" { link($0); next } +$2 == "doc" { link($0); next } +$2 == "icons" { link($0); next } +$2 == "terminfo" { link($0); next } +$2 == "data" { link($0); next } +$2 == "include" { link($0); next } + +{ printf "genlinks ##%s## skipped\n", $0 >>"/dev/stderr" } + +END { + for(fname in x) { printf "DEBUG: x[\"%s\"]=\"%s\"\n", fname, x[fname] >"/dev/stderr" } + for(fname in x) { + if(x[fname]) { + printf "ERROR: missing expected file \"%s\"\n", fname >"/dev/stderr" + exit 3 + } + } +}' >.install-links.new +mv .install-links.new .install-links diff --git a/packages/default.environment b/packages/default.environment @@ -34,4 +34,6 @@ #+apk-tools.c9cdb867562a26201a1618e0b1bf2147e6cee6aff1a6901909ee911a4462327a #+getent.15c11d87a5194766f1ba7b78feac3b77792756cfb12a84c5f5d0f2c7c1cfd25d #+getconf.d16039d91561f2bb7f430eb2250f1e7c03d59ddeea80a9c55c21e293fb528fd9 -#+iconv.0b381a2e57a5e7b3df6b6a68d72230eec4e5ef2f6a460509c94d3d502fe1f2cf- \ No newline at end of file +#+iconv.0b381a2e57a5e7b3df6b6a68d72230eec4e5ef2f6a460509c94d3d502fe1f2cf +#+libcap.3528f93ae9873fceae62855cb7c0fa521ac2c3cfabe71bf58ba01483136bf5fd +#+applyuidgid-caps.c36c2852aba239646b379f9ea3dfc520be308a1d263c577f0da97a0d0b20b307+ \ No newline at end of file diff --git a/packages/libcap b/packages/libcap @@ -0,0 +1,119 @@ +#!/usr/bin/env pthbs-build +#+musl-cross-make.65f98305f5666435bf0c6b9ccedffae2179ff1b3286752756886f760cf7771d2 +#+gnu-make.782c9e6625fd7420e2cd38b847afed19db3b3844cae8a0426a0dbf73e10d78e5 +#+busybox.e60885fe93ee85c01831673bb29f0e62a64903f4ce3094e3dc35bc8ec8887ad9 +#+busybox-diffutils.4f5a07b29246414b77a7d71b103263af8f1249d75ddcbd9864e00def3d6feded +#+pkgconf-pkg-config.2993a64b810b50b0fa289b8d8eaf614f6f1719d9f2473960b2cbf5856939b834 +#@untar:-J:sha256:f311f8f3dad84699d0566d1d6f7ec943a9298b28f714cae3c931dfd57492d7eb:. + +check_static() { + local exe || true + exe=$pthbs_destdir/'/versions'/$pthbs_package/$1 + if ! test -f $exe; then + printf '%s\n' "Error: file '$1' doesn't exist!" + exit 1 + fi + interp_info=$(readelf --string-dump=.interp "$exe") || exit $? + if test x '!=' "x$interp_info"; then + printf '%s\n' "Error: '$1' is a dynamic binary!" + exit 1 + fi +} +build_env_static() { + export LD_LIBRARY_PATH="$pthbs_build_environment/library" + export CPATH="$pthbs_build_environment/include" + export LDFLAGS="-static -L$pthbs_build_environment/library $LDFLAGS" +} +def_prefix() { + prefix=/versions/$pthbs_package +} +def_dest() { + dest=${pthbs_destdir%/}//versions/$pthbs_package +} +def_prefix +LDFLAGS=--static +build_env_static + +cd libcap-2.69 +sed -i '1 s|^#!/bin/bash|#!/bin/sh|' progs/*.sh +make \ + DESTDIR="$pthbs_destdir" \ + SHARED=no DYNAMIC=no LIBCSTATIC=yes \ + prefix="$prefix" \ + exec_prefix="$prefix" \ + lib_prefix="$prefix" \ + inc_prefix="$prefix" \ + man_prefix="$prefix/share" \ + MANDIR="$prefix/man" \ + sbin=command \ + SBINDIR="$prefix/command" \ + INCDIR="$prefix/include" \ + lib=library \ + LIBDIR="$prefix/library" \ + PKGCONFIGDIR="$prefix/library/pkgconfig" \ + CAPSH_SHELL="'-DSHELL=\"$(which sh)\"'" \ + LDFLAGS="$LDFLAGS" \ + all install + +check_static command/capsh +check_static command/getcap +check_static command/setcap +check_static command/getpcaps + + +cd "$pthbs_destdir/versions/$pthbs_package" +find -type d -o -print | awk -F/ ' +BEGIN { + x["./command/capsh"]=1 + x["./command/getcap"]=1 + x["./command/setcap"]=1 + x["./command/getpcaps"]=1 + x["./library/libcap.a"]=1 +} + +function r1(s) { + sub("^[.]/[^/]*", ".", s) + return s +} +function s1(repl, s) { + sub("^[.]/[^/]*", "./"repl, s) + return s +} +function link(src) { + x[$0]=0 + printf "%s\t%s\n", $0, src + printf "genlinks >>%s\t%s<<\n", $0, src >>"/dev/stderr" +} +$1!="."{exit 1} + + +$2 == "command" { link($0); next } +$2 == "bin" { link(s1("command", $0)); next } + +$2 == "library.so" { link($0); next } +$2 == "library" { link($0); next } +$2 == "lib" && $NF ~ /\.l?a$/ { link(s1("library", $0)); next } +$2 == "lib" && $NF ~ /\.so(|\..*)$/ { link(s1("library.so", $0)); next } + +$2 == "share" && $3 ~ /^(info|man|doc|icons|terminfo)$/ { link(r1($0)); next } + +$2 == "man" { link($0); next } +$2 == "info" { link($0); next } +$2 == "doc" { link($0); next } +$2 == "icons" { link($0); next } +$2 == "terminfo" { link($0); next } +$2 == "data" { link($0); next } +$2 == "include" { link($0); next } + +{ printf "genlinks ##%s## skipped\n", $0 >>"/dev/stderr" } + +END { + for(fname in x) { printf "DEBUG: x[\"%s\"]=\"%s\"\n", fname, x[fname] >"/dev/stderr" } + for(fname in x) { + if(x[fname]) { + printf "ERROR: missing expected file \"%s\"\n", fname >"/dev/stderr" + exit 3 + } + } +}' >.install-links.new +mv .install-links.new .install-links diff --git a/packages/userspace.environment b/packages/userspace.environment @@ -30,4 +30,6 @@ #+apk-tools.c9cdb867562a26201a1618e0b1bf2147e6cee6aff1a6901909ee911a4462327a #+getent.15c11d87a5194766f1ba7b78feac3b77792756cfb12a84c5f5d0f2c7c1cfd25d #+getconf.d16039d91561f2bb7f430eb2250f1e7c03d59ddeea80a9c55c21e293fb528fd9 -#+iconv.0b381a2e57a5e7b3df6b6a68d72230eec4e5ef2f6a460509c94d3d502fe1f2cf- \ No newline at end of file +#+iconv.0b381a2e57a5e7b3df6b6a68d72230eec4e5ef2f6a460509c94d3d502fe1f2cf +#+libcap.3528f93ae9873fceae62855cb7c0fa521ac2c3cfabe71bf58ba01483136bf5fd +#+applyuidgid-caps.c36c2852aba239646b379f9ea3dfc520be308a1d263c577f0da97a0d0b20b307+ \ No newline at end of file diff --git a/templates/pkg/applyuidgid-caps b/templates/pkg/applyuidgid-caps @@ -0,0 +1,25 @@ +{% extends "genlinks" %} +{%- block script %} +#+{{pkg_install_name("musl-cross-make")}} +#+{{pkg_install_name("gnu-make")}} +#+{{pkg_install_name("busybox")}} +#+{{pkg_install_name("skalibs")}} +#+{{pkg_install_name("libcap")}} +#@sha256:{{files["applyuidgid-caps.c"]}}:applyuidgid-caps.c + +name=applyuidgid-caps +{% include "functions/check_static" %} +{% include "functions/build_env_static" %} +{% include "functions/vars" %} +build_env_static +def_prefix + +gcc -D_GNU_SOURCE -static -o $name $name.c $LDFLAGS -lskarnet -lcap + +install -d "$pthbs_destdir/$prefix/command" +install -m 755 $name "$pthbs_destdir/$prefix/command" +check_static command/$name +{% endblock %} +{% block genlinks_begin %} + x["./command/applyuidgid-caps"]=1 +{%- endblock %} diff --git a/templates/pkg/libcap b/templates/pkg/libcap @@ -0,0 +1,50 @@ +{% extends "genlinks" %} +{%- block script %} +#+{{pkg_install_name("musl-cross-make")}} +#+{{pkg_install_name("gnu-make")}} +#+{{pkg_install_name("busybox")}} +#+{{pkg_install_name("busybox-diffutils")}} +#+{{pkg_install_name("pkgconf-pkg-config")}} +#@untar:-J:sha256:f311f8f3dad84699d0566d1d6f7ec943a9298b28f714cae3c931dfd57492d7eb:. + +{% include "functions/check_static" %} +{% include "functions/build_env_static" %} +{% include "functions/vars" %} +def_prefix +LDFLAGS=--static +build_env_static + +cd libcap-2.69 +sed -i '1 s|^#!/bin/bash|#!/bin/sh|' progs/*.sh +make \ + DESTDIR="$pthbs_destdir" \ + SHARED=no DYNAMIC=no LIBCSTATIC=yes \ + prefix="$prefix" \ + exec_prefix="$prefix" \ + lib_prefix="$prefix" \ + inc_prefix="$prefix" \ + man_prefix="$prefix/share" \ + MANDIR="$prefix/man" \ + sbin=command \ + SBINDIR="$prefix/command" \ + INCDIR="$prefix/include" \ + lib=library \ + LIBDIR="$prefix/library" \ + PKGCONFIGDIR="$prefix/library/pkgconfig" \ + CAPSH_SHELL="'-DSHELL=\"$(which sh)\"'" \ + LDFLAGS="$LDFLAGS" \ + all install + +check_static command/capsh +check_static command/getcap +check_static command/setcap +check_static command/getpcaps + +{% endblock %} +{% block genlinks_begin %} + x["./command/capsh"]=1 + x["./command/getcap"]=1 + x["./command/setcap"]=1 + x["./command/getpcaps"]=1 + x["./library/libcap.a"]=1 +{% endblock %} diff --git a/templates/pkg/userspace.environment b/templates/pkg/userspace.environment @@ -31,3 +31,5 @@ #+{{pkg_install_name("getent")}} #+{{pkg_install_name("getconf")}} #+{{pkg_install_name("iconv")}} +#+{{pkg_install_name("libcap")}} +#+{{pkg_install_name("applyuidgid-caps")}}