diff --git a/copyextfiles.sh b/copyextfiles.sh index 56983b8..dd2f795 100755 --- a/copyextfiles.sh +++ b/copyextfiles.sh @@ -2,6 +2,11 @@ mkdir -p stage2/01-sys-tweaks/extfiles +# +# tools +# +cp tools/setuidgids stage2/01-sys-tweaks/extfiles/ + # # openjdk # diff --git a/stage2/01-sys-tweaks/01-run.sh b/stage2/01-sys-tweaks/01-run.sh index 64c8881..59e5ad4 100755 --- a/stage2/01-sys-tweaks/01-run.sh +++ b/stage2/01-sys-tweaks/01-run.sh @@ -16,6 +16,8 @@ install -m 644 files/raspi-blacklist.conf "${ROOTFS_DIR}/etc/modprobe.d/" install -m 644 files/frc.json "${ROOTFS_DIR}/boot/" +install -m 755 extfiles/setuidgids "${ROOTFS_DIR}/usr/local/bin/" + install -m 755 -o 1000 -g 1000 extfiles/multiCameraServer "${ROOTFS_DIR}/home/pi/" cat extfiles/jdk_11.0.1-strip.tar.gz | sh -c "mkdir -p ${ROOTFS_DIR}/usr/lib/jvm && cd ${ROOTFS_DIR}/usr/lib/jvm/ && tar xzf - --exclude=\*.diz --exclude=src.zip --transform=s/^jdk/jdk-11.0.1/" diff --git a/stage2/01-sys-tweaks/files/camera_run b/stage2/01-sys-tweaks/files/camera_run index e278c78..5d72da8 100755 --- a/stage2/01-sys-tweaks/files/camera_run +++ b/stage2/01-sys-tweaks/files/camera_run @@ -1,4 +1,4 @@ #!/bin/sh sleep 1 cd /home/pi -exec pgrphack sudo -u pi /usr/local/bin/netconsoleServer -u ./runCamera +exec pgrphack /usr/local/bin/setuidgids pi /usr/local/bin/netconsoleServer -u ./runCamera diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 0000000..87882c9 --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,2 @@ +setuidgids: setuidgids.c + arm-raspbian9-linux-gnueabihf-gcc -O -Wall -D_GNU_SOURCE -o $@ $< diff --git a/tools/setuidgids.c b/tools/setuidgids.c new file mode 100644 index 0000000..570b1ab --- /dev/null +++ b/tools/setuidgids.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include +#include + +static int prot_gid(gid_t gid) +{ + if (setgroups(1,&gid) == -1) return -1; + return setgid(gid); /* _should_ be redundant, but on some systems it isn't */ +} + +const char *account; +struct passwd *pw; + +int main(int argc, char **argv, char **envp) +{ + account = *++argv; + if (!account || !*++argv) { + fprintf(stderr, "setuidgids: usage: setuidgids account child"); + exit(EXIT_FAILURE); + } + + pw = getpwnam(account); + if (!pw) { + fprintf(stderr, "setuidgids: FATAL: unknown account %s", account); + return EXIT_FAILURE; + } + + if (prot_gid(pw->pw_gid) == -1) { + fprintf(stderr, "setuidgids: FATAL: unable to setgid\n"); + return EXIT_FAILURE; + } + if (initgroups(pw->pw_name, pw->pw_gid) == -1) { + fprintf(stderr, "setuidgids: FATAL: unable to initgroups\n"); + return EXIT_FAILURE; + } + if (setuid(pw->pw_uid) == -1) { + fprintf(stderr, "setuidgids: FATAL: unable to setuid\n"); + return EXIT_FAILURE; + } + + execvpe(*argv,argv,envp); + fprintf(stderr, "setuidgids: FATAL: unable to run %s\n", *argv); + return EXIT_FAILURE; +}