Commit Graph
19063 Commits
Author SHA1 Message Date
Commentator2.0andpiegames 8c857790a3 lix/code-generation: clean up code properly
The code within the code-generation had tons of code-duplicates and was
overall quite meh to read, understand and expand.

This commit refactors the code-generation to make it more readable and
comprehensible, while also unifying its usage a bit more

Change-Id: I3a5df8b7d8d9b6c76e02ef47dfb151c7dab7d0ab
2026-01-31 15:32:27 +01:00
eldritch horrors 279926d215 meson: merge libs
lix, where modularity is made up and the patterns don't matter. merging
everything to match actual behavior of the system makes using rust much
easier because we'll have only *one* library to link, not half a dozen.

Change-Id: Ie3cb1db659798511128716402497697320bd0484
2026-01-30 17:29:51 +00:00
eldritch horrors 2e0cc67ec8 libstore: start pasta much earlier
starting pasta as soon as we have all namespaces it must be in available
lets it start up while we finish creating the sandbox. this may speed up
sandbox launches somewhat, but likely not enough to show up in practice.

Change-Id: Id6724cbdc48b99284cd7ba7b56c98829d74557c5
2026-01-30 00:29:27 +00:00
eldritch horrors a2500db977 libstore: remove unnecessary linux-specific RunOptions
Change-Id: I07303c2aea78cf9f17b89b5cea922271ce26f029
2026-01-30 00:29:27 +00:00
eldritch horrors d43c6dd100 libstore: use raw syscall for inVFork setgroups
Change-Id: Ia656d2697b883d2b058984787556915b34f44211
2026-01-30 00:29:27 +00:00
eldritch horrors ab4f8718f9 libstore: start pasta from a vfork child
mostly as a prototype for other process launching optimizations, but
also to move linux-only bits out of runProgram2. we want to stop the
fork+exec dance we do now and migrate to posix_spawn, but linux will
always need an amount special handling for launching build children.

Change-Id: Ied55dc0de95c05b52aaca923be2e3c1d101f47e0
2026-01-30 00:29:05 +00:00
eldritch horrors b6c8f412a2 libstore: generalize linux vfork infra to also allow exec'ing
we'll use this to run programs from a vforked child instead of using
runProgram. ideally we would like to have runProgram be as efficient
as possible, but our mount namespace handling makes this harder than
is worth dealing with right now. the linux derivation goal is a good
place to prototype functionality like this, especially since we need
fine control over credentials and file descriptor tables of children

Change-Id: Ibc356613ae10b06ea81de9575611948f5ee353b6
2026-01-29 19:00:56 +01:00
eldritch horrors 05fed0687d libstore: add processes to cgroups earlier
this was racy previously; a builder may have spawned processes before we
added it to a cgroup. these processes would not be registered correctly.

Change-Id: If60a64a798ee806d5701590a83d1015f55d7b867
2026-01-28 18:49:02 +01:00
eldritch horrors b23bbd5b19 libstore: fix personality setting for unsandboxed linux builds
oops. this was supposed to always happen on function exit.

Change-Id: I25465b4248c33389ca7e70b2a0b52dcc10d86a38
2026-01-28 18:49:02 +01:00
eldritch horrors 56988d8605 libstore: use vfork for linux sandbox launch wrappers
this halves sandbox launch overhead, reducing the build time for 3000
trivial runCommand derivations on our machine from 80 seconds to 44s.
as a nice side effect we also get better error message propagation in
some cases, most notably setgroups failing when run in lix sandboxes.

Change-Id: Ia7c50a844915d9b8a20475b90b2d0179fd2fff34
2026-01-28 15:01:13 +00:00
eldritch horrors bf3d4e8721 libstore: simplify user/net namespace setup
creating user namespaces early means we don't need pipes to signal that
a namespace has been created and set up. we'll also create the netns at
the same time because they're privilege-bound to the userns, and having
both available will let us launch pasta earlier to have it ready sooner

Change-Id: Ie66fe2ab7f50a520fb81dd90944384e168d94476
2026-01-28 15:00:55 +00:00
eldritch horrors c9fe3befc1 libstore: add vfork infra to linux platform bits
vfork can be a lot faster than fork on linux, and we want to use it.

Change-Id: If1665d3c49e525f2722b1e040cd7058f376bd20e
2026-01-28 15:00:43 +00:00
eldritch horrors 7e8f7d0e66 libstore: set up linux sandbox /etc earlier
permissions and ownership will be the same since the sandbox process
will not have changed uid/gid or umask by the time it gets around to
writing these files. all of these files contain some information the
host must provide, be it contents or configuration info of some kind

Change-Id: I0b57cb0699fd29e798ccf330dff99f571f3c0692
2026-01-28 12:41:26 +01:00
eldritch horrors 7d3dde851a libstore: make runPasta a function of LinuxLocalDerivationGoal
this way we can use it anywhere without fear of it being uninitialized.
only the linux platform bit uses this anyway, so we will move it there.

Change-Id: I35e207eec91daa8aa327c4f8b36c0dc8e703a7c4
2026-01-28 12:41:26 +01:00
eldritch horrors bd458f9f89 libstore: make privateNetwork a function of LinuxLocalDerivationGoal
it's only used there, and this avoids using it uninitialized.

Change-Id: I6bd84e3c441dc6750e8ab07822f896136586cd66
2026-01-28 12:41:26 +01:00
Raito Bezarius 57373cba6f nix/daemon: receive supplementary groups on macOS/FreeBSD
`xucred` already contain `cr_ngroups` and `cr_groups`, we just have to
use it properly.

Change-Id: Ic29b4c551f9d93e86e9ed2bef20889d27d5438f4
Signed-off-by: Raito Bezarius <raito@lix.systems>
2026-01-28 08:24:24 +00:00
Raito BezariusandTom Hubrecht c493fb668e nix/daemon: consider supplementary groups during authentication
Two things happens here:

- we consider supplementary groups that are known for authentication,
fixes #968.

- we check supplementary groups if they are our build users group and
throw an error if they are (new behavior).

Nonetheless, we did not remove the ability for `matchUser` to recurse
and check for groups that the user may have but the connection might not
have communicated as part of their groups, i.e. if a process reduces its
list of groups via a call to setgroups, it will still be authorized.
This will come in another commit.

The authorization NixOS test has been extended with a store ping test
running in systemd with DynamicUser=true *AND* a supplementary group in
allowed-users.

Co-authored-by: Tom Hubrecht <github@mail.hubrecht.ovh>
Change-Id: I25b2b8304d66a04651cea523b5585a5d15ceebe8
Signed-off-by: Raito Bezarius <raito@lix.systems>
2026-01-28 08:24:24 +00:00
Raito Bezarius 9e55dd6b8f nix/daemon: receive supplementary groups on Linux
On Linux, SO_PEERGROUPS is an option introduced in 2017, that is, in
Linux 4.13.

Thankfully, Lix targets 5.10+ kernels minimum.

It was chosen to allocate 128 gids by default and ramp up (2x) as needed
rather than allocate a full 65k of integers as it seems wasteful. I bet
the time to the 16 allocations should incur at most an additional
millisecond on a modern system, don't quote me on that though.

This is preparation to enable ability for the daemon to vet based on
supplementary groups.

Related to #968.

Suggested-by: alois31
Suggested-by: eldritch horrors
Change-Id: I26d698327db5d174bf70ca25b0afede132bd9169
Signed-off-by: Raito Bezarius <raito@lix.systems>
2026-01-28 08:24:09 +00:00
Raito Bezarius dbb3edcfea nix/daemon: clean up PeerInfo
Rather than a bunch of booleans, use optional<T> as a way to convey that
the identifier is known or not.

This is preparatory work for SO_PEERGROUP usage.

Change-Id: I0e3ce69e4103f9df5a2161c695bfc650123c1549
Signed-off-by: Raito Bezarius <raito@lix.systems>
2026-01-28 09:20:57 +01:00
eldritch horrors 986191534e libstore: allow config loading without a home dir set
we can already handle this case (by forbidding any ~/... paths in option
values), and since builtin builders are now run via exec we may not have
a home dir set, or even available, for them to resolve. loading a config
file in this situation will fail with an error even if the config is ok.

fixes #1109

Change-Id: I3491b31558871faa34766462747e3c15d1eccc64
2026-01-27 17:13:07 +01:00
eldritch horrors ef8a6cc5f5 libutil: add tryGetHome that doesn't throw on errors
Change-Id: Ib5bcb277e39093b303fe4a66a8903a7c5692f305
2026-01-27 17:13:07 +01:00
Raito Bezarius e083a68a9f libstore/linux: forbid xattrs syscalls
xattrs are revealing some unfortunate brittleness in real world
derivations that are getting -EINVAL errors while executing their test
code.

The reason for this is that Linux checks [1] UID delegations for xattrs
writes.

In the Lix sandbox, except if you enabled a uid-range feature, you have
exactly 3 UIDs: root, nixbld and nobody.

If your test code makes use of UIDs which have not been delegated, you
will receive an EINVAL on your operation. Test code is not resilient
with respect to the number of available UIDs in their namespace.

To avoid further issues for end users who are running into spurious
derivation build failures, we forbid xattrs again for now.

For more information about the plans, please consult or chime in [2].

Fixes #1105. Reopens #838. Fixes #1103.

[1]: https://elixir.bootlin.com/linux/v6.18.6/source/fs/posix_acl.c#L257
[2]: https://zulip.lix.systems/#narrow/channel/9-Store/topic/disablement.20of.20xattrs/with/5295

Change-Id: I864066b34cd8319d2271fac1b179cb4f950d836e
Signed-off-by: Raito Bezarius <raito@lix.systems>
2026-01-26 18:54:51 +00:00
eldritch horrors cfabc37828 libstore: add unix:// uri protocol argument
Change-Id: I7fc27926aa1d89e2190b1deb0252ad33f2b364a5
2026-01-26 18:17:07 +00:00
eldritch horrors bdc220b8ec libstore: allow for multiple daemon sockets with preference
this will let us configure more than one socket to connect/bind to,
which in turn lets us use posix acls on sockets for access control.
we will also need something like this for the final rpc transition.

Change-Id: I9c39f14906e9bf809055ab5c94bf687745b4f69e
2026-01-26 18:17:07 +00:00
eldritch horrors f4458b8e46 libstore: simplify netrc, cafile loading for builtin builders
Change-Id: I8370a1434729c7ff2e44ddbaf173d7068e8ace9f
2026-01-25 19:47:24 +01:00
eldritch horrors 99d674b785 libstore: despecialize sandbox launching
now that builtin builders are regular executables we no longer need to
treat them specially during sandbox launch itself, only while we build
the command line and environment for the sandboxed process. we are not
far from being able to extract platform-dependent sandbox launch code,
ideally moving all of it into (much more replaceable) libexec helpers.

Change-Id: I9b7041314683c56cd70eec9b1b4eae6de228883f
2026-01-25 19:43:13 +01:00
eldritch horrors 049c7b3369 libstore: move the builtin builders to our new executable
this means that builtinFetchurl runs in a real process now, and thus we
no longer need its workarounds for running in a forked process. forking
dropped the signal handler thread and broke the curl state via sharing,
neither of which happens any more now. we can run fetchurl builtins and
their actions straight from the main thread of our builder now, and the
temporary files and settings overrides we did are now also unnecessary.

Change-Id: I738171bc120ffcd541b7ff1424fed7924c2cdc1d
2026-01-25 19:31:38 +01:00
eldritch horrors 58c3ee4c8e builtin-builder: remove unescapeNul that snuck back in
fuck

Change-Id: I5d203fc36c4a2eb2aefde9208d6cefd3619cdf03
2026-01-25 19:30:10 +01:00
eldritch horrors 5abf26a19f add a builtin-builder command for ... builtin builders
this will let us migrate the fork+do_stuff combo of builtin builders we
have today to fork+exec of this new command. we use a subcommand rather
than a simple libexec helper because we would like to avoid linking all
of lix into the simple libexec helpers if possible. this is only hookup
for the builders, none of the buiders are migrated here to ease review.

Change-Id: I9358f1f3fee6ca640c81a7bd865128ae0d0e35a5
2026-01-25 17:26:39 +00:00
eldritch horrors c50a3a426f libutil: add simple NUL escaping/unescaping functions
Change-Id: Ia4cc7b8f1058439f312066422eebfaff1c2c0c6c
2026-01-25 17:29:32 +01:00
eldritch horrors ed6a1e58ea libstore: don't call builtin builders with derivations
call them with their individual parameters instead. this will make it
much easier to turn them into executables we can exec in the sandbox.

Change-Id: Ib49cf44715b2a480fecadabd21216c69cd730ef5
2026-01-25 15:34:59 +01:00
eldritch horrors 21e8347bb6 libstore: make netrc/cafile child args plain strings again
not having the optionals set when the builder runs (e.g. because FOD
hashes were not configured correctly) could cause assertion failures
in the builder process. while this should usually not happen we *do*
want to print a useful error message here instead of a crash report.

Change-Id: I81fb1d45fcbf660d0d9a7f0c0a12c38379ecd4c6
2026-01-25 15:34:59 +01:00
rootile 2f7644c420 tests/functional2: fix wrong usage of env var
Change-Id: I37580e0d74e26e064261c98a1162fbd9e23a9d46
2026-01-23 16:15:55 +01:00
Rebecca Turnerandrootile cb34b56fea tests/functional2: Fix Python LSP by adjusting imports
See: cl/4840

When importing Python modules, we include `functional2` in the module
path, like this:

    from functional2.testlib.fixtures.env import ManagedEnv

This means that python expects to see a file like
`functional2/testlib/fixtures/env.py`. We run `pytest` from `tests/` in
the `justfile` and have `tests/functional2/__init__.py` so `pytest` in
`meson` is able to find these imports.

However, language servers generally consider the `pyproject.toml` to be
the project root, so (e.g.) `pyright` is unable to follow any of the
`functional2` imports, leading to lots of spurious errors.

In cl/4840 I moved `tests/functional2/pyproject.toml` to
`tests/pyproject.toml`, which worked but was considered aesthetically
unappealing.

This diff is much larger but it's a more elegant solution.

Change-Id: I2983c7b87f88f59a4e3521451a9f5acd6a6a6964
2026-01-23 15:06:51 +01:00
eldritch horrors 0453be06b6 libutil: remove unused RunOptions::{chdir, createSession}
Change-Id: Ib2b9f5c094233661a01ad8cea30a44e11931c941
2026-01-22 16:59:39 +01:00
eldritch horrors b5a25f0fb6 libstore: move build hook launching to libexec helper
like diff hooks before the build hooks also use runProgram features that
aren't present in posix_spawn. just like diff hooks we do not expect the
build hook processes to be so fast that launch overhead matters somehow.

Change-Id: If3c33dbd7d2ac20c95886e06d24feda312946c78
2026-01-22 16:59:37 +01:00
eldritch horrors a7f4a675b6 libutil: remove Pid::setSeparatePG
use a wrapper type instead. whether something should be treated as a
single process or a group is a type decision more than a runtime one

Change-Id: I966e998c19e74be64ddd72ab11af809d001f61b5
2026-01-22 16:57:26 +01:00
eldritch horrors 0b03ae1a13 libutil: remove unused Pid::{killSignal, setKillSignal}
Change-Id: Ic7cceef2d82a98cf8fe23260603b1262c097cad4
2026-01-22 15:23:38 +00:00
eldritch horrors 5351518c75 libstore: add a diff hook helper libexec binary
diff hooks use uid/gid switch functionality that is otherwise only
needed for linux sandbox setup and unsupported by posix_spawn. not
doing these switches inside lix core code may let us move to using
posix_spawn for most process launching in the future, and for diff
hooks the added overhead of a wrapper program really does not hurt
at all. diff hooks are expected to be expensive in terms of output
size, process launch overhead is not likely to even be noticeable.

Change-Id: Ifa4b3eedef237632db3eb88d10e6469acae01f9e
2026-01-22 15:23:38 +00:00
eldritch horrors d7b0d322f7 libstore: make diff-hooks work for non-root users
it's kind of weird to not allow diff-hooks in single user mode unless
that user is root. maybe that's why we have no tests for them? we can
at least add a test that diff hooks are run at all when we expect it.

Change-Id: I54d623b5416acda1c205cc062b0f3a33c9f4aaa7
2026-01-22 15:23:38 +00:00
eldritch horrors 36168de584 libutil: remove {Process,Run}Options::dieWithParent
nothing except the linux sandbox actually *needs* this for correctness.
the linux sandbox only uses it to ensure that builder uids are freed up
when the sandbox is torn down, and even *then* it only works as we need
it to with PID namespaces enabled since the parent death signals is not
inherited across fork, but when pid1 of a pid namespace dies the kernel
also kills all namespace members. in all other cases this flag does not
help us that much because it actively prevents child processes cleaning
up after themselves, possibly leaving more trash around than otherwise.

Change-Id: I9ae0a9e91833a91d1011375dda402ac6c0a7ef6f
2026-01-22 15:23:38 +00:00
Raito BezariusandNiko Klanecek 728d2bfee7 contrib/plugins: add mTLS binary cache store plugin
Adds an example plugin implementing an mTLS-enabled binary cache store
(https+mtls:// scheme) using client certificates for authentication.

Darwin fix: don't link liblix* into plugins (host resolves symbols at
runtime via dynamic_lookup). Explicitly link curl so it binds to
Nix-store libcurl, not /usr/lib/libcurl. This prevents the plugin's
curl_easy_setopt calls from operating on the wrong libcurl instance.

Test portability: BSD sed -i wrapper, OpenSSL -sha256 for cert signing,
redirect test server output to log file.

Change-Id: I652b987d3ac45e31df50ff4ba1f523294438c2b6
2026-01-21 22:50:35 +00:00
eldritch horrors 7068cbf010 libstore: extract env and args rewriting from child
this really doesn't have to be here, it doesn't help very much. doing it
in the parent is cheap enough to not care and sandbox setup is not async
yet *anyway*, so we would not even notice if the old way was any faster.

Change-Id: I5a3a99af0fa5928e9a42f9c6589d98ff38b8c775
2026-01-21 15:59:30 +01:00
eldritch horrors 6da0389d0f libstore: move netrc/ca init outside of the build child process
this will make it easier to turn build sandbox processes into helpers.
the point they were at was effectivly unsandboxed except for a few fds
that were redirected by commonExecveingChildInit, which only made logs
of any errors that much harder to convey from the child to the parent.

Change-Id: I67006eb33e1e13311bb8d14e6a0c3d5e6baf0c13
2026-01-21 15:59:30 +01:00
eldritch horrors 5ba9a3961c libstore: move setupSyscallFilter to linux platform bits
setting them that little bit later really doesn't hurt us at all.

Change-Id: I6b50fbe0b58d037de729748cb4f87dd628bd111b
2026-01-21 15:59:30 +01:00
eldritch horrors 95c65ce637 libstore: move setPersonality to linux platform
it doesn't do anything anywhere else, and personality setup is not a
critical operation (all it does is change which arch uname returns).

Change-Id: I39d7fcc4916e6882e49191d2294f9b7ee0dbbcd0
2026-01-21 15:59:30 +01:00
eldritch horrors 6edbef7338 libstore: move some macos-specific bits to platform
Change-Id: I9236ffb8e098d09215067b872b5da5e210557815
2026-01-21 15:59:30 +01:00
eldritch horrors c39488d2a4 libstore: move some linux-specific child setup to platform code
best viewed with --color-moved --color-moved-ws=all

Change-Id: I3738f07fd0b39498abf253967906270dc0b215f4
2026-01-21 15:59:30 +01:00
eldritch horrors 113c6fd618 libstore: reformat bits of LocalDerivationGoal
mathbb overbar sigh

Change-Id: I9b5361ba03ff11a89773f7da2262d38fbf39b7af
2026-01-21 15:59:30 +01:00
eldritch horrors 3937eb9ecc libstore: open builder log pty in parent
there's no need to do it in the fork, we're not changing security
domains before opening the pty anyway. we do change who owns this
pty device, but since we change it via chown we can just *not* do
that before we have an open fd to the pty. in practice this isn't
even necessary because the daemon runs as root, but if we ever do
run the daemon as an unprivileged user we'd need this to be split

Change-Id: I35264ab2954c7ba2c9c24c927366d64acada6772
2026-01-21 15:59:30 +01:00