From fb295aa908f0f7e73e7efdd587dffcbdd5685694 Mon Sep 17 00:00:00 2001 From: Dima Krasner Date: Sun, 20 Oct 2024 19:56:33 +0300 Subject: [PATCH] override clock_adjtime() with eBPF instead of ld.so.preload --- kernel-kit/build.sh | 1 + .../rootfs-petbuilds/connman-puppy/README.md | 3 -- .../connman-puppy/libadjtime.c | 8 ----- .../rootfs-petbuilds/connman-puppy/petbuild | 8 ----- .../connman-puppy/pinstall.sh | 1 - woof-code/rootfs-petbuilds/rtclock/Makefile | 21 +++++++++++++ woof-code/rootfs-petbuilds/rtclock/README.md | 3 ++ woof-code/rootfs-petbuilds/rtclock/petbuild | 7 +++++ .../rootfs-petbuilds/rtclock/rtclock.bpf.c | 22 +++++++++++++ woof-code/rootfs-petbuilds/rtclock/rtclock.c | 31 +++++++++++++++++++ woof-code/rootfs-skeleton/etc/rc.d/rc.sysinit | 2 ++ woof-code/support/petbuilds.sh | 2 ++ .../trixie64/DISTRO_PKGS_SPECS-debian-trixie | 4 +++ .../x86_64/debian/trixie64/_00build.conf | 2 +- 14 files changed, 94 insertions(+), 21 deletions(-) delete mode 100644 woof-code/rootfs-petbuilds/connman-puppy/README.md delete mode 100644 woof-code/rootfs-petbuilds/connman-puppy/libadjtime.c delete mode 100644 woof-code/rootfs-petbuilds/connman-puppy/petbuild delete mode 100644 woof-code/rootfs-petbuilds/connman-puppy/pinstall.sh create mode 100644 woof-code/rootfs-petbuilds/rtclock/Makefile create mode 100644 woof-code/rootfs-petbuilds/rtclock/README.md create mode 100644 woof-code/rootfs-petbuilds/rtclock/petbuild create mode 100644 woof-code/rootfs-petbuilds/rtclock/rtclock.bpf.c create mode 100644 woof-code/rootfs-petbuilds/rtclock/rtclock.c diff --git a/kernel-kit/build.sh b/kernel-kit/build.sh index 9a92d66ca5c..4b65b894699 100755 --- a/kernel-kit/build.sh +++ b/kernel-kit/build.sh @@ -43,6 +43,7 @@ make -j`nproc` bzImage modules || exit 1 echo "Creating the kernel package" make INSTALL_MOD_PATH=`pwd`/../output/linux_kernel-${kernel_version}/usr INSTALL_MOD_STRIP=1 modules_install cp -f arch/x86/boot/bzImage ../output/vmlinuz-${kernel_version} +bpftool btf dump file vmlinux format c > ../output/vmlinux-${kernel_version}.h rm -f ../output/linux_kernel-${kernel_version}/usr/lib/modules/${kernel_version}/{build,source} mkdir -p ../output/linux_kernel-${kernel_version}/boot cp -f .config ../output/linux_kernel-${kernel_version}/boot/config-${kernel_version} diff --git a/woof-code/rootfs-petbuilds/connman-puppy/README.md b/woof-code/rootfs-petbuilds/connman-puppy/README.md deleted file mode 100644 index 57aa0d57270..00000000000 --- a/woof-code/rootfs-petbuilds/connman-puppy/README.md +++ /dev/null @@ -1,3 +0,0 @@ -libadjtime.so prevents connman from changing the hardware clock, to prevent conflicts with other OSs running on the same machine that may save time in UTC rather than local time. - -When connman loads this library through /etc/ld.so.preload, clock synchronization over NTP only sets the software clock. /etc/rc.d/rc.sysinit is responsible for synchronizing the software clock with RTC at boot time, so if RTC is set correctly (by another OS), the software clock will show the correct time even before network is ready. diff --git a/woof-code/rootfs-petbuilds/connman-puppy/libadjtime.c b/woof-code/rootfs-petbuilds/connman-puppy/libadjtime.c deleted file mode 100644 index 3f3cfcc9884..00000000000 --- a/woof-code/rootfs-petbuilds/connman-puppy/libadjtime.c +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include - -int adjtimex(struct timex *buf) -{ - buf->status |= STA_UNSYNC; - return clock_adjtime(CLOCK_REALTIME, buf); -} diff --git a/woof-code/rootfs-petbuilds/connman-puppy/petbuild b/woof-code/rootfs-petbuilds/connman-puppy/petbuild deleted file mode 100644 index 8f0125ac679..00000000000 --- a/woof-code/rootfs-petbuilds/connman-puppy/petbuild +++ /dev/null @@ -1,8 +0,0 @@ -download() { - : -} - -build() { - mkdir -p /usr/local/lib/connman - $CC -D_GNU_SOURCE $CFLAGS libadjtime.c $LDFLAGS -shared -o /usr/local/lib/connman/libadjtime.so -} diff --git a/woof-code/rootfs-petbuilds/connman-puppy/pinstall.sh b/woof-code/rootfs-petbuilds/connman-puppy/pinstall.sh deleted file mode 100644 index 8b540dcc0e0..00000000000 --- a/woof-code/rootfs-petbuilds/connman-puppy/pinstall.sh +++ /dev/null @@ -1 +0,0 @@ -echo /usr/local/lib/connman/libadjtime.so >> etc/ld.so.preload diff --git a/woof-code/rootfs-petbuilds/rtclock/Makefile b/woof-code/rootfs-petbuilds/rtclock/Makefile new file mode 100644 index 00000000000..4b68648a02c --- /dev/null +++ b/woof-code/rootfs-petbuilds/rtclock/Makefile @@ -0,0 +1,21 @@ +CFLAGS ?= -O2 -Wall -pedantic +CLANG ?= clang +LLVM_STRIP ?= llvm-strip +LIBS = $(shell pkg-config --libs libbpf) +PREFIX = /usr/local + +rtclock: rtclock.c rtclock.skel.h + $(CC) $(CFLAGS) -o $@ $< $(LIBS) + +rtclock.skel.h: rtclock.bpf.o + bpftool gen skeleton $< > $@ + +rtclock.bpf.o: rtclock.bpf.c + $(CLANG) -g -O2 -Wall -target bpf -D__KERNEL__ -c $< -o $@ + $(LLVM_STRIP) -g $@ + +install: rtclock + install -D -m 755 $< $(DESTDIR)$(PREFIX)/bin/$< + +clean: + rm -f rtclock rtclock.skel.h rtclock.bpf.o diff --git a/woof-code/rootfs-petbuilds/rtclock/README.md b/woof-code/rootfs-petbuilds/rtclock/README.md new file mode 100644 index 00000000000..47524138124 --- /dev/null +++ b/woof-code/rootfs-petbuilds/rtclock/README.md @@ -0,0 +1,3 @@ +rtclock prevents connman from changing the hardware clock using eBPF, to prevent conflicts with other OSs running on the same machine that may save time in UTC rather than local time. + +When connman's clock_adjtime() calls get intercepted by rtclock, clock synchronization over NTP only sets the software clock. /etc/rc.d/rc.sysinit is responsible for synchronizing the software clock with RTC at boot time, so if RTC is set correctly (by another OS), the software clock will show the correct time even before network is ready. diff --git a/woof-code/rootfs-petbuilds/rtclock/petbuild b/woof-code/rootfs-petbuilds/rtclock/petbuild new file mode 100644 index 00000000000..2bf7ed553e0 --- /dev/null +++ b/woof-code/rootfs-petbuilds/rtclock/petbuild @@ -0,0 +1,7 @@ +download() { + : +} + +build() { + make install +} diff --git a/woof-code/rootfs-petbuilds/rtclock/rtclock.bpf.c b/woof-code/rootfs-petbuilds/rtclock/rtclock.bpf.c new file mode 100644 index 00000000000..fa986811202 --- /dev/null +++ b/woof-code/rootfs-petbuilds/rtclock/rtclock.bpf.c @@ -0,0 +1,22 @@ +#include + +#include + +#define STA_UNSYNC 0x0040 + +char LICENSE[] SEC("license") = "GPL"; + +SEC("tracepoint/syscalls/sys_enter_clock_adjtime") +int override_clock_adjtime(struct trace_event_raw_sys_enter *ctx) +{ + struct __kernel_timex ktx; + + if (bpf_probe_read_user(&ktx, sizeof(ktx), (void *)ctx->args[1]) < 0) { + return 0; + } + + ktx.status |= STA_UNSYNC; + bpf_probe_write_user((void *)ctx->args[1], &ktx, sizeof(ktx)); + + return 0; +} diff --git a/woof-code/rootfs-petbuilds/rtclock/rtclock.c b/woof-code/rootfs-petbuilds/rtclock/rtclock.c new file mode 100644 index 00000000000..c8786663c72 --- /dev/null +++ b/woof-code/rootfs-petbuilds/rtclock/rtclock.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include + +#include "rtclock.skel.h" + +int main(int argc, char *argv[]) +{ + sigset_t set; + struct rtclock_bpf *skel; + int sig; + + if (sigemptyset(&set) < 0 || sigaddset(&set, SIGTERM) < 0 || sigaddset(&set, SIGINT) < 0 || sigprocmask(SIG_BLOCK, &set, NULL) < 0) return EXIT_FAILURE; + + libbpf_set_strict_mode(LIBBPF_STRICT_ALL); + libbpf_set_print(NULL); + + if (!(skel = rtclock_bpf__open_and_load())) return EXIT_FAILURE; + + if (rtclock_bpf__attach(skel)) { + rtclock_bpf__destroy(skel); + return EXIT_FAILURE; + } + + daemon(0, 0); + sigwait(&set, &sig); + + rtclock_bpf__destroy(skel); + return EXIT_FAILURE; +} diff --git a/woof-code/rootfs-skeleton/etc/rc.d/rc.sysinit b/woof-code/rootfs-skeleton/etc/rc.d/rc.sysinit index d0da96dcd04..edfa7d35181 100755 --- a/woof-code/rootfs-skeleton/etc/rc.d/rc.sysinit +++ b/woof-code/rootfs-skeleton/etc/rc.d/rc.sysinit @@ -128,6 +128,7 @@ mount -t tmpfs -onosuid,noexec,size=10%,mode=755 tmpfs /run mount -t tmpfs -onodev,noexec,nosuid,size=20%,mode=1777 /run/lock mount -t proc -onodev,noexec,nosuid proc /proc mount -t sysfs -onodev,noexec,nosuid sysfs /sys +mount -t debugfs none /sys/kernel/debug mount -t pstore pstore /sys/fs/pstore [ -d /sys/firmware/efi/efivars ] && mount -t efivarfs none /sys/firmware/efi/efivars @@ -296,6 +297,7 @@ echo -n "Setting up services (network" >/dev/console hostname -F /etc/hostname busybox hwclock -s +rtclock mkdir -p /var/run/dbus chown messagebus /var/run/dbus diff --git a/woof-code/support/petbuilds.sh b/woof-code/support/petbuilds.sh index b3595c5456e..fa9d00bb96d 100644 --- a/woof-code/support/petbuilds.sh +++ b/woof-code/support/petbuilds.sh @@ -50,6 +50,8 @@ EOF chmod 755 petbuild-rootfs-complete/usr/bin/$PROG done + cp -f ../kernel-kit/output/vmlinux-*.h petbuild-rootfs-complete/usr/include/vmlinux.h + cp -f /etc/resolv.conf petbuild-rootfs-complete/etc/ HAVE_ROOTFS=1 diff --git a/woof-distro/x86_64/debian/trixie64/DISTRO_PKGS_SPECS-debian-trixie b/woof-distro/x86_64/debian/trixie64/DISTRO_PKGS_SPECS-debian-trixie index 90d7cf6e5fc..ec150fc456a 100644 --- a/woof-distro/x86_64/debian/trixie64/DISTRO_PKGS_SPECS-debian-trixie +++ b/woof-distro/x86_64/debian/trixie64/DISTRO_PKGS_SPECS-debian-trixie @@ -52,6 +52,7 @@ yes|locales|locales|exe,dev,doc,nls>exe||deps:yes yes|kmod|kmod|exe,dev,doc,nls||deps:yes yes|l3afpad|l3afpad|exe,dev,doc,nls||deps:yes yes|less|less|exe,dev>null,doc,nls||deps:yes +yes|libbpf-dev|libbpf-dev|exe,dev,doc,nls||deps:yes yes|libc6-dev|libc6-dev|exe,dev,doc,nls||deps:yes yes|libargon2-dev|libargon2-dev|exe,dev,doc,nls||deps:yes # needed by pfscrypt yes|libfreetype-dev|libfreetype-dev|exe,dev,doc,nls||deps:yes @@ -187,7 +188,9 @@ yes|automake|automake,autotools-dev|exe>dev,dev,doc>dev,nls>dev||deps:yes yes|autopoint|autopoint|exe>dev,dev,doc>dev,nls>dev||deps:yes yes|binutils|binutils|exe>dev,dev,doc>dev,nls>dev||deps:yes yes|bison|bison|exe>dev,dev,doc>dev,nls>dev||deps:yes +yes|bpftool|bpftool|exe>dev,dev,doc>dev,nls>dev||deps:yes yes|ccache|ccache|exe>dev,dev,doc>dev,nls>dev||deps:yes +yes|clang|clang|exe>dev,dev,doc>dev,nls>dev||deps:yes yes|cmake|cmake|exe>dev,dev,doc>dev,nls>dev||deps:yes # build-time dependency of hardinfo yes|dwarves|dwarves|exe>dev,dev,doc>dev,nls>dev||deps:yes # kernel-kit yes|flex|flex|exe>dev,dev,doc>dev,nls>dev||deps:yes @@ -200,6 +203,7 @@ yes|libelf-dev|libelf-dev|exe>dev,dev,doc>dev,nls>dev||deps:yes # kernel-kit yes|libtool|libtool,libtool-bin|exe>dev,dev,doc>dev,nls>dev||deps:yes yes|linux-header|linux-libc-dev|exe>dev,dev,doc>dev,nls>dev||deps:yes yes|linux-source|linux-source|exe>dev,dev,doc>dev,nls>dev||deps:yes # kernel-kit +yes|llvm|llvm|exe>dev,dev,doc>dev,nls>dev||deps:yes yes|m4|m4|exe>dev,dev,doc>dev,nls>dev||deps:yes yes|make|make|exe>dev,dev,doc>dev,nls>dev||deps:yes yes|meson|meson|exe>dev,dev,doc>dev,nls>dev||deps:yes diff --git a/woof-distro/x86_64/debian/trixie64/_00build.conf b/woof-distro/x86_64/debian/trixie64/_00build.conf index 689c4573e6e..69ebd55a1ba 100644 --- a/woof-distro/x86_64/debian/trixie64/_00build.conf +++ b/woof-distro/x86_64/debian/trixie64/_00build.conf @@ -8,7 +8,7 @@ # ## packages to build from source -PETBUILDS="aaa_pup_c gexec yad connman-puppy ram-saver fixmenusd spot-pkexec swaylock swayidle chayang spacefm mdview pup_advert_blocker" +PETBUILDS="aaa_pup_c gexec yad rtclock ram-saver fixmenusd spot-pkexec swaylock swayidle chayang spacefm mdview pup_advert_blocker" [ "$DISTRO_TARGETARCH" = "x86_64" ] && PETBUILDS="$PETBUILDS efilinux" if [ "$DISTRO_VARIANT" = "dwl" ]; then PETBUILDS="$PETBUILDS dwl foot-puppy yambar-dwl"