commit 81d7bfeb7a4406ac5c4bbef2c1cc31430777efd1
parent b67e94c3cab9a702cc40e7c0c25dbb869ed9b5a2
Author: ccx <ccx@te2000.cz>
Date: Sun, 10 Mar 2024 00:24:34 +0000
applyuidgid-caps code and package
Diffstat:
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")}}