Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
0a269f3
libink: a brokerless D-Bus implementation for Finit
troglobit Aug 13, 2026
dd1390a
initctl: monitor and condition control over the bus
troglobit Aug 13, 2026
ebc0ef6
libink/finit: properties, and org.finit on the system bus
troglobit Aug 13, 2026
6310d9e
initctl: the status views over D-Bus
troglobit Aug 13, 2026
b55dada
libink: a message bus is not a peer
troglobit Aug 13, 2026
3499a5e
dbus: say why the system-bus attach failed
troglobit Aug 7, 2026
abab0e0
test: depserv waits for the transition to settle
troglobit Aug 7, 2026
c71ccce
libink: a broker peer is not an ordinary client
troglobit Aug 7, 2026
d710a23
dbus: gate the bus socket like INIT_SOCKET
troglobit Aug 7, 2026
63aabaa
libink/dbus: identify the caller behind a broker
troglobit Aug 13, 2026
1e508f9
libink: trace connections, calls, and authorization decisions
troglobit Aug 7, 2026
9875e76
dbus: let a dropped peer outlive its own read loop
troglobit Aug 13, 2026
2e0b1d6
plugin: start a system bus by default
troglobit Aug 12, 2026
127049d
test: Finit against a real dbus-daemon
troglobit Aug 12, 2026
44e7da6
dbus: policy comment predates the per-sender uid lookup
troglobit Aug 12, 2026
a1969ef
libink: broker state belongs to the connection that has a broker
troglobit Aug 12, 2026
853e226
libink/dbus: give parked and outstanding calls a deadline
troglobit Aug 13, 2026
bb43b56
libink: mark the big-endian gap where it is decided
troglobit Aug 12, 2026
f3c73f1
doc: Properties.Set is absent by design, not pending
troglobit Aug 12, 2026
5cc41b3
libink: take the match keys clients send without asking
troglobit Aug 12, 2026
c28acf2
test: fuzz target for the message parser
troglobit Aug 12, 2026
e62b463
.github: bump actions to node24
troglobit Aug 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 68 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,71 @@ concurrency:
cancel-in-progress: true

jobs:
fuzz:
name: fuzz
runs-on: ubuntu-latest
if: github.event_name != 'push' || github.ref == 'refs/heads/master'
steps:
- name: Install dependencies
run: |
sudo apt-get -y update
sudo apt-get -y install pkg-config libconfuse-dev clang
# clang picks the newest gcc tree it finds and needs the
# matching libstdc++ headers to link the fuzzer runtime
sudo apt-get -y install libstdc++-14-dev || true
wget https://github.com/troglobit/libuev/releases/download/v2.4.1/libuev-2.4.1.tar.xz
wget https://github.com/troglobit/libite/releases/download/v2.6.2/libite-2.6.2.tar.gz
tar xf libuev-2.4.1.tar.xz
tar xf libite-2.6.2.tar.gz
(cd libuev-2.4.1 && ./configure && make -j9 && sudo make install-strip)
(cd libite-2.6.2 && ./configure && make -j9 && sudo make install-strip)
sudo ldconfig
- uses: actions/checkout@v7
- name: Configure
run: |
./autogen.sh
./configure --prefix=/usr --exec-prefix= --sysconfdir=/etc --localstatedir=/var
- name: Build fuzz target
run: |
clang -fsanitize=fuzzer,address -DLINK_FUZZ_LIBFUZZER -D_GNU_SOURCE \
-I libink -I . -o fuzz-msg-parse \
test/src/fuzz-msg-parse.c libink/*.c
# Restores the newest corpus and saves a fresh one, since a cache
# entry is immutable once written. Caches made on a branch are
# private to it, so the corpus that accumulates on master is what
# pull requests start from, rather than nothing.
- name: Restore corpus
uses: actions/cache@v6
with:
path: .fuzz-corpus
key: fuzz-corpus-${{ github.run_id }}
restore-keys: fuzz-corpus-
- name: Fuzz
run: |
mkdir -p .fuzz-corpus
./fuzz-msg-parse .fuzz-corpus -max_total_time=120 -max_len=4096 \
-print_final_stats=1
# Without this the corpus only ever grows, and most of what it
# accumulates reaches code some earlier input already reached.
- name: Minimise corpus
if: always()
run: |
mkdir -p .fuzz-corpus-min
./fuzz-msg-parse -merge=1 .fuzz-corpus-min .fuzz-corpus
rm -rf .fuzz-corpus
mv .fuzz-corpus-min .fuzz-corpus
echo "corpus: $(ls .fuzz-corpus | wc -l) inputs"
- name: Upload crashers
if: failure()
uses: actions/upload-artifact@v7
with:
name: fuzz-crashers
path: |
crash-*
leak-*
timeout-*
if-no-files-found: ignore

build:
# Verify we can build on latest Ubuntu with both gcc and clang
name: ${{ matrix.compiler }}
Expand All @@ -42,7 +107,7 @@ jobs:
(cd libuev-2.4.1 && ./configure && make -j9 && sudo make install-strip)
(cd libite-2.6.2 && ./configure && make -j9 && sudo make install-strip)
sudo ldconfig
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Static Finit
run: |
./autogen.sh
Expand All @@ -52,7 +117,7 @@ jobs:
run: |
./configure --prefix=/usr --exec-prefix= --sysconfdir=/etc --localstatedir=/var \
--enable-x11-common-plugin --enable-testserv-plugin --with-watchdog \
--with-keventd --with-libsystemd \
--with-keventd \
CFLAGS="-fsanitize=address -ggdb"
make -j9 clean
make -j9 V=1
Expand Down Expand Up @@ -80,7 +145,7 @@ jobs:
make -j1 check || (cat test/test-suite.log; false)
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: finit-test-${{ matrix.compiler }}
path: test/*.log
6 changes: 3 additions & 3 deletions .github/workflows/coverity.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
coverity:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Fetch latest Coverity Scan MD5
id: var
env:
Expand All @@ -29,7 +29,7 @@ jobs:
--post-data "token=$TOKEN&project=${COVERITY_PROJ}&md5=1" \
-O coverity-latest.tar.gz.md5
echo "md5=$(cat coverity-latest.tar.gz.md5)" | tee -a $GITHUB_OUTPUT
- uses: actions/cache@v4
- uses: actions/cache@v6
id: cache
with:
path: coverity-latest.tar.gz
Expand Down Expand Up @@ -86,7 +86,7 @@ jobs:
--form description="${PROJECT_NAME} $(git rev-parse HEAD)" \
https://scan.coverity.com/builds?project=${COVERITY_PROJ}
- name: Upload build.log
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: coverity-build.log
path: cov-int/build-log.txt
10 changes: 5 additions & 5 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
fetch-depth: 0 # Needed for git-revision-date-localized plugin

Expand All @@ -42,7 +42,7 @@ jobs:
echo "version=$version" >> $GITHUB_OUTPUT

- name: Setup Python
uses: actions/setup-python@v4
uses: actions/setup-python@v7
with:
python-version: '3.x'

Expand All @@ -58,7 +58,7 @@ jobs:
run: mkdocs build --clean

- name: Upload site artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: site
path: site/
Expand All @@ -72,13 +72,13 @@ jobs:

steps:
- name: Download site artifact
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
name: site
path: site/

- name: Checkout pages repo
uses: actions/checkout@v4
uses: actions/checkout@v7
with:
repository: finit-project/finit-project.github.io
path: pages
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Installing dependencies ...
run: |
sudo apt-get -y update
Expand Down Expand Up @@ -64,7 +64,7 @@ jobs:
mv ../*.tar.* artifacts/
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: finit-release-test-logs
path: finit-*/_build/sub/test/*.log
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/weekly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
outputs:
run: ${{ steps.schedule.outputs.run }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Check for any commits since last week
id: schedule
run: |
Expand All @@ -42,7 +42,7 @@ jobs:
(cd libuev-2.4.1 && ./configure && make -j9 && sudo make install-strip)
(cd libite-2.6.2 && ./configure && make -j9 && sudo make install-strip)
sudo ldconfig
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- name: Base run
run: |
./autogen.sh
Expand All @@ -61,7 +61,7 @@ jobs:
make -j1 distcheck || (cat $dir/test/test-suite.log; false)
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: finit-weekly-test-logs
path: finit-*/_build/sub/test/*.log
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,8 @@ GTAGS

# VS Code user settings
.vscode

# Fuzzing: the target is built by hand with clang, see doc/build.md,
# and the corpus it grows is a local artefact, not something to ship
/fuzz-msg-parse
/.fuzz-corpus/
20 changes: 19 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = man plugins src system tmpfiles.d

# libink must precede src in SUBDIRS because finit links against
# libink at build time. Automake recurses subdirs strictly in
# declaration order, so the typical "explicit dependency" pattern
# (foo: bar) doesn't help here — ordering is the only thing that
# does. libsystemd is consumed by test/serv only, so its position
# after src is fine.
SUBDIRS = man plugins
if DBUS
SUBDIRS += libink dbus-1
endif
SUBDIRS += src system tmpfiles.d
dist_doc_DATA = README.md LICENSE contrib/finit.conf

if CONTRIB
Expand All @@ -24,6 +35,13 @@ endif
install-dev:
@make -C src install-pkgincludeHEADERS

# The fuzz target is built by hand with clang (doc/build.md), so it is
# not in any _PROGRAMS and nothing else would clear it or the corpus
# it grows.
distclean-local:
-rm -f $(top_builddir)/fuzz-msg-parse
-rm -rf $(top_builddir)/.fuzz-corpus

# Target to run when building a release
release: distcheck
@for file in $(DIST_ARCHIVES); do \
Expand Down
17 changes: 14 additions & 3 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ AC_CONFIG_FILES([Makefile
contrib/debian/Makefile contrib/debian/finit.d/Makefile contrib/debian/finit.d/available/Makefile
contrib/void/Makefile contrib/void/finit.d/Makefile contrib/void/finit.d/available/Makefile
doc/Makefile doc/config/Makefile
dbus-1/Makefile
libink/Makefile
libsystemd/Makefile libsystemd/libsystemd.pc
man/Makefile
plugins/Makefile
Expand Down Expand Up @@ -94,6 +96,10 @@ AC_ARG_ENABLE(logrotate,
AS_HELP_STRING([--disable-logrotate], [Disable built-in rotation of /var/log/wtmp]),,[
enable_logrotate=yes])

AC_ARG_ENABLE(dbus,
AS_HELP_STRING([--disable-dbus], [Disable D-Bus support (libink + Finit object tree)]),,[
enable_dbus=yes])

AC_ARG_ENABLE(doc,
AS_HELP_STRING([--disable-doc], [Disable build and install of doc/ section]),,[
enable_doc=yes])
Expand All @@ -111,7 +117,7 @@ AC_ARG_ENABLE(all_plugins,
AS_HELP_STRING([--enable-all-plugins], [Enable all plugins, default: auto]),
enable_all_plugins=$enableval, enable_all_plugins=auto)
AC_PLUGIN([alsa-utils], [no], [Save and restore ALSA sound settings using alsactl])
AC_PLUGIN([dbus], [no], [Setup and start system message bus, D-Bus])
AC_PLUGIN([dbus], [yes], [Setup and start system message bus, D-Bus])
AC_PLUGIN([modules-load], [no], [Scans /etc/modules-load.d for modules to load])
AC_PLUGIN([modprobe], [no], [Coldplug modules using modalias magic])
AC_PLUGIN([resolvconf], [no], [Setup necessary files for resolvconf])
Expand Down Expand Up @@ -155,7 +161,7 @@ AC_ARG_WITH(sysconfig,
[sysconfig=$withval], [sysconfig=default])

AC_ARG_WITH(group,
AS_HELP_STRING([--with-group=NAME], [Group for /run/finit/socket (initctl), default: root]),
AS_HELP_STRING([--with-group=NAME], [Group for /run/finit/socket and /run/finit/bus, default: root]),
[group=$withval], [group=root])

AC_ARG_WITH(hostname,
Expand Down Expand Up @@ -243,6 +249,10 @@ AS_IF([test "x$enable_rescue" != "xno"], [

AM_CONDITIONAL(LOGROTATE, [test "x$enable_logrotate" = "xyes"])

AS_IF([test "x$enable_dbus" = "xyes"], [
AC_DEFINE(HAVE_DBUS, 1, [Build D-Bus support via libink])])
AM_CONDITIONAL(DBUS, [test "x$enable_dbus" = "xyes"])

### With features ##############################################################################
AS_IF([test "x$bash_dir" = "xyes"], [
PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0],
Expand Down Expand Up @@ -288,7 +298,7 @@ AS_IF([test "x$with_heading" != "xno"], [
AS_IF([test "x$with_group" != "xno"], [
AS_IF([test "x$group" = "xyes"], [
group=root])])
AC_DEFINE_UNQUOTED(DEFGROUP, "$group", [For /run/finit/socket])
AC_DEFINE_UNQUOTED(DEFGROUP, "$group", [For /run/finit/socket and /run/finit/bus])

AS_IF([test "x$with_hostname" != "xno"], [
AS_IF([test "x$hostname" = "xyes"], [
Expand Down Expand Up @@ -438,6 +448,7 @@ Optional features:
Built-in sulogin......: $with_sulogin $sulogin
Built-in watchdogd....: $with_watchdog $watchdog
Built-in logrotate....: $enable_logrotate
D-Bus support (libink): $enable_dbus
Replacement libsystemd: $with_libsystemd
Use cgroup v2.........: $enable_cgroup
Use libcap............: $enable_libcap
Expand Down
2 changes: 2 additions & 0 deletions dbus-1/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/Makefile
/Makefile.in
6 changes: 6 additions & 0 deletions dbus-1/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
EXTRA_DIST = org.finit.conf

if DBUS
dbuspolicydir = $(sysconfdir)/dbus-1/system.d
dist_dbuspolicy_DATA = org.finit.conf
endif
63 changes: 63 additions & 0 deletions dbus-1/org.finit.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<!--
System-bus policy for finit.

finit (PID 1, root) owns the `org.finit` well-known name. The
policy below lets unprivileged callers introspect, read
properties, and query service / condition state, but disallows
every state-changing method at the broker. finit *also* enforces
per-method authorisation itself (LINK_METHOD_PRIVILEGED), so
defense-in-depth: even if a permissive policy is installed by
mistake, finit rejects unprivileged state changes. It reads the
caller from SO_PEERCRED on the local bus, and on the system bus it
asks the broker who sent each privileged call, via
GetConnectionUnixUser.
-->
<busconfig>

<!-- Only finit (root) may own the org.finit bus name. -->
<policy user="root">
<allow own="org.finit"/>
<allow send_destination="org.finit"/>
<allow receive_sender="org.finit"/>
</policy>

<!-- Everyone may introspect, read properties, and call the
read-only Manager1 / Cond1 methods. Signals fan out
unconditionally. -->
<policy context="default">
<allow send_destination="org.finit"
send_interface="org.freedesktop.DBus.Introspectable"/>
<allow send_destination="org.finit"
send_interface="org.freedesktop.DBus.Peer"/>
<allow send_destination="org.finit"
send_interface="org.freedesktop.DBus.Properties"
send_member="Get"/>
<allow send_destination="org.finit"
send_interface="org.freedesktop.DBus.Properties"
send_member="GetAll"/>

<allow send_destination="org.finit"
send_interface="org.finit.Manager1"
send_member="ListServices"/>
<allow send_destination="org.finit"
send_interface="org.finit.Manager1"
send_member="GetService"/>

<allow send_destination="org.finit"
send_interface="org.finit.Cond1"
send_member="Get"/>
<allow send_destination="org.finit"
send_interface="org.finit.Cond1"
send_member="List"/>
<allow send_destination="org.finit"
send_interface="org.finit.Cond1"
send_member="Dump"/>

<allow receive_sender="org.finit"/>
</policy>

</busconfig>
Loading