Merge staging-next into staging

This commit is contained in:
nixpkgs-ci[bot] 2025-06-24 18:06:44 +00:00 committed by GitHub
commit 367477b054
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
77 changed files with 5477 additions and 355 deletions

View File

@ -49,7 +49,7 @@ jobs:
mergedSha: ${{ inputs.mergedSha }}
merged-as-untrusted: true
- uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
- uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
with:
extra_nix_config: sandbox = true

View File

@ -59,7 +59,7 @@ jobs:
merged-as-untrusted: true
target-as-trusted: true
- uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
- uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
- uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
with:
@ -107,7 +107,7 @@ jobs:
name: Request
runs-on: ubuntu-24.04-arm
steps:
- uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
- uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
# Important: Because we use pull_request_target, this checks out the base branch of the PR, not the PR head.
# This is intentional, because we need to request the review of owners as declared in the base branch.

View File

@ -46,7 +46,7 @@ jobs:
path: untrusted
- name: Install Nix
uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
with:
extra_nix_config: sandbox = true
@ -166,7 +166,7 @@ jobs:
path: trusted
- name: Install Nix
uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
with:
extra_nix_config: sandbox = true
@ -243,7 +243,7 @@ jobs:
merged-as-untrusted: true
- name: Install Nix
uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
with:
extra_nix_config: sandbox = true

View File

@ -29,7 +29,7 @@ jobs:
mergedSha: ${{ inputs.mergedSha }}
merged-as-untrusted: true
- uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
- uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
with:
extra_nix_config: sandbox = true
@ -61,7 +61,7 @@ jobs:
mergedSha: ${{ inputs.mergedSha }}
merged-as-untrusted: true
- uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
- uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
with:
extra_nix_config: sandbox = true
@ -86,7 +86,7 @@ jobs:
targetSha: ${{ inputs.targetSha }}
target-as-trusted: true
- uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
- uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
with:
extra_nix_config: sandbox = true

View File

@ -35,7 +35,7 @@ jobs:
sparse-checkout: ci
- name: Install Nix
uses: cachix/install-nix-action@17fe5fb4a23ad6cbbe47d6b3f359611ad276644c # v31
uses: cachix/install-nix-action@f0fe604f8a612776892427721526b4c7cfb23aba # v31
with:
extra_nix_config: sandbox = true

View File

@ -27506,6 +27506,11 @@
github = "yanganto";
githubId = 10803111;
};
yannham = {
github = "yannham";
githubId = 6530104;
name = "Yann Hamdaoui";
};
yannickulrich = {
email = "yannick.ulrich@proton.me";
github = "yannickulrich";

View File

@ -45,6 +45,7 @@ lpeg,,,,,,vyp
lpeg_patterns,,,,,,
lpeglabel,,,,1.6.0,,
lrexlib-gnu,,,,,,
lrexlib-oniguruma,,,,,,junestepp
lrexlib-pcre,,,,,,vyp
lrexlib-posix,,,,,,
lsp-progress.nvim,,,,,,gepbird

1 name rockspec ref server version luaversion maintainers
45 lpeg_patterns
46 lpeglabel 1.6.0
47 lrexlib-gnu
48 lrexlib-oniguruma junestepp
49 lrexlib-pcre vyp
50 lrexlib-posix
51 lsp-progress.nvim gepbird

View File

@ -630,6 +630,7 @@ with lib.maintainers;
leona
theCapypara
thiagokokada
jamesward
];
shortName = "Jetbrains";
scope = "Maintainers of the Jetbrains IDEs in nixpkgs";

View File

@ -42,6 +42,8 @@
- [Szurubooru](https://github.com/rr-/szurubooru), an image board engine inspired by services such as Danbooru, dedicated for small and medium communities. Available as [services.szurubooru](#opt-services.szurubooru.enable).
- The [Neat IP Address Planner](https://spritelink.github.io/NIPAP/) (NIPAP) can now be enabled through [services.nipap.enable](#opt-services.nipap.enable).
- [nix-store-veritysetup](https://github.com/nikstur/nix-store-veritysetup-generator), a systemd generator to unlock the Nix Store as a dm-verity protected block device. Available as [boot.initrd.nix-store-veritysetup](options.html#opt-boot.initrd.nix-store-veritysetup.enable).
- [SuiteNumérique Docs](https://github.com/suitenumerique/docs), a collaborative note taking, wiki and documentation web platform and alternative to Notion or Outline. Available as [services.lasuite-docs](#opt-services.lasuite-docs.enable).

View File

@ -1618,6 +1618,7 @@
./services/web-apps/nextjs-ollama-llm-ui.nix
./services/web-apps/nexus.nix
./services/web-apps/nifi.nix
./services/web-apps/nipap.nix
./services/web-apps/node-red.nix
./services/web-apps/nostr-rs-relay.nix
./services/web-apps/ocis.nix

View File

@ -0,0 +1,331 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.services.nipap;
iniFmt = pkgs.formats.ini { };
configFile = iniFmt.generate "nipap.conf" cfg.settings;
defaultUser = "nipap";
defaultAuthBackend = "local";
dataDir = "/var/lib/nipap";
defaultServiceConfig = {
WorkingDirectory = dataDir;
User = cfg.user;
Group = config.users.users."${cfg.user}".group;
Restart = "on-failure";
RestartSec = 30;
};
escapedHost = host: if lib.hasInfix ":" host then "[${host}]" else host;
in
{
options.services.nipap = {
enable = lib.mkEnableOption "global Neat IP Address Planner (NIPAP) configuration";
user = lib.mkOption {
type = lib.types.str;
description = "User to use for running NIPAP services.";
default = defaultUser;
};
settings = lib.mkOption {
description = ''
Configuration options to set in /etc/nipap/nipap.conf.
'';
default = { };
type = lib.types.submodule {
freeformType = iniFmt.type;
options = {
nipapd = {
listen = lib.mkOption {
type = lib.types.str;
default = "::1";
description = "IP address to bind nipapd to.";
};
port = lib.mkOption {
type = lib.types.port;
default = 1337;
description = "Port to bind nipapd to.";
};
foreground = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Remain in foreground rather than forking to background.";
};
debug = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Enable debug logging.";
};
db_host = lib.mkOption {
type = lib.types.str;
default = "";
description = "PostgreSQL host to connect to. Empty means use UNIX socket.";
};
db_name = lib.mkOption {
type = lib.types.str;
default = cfg.user;
defaultText = defaultUser;
description = "Name of database to use on PostgreSQL server.";
};
};
auth = {
default_backend = lib.mkOption {
type = lib.types.str;
default = defaultAuthBackend;
description = "Name of auth backend to use by default.";
};
auth_cache_timeout = lib.mkOption {
type = lib.types.int;
default = 3600;
description = "Seconds to store cached auth entries for.";
};
};
};
};
};
authBackendSettings = lib.mkOption {
description = ''
auth.backends options to set in /etc/nipap/nipap.conf.
'';
default = {
"${defaultAuthBackend}" = {
type = "SqliteAuth";
db_path = "${dataDir}/local_auth.db";
};
};
type = lib.types.submodule {
freeformType = iniFmt.type;
};
};
nipapd = {
enable = lib.mkEnableOption "nipapd server";
package = lib.mkPackageOption pkgs "nipap" { };
database.createLocally = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Create a nipap database automatically.";
};
};
nipap-www = {
enable = lib.mkEnableOption "nipap-www server";
package = lib.mkPackageOption pkgs "nipap-www" { };
xmlrpcURIFile = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = "Path to file containing XMLRPC URI for use by web UI - this is a secret, since it contains auth credentials. If null, it will be initialized assuming that the auth database is local.";
};
workers = lib.mkOption {
type = lib.types.int;
default = 4;
description = "Number of worker processes for Gunicorn to fork.";
};
umask = lib.mkOption {
type = lib.types.str;
default = "0";
description = "umask for files written by Gunicorn, including UNIX socket.";
};
unixSocket = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = "Path to UNIX socket to bind to.";
example = "/run/nipap/nipap-www.sock";
};
host = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "::";
description = "Host to bind to.";
};
port = lib.mkOption {
type = lib.types.nullOr lib.types.port;
default = 21337;
description = "Port to bind to.";
};
};
};
config = lib.mkIf cfg.enable (
lib.mkMerge [
{
systemd.tmpfiles.rules = [
"d '${dataDir}' - ${cfg.user} ${config.users.users."${cfg.user}".group} - -"
];
environment.etc."nipap/nipap.conf" = {
source = configFile;
};
services.nipap.settings = lib.attrsets.mapAttrs' (name: value: {
name = "auth.backends.${name}";
inherit value;
}) cfg.authBackendSettings;
services.nipap.nipapd.enable = lib.mkDefault true;
services.nipap.nipap-www.enable = lib.mkDefault true;
environment.systemPackages = [
cfg.nipapd.package
];
}
(lib.mkIf (cfg.user == defaultUser) {
users.users."${defaultUser}" = {
isSystemUser = true;
group = defaultUser;
home = dataDir;
};
users.groups."${defaultUser}" = { };
})
(lib.mkIf (cfg.nipapd.enable && cfg.nipapd.database.createLocally) {
services.postgresql = {
enable = true;
extensions = ps: with ps; [ ip4r ];
ensureUsers = [
{
name = cfg.user;
}
];
ensureDatabases = [ cfg.settings.nipapd.db_name ];
};
systemd.services.postgresql.serviceConfig.ExecStartPost =
let
sqlFile = pkgs.writeText "nipapd-setup.sql" ''
CREATE EXTENSION IF NOT EXISTS ip4r;
ALTER SCHEMA public OWNER TO "${cfg.user}";
ALTER DATABASE "${cfg.settings.nipapd.db_name}" OWNER TO "${cfg.user}";
'';
in
[
''
${lib.getExe' config.services.postgresql.finalPackage "psql"} -d "${cfg.settings.nipapd.db_name}" -f "${sqlFile}"
''
];
})
(lib.mkIf cfg.nipapd.enable {
systemd.services.nipapd =
let
pkg = cfg.nipapd.package;
in
{
description = "Neat IP Address Planner";
after = [
"network.target"
"systemd-tmpfiles-setup.service"
] ++ lib.optional (cfg.settings.nipapd.db_host == "") "postgresql.service";
requires = lib.optional (cfg.settings.nipapd.db_host == "") "postgresql.service";
wantedBy = [ "multi-user.target" ];
preStart = lib.optionalString (cfg.settings.auth.default_backend == defaultAuthBackend) ''
# Create/upgrade local auth database
umask 077
${pkg}/bin/nipap-passwd create-database >/dev/null 2>&1
${pkg}/bin/nipap-passwd upgrade-database >/dev/null 2>&1
'';
serviceConfig = defaultServiceConfig // {
KillSignal = "SIGINT";
ExecStart = ''
${pkg}/bin/nipapd \
--auto-install-db \
--auto-upgrade-db \
--foreground \
--no-pid-file
'';
};
};
})
(lib.mkIf cfg.nipap-www.enable {
assertions = [
{
assertion =
cfg.nipap-www.xmlrpcURIFile == null -> cfg.settings.auth.default_backend == defaultAuthBackend;
message = "If no XMLRPC URI secret file is specified, then the default auth backend must be in use to automatically generate credentials.";
}
];
# Ensure that _something_ exists in the [www] group.
services.nipap.settings.www = lib.mkDefault { };
systemd.services.nipap-www =
let
pkg = cfg.nipap-www.package;
in
{
description = "Neat IP Address Planner web server";
after = [
"network.target"
"systemd-tmpfiles-setup.service"
] ++ lib.optional cfg.nipapd.enable "nipapd.service";
wantedBy = [ "multi-user.target" ];
environment = {
PYTHONPATH = pkg.pythonPath;
};
serviceConfig = defaultServiceConfig;
script =
let
bind =
if cfg.nipap-www.unixSocket != null then
"unix:${cfg.nipap-www.unixSocket}"
else
"${escapedHost cfg.nipap-www.host}:${toString cfg.nipap-www.port}";
generateXMLRPC = cfg.nipap-www.xmlrpcURIFile == null;
xmlrpcURIFile = if generateXMLRPC then "${dataDir}/www_xmlrpc_uri" else cfg.nipap-www.xmlrpcURIFile;
in
''
test -f "${dataDir}/www_secret" || {
umask 0077
${pkg.python}/bin/python -c "import secrets; print(secrets.token_hex())" > "${dataDir}/www_secret"
}
export FLASK_SECRET_KEY="$(cat "${dataDir}/www_secret")"
# Ensure that we have an XMLRPC URI.
${
if generateXMLRPC then
''
test -f "${dataDir}/www_xmlrpc_uri" || {
umask 0077
www_password="$(${pkg.python}/bin/python -c "import secrets; print(secrets.token_hex())")"
${cfg.nipapd.package}/bin/nipap-passwd add --username nipap-www --password "''${www_password}" --name "User account for the web UI" --trusted
echo "http://nipap-www@${defaultAuthBackend}:''${www_password}@${escapedHost cfg.settings.nipapd.listen}:${toString cfg.settings.nipapd.port}" > "${xmlrpcURIFile}"
}
''
else
""
}
export FLASK_XMLRPC_URI="$(cat "${xmlrpcURIFile}")"
exec "${pkg.gunicorn}/bin/gunicorn" \
--preload --workers ${toString cfg.nipap-www.workers} \
--pythonpath "${pkg}/${pkg.python.sitePackages}" \
--bind ${bind} --umask ${cfg.nipap-www.umask} \
"nipapwww:create_app()"
'';
};
})
]
);
meta.maintainers = with lib.maintainers; [ lukegb ];
}

View File

@ -8,7 +8,6 @@
let
cfg = config.virtualisation.waydroid;
kCfg = config.lib.kernelConfig;
kernelPackages = config.boot.kernelPackages;
waydroidGbinderConf = pkgs.writeText "waydroid.conf" ''
[Protocol]
/dev/binder = aidl2
@ -26,6 +25,7 @@ in
options.virtualisation.waydroid = {
enable = lib.mkEnableOption "Waydroid";
package = lib.mkPackageOption pkgs "waydroid" { };
};
config = lib.mkIf cfg.enable {
@ -49,7 +49,7 @@ in
environment.etc."gbinder.d/waydroid.conf".source = waydroidGbinderConf;
environment.systemPackages = with pkgs; [ waydroid ];
environment.systemPackages = [ cfg.package ];
networking.firewall.trustedInterfaces = [ "waydroid0" ];
@ -63,7 +63,7 @@ in
serviceConfig = {
Type = "dbus";
UMask = "0022";
ExecStart = "${pkgs.waydroid}/bin/waydroid -w container start";
ExecStart = "${cfg.package}/bin/waydroid -w container start";
BusName = "id.waydro.Container";
};
};
@ -72,7 +72,7 @@ in
"d /var/lib/misc 0755 root root -" # for dnsmasq.leases
];
services.dbus.packages = with pkgs; [ waydroid ];
services.dbus.packages = [ cfg.package ];
};
}

View File

@ -946,6 +946,7 @@ in
nginx-unix-socket = runTest ./nginx-unix-socket.nix;
nginx-variants = import ./nginx-variants.nix { inherit pkgs runTest; };
nifi = runTestOn [ "x86_64-linux" ] ./web-apps/nifi.nix;
nipap = runTest ./web-apps/nipap.nix;
nitter = runTest ./nitter.nix;
nix-config = runTest ./nix-config.nix;
nix-ld = runTest ./nix-ld.nix;

View File

@ -0,0 +1,69 @@
{ pkgs, lib, ... }:
let
nipapRc = pkgs.writeText "nipaprc" ''
[global]
hostname = [::1]
port = 1337
username = nixostest
password = nIx0st3st
default_vrf_rt = -
default_list_vrf_rt = all
'';
in
{
name = "lukegb";
meta.maintainers = [ lib.maintainers.lukegb ];
nodes.main =
{ ... }:
{
services.nipap = {
enable = true;
};
environment.systemPackages = [
pkgs.nipap-cli
];
};
testScript = ''
main.wait_for_unit("nipapd.service")
main.wait_for_unit("nipap-www.service")
# Make sure the web UI is up.
main.wait_for_open_port(21337)
main.succeed("curl -fvvv -Ls http://localhost:21337/ | grep 'NIPAP'")
# Check that none of the files we created in /var/lib/nipap are readable.
out = main.succeed("ls -l /var/lib/nipap")
bad_perms = False
for ln in out.split("\n"):
ln = ln.strip()
if not ln or ln.startswith('total '):
continue
if not ln.startswith('-rw------- '):
print(f"Bad file permissions: {ln}")
bad_perms = True
if bad_perms:
t.fail("One or more files were overly permissive.")
# Check we created a web-frontend user.
main.succeed("nipap-passwd list | grep nipap-www")
# Create a test user
main.succeed("nipap-passwd add -u nixostest -p nIx0st3st -n 'NixOS Test User'")
# Try to log in with it on the web frontend
main.succeed("curl -fvvv -Ls -b \"\" -d username=nixostest -d password=nIx0st3st http://localhost:21337/auth/login | grep 'PrefixListController'")
# Try to log in with it using the CLI
main.copy_from_host("${nipapRc}", "/root/.nipaprc")
main.succeed("chmod u=rw,go= /root/.nipaprc")
main.succeed("nipap address add prefix 192.0.2.0/24 type assignment description RFC1166")
main.succeed("nipap address add prefix 192.0.2.1/32 type host description 'test host'")
main.succeed("nipap address add prefix 2001:db8::/32 type reservation description RFC3849")
main.succeed("nipap address add prefix 2001:db8:f00f::/48 type assignment description 'eye pee vee six'")
main.succeed("nipap address add prefix 2001:db8:f00f:face:dead:beef:cafe:feed/128 type host description 'test host 2'")
'';
}

View File

@ -1,15 +1,13 @@
{
lib,
fetchFromGitLab,
stdenv,
glib,
gtk3,
gobject-introspection,
meson,
ninja,
pkg-config,
gobject-introspection,
vala,
stdenv,
wrapGAppsHook3,
}:
stdenv.mkDerivation (finalAttrs: {
pname = "appmenu-glib-translator";
@ -19,7 +17,6 @@ stdenv.mkDerivation (finalAttrs: {
owner = "vala-panel-project";
repo = "vala-panel-appmenu";
tag = finalAttrs.version;
fetchSubmodules = true;
hash = "sha256-v5J3nwViNiSKRPdJr+lhNUdKaPG82fShPDlnmix5tlY=";
};
@ -30,19 +27,15 @@ stdenv.mkDerivation (finalAttrs: {
ninja
pkg-config
wrapGAppsHook3
gobject-introspection
vala
];
buildInputs = [
glib
gobject-introspection
gtk3
];
propagatedBuildInputs = [ glib ];
meta = {
description = "GTK module that strips menus from all GTK programs, converts to MenuModel and sends to AppMenu";
homepage = "https://gitlab.com/vala-panel-project/vala-panel-appmenu/-/tree/${finalAttrs.version}/subprojects/appmenu-gtk-module";
description = "Library for translating from DBusMenu to GMenuModel";
homepage = "https://gitlab.com/vala-panel-project/vala-panel-appmenu/-/tree/${finalAttrs.version}/subprojects/appmenu-glib-translator";
license = lib.licenses.lgpl3Plus;
maintainers = with lib.maintainers; [ perchun ];
platforms = lib.platforms.linux;

View File

@ -0,0 +1,75 @@
{
mkDerivation,
array,
base,
binary,
bitstring,
bytestring,
clock,
containers,
deepseq,
directory,
fetchzip,
filepath,
haskeline,
lib,
megaparsec,
mtl,
optparse-applicative,
process,
random,
time,
}:
mkDerivation {
pname = "bruijn";
version = "0.1.0.0";
src = fetchzip {
url = "https://github.com/marvinborner/bruijn/archive/d60ad52f135370635db3a2db3363005670af14b8.tar.gz";
sha256 = "182v56vc71467q8x7bp83ch6wp3kv5wgxrm53l2vvnvfqyqswpi2";
};
isLibrary = true;
isExecutable = true;
enableSeparateDataOutput = true;
libraryHaskellDepends = [
array
base
binary
bitstring
bytestring
clock
containers
deepseq
directory
filepath
haskeline
megaparsec
mtl
optparse-applicative
process
random
time
];
executableHaskellDepends = [
array
base
binary
bitstring
bytestring
clock
containers
deepseq
directory
filepath
haskeline
megaparsec
mtl
optparse-applicative
process
random
time
];
homepage = "https://github.com/githubuser/bruijn#readme";
license = lib.licenses.mit;
mainProgram = "bruijn";
maintainers = [ lib.maintainers.defelo ];
}

View File

@ -0,0 +1,25 @@
{
haskell,
haskellPackages,
lib,
}:
let
inherit (haskell.lib.compose) justStaticExecutables overrideCabal;
generated = haskellPackages.callPackage ./generated.nix { };
overrides = {
version = lib.fileContents ./version.txt;
passthru.updateScript = ./update.sh;
description = "Purely functional programming language based on lambda calculus and de Bruijn indices";
homepage = "https://bruijn.marvinborner.de/";
};
in
lib.pipe generated [
(overrideCabal overrides)
justStaticExecutables
]

View File

@ -0,0 +1,16 @@
#!/usr/bin/env nix-shell
#!nix-shell -i bash -p coreutils cabal2nix curl jq nixfmt-rfc-style
set -euo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")"
{ read -r rev; read -r committer_date; } \
< <(curl ${GITHUB_TOKEN:+-u ":$GITHUB_TOKEN"} -sfL https://api.github.com/repos/marvinborner/bruijn/branches/main \
| jq -r '.commit | .sha, .commit.committer.date')
cabal2nix --maintainer defelo "https://github.com/marvinborner/bruijn/archive/${rev}.tar.gz" \
| nixfmt \
> generated.nix
echo "0-unstable-$(date -I --date="$committer_date")" > version.txt

View File

@ -0,0 +1 @@
0-unstable-2025-06-23

View File

@ -10,15 +10,15 @@
rustPlatform.buildRustPackage rec {
pname = "cargo-show-asm";
version = "0.2.49";
version = "0.2.50";
src = fetchCrate {
inherit pname version;
hash = "sha256-DH3jE7nGdwIQVHk80EsC4gYh5+wk6VMWS0d+jZYnX1I=";
hash = "sha256-BmRcaZKAWwRJQyVsymudDg6l7O9pcE2s+Y9VgaJ/Q48=";
};
useFetchCargoVendor = true;
cargoHash = "sha256-R+I6EVzHvI1Et4nvxENc3IvfmSLr/g77x4wCMNb2R88=";
cargoHash = "sha256-+NOk3lzBsgPs1AIUfwWP4sOKSV3XPZsPxl0QNPXPgZQ=";
nativeBuildInputs = [
installShellFiles

View File

@ -21,12 +21,12 @@
rustPlatform.buildRustPackage {
pname = "crosvm";
version = "0-unstable-2025-06-06";
version = "0-unstable-2025-06-17";
src = fetchgit {
url = "https://chromium.googlesource.com/chromiumos/platform/crosvm";
rev = "7083e31d219cdcd57866c70144e1b39ddc008f0f";
hash = "sha256-oZR4UcN8lDoqNoUFGLbIDDRO55noDX0xMWa8W0DbVl4=";
rev = "49e226a57f905b00e44a996c93d9a2439dcb86f3";
hash = "sha256-+HtF9nBv6unnrav5Z84xSOhK+RrlOFBHed6SiuHAcfs=";
fetchSubmodules = true;
};

View File

@ -8,13 +8,13 @@
stdenv.mkDerivation rec {
pname = "expected-lite";
version = "0.8.0";
version = "0.9.0";
src = fetchFromGitHub {
owner = "martinmoene";
repo = "expected-lite";
rev = "v${version}";
hash = "sha256-8Lf+R7wC7f2YliXqhR6pwVVSLZ6qheu7YOV5jHc0Cjc=";
hash = "sha256-LRXxUaDQT5q9dXK2uYFvCgEuGWEHKr95lfdGTGjke0g=";
};
nativeBuildInputs = [

View File

@ -13,13 +13,13 @@
stdenvNoCC.mkDerivation (finalAttrs: {
pname = "firefly-iii";
version = "6.2.17";
version = "6.2.18";
src = fetchFromGitHub {
owner = "firefly-iii";
repo = "firefly-iii";
tag = "v${finalAttrs.version}";
hash = "sha256-g/mGCc7JxfWrbrh14OXaKgn0rjf4RMNL2NI4GzrphaY=";
hash = "sha256-QQlfUbDanyj3n0EOhPxfMqsrl9laQq2CQbwRY4/gH8k=";
};
buildInputs = [ php84 ];
@ -38,13 +38,13 @@ stdenvNoCC.mkDerivation (finalAttrs: {
composerNoScripts = true;
composerStrictValidation = true;
strictDeps = true;
vendorHash = "sha256-2GvBlKRTqehD7eVpEGd9zBoiom30DRMqatyHNF4eDiU=";
vendorHash = "sha256-h/DWKOlffEBWZhdf5iQf4f33IK+1Ie289Oqjb7GHfVY=";
};
npmDeps = fetchNpmDeps {
inherit (finalAttrs) src;
name = "${finalAttrs.pname}-npm-deps";
hash = "sha256-uZluWsHpbD2lMG/yNoZxry5X+Hiv3z/H4KqV7pydu/A=";
hash = "sha256-YbMUM+fXIuXVrv7QMlPklct3mDHI05PoOW+fgHf8c3I=";
};
preInstall = ''

View File

@ -35,18 +35,18 @@ let
in
buildGoModule rec {
pname = "gitea";
version = "1.24.0";
version = "1.24.2";
src = fetchFromGitHub {
owner = "go-gitea";
repo = "gitea";
tag = "v${gitea.version}";
hash = "sha256-lKeqoNL6RMjhm9egk6upbovJaWwm3r2kxi0Z9bjNxtI=";
hash = "sha256-NQSilSF/W69j1qEYYmlQfu2T0OefB+8yf9rCHAL8a6c=";
};
proxyVendor = true;
vendorHash = "sha256-nC8y3skBhnOo7Ki9nc7Ni6UpheArB8bGK4AR/1Gdjr0=";
vendorHash = "sha256-VmlF86Sv6R2NmCtWi4kZ4rfmFAjgMB1RU/1jmnPiIkw=";
outputs = [
"out"

View File

@ -13,6 +13,11 @@ stdenv.mkDerivation (finalAttrs: {
pname = "libblake3";
version = "1.8.2";
outputs = [
"out"
"dev"
];
src = fetchFromGitHub {
owner = "BLAKE3-team";
repo = "BLAKE3";

View File

@ -8,8 +8,8 @@ This patch hinders libnvidia-container from using the loader cache, which doesn'
src/ldcache.c | 46 +++++++++++++++++-----------------------------
src/ldcache.h | 2 +-
src/nvc_info.c | 8 ++------
src/nvc_ldcache.c | 2 +-
4 files changed, 21 insertions(+), 37 deletions(-)
src/nvc_ldcache.c | 4 ++--
4 files changed, 22 insertions(+), 38 deletions(-)
diff --git a/src/ldcache.c b/src/ldcache.c
index 38bab0553208f66b2866ccea6cdb0faca4357f19..1c4acd52b622be4ca6accdc80da5a6fcf9ae67dd 100644
@ -86,7 +86,7 @@ index 33d78dd7e21f65eb696535c115bbd2839a6c67ca..2b087dbca1a6a2946cd495e676a61e95
#endif /* HEADER_LDCACHE_H */
diff --git a/src/nvc_info.c b/src/nvc_info.c
index b7b8adfa7c79c326a1acb481a06a05d1463e810f..cf4b1905fd2127c28ee16649501be122d3be5261 100644
index bcc887b2345bd42a098f9b85d9c66fae2775f736..5eaef61ada5e955ab11c6a4eb8429c50468e3370 100644
--- a/src/nvc_info.c
+++ b/src/nvc_info.c
@@ -217,15 +217,13 @@ find_library_paths(struct error *err, struct dxcore_context *dxcore, struct nvc_
@ -122,15 +122,17 @@ index b7b8adfa7c79c326a1acb481a06a05d1463e810f..cf4b1905fd2127c28ee16649501be122
}
diff --git a/src/nvc_ldcache.c b/src/nvc_ldcache.c
index db3b2f69692270e9058b2e26f18eb31677909d05..ae5def43b4cb3973af3aad55361265173ca938a7 100644
index 0535090dafbae5a00acb707bbbb5a35dbcea4a7a..5de429f4c2ea62775403a5fc1ed0f23a6c88655c 100644
--- a/src/nvc_ldcache.c
+++ b/src/nvc_ldcache.c
@@ -367,7 +367,7 @@ nvc_ldcache_update(struct nvc_context *ctx, const struct nvc_container *cnt)
if (validate_args(ctx, cnt != NULL) < 0)
return (-1);
- argv = (char * []){cnt->cfg.ldconfig, "-f", "/etc/ld.so.conf", "-C", "/etc/ld.so.cache", cnt->cfg.libs_dir, cnt->cfg.libs32_dir, NULL};
+ argv = (char * []){cnt->cfg.ldconfig, "-f", "/tmp/ld.so.conf.nvidia-host", "-C", "/tmp/ld.so.cache.nvidia-host", cnt->cfg.libs_dir, cnt->cfg.libs32_dir, NULL};
if (*argv[0] == '@') {
@@ -482,8 +482,8 @@ nvc_ldcache_update(struct nvc_context *ctx, const struct nvc_container *cnt)
* See https://github.com/NVIDIA/libnvidia-container/issues/316 for an
* in-depth investigation.
*/
- char *argv_default[] = {cnt->cfg.ldconfig, "-f", "/etc/ld.so.conf", "-C", "/etc/ld.so.cache", cnt->cfg.libs_dir, cnt->cfg.libs32_dir, NULL};
- char *argv_with_compat_dir[] = {cnt->cfg.ldconfig, "-f", "/etc/ld.so.conf", "-C", "/etc/ld.so.cache", cnt->cuda_compat_dir, cnt->cfg.libs_dir, cnt->cfg.libs32_dir, NULL};
+ char *argv_default[] = {cnt->cfg.ldconfig, "-f", "/tmp/ld.so.conf.nvidia-host", "-C", "/tmp/ld.so.cache.nvidia-host", cnt->cfg.libs_dir, cnt->cfg.libs32_dir, NULL};
+ char *argv_with_compat_dir[] = {cnt->cfg.ldconfig, "-f", "/tmp/ld.so.conf.nvidia-host", "-C", "/tmp/ld.so.cache.nvidia-host", cnt->cuda_compat_dir, cnt->cfg.libs_dir, cnt->cfg.libs32_dir, NULL};
if ((cnt->flags & OPT_CUDA_COMPAT_MODE_LDCONFIG) && (cnt->cuda_compat_dir != NULL)) {
/*
* We treat this path specially to be relative to the host filesystem.
* We include the cuda_compat_dir directory on the ldconfig

View File

@ -9,7 +9,7 @@ This patch maintains compatibility with NixOS' `virtualisation.docker.enableNvid
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/nvc_info.c b/src/nvc_info.c
index cf4b1905fd2127c28ee16649501be122d3be5261..cdfa19721bc913d8e2adb96d106cd65ee6111623 100644
index 5eaef61ada5e955ab11c6a4eb8429c50468e3370..cac87500213e961e603494ac842d02522fc46a5e 100644
--- a/src/nvc_info.c
+++ b/src/nvc_info.c
@@ -249,10 +249,13 @@ find_binary_paths(struct error *err, struct dxcore_context* dxcore, struct nvc_d

View File

@ -32,13 +32,13 @@ let
in
stdenv.mkDerivation (finalAttrs: {
pname = "libnvidia-container";
version = "1.17.6";
version = "1.17.8";
src = fetchFromGitHub {
owner = "NVIDIA";
repo = "libnvidia-container";
tag = "v${finalAttrs.version}";
hash = "sha256-kveP0Px9Fds7pS39aW+cqg2jtiQCMN2zG4GTGRqRrc0=";
hash = "sha256-OzjcYxnWjzgmrjERyPN3Ch3EQj4t1J5/TbATluoDESg=";
};
patches = [
@ -175,6 +175,7 @@ stdenv.mkDerivation (finalAttrs: {
maintainers = with lib.maintainers; [
cpcloud
msanft
katexochen
];
};
})

View File

@ -11,16 +11,16 @@
rustPlatform.buildRustPackage (finalAttrs: {
pname = "lstr";
version = "0.2.0";
version = "0.2.1";
src = fetchFromGitHub {
owner = "bgreenwell";
repo = "lstr";
tag = "v${finalAttrs.version}";
hash = "sha256-Bg2tJYnXpJQasmcRv+ZIZAVteKUCuTgFKVRHw1CCiAQ=";
hash = "sha256-uaefVDSTphboWW1BP2HkcuMiW87FmnVYxCthlrAKF5Y=";
};
cargoHash = "sha256-KlO/Uz9UPea4DFC6U4hvn4kOWSzUmYmckw+IUstcmeQ=";
cargoHash = "sha256-UVaqkNV1cNpbCNphk6YMqOz077xY9dUBgCGt7SLIH0U=";
nativeBuildInputs = [ pkg-config ];

View File

@ -9,13 +9,13 @@
}:
buildGoModule (finalAttrs: {
pname = "nelm";
version = "1.6.0";
version = "1.7.0";
src = fetchFromGitHub {
owner = "werf";
repo = "nelm";
tag = "v${finalAttrs.version}";
hash = "sha256-bqVas9zF/xtL5K/7cOF/4q4weZtEBhfB5ngdAq0ZfjI=";
hash = "sha256-XAieAxfpNi2XpjG8lyatAqP13wicx3JFjckgSmiKqjA=";
};
vendorHash = "sha256-bx8e5jV+ORnJg/35VwO7qodFjmSf7XbzTKZKp3b8hqc=";

View File

@ -9,22 +9,22 @@
pkg-config,
nixVersions,
nix-update-script,
enableNixImport ? true,
enableNixImport ? false,
}:
rustPlatform.buildRustPackage (finalAttrs: {
pname = "nickel";
version = "1.11.0";
version = "1.12.0";
src = fetchFromGitHub {
owner = "tweag";
repo = "nickel";
tag = finalAttrs.version;
hash = "sha256-I7cLVrkJhB3aJeE/A3tpFEUj0AkvcONSXD8NtnE5eQ0=";
hash = "sha256-iKLjYE4uT+luIRXjEuO7KjgkO+/jFpLjhCI5tO7TVMM=";
};
useFetchCargoVendor = true;
cargoHash = "sha256-DzSfwBVeRT/GAXWyZKZjlDvj95bQzrkqIgZZ2EZw7eQ=";
cargoHash = "sha256-O/iat0JOvA90LD+ngAByLYQyd1VBeoa8yj7/NdEYprE=";
cargoBuildFlags = [
"-p nickel-lang-cli"
@ -99,6 +99,7 @@ rustPlatform.buildRustPackage (finalAttrs: {
maintainers = with lib.maintainers; [
felschr
matthiasbeyer
yannham
];
mainProgram = "nickel";
};

View File

@ -0,0 +1,56 @@
{
lib,
python312Packages,
nixosTests,
}:
let
python3Packages = python312Packages;
in
python3Packages.buildPythonApplication rec {
pname = "nipap-cli";
inherit (python3Packages.nipap) version src;
pyproject = true;
sourceRoot = "${src.name}/nipap-cli";
postPatch = ''
substituteInPlace pyproject.toml \
--replace-fail 'docutils==0.20.1' 'docutils'
'';
build-system = with python3Packages; [
setuptools
docutils
];
dependencies = with python3Packages; [
ipy
pynipap
];
checkInputs = with python3Packages; [
pythonImportsCheckHook
];
pythonImportsCheck = [
"nipap_cli.nipap_cli"
];
passthru.tests.nixos = nixosTests.nipap;
meta = {
description = "Neat IP Address Planner CLI";
longDescription = ''
NIPAP is the best open source IPAM in the known universe,
challenging classical IP address management (IPAM) systems in many areas.
'';
homepage = "https://github.com/SpriteLink/NIPAP";
changelog = "https://github.com/SpriteLink/NIPAP/releases/tag/v${version}";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [
lukegb
];
platforms = lib.platforms.all;
mainProgram = "nipap";
};
}

View File

@ -0,0 +1,53 @@
{
lib,
python3Packages,
nixosTests,
}:
python3Packages.buildPythonApplication rec {
pname = "nipap-www";
inherit (python3Packages.nipap) version src;
pyproject = true;
sourceRoot = "${src.name}/nipap-www";
postPatch = ''
# Load Flask config additionally from FLASK_ environment variables.
# This makes providing secrets easier.
sed -i nipapwww/__init__.py \
-e '/^\s*app =/a\ app.config.from_prefixed_env()'
'';
pythonRelaxDeps = true; # deps are tightly specified
build-system = with python3Packages; [
setuptools
];
dependencies = with python3Packages; [
flask
nipap
pynipap
];
passthru = {
inherit (python3Packages) gunicorn python;
pythonPath = python3Packages.makePythonPath dependencies;
tests.nixos = nixosTests.nipap;
};
meta = {
description = "Neat IP Address Planner CLI, web UI";
longDescription = ''
NIPAP is the best open source IPAM in the known universe,
challenging classical IP address management (IPAM) systems in many areas.
'';
homepage = "https://github.com/SpriteLink/NIPAP";
changelog = "https://github.com/SpriteLink/NIPAP/releases/tag/v${version}";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [
lukegb
];
platforms = lib.platforms.all;
};
}

View File

@ -0,0 +1,5 @@
{
python3Packages,
}:
python3Packages.toPythonApplication python3Packages.nipap

View File

@ -49,7 +49,7 @@ buildGoModule (
'';
outputHashMode = "recursive";
outputHash = "sha256-KygZ7NqkfhczYy1YMR824Om4NTq06+KHa/jvmsCty3s=";
outputHash = "sha256-3CtcjqjPmK//f15aTE4bUA+moaXNz+AeWiopqWf9qq8=";
};
webui = buildNpmPackage {
@ -81,13 +81,13 @@ buildGoModule (
{
pname = "olivetin";
version = "2025.6.6";
version = "2025.6.22";
src = fetchFromGitHub {
owner = "OliveTin";
repo = "OliveTin";
tag = finalAttrs.version;
hash = "sha256-yzAuhrkJEBErf9yYuRoq5B7PT0XA0w668AG5LNSSRFM=";
hash = "sha256-fNE8x0d0lnKVxy4fk3h5QrcWnMKBcxhrxpDbZYTXimc=";
};
modRoot = "service";

View File

@ -1,6 +1,7 @@
{
lib,
fetchFromGitHub,
fetchpatch,
stdenv,
makeWrapper,
gitUpdater,
@ -67,6 +68,14 @@ stdenv.mkDerivation (finalAttrs: {
hash = "sha256-sCoCcN6950pH33bRZsLoLc1oSs5Qfpj9Bbywn/uA6Bc=";
};
patches = [
(fetchpatch {
name = "correctly-handle-version-10.0.0-of-qemu.patch";
url = "https://github.com/quickemu-project/quickemu/commit/f25205f4513c4fa72be6940081c62e613d1fddc6.patch";
hash = "sha256-OAXGyhMVDwbUypEPj/eRnH0wZYaL9WLGjbyoobe20UY=";
})
];
postPatch = ''
sed -i \
-e '/OVMF_CODE_4M.secboot.fd/s|ovmfs=(|ovmfs=("${OVMFFull.firmware}","${OVMFFull.variables}" |' \

View File

@ -16,13 +16,13 @@
stdenv.mkDerivation (finalAttrs: {
pname = "supermariowar";
version = "2024-unstable-2025-04-03";
version = "2024-unstable-2025-06-18";
src = fetchFromGitHub {
owner = "mmatyas";
repo = "supermariowar";
rev = "c0ed774a2415ad45e72bd6086add2a5cbfc88898";
hash = "sha256-vh8SSMxAOG8f9nyJmKUlA8yb+G61Bfc62dhB2eLdo20=";
rev = "71383b07b99a52b57be79cf371ab718337365019";
hash = "sha256-PjweE8cGAp8V4LY0/6QzLekQ80Q1qbwDiiSzDirA29s=";
fetchSubmodules = true;
};

View File

@ -62,7 +62,7 @@ let
stdenv.cc.cc
stdenv.cc.libc
];
version = "1.0.32";
version = "1.0.36";
in
stdenv.mkDerivation {
pname = "tana";
@ -70,7 +70,7 @@ stdenv.mkDerivation {
src = fetchurl {
url = "https://github.com/tanainc/tana-desktop-releases/releases/download/v${version}/tana_${version}_amd64.deb";
hash = "sha256-oAW9Vx4z0TOweKA6bsmCm7DY72pFWBnPLG0dS05oCw8=";
hash = "sha256-dDB2RcTk58IQGqNGepaIvxGhR0/soWWDbBXxnSEYkdw=";
};
nativeBuildInputs = [

View File

@ -45,13 +45,13 @@ lib.checkListOfEnum "${pname}: theme variants"
stdenvNoCC.mkDerivation
rec {
inherit pname;
version = "2024-04-20";
version = "2025-06-20";
src = fetchFromGitHub {
owner = "vinceliuice";
repo = "vimix-gtk-themes";
rev = version;
sha256 = "RbAdoix+UWKiLB+04YiPa0UwzO1fFLy56IG1MipmE+E=";
sha256 = "uRm6v+Zag4FO7nFVcHhZjVhOfdOeYBZYQym0IBR8+HU=";
};
nativeBuildInputs = [

View File

@ -1,14 +1,14 @@
{
"darwin": {
"hash": "sha256-wlFmfHBSwBh9UFq6by52fGYN2EftP793u3L57XSDDKQ=",
"version": "0.2025.06.18.08.11.stable_03"
"hash": "sha256-UJAirS6JFFLW0OsOYj8RNUfG85dRHnxXasNw2QHX1Xs=",
"version": "0.2025.06.20.22.47.stable_05"
},
"linux_x86_64": {
"hash": "sha256-7CfqTRUMkqLXmJg7RQK0liVEhucMOgMtsJl4/lrg4XI=",
"version": "0.2025.06.18.08.11.stable_03"
"hash": "sha256-h0ODaO3SJcZAxFRFBYYjWXQYsRAemGizn/YA7AF36pw=",
"version": "0.2025.06.20.22.47.stable_05"
},
"linux_aarch64": {
"hash": "sha256-iDXAchU/b2ApDsmV0dnkXI1o0VOaegYWz4DufHtPFJM=",
"version": "0.2025.06.18.08.11.stable_03"
"hash": "sha256-H4xldFBMpfu6UFGFA/IkA1zPFqhFN6abhfHTRdYNpGA=",
"version": "0.2025.06.20.22.47.stable_05"
}
}

View File

@ -108,6 +108,6 @@ python3Packages.buildPythonApplication rec {
homepage = "https://github.com/waydroid/waydroid";
license = lib.licenses.gpl3Only;
platforms = lib.platforms.linux;
maintainers = with lib.maintainers; [ ];
maintainers = with lib.maintainers; [ bot-wxt1221 ];
};
}

View File

@ -27,7 +27,7 @@ let
in
python.pkgs.buildPythonApplication rec {
pname = "weblate";
version = "5.12.1";
version = "5.12.2";
pyproject = true;
@ -40,7 +40,7 @@ python.pkgs.buildPythonApplication rec {
owner = "WeblateOrg";
repo = "weblate";
tag = "weblate-${version}";
hash = "sha256-8tqPxvSvVG1j/TGMozihtBYsn7oly41lP4iK3BwTmVk=";
hash = "sha256-YaP0lhL7E0pv3ZyfpQ47CjhrzjJPDwGpSTcgXDaMZdA=";
};
patches = [

View File

@ -119,7 +119,12 @@ rustPlatform.buildRustPackage rec {
cp -r assets/macos/WezTerm.app "$OUT_APP"
rm $OUT_APP/*.dylib
cp -r assets/shell-integration/* "$OUT_APP"
ln -s $out/bin/{wezterm,wezterm-mux-server,wezterm-gui,strip-ansi-escapes} "$OUT_APP"
# https://github.com/wezterm/wezterm/pull/6886
# macOS will only recognize our application bundle
# if the binaries are inside of it. Move them there
# and create symbolic links for them in bin/.
mv $out/bin/{wezterm,wezterm-mux-server,wezterm-gui,strip-ansi-escapes} "$OUT_APP"
ln -s "$OUT_APP"/{wezterm,wezterm-mux-server,wezterm-gui,strip-ansi-escapes} "$out/bin"
'';
passthru = {

View File

@ -7,12 +7,12 @@
}:
let
version = "3.10";
version = "3.16";
srcAll = fetchFromGitHub {
owner = "WiringPi";
repo = "WiringPi";
rev = version;
sha256 = "sha256-OWR+yo+SnYaMd8J+ku9ettZi+rDHcHlGZCoucCiRkCI=";
tag = version;
hash = "sha256-NBHmRA+6Os6/IpW8behbgpVjtN8QF9gkffXU2ZVC8ts=";
};
mkSubProject =
{
@ -78,11 +78,14 @@ symlinkJoin {
passthru.wiringPiD
passthru.gpio
];
meta = with lib; {
meta = {
description = "Gordon's Arduino wiring-like WiringPi Library for the Raspberry Pi (Unofficial Mirror for WiringPi bindings)";
homepage = "https://github.com/WiringPi/WiringPi";
license = licenses.lgpl3Plus;
maintainers = with maintainers; [ doronbehar ];
platforms = platforms.linux;
license = lib.licenses.lgpl3Plus;
maintainers = with lib.maintainers; [
doronbehar
ryand56
];
platforms = lib.platforms.linux;
};
}

View File

@ -1511,6 +1511,39 @@ final: prev: {
}
) { };
lrexlib-oniguruma = callPackage (
{
buildLuarocksPackage,
fetchFromGitHub,
fetchurl,
luaOlder,
}:
buildLuarocksPackage {
pname = "lrexlib-oniguruma";
version = "2.9.2-1";
knownRockspec =
(fetchurl {
url = "mirror://luarocks/lrexlib-oniguruma-2.9.2-1.rockspec";
sha256 = "13m2v6mmmlkf2bd1mnngg118s4ymrqs7n34la6hrb4m1x772adhd";
}).outPath;
src = fetchFromGitHub {
owner = "rrthomas";
repo = "lrexlib";
rev = "rel-2-9-2";
hash = "sha256-DzNDve+xeKb+kAcW+o7GK/RsoDhaDAVAWAhgjISCyZc=";
};
disabled = luaOlder "5.1";
meta = {
homepage = "https://github.com/rrthomas/lrexlib";
description = "Regular expression library binding (oniguruma flavour).";
maintainers = with lib.maintainers; [ junestepp ];
license.fullName = "MIT/X11";
};
}
) { };
lrexlib-pcre = callPackage (
{
buildLuarocksPackage,

View File

@ -39,6 +39,7 @@
mariadb,
mpfr,
neovim-unwrapped,
oniguruma,
openldap,
openssl,
pcre,
@ -380,6 +381,15 @@ in
];
});
lrexlib-oniguruma = prev.lrexlib-oniguruma.overrideAttrs (oa: {
externalDeps = [
{
name = "ONIG";
dep = oniguruma;
}
];
});
lrexlib-pcre = prev.lrexlib-pcre.overrideAttrs (oa: {
externalDeps = [
{

View File

@ -16,14 +16,14 @@
buildPythonPackage rec {
pname = "aioamazondevices";
version = "3.1.12";
version = "3.1.14";
pyproject = true;
src = fetchFromGitHub {
owner = "chemelli74";
repo = "aioamazondevices";
tag = "v${version}";
hash = "sha256-nilYImyK057/yO/pnnhM9S+vRcslLLKTsYIzGNFM2UQ=";
hash = "sha256-xCXzNeUIw2UxBcOMgab1lpN9/0RGLZAwgtHkZhwqxxY=";
};
build-system = [ poetry-core ];

View File

@ -26,7 +26,7 @@
buildPythonPackage rec {
pname = "aioesphomeapi";
version = "32.2.1";
version = "33.1.1";
pyproject = true;
disabled = pythonOlder "3.9";
@ -35,7 +35,7 @@ buildPythonPackage rec {
owner = "esphome";
repo = "aioesphomeapi";
tag = "v${version}";
hash = "sha256-1ZepZJdJosPPdFhx8PwArIaoz415GfA1vfc3JJ77LNo=";
hash = "sha256-vXBTumh1oB1vTVlX4VJvIUTnkYLG9j/8cNuHFQ2PklY=";
};
build-system = [

View File

@ -8,23 +8,20 @@
poetry-core,
pytest-cov-stub,
pytestCheckHook,
pythonOlder,
pytz,
sensor-state-data,
}:
buildPythonPackage rec {
pname = "bthome-ble";
version = "3.13.0";
version = "3.13.1";
pyproject = true;
disabled = pythonOlder "3.9";
src = fetchFromGitHub {
owner = "Bluetooth-Devices";
repo = "bthome-ble";
tag = "v${version}";
hash = "sha256-e6R3Qjj82z0E+gIxqDVM08Op3KlK9ZG1iNmkqqIEjWY=";
hash = "sha256-oGFjWe9e386EPAJGKL8Qk55iXoyW3rXuyG7ElyQYurg=";
};
build-system = [ poetry-core ];

View File

@ -20,7 +20,7 @@
buildPythonPackage rec {
pname = "deebot-client";
version = "13.3.0";
version = "13.4.0";
pyproject = true;
disabled = pythonOlder "3.13";
@ -29,12 +29,12 @@ buildPythonPackage rec {
owner = "DeebotUniverse";
repo = "client.py";
tag = version;
hash = "sha256-dnh+3/viaaxlx3H0ceDH1N72kC1HBC7Szz+Gb6ryUJM=";
hash = "sha256-CEE6RDcYQLJ9a8QFYpCURYV8hvs0mLK8R+p68OfHKWQ=";
};
cargoDeps = rustPlatform.fetchCargoVendor {
inherit pname version src;
hash = "sha256-v8FtW1gPoPfOpcxUrM7g0LKR8k0VPR13hsHCPT8uLzs=";
hash = "sha256-0WdRkF5UAaPQS3A9DiAe9BuqF0aAaU0c2C0BU3Ue4n0=";
};
pythonRelaxDeps = [

View File

@ -0,0 +1,50 @@
{
lib,
buildPythonPackage,
fetchFromGitHub,
setuptools,
flask,
nose2,
}:
buildPythonPackage rec {
pname = "flask-xml-rpc-re";
version = "0.2.0";
src = fetchFromGitHub {
owner = "Croydon";
repo = "flask-xml-rpc-reloaded";
tag = version;
hash = "sha256-S+9Ur22ExgVjKMOKG19cBz2aCVdEyOoS7uoz17CDzd8=";
};
build-system = [
setuptools
];
dependencies = [
flask
];
nativeCheckInputs = [
nose2
];
installCheckPhase = ''
runHook preInstallCheck
nose2 -v
runHook postInstallCheck
'';
pythonImportsCheck = [ "flask_xmlrpcre" ];
meta = {
description = "Let your Flask apps provide XML-RPC APIs";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [
lukegb
];
homepage = "https://github.com/Croydon/flask-xml-rpc-reloaded";
changelog = "https://github.com/Croydon/flask-xml-rpc-reloaded/releases/tag/${version}";
};
}

View File

@ -20,13 +20,13 @@
buildPythonPackage rec {
pname = "guidance-stitch";
version = "0.1.4";
version = "0.1.5";
pyproject = true;
src = fetchPypi {
pname = "guidance_stitch";
inherit version;
hash = "sha256-Wthz02C2AU6hzQ+TTGs+sI73ejwHQRCStZXZts0i1+w=";
hash = "sha256-Kg0O3oZds4eFfUlKe8sakDYhwT9XGGnN4RCcLFVpzZU=";
};
build-system = [

View File

@ -16,7 +16,7 @@
buildPythonPackage rec {
pname = "homematicip";
version = "2.0.5";
version = "2.0.6";
pyproject = true;
disabled = pythonOlder "3.12";
@ -25,7 +25,7 @@ buildPythonPackage rec {
owner = "hahn-th";
repo = "homematicip-rest-api";
tag = version;
hash = "sha256-WvE5JTpAjRGLP7haIwD5hKOvz3hM7paV2jyds/yCxg8=";
hash = "sha256-HV+4ZmYr6LsSBbQnr4PUD2u0y6uWxuCMUgNh7gG9IH8=";
};
build-system = [

View File

@ -0,0 +1,100 @@
{
lib,
buildPythonPackage,
fetchFromGitHub,
# build deps
setuptools,
docutils,
# dependencies
zipp,
importlib-metadata,
flask,
flask-compress,
flask-xml-rpc-re,
flask-restx,
requests,
ipy,
# indirect deps omitted: jinja2/markupsafe/werkzeug,
parsedatetime,
psutil,
psycopg2,
pyparsing,
python-dateutil,
pytz,
pyjwt,
tornado,
# optional deps
## ldap
python-ldap,
}:
buildPythonPackage rec {
pname = "nipap";
version = "0.32.7";
pyproject = true;
src = fetchFromGitHub {
owner = "SpriteLink";
repo = "NIPAP";
tag = "v${version}";
hash = "sha256-FnCHW/yEhWtx+2fU+G6vxz50lWC7WL3cYKYOQzmH8zs=";
};
sourceRoot = "${src.name}/nipap";
pythonRelaxDeps = true; # deps are tightly specified by upstream
postPatch = ''
substituteInPlace pyproject.toml \
--replace-fail 'docutils==0.20.1' 'docutils'
'';
build-system = [
setuptools
docutils
];
dependencies = [
zipp
importlib-metadata
flask
flask-compress
flask-xml-rpc-re
flask-restx
requests
ipy
# indirect deps omitted: jinja2/markupsafe/werkzeug
parsedatetime
psutil
psycopg2
pyparsing
python-dateutil
pytz
pyjwt
tornado
];
optional-dependencies = {
ldap = [ python-ldap ];
};
doCheck = false; # tests require nose, /etc/nipap/nipap.conf and a running nipapd
meta = {
description = "Neat IP Address Planner";
longDescription = ''
NIPAP is the best open source IPAM in the known universe,
challenging classical IP address management (IPAM) systems in many areas.
'';
homepage = "https://github.com/SpriteLink/NIPAP";
changelog = "https://github.com/SpriteLink/NIPAP/releases/tag/v${version}";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [
lukegb
];
platforms = lib.platforms.all;
};
}

View File

@ -0,0 +1,38 @@
{
lib,
buildPythonPackage,
nipap,
# build deps
setuptools,
}:
buildPythonPackage rec {
pname = "pynipap";
pyproject = true;
inherit (nipap) version src;
sourceRoot = "${src.name}/pynipap";
build-system = [
setuptools
];
doCheck = false; # tests require nose, /etc/nipap/nipap.conf and a running nipapd
meta = {
description = "Python client library for Neat IP Address Planner";
longDescription = ''
NIPAP is the best open source IPAM in the known universe,
challenging classical IP address management (IPAM) systems in many areas.
'';
homepage = "https://github.com/SpriteLink/NIPAP";
changelog = "https://github.com/SpriteLink/NIPAP/releases/tag/v${version}";
license = lib.licenses.mit;
maintainers = with lib.maintainers; [
lukegb
];
platforms = lib.platforms.all;
};
}

View File

@ -27,7 +27,7 @@
buildPythonPackage rec {
pname = "zha";
version = "0.0.59";
version = "0.0.60";
pyproject = true;
disabled = pythonOlder "3.12";
@ -36,7 +36,7 @@ buildPythonPackage rec {
owner = "zigpy";
repo = "zha";
tag = version;
hash = "sha256-wddMeXFKk8HBz8Hle5kbRaOkZLOr98HoiHYYlBtuxSA=";
hash = "sha256-Bx6JcVKosf6wXe+LRP9R4iFAva/rJ15JhYchCx2CbJk=";
};
postPatch = ''

View File

@ -16,7 +16,7 @@
buildPythonPackage rec {
pname = "zigpy-zigate";
version = "0.13.2";
version = "0.13.3";
pyproject = true;
disabled = pythonOlder "3.8";
@ -25,7 +25,7 @@ buildPythonPackage rec {
owner = "zigpy";
repo = "zigpy-zigate";
tag = version;
hash = "sha256-MlAX7dcRZziMYCpG64OemZ8czwvDXpdoRaDVo1sUCno=";
hash = "sha256-reOt0bPPkKDKeu8CESJtLDEmpkOmgopXk65BqBlBIhY=";
};
postPatch = ''

View File

@ -19,7 +19,7 @@
buildPythonPackage rec {
pname = "zigpy-znp";
version = "0.14.0";
version = "0.14.1";
pyproject = true;
disabled = pythonOlder "3.7";
@ -28,7 +28,7 @@ buildPythonPackage rec {
owner = "zigpy";
repo = "zigpy-znp";
tag = "v${version}";
hash = "sha256-vYB04vEFqpqrjJMS73mtYXakp7lEIJjB+tT0SF9hpWM=";
hash = "sha256-V662zDUBMbr+cARxrwt8196Ml4zlGEAudR3BtvY96HM=";
};
postPatch = ''

View File

@ -1,347 +1,347 @@
{
"aurorae": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/aurorae-6.4.0.tar.xz",
"hash": "sha256-VjxChfQmhIJW6SyISgWKVy1Z31q5pMi5BzhSJuxKwLI="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/aurorae-6.4.1.tar.xz",
"hash": "sha256-4hZ73nLjVc0AZXOeqNLNnR3z9D6beAn8VwKzs1K7/WU="
},
"bluedevil": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/bluedevil-6.4.0.tar.xz",
"hash": "sha256-8yb1EFCmDqwRNlKeFojg3ZAL1brP3cDn3ZQbLXV2rrk="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/bluedevil-6.4.1.tar.xz",
"hash": "sha256-mtR03dabzoVJgNMEL96JBb2UBZ/aqoAEJcds12J+Bu8="
},
"breeze": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/breeze-6.4.0.tar.xz",
"hash": "sha256-z9s48KTixCjpylpf0SQAtoBKvN1TWbY2+lMno1Eh6GY="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/breeze-6.4.1.tar.xz",
"hash": "sha256-T+AIX/ohsuOu9J3E5chi8i7xM5WpaBOHqZAwh0PwHFU="
},
"breeze-grub": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/breeze-grub-6.4.0.tar.xz",
"hash": "sha256-syzAxAqtGM7tbowlxlTc/ELUbd2Zm8oFBKCSlZhvYwI="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/breeze-grub-6.4.1.tar.xz",
"hash": "sha256-c6yyJ5vbMtXpeqeHha4P6vBuQnQTtNvR3LZbu9zacwM="
},
"breeze-gtk": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/breeze-gtk-6.4.0.tar.xz",
"hash": "sha256-WFJjJxTE17d1SBUe9efe2t7TMfbpARGxbdcQ4Bu6j60="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/breeze-gtk-6.4.1.tar.xz",
"hash": "sha256-4Qj+nLx2oPUf2N+cYw05l4o8H7bPrznZqy9VVJRie1g="
},
"breeze-plymouth": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/breeze-plymouth-6.4.0.tar.xz",
"hash": "sha256-S1DBCbItJbH7YT/K5Qq+NbEAuQgyaudqPdgydMoPTPI="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/breeze-plymouth-6.4.1.tar.xz",
"hash": "sha256-JSE/12TBsME2nbqFASXjsC2ZkKuQwcZ0PKodCHy3BkU="
},
"discover": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/discover-6.4.0.tar.xz",
"hash": "sha256-CfsdY6puw61W5gb0i24Q1Z7rN9m1J+VKIRtKedblIkI="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/discover-6.4.1.tar.xz",
"hash": "sha256-80zqQ4qKCuC7b9E+QWTUnHoqmFfiBDAMzCdvLV+JgjA="
},
"drkonqi": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/drkonqi-6.4.0.tar.xz",
"hash": "sha256-BGqJ475WIGBu2tlF6/L1KHWlytZ0A8Ha86G/5ShoPqI="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/drkonqi-6.4.1.tar.xz",
"hash": "sha256-REnekqvM46h7RyeWQffxcmqo0C5vMVSPDzJ3ks6C/UM="
},
"flatpak-kcm": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/flatpak-kcm-6.4.0.tar.xz",
"hash": "sha256-KCw6dSf4sdsTLaB992jXLFK7yj4n8iFvS6ahcx3QTeI="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/flatpak-kcm-6.4.1.tar.xz",
"hash": "sha256-27UINtKXUF5efF/LKeIrb/IbUtBE7gf4QriZlMXapd4="
},
"kactivitymanagerd": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kactivitymanagerd-6.4.0.tar.xz",
"hash": "sha256-zVaf4lsNZwHDMOCPw+3lfVf/guluxtNH51dbsy+qurs="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kactivitymanagerd-6.4.1.tar.xz",
"hash": "sha256-tt1cG4TT0ucNt58W7O/iOsr1PEX9XCursu6ZS0ZsrJk="
},
"kde-cli-tools": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kde-cli-tools-6.4.0.tar.xz",
"hash": "sha256-T06+18F6JQecVO8DGSmsVdZ3es089ZXKY0P00KTwC6k="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kde-cli-tools-6.4.1.tar.xz",
"hash": "sha256-LZCrDANPudKBZ1Dams45twi3EtP3NBZj67v+iNWwLKQ="
},
"kde-gtk-config": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kde-gtk-config-6.4.0.tar.xz",
"hash": "sha256-ygZtqEJyKAw/1qGBlw2U854Re+yM7pHXGi4lLCFF788="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kde-gtk-config-6.4.1.tar.xz",
"hash": "sha256-S79X5NeYqJnD8SM1BClZrvz11q81SwSJXk6N3ujIxD4="
},
"kdecoration": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kdecoration-6.4.0.tar.xz",
"hash": "sha256-pMyMS8dB0KQj11DO1m4UG5uY/McUaKshDlTaOCFTtYA="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kdecoration-6.4.1.tar.xz",
"hash": "sha256-obRAHtr3/iFjw+HKtUjZPDExlXuFNPISSe787uSW4SI="
},
"kdeplasma-addons": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kdeplasma-addons-6.4.0.tar.xz",
"hash": "sha256-XwS3FmjLhADglL7Oa7bHRra7k2W8EWk4tm2Kq9hJNVo="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kdeplasma-addons-6.4.1.tar.xz",
"hash": "sha256-iUv51ID9vwo+AFczkVNaQemlfO5yP7rQ+NosFtKZ0vY="
},
"kgamma": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kgamma-6.4.0.tar.xz",
"hash": "sha256-IRQh+vjZAB3JNgkv0fTyEVNIWvQ08AcfVdIovRo5xUg="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kgamma-6.4.1.tar.xz",
"hash": "sha256-zClBxUYyHA9ACHqB4sPY1E6jhFA0wWQXmmOEtU7w+5A="
},
"kglobalacceld": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kglobalacceld-6.4.0.tar.xz",
"hash": "sha256-9+Z6c2e2C9RTBVjvkZgN+ha7UA1VFutonrUAQeELDzI="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kglobalacceld-6.4.1.tar.xz",
"hash": "sha256-PuOK9MlVHeZAoYZ9J4NS2BcUaSz3AAwg0Z3CYuBL9DM="
},
"kinfocenter": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kinfocenter-6.4.0.tar.xz",
"hash": "sha256-TS3q9MH/dv8QDtawfXyxWLoRbEwiG3tfeyVEAoUFRJQ="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kinfocenter-6.4.1.tar.xz",
"hash": "sha256-IOr7rnikN/dnuLbpSTh1sjADP5dgRUcy6BBIPIISeSc="
},
"kmenuedit": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kmenuedit-6.4.0.tar.xz",
"hash": "sha256-SuSmetygfhDCR1uaGay9KD0YQKmWu8CE2bGyN8fm74g="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kmenuedit-6.4.1.tar.xz",
"hash": "sha256-VdsXXw897aYVS/sMchrfGD9jwTS3eFjJ+74IWK6cd3M="
},
"kpipewire": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kpipewire-6.4.0.tar.xz",
"hash": "sha256-1ZdmWk7lekmT2QjmIVEkKumlo6JedtC6AD85ymhp41o="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kpipewire-6.4.1.tar.xz",
"hash": "sha256-Npbf0ZtT5e+h57xpDDggkZuLvcDXj5Z3nMOzGekDX+I="
},
"krdp": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/krdp-6.4.0.tar.xz",
"hash": "sha256-78FnobeNIWoopi/TzJmBhQKGK6hB7/F1k+4VchzhRdU="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/krdp-6.4.1.tar.xz",
"hash": "sha256-zoGR8xXF9HBGuZh/Uv/wqI/8P51AmJ7yQj8QuY4sWMI="
},
"kscreen": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kscreen-6.4.0.tar.xz",
"hash": "sha256-5M7giQpTQFMVH6XoU3Ktgukmm5TNPcMytzfDbEcRcn8="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kscreen-6.4.1.tar.xz",
"hash": "sha256-w6KFacTwkt74RWTpFi64p/poGo9GWKFNgkNuohdU3Fs="
},
"kscreenlocker": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kscreenlocker-6.4.0.tar.xz",
"hash": "sha256-uEAgK6a1vXgyqyEWvu4sjjhvqbhE5tsOQlqEAGtmmPo="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kscreenlocker-6.4.1.tar.xz",
"hash": "sha256-yEnck5oFCibycDk/i1nouG1nGYOnUuAUr3yJoclVuSU="
},
"ksshaskpass": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/ksshaskpass-6.4.0.tar.xz",
"hash": "sha256-zjx7qfFmOOteA3iCFEioS5oGGSKL6BluVcOV/U10OAY="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/ksshaskpass-6.4.1.tar.xz",
"hash": "sha256-VJXbLUX5sqxQqBOC9+OMmauD1+o0rc9ysFwmDZ2KNDM="
},
"ksystemstats": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/ksystemstats-6.4.0.tar.xz",
"hash": "sha256-4PiFWk25FQgGa52lEI3bzki7rdpku5ZlOsL7MS/BRo4="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/ksystemstats-6.4.1.tar.xz",
"hash": "sha256-pwp0070kEW9gAQhrlCzJ1p91FPP1t8KgOC1dwoHn8Ko="
},
"kwallet-pam": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kwallet-pam-6.4.0.tar.xz",
"hash": "sha256-RQ5Na4BMWX61EVkADhk2iJJuTYIlrhmhYn4l0R/ri14="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kwallet-pam-6.4.1.tar.xz",
"hash": "sha256-BNTXB1y5PKwQp+BQSDbZYcei7aTwiYe7UA+ScgApi3w="
},
"kwayland": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kwayland-6.4.0.tar.xz",
"hash": "sha256-CmSafVAjcCLJsMDz798qe/vreU43zzdcohkOZLXR2x8="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kwayland-6.4.1.tar.xz",
"hash": "sha256-f48oQSL/2kTF4dZEJ76QWcoj9an78JLiod5tQd5FhiU="
},
"kwayland-integration": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kwayland-integration-6.4.0.tar.xz",
"hash": "sha256-olIYm9HKCRWbtweBb/nVUqWzAJMpyTCg6YN3KEvw8Rw="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kwayland-integration-6.4.1.tar.xz",
"hash": "sha256-IQk2AksNGsr5zZOo94SjSBBhno6zVvaPAgVHU1QK5gs="
},
"kwin": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kwin-6.4.0.tar.xz",
"hash": "sha256-DTSSMXpxmmRb8ok/ysIbspeWBrrzcDYQ5Va1961U3mo="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kwin-6.4.1.tar.xz",
"hash": "sha256-1OQwbJbMLouoYw6sMjT7wIVoWwCrxeWvwsLBxsb8pNQ="
},
"kwin-x11": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kwin-x11-6.4.0.tar.xz",
"hash": "sha256-dtfAGOtu5lcpLIkquc50CYKQ7uB8P9+p18UxSX2OW3c="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kwin-x11-6.4.1.tar.xz",
"hash": "sha256-eYy9ba9fstfr20lOaxLzmp7A4CWicjNiEhOWYUEgfAs="
},
"kwrited": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/kwrited-6.4.0.tar.xz",
"hash": "sha256-ZCxWdKsNlcoKQtbRstrKtf+/wGcZgZUo+iUVPGimRUo="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/kwrited-6.4.1.tar.xz",
"hash": "sha256-qApe1F7WM/Fc86QrLZVmCNnmpaePJn3zOslqr8wg2NQ="
},
"layer-shell-qt": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/layer-shell-qt-6.4.0.tar.xz",
"hash": "sha256-K55BM9Cb6Fji7mEHpWir0xoWC0ZlRatLZjEcaDlcd7A="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/layer-shell-qt-6.4.1.tar.xz",
"hash": "sha256-54HK3sALTDibkUPLOkDfd4iqTU0hHIhH9rm2UXbm6c4="
},
"libkscreen": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/libkscreen-6.4.0.tar.xz",
"hash": "sha256-4kBHbhXFfoWnkQf++9zLBwgoiaSUtXqlx8Tm8gjpEho="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/libkscreen-6.4.1.tar.xz",
"hash": "sha256-dBU8GUDd7sCZuhIMenm7yzn/42NE581cQ2CHdq9bLRQ="
},
"libksysguard": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/libksysguard-6.4.0.tar.xz",
"hash": "sha256-v9C695c0B0RAk+E6XOKzEM7lhuO7xdThB4W8Gg1FpmM="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/libksysguard-6.4.1.tar.xz",
"hash": "sha256-fDOUnb3MzuzjX779JEpESbI7UHHgytCC+RruZPeygeE="
},
"libplasma": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/libplasma-6.4.0.tar.xz",
"hash": "sha256-/4bw2QYlS7yfkQfzg7Gfu1un2yQ/q38tfSeP6DFGNUw="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/libplasma-6.4.1.tar.xz",
"hash": "sha256-O6Tx+KmWix0zlWT5GzOBjoDmEt5+U0WREXJGlj0scXs="
},
"milou": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/milou-6.4.0.tar.xz",
"hash": "sha256-7SWKx4tH2O7oFxOIq8EtxzuvP+gkK8EZpqMUMdfbPzA="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/milou-6.4.1.tar.xz",
"hash": "sha256-IZQ2nUxFpTe3kyK/3T7MUlL7Vd/Y968hA8j3t9ouUIA="
},
"ocean-sound-theme": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/ocean-sound-theme-6.4.0.tar.xz",
"hash": "sha256-r6ZyqRyuqaNPn+aZA7/02M+ZsWOT21LVRvq+K1uOp3M="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/ocean-sound-theme-6.4.1.tar.xz",
"hash": "sha256-o/ddckD0SKRnOT6xTxQxrAsFNf5JKYyf+hdLAFAJl/M="
},
"oxygen": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/oxygen-6.4.0.tar.xz",
"hash": "sha256-p29NbjoPnvZzq3W3sULfUTbYevHwlMz63Svm5s5sLCQ="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/oxygen-6.4.1.tar.xz",
"hash": "sha256-b5siN5HxUR5v7sS2i6YDThJF4D6iHRMf4YxKhJdVRqU="
},
"oxygen-sounds": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/oxygen-sounds-6.4.0.tar.xz",
"hash": "sha256-Wz1d8nOQ7ggmCWSypo1Zl/L1B9F1MRRg+6Gs6kFNyFI="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/oxygen-sounds-6.4.1.tar.xz",
"hash": "sha256-pv3YCBYyLq0GRdiJUQpUAh/UvYGEiBTfh1SM8m4HaD8="
},
"plasma-activities": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-activities-6.4.0.tar.xz",
"hash": "sha256-Go8DS7iVx1d5jFvoeiDbVGlvRe7ePXG4uBXPZmz864w="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-activities-6.4.1.tar.xz",
"hash": "sha256-DsBpK13LBfyC0ef3KFq4LaImndt9Axi49KYQONpE2WM="
},
"plasma-activities-stats": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-activities-stats-6.4.0.tar.xz",
"hash": "sha256-kxNliQbYG/KW2emKwZeQuD6Ii6ifESPGKwpy+TjyjuY="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-activities-stats-6.4.1.tar.xz",
"hash": "sha256-rfX0v6dY/0EwmXjvULv1/wpZbq+RNzhtS4cOe8wjMLc="
},
"plasma-browser-integration": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-browser-integration-6.4.0.tar.xz",
"hash": "sha256-FH4LixBeR8o/xpTdLYbsvqp8PDFdi/PaDUtuNagp56Q="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-browser-integration-6.4.1.tar.xz",
"hash": "sha256-eqDYwMci6fdjuu9cFTp/iC9JDbz5lWPQRye3WcXC1jQ="
},
"plasma-desktop": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-desktop-6.4.0.tar.xz",
"hash": "sha256-GOEUAzwYLSY8k39bxBeTJSkx3NrCKwTUnTOgEJuyrrI="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-desktop-6.4.1.tar.xz",
"hash": "sha256-tc979WDIpK/1oSGc+kF6h2uYIHGju4AdKv9T2/GKBYQ="
},
"plasma-dialer": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-dialer-6.4.0.tar.xz",
"hash": "sha256-pyPbCGLDWhw48Fn8zs8rUECrOiv/+gHPY7fh+yUh45A="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-dialer-6.4.1.tar.xz",
"hash": "sha256-8bIXU1QRiWxHwQ4cc99Zsp9mQwU8cdfuHWXqLiUr0Q4="
},
"plasma-disks": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-disks-6.4.0.tar.xz",
"hash": "sha256-lMle0b1JREjIHjU2Dci0muBazsExZR7IFxb0pSIY6pA="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-disks-6.4.1.tar.xz",
"hash": "sha256-yY+aDVMimCqQhJfXzAKGeCVIYle44lRi0ZfzNgEcUxQ="
},
"plasma-firewall": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-firewall-6.4.0.tar.xz",
"hash": "sha256-8MCE2Yxff3Kjc1X9vN/nwv8CBe0kAJAUQGqSRNZIRoU="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-firewall-6.4.1.tar.xz",
"hash": "sha256-ctXVNJPuOQGEf+Y8+XamjX9gGwh40spnBOhkoFwPv5w="
},
"plasma-integration": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-integration-6.4.0.tar.xz",
"hash": "sha256-pxhoIFKN72+Ie2Qu+nv7TE4UjRTmXvCreH/DWmLigdA="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-integration-6.4.1.tar.xz",
"hash": "sha256-EoE9sNZoVVBXAammIi5qUTpVV4kDJfEMofy/eH2R7eM="
},
"plasma-mobile": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-mobile-6.4.0.tar.xz",
"hash": "sha256-1m4fkOvV+ZPueDW3+K6suq0VtB5W3wqyq65Ve0Ck2Dg="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-mobile-6.4.1.tar.xz",
"hash": "sha256-+1ivtVRjh7bYN7rGEyNXTgywKBvKob3gH0KKzsWZ8xY="
},
"plasma-nano": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-nano-6.4.0.tar.xz",
"hash": "sha256-gF400TsjLpf5D3pU/DnLx5qU2ZZ83e3t4GAgKD4+n/E="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-nano-6.4.1.tar.xz",
"hash": "sha256-dg9AAdpOMJqWH27gpbl+df+cyzLwQgcLNAz/cHhbMRM="
},
"plasma-nm": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-nm-6.4.0.tar.xz",
"hash": "sha256-JZC7gTpX7UEdNwfrrUuo4tvE7V2DC/I1R/loYpcV1Tc="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-nm-6.4.1.tar.xz",
"hash": "sha256-UdwzjlHWBuEx9OM9T7e7KOrYpJzWikYiUtySClkRHFA="
},
"plasma-pa": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-pa-6.4.0.tar.xz",
"hash": "sha256-exm0FHhwiDWhWASU5VIYA7ybeUdLUO0ev5MYog4e0ag="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-pa-6.4.1.tar.xz",
"hash": "sha256-C3lyY/Ug3n1zgbcFsW1e/Ul2ZMTzdhoty6k8axxKttE="
},
"plasma-sdk": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-sdk-6.4.0.tar.xz",
"hash": "sha256-s/ExaxY7tearhpcDBuZjdgrpOBSkPtQ/Ky92ESisKIU="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-sdk-6.4.1.tar.xz",
"hash": "sha256-c6hlAmveq0XI9ItQrGVvDmJrsEE+dkfAFtkGi8sPVEY="
},
"plasma-systemmonitor": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-systemmonitor-6.4.0.tar.xz",
"hash": "sha256-lDac1svv9f+vNgXudmDqSqoD2VkoKw8g1lmpU64tl1o="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-systemmonitor-6.4.1.tar.xz",
"hash": "sha256-sYENMpuBrDWvynX1/yiHtyTi/HsfnFEBmLh8KcuL3l8="
},
"plasma-thunderbolt": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-thunderbolt-6.4.0.tar.xz",
"hash": "sha256-w92KudTZFGkp87OWftV/ZpXQpW+Q8oGWTRzwTa9uXI4="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-thunderbolt-6.4.1.tar.xz",
"hash": "sha256-FSxKrKBrV5HBGyBdehA+gGHcX/qt/3T0/Q8Zhc/Jzj0="
},
"plasma-vault": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-vault-6.4.0.tar.xz",
"hash": "sha256-zdDtq+GiFchWaMRzSfOsju2VpGG71WTWfsjfIXDq52w="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-vault-6.4.1.tar.xz",
"hash": "sha256-ayOumkp28MaGltQ0awdjtD5STWBceFcNsy/RC4Znp2w="
},
"plasma-welcome": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-welcome-6.4.0.tar.xz",
"hash": "sha256-Lw08NImQOoZYa4Otb7UrwVLhtFnkq+yC/wIrUbjStDY="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-welcome-6.4.1.tar.xz",
"hash": "sha256-BpW/epqDX01kBq2bdjycyWwH14GVlMT1CIfrcnfnToA="
},
"plasma-workspace": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-workspace-6.4.0.tar.xz",
"hash": "sha256-lh71T3/SHyEvjWMzAPG7BSBSSql5TkM64avhasBWCys="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-workspace-6.4.1.tar.xz",
"hash": "sha256-IGe1OeV0Rbs1/DtYmk9feu4xVJkG4iDojYeQ168yruQ="
},
"plasma-workspace-wallpapers": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma-workspace-wallpapers-6.4.0.tar.xz",
"hash": "sha256-zEs1PLI63zJos4sVxvb70lpjd0tJgkaPgORQ9gDTkwI="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma-workspace-wallpapers-6.4.1.tar.xz",
"hash": "sha256-ckXn4lj1YoL+IUJZ+ughSV78ArO5GqnWo58r7Z9eYdc="
},
"plasma5support": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plasma5support-6.4.0.tar.xz",
"hash": "sha256-OuNktBqGjQ/ZlHxTs9iHI5OLsIA/H4Yphfkztslz6EM="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plasma5support-6.4.1.tar.xz",
"hash": "sha256-EXo7m806Y96DcZ2U85o0zM9kOnFDXISlxQWwRERrjas="
},
"plymouth-kcm": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/plymouth-kcm-6.4.0.tar.xz",
"hash": "sha256-WW0OK4QQbLkS1Poo38mmLPppMAEPJ7aPw0ph2TQSWVM="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/plymouth-kcm-6.4.1.tar.xz",
"hash": "sha256-KL2d+x5qiAoCsJ3ylJLBbF+7KAU6oqe3wTao4+cGxF0="
},
"polkit-kde-agent-1": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/polkit-kde-agent-1-6.4.0.tar.xz",
"hash": "sha256-qKtd9qseoF5j7wjrvlNuE5PU9tbdSylzBWGfweh1FcU="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/polkit-kde-agent-1-6.4.1.tar.xz",
"hash": "sha256-uxzAN3JTaDNEOdE9x94SxfUXs5g4XxyfUpVxpTkqkwI="
},
"powerdevil": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/powerdevil-6.4.0.tar.xz",
"hash": "sha256-0K1Uy21MzznA1bfwx98vUbyZ/9P9bKdTjtP0HfxPZ34="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/powerdevil-6.4.1.tar.xz",
"hash": "sha256-k+Q4HyU/npYHh/61/LhuoafA4peOOzAJrhkqhq5zRi8="
},
"print-manager": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/print-manager-6.4.0.tar.xz",
"hash": "sha256-KrsouJRLPkxIQTyzG1TgeMn6jR/YwRWmFQcxA52Sy/0="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/print-manager-6.4.1.tar.xz",
"hash": "sha256-kJbF8osp9hmb8Kzph2Nh8zZ7efII4FxKWTOdF9S8GfI="
},
"qqc2-breeze-style": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/qqc2-breeze-style-6.4.0.tar.xz",
"hash": "sha256-S+kIS9VZdE2Awgs4k8K7tE3Bk/2TJPTbjSf2rQl++kw="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/qqc2-breeze-style-6.4.1.tar.xz",
"hash": "sha256-YI/1NtUTVx861Kyv1JYOwLWiq/z/MZMhS6wnonR5a+c="
},
"sddm-kcm": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/sddm-kcm-6.4.0.tar.xz",
"hash": "sha256-N4t+twvSPMm7ZUs2a4X7YVgkdqvECIYRU0vDyJGPa/I="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/sddm-kcm-6.4.1.tar.xz",
"hash": "sha256-otENV7QyyCJ83OGTrbuVAAaaKrHY1kYsahgZknXLnsY="
},
"spacebar": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/spacebar-6.4.0.tar.xz",
"hash": "sha256-LHSJ/AczyJjSTexA0fuOUHFAMcJkFPaCYma9PJnAFYA="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/spacebar-6.4.1.tar.xz",
"hash": "sha256-X/eec6cvsOSdE+PTQwPTRcqzP6T/IkdQWErePFJE/4k="
},
"spectacle": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/spectacle-6.4.0.tar.xz",
"hash": "sha256-cxdWeX6+/p9evbYymwz0zdX2wWmq8WpYwpQF/5emprA="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/spectacle-6.4.1.tar.xz",
"hash": "sha256-VHuMxlFzCRYQSosTE1BIFOyn/mpavOJUwQs3/6GxPjQ="
},
"systemsettings": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/systemsettings-6.4.0.tar.xz",
"hash": "sha256-TDhVGapA6Q3LCxoLBw0zE/2e1fszyWPqVFnOXTFpLz8="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/systemsettings-6.4.1.tar.xz",
"hash": "sha256-on8xKikqxMXD76GvcecMqDTX7I6PN6cQz4WuLXu+/5U="
},
"wacomtablet": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/wacomtablet-6.4.0.tar.xz",
"hash": "sha256-c3FmxmiOSOIdTaNp3C83yG/kjx6rv4ndjPJ4WeGiltk="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/wacomtablet-6.4.1.tar.xz",
"hash": "sha256-9n38GT270K5Rxt8IWb6HpNXtae4oO64HzpG0JF++4NE="
},
"xdg-desktop-portal-kde": {
"version": "6.4.0",
"url": "mirror://kde/stable/plasma/6.4.0/xdg-desktop-portal-kde-6.4.0.tar.xz",
"hash": "sha256-ANt7FVEUaw2pEHi/VAyir1bJ0g+fJUaeJYOdCUVams4="
"version": "6.4.1",
"url": "mirror://kde/stable/plasma/6.4.1/xdg-desktop-portal-kde-6.4.1.tar.xz",
"hash": "sha256-HwHWKfaBjkiqas+D9YwH8N3z4b8qHstEgDr2XN4RlYM="
}
}

View File

@ -2,6 +2,7 @@
mkKdeDerivation,
pkg-config,
systemd,
elfutils,
gdb,
python3,
replaceVars,
@ -20,8 +21,9 @@ mkKdeDerivation {
pname = "drkonqi";
patches = [
(replaceVars ./gdb-path.patch {
(replaceVars ./hardcode-paths.patch {
gdb = "${gdb'}/bin/gdb";
eu-unstrip = "${elfutils}/bin/eu-unstrip";
})
];

View File

@ -1,5 +1,18 @@
diff --git a/src/data/gdb_preamble/preamble.py b/src/data/gdb_preamble/preamble.py
index 4855231b5..a488025c1 100644
--- a/src/data/gdb_preamble/preamble.py
+++ b/src/data/gdb_preamble/preamble.py
@@ -773,7 +773,7 @@ def resolve_modules():
# core doesn't contain one. That makes the ids a bit unreliable but still better than nothing I suppose.
# Ultimately we'll want to use gdb here.
# https://sourceware.org/bugzilla/show_bug.cgi?id=32844
- output = get_stdout(['eu-unstrip', "--list-only", f"--core={corefile}"], env=env)
+ output = get_stdout(['@eu-unstrip@', "--list-only", f"--core={corefile}"], env=env)
for line in output.splitlines():
image = CoreImage(line)
if image.valid:
diff --git a/src/debugger.cpp b/src/debugger.cpp
index 946bdd12..5c24b371 100644
index 946bdd12e..5c24b3713 100644
--- a/src/debugger.cpp
+++ b/src/debugger.cpp
@@ -36,12 +36,12 @@ QList<Debugger> Debugger::availableInternalDebuggers(const QString &backend)

View File

@ -2,7 +2,7 @@
# Do not edit!
{
version = "2025.6.1";
version = "2025.6.2";
components = {
"3_day_blinds" =
ps: with ps; [

View File

@ -386,7 +386,7 @@ let
extraBuildInputs = extraPackages python.pkgs;
# Don't forget to run update-component-packages.py after updating
hassVersion = "2025.6.1";
hassVersion = "2025.6.2";
in
python.pkgs.buildPythonApplication rec {
@ -407,13 +407,13 @@ python.pkgs.buildPythonApplication rec {
owner = "home-assistant";
repo = "core";
tag = version;
hash = "sha256-Pp2IIpVfzYE4BBJEq4Ll2s0vgsqxAApE8TmVd1zAg38=";
hash = "sha256-5+L687sUD+e8F9UYnFURSUMG2/USuOpNu5a9By0yZ/g=";
};
# Secondary source is pypi sdist for translations
sdist = fetchPypi {
inherit pname version;
hash = "sha256-yc4tEyR3xpo4x9daWEwXFJBhSH3xeOc2ckO+7LWVRlA=";
hash = "sha256-DLqP9/b68ikGuxrvFiJCqguE2WgnKP0HtiU2X7tUbkE=";
};
build-system = with python.pkgs; [

View File

@ -18,7 +18,7 @@
buildPythonPackage rec {
pname = "pytest-homeassistant-custom-component";
version = "0.13.251";
version = "0.13.253";
pyproject = true;
disabled = pythonOlder "3.13";
@ -27,7 +27,7 @@ buildPythonPackage rec {
owner = "MatthewFlamm";
repo = "pytest-homeassistant-custom-component";
rev = "refs/tags/${version}";
hash = "sha256-S+BC3ohAsY11SdZZdlETskCAopKeohgb16vMpko01YY=";
hash = "sha256-P2ZYOHUc8tTzwSSUGKdm+zQD4hgVpewkKSg3GRpF70M=";
};
build-system = [ setuptools ];

View File

@ -10,7 +10,7 @@
buildPythonPackage rec {
pname = "homeassistant-stubs";
version = "2025.6.1";
version = "2025.6.2";
pyproject = true;
disabled = python.version != home-assistant.python.version;
@ -19,7 +19,7 @@ buildPythonPackage rec {
owner = "KapJI";
repo = "homeassistant-stubs";
tag = version;
hash = "sha256-JTSIVe25EXZ7Bslkcz8/wLFJDx3f78OGsfDodtHMZ/Y=";
hash = "sha256-Hdk7Lf0J4wgx+xhrKtBgBtO+DzCqQ2sih5DaoYcsWww=";
};
build-system = [

View File

@ -0,0 +1,34 @@
{
fetchFromGitHub,
lib,
postgresql,
postgresqlBuildExtension,
postgresqlTestExtension,
}:
postgresqlBuildExtension (finalAttrs: {
pname = "ip4r";
version = "2.4.2";
src = fetchFromGitHub {
owner = "RhodiumToad";
repo = "ip4r";
tag = "${finalAttrs.version}";
hash = "sha256-3chAD4f4A6VlXVSI0kfC/ANcnFy4vBp4FZpT6QRAueQ=";
};
passthru.tests = {
extension = postgresqlTestExtension {
inherit (finalAttrs) finalPackage;
sql = "CREATE EXTENSION ip4r;";
};
};
meta = {
description = "IPv4/v6 and IPv4/v6 range index type for PostgreSQL";
homepage = "https://github.com/RhodiumToad/ip4r";
license = lib.licenses.postgresql;
maintainers = with lib.maintainers; [ lukegb ];
inherit (postgresql.meta) platforms;
};
})

View File

@ -9,6 +9,7 @@
# `lix-doc`.
docCargoDeps ? null,
patches ? [ ],
knownVulnerabilities ? [ ],
}@args:
assert lib.assertMsg (
@ -390,5 +391,6 @@ stdenv.mkDerivation (finalAttrs: {
platforms = lib.platforms.unix;
outputsToInstall = [ "out" ] ++ lib.optional enableDocumentation "man";
mainProgram = "nix";
inherit knownVulnerabilities;
};
})

View File

@ -133,6 +133,10 @@ lib.makeExtensible (self: {
sourceRoot = "${src.name or src}/lix-doc";
hash = "sha256-VPcrf78gfLlkTRrcbLkPgLOk0o6lsOJBm6HYLvavpNU=";
};
knownVulnerabilities = [
"Lix 2.90 is vulnerable to CVE-2025-46415 and CVE-2025-46416 and will not receive updates."
];
};
nix-eval-jobs-args = {
@ -150,13 +154,13 @@ lib.makeExtensible (self: {
attrName = "lix_2_91";
lix-args = rec {
version = "2.91.1";
version = "2.91.2";
src = fetchFromGitHub {
owner = "lix-project";
repo = "lix";
rev = version;
hash = "sha256-hiGtfzxFkDc9TSYsb96Whg0vnqBVV7CUxyscZNhed0U=";
hash = "sha256-TkRjskDnxMPugdLQE/LqIh59RYQFJLYpIuL8YZva2lM=";
};
docCargoDeps = rustPlatform.fetchCargoVendor {
@ -182,13 +186,13 @@ lib.makeExtensible (self: {
attrName = "lix_2_92";
lix-args = rec {
version = "2.92.0";
version = "2.92.2";
src = fetchFromGitHub {
owner = "lix-project";
repo = "lix";
rev = version;
hash = "sha256-CCKIAE84dzkrnlxJCKFyffAxP3yfsOAbdvydUGqq24g=";
hash = "sha256-D7YepvFkGE4K1rOkEYA1P6wGj/eFbQXb03nLdBRjjwA=";
};
cargoDeps = rustPlatform.fetchCargoVendor {
@ -212,14 +216,14 @@ lib.makeExtensible (self: {
attrName = "lix_2_93";
lix-args = rec {
version = "2.93.0";
version = "2.93.1";
src = fetchFromGitea {
domain = "git.lix.systems";
owner = "lix-project";
repo = "lix";
rev = version;
hash = "sha256-hsFe4Tsqqg4l+FfQWphDtjC79WzNCZbEFhHI8j2KJzw=";
hash = "sha256-LmQhjQ7c+AOkwhvR9GFgJOy8oHW35MoQRELtrwyVnPw=";
};
cargoDeps = rustPlatform.fetchCargoVendor {
@ -249,6 +253,10 @@ lib.makeExtensible (self: {
inherit src;
hash = "sha256-YMyNOXdlx0I30SkcmdW/6DU0BYc3ZOa2FMJSKMkr7I8=";
};
patches = [
./patches/LIX_HEAD_CVE-2025-46415_46416.patch
];
};
};

File diff suppressed because it is too large Load Diff

View File

@ -111,7 +111,7 @@ let
"shadowstack"
] ++ lib.optional stdenv.hostPlatform.isMusl "fortify";
nativeInstallCheckInputs = lib.optional atLeast224 [
nativeInstallCheckInputs = lib.optionals atLeast224 [
git
man
];

View File

@ -171,34 +171,39 @@ lib.makeExtensible (
nix_2_24 = commonAutoconf {
version = "2.24.14";
hash = "sha256-SthMCsj6POjawLnJq9+lj/UzObX9skaeN1UGmMZiwTY=";
patches = [ ./patches/ghsa-g948-229j-48j3-2.24.patch ];
self_attribute_name = "nix_2_24";
};
nix_2_26 = commonMeson {
version = "2.26.3";
hash = "sha256-5ZV8YqU8mfFmoAMiUEuBqNwk0T3vUR//x1D12BiYCeY=";
patches = [ ./patches/ghsa-g948-229j-48j3-2.26.patch ];
self_attribute_name = "nix_2_26";
};
nix_2_28 = commonMeson {
version = "2.28.3";
hash = "sha256-TjZp5ITSUvNRAzNznmkZRQxNRzMLiSAplz4bV2T8cbs=";
patches = [ ./patches/ghsa-g948-229j-48j3-2.28.patch ];
self_attribute_name = "nix_2_28";
};
nixComponents_2_29 = nixDependencies.callPackage ./modular/packages.nix rec {
version = "2.29.0";
inherit (self.nix_2_24.meta) maintainers teams;
otherSplices = generateSplicesForNixComponents "nixComponents_2_29";
src = fetchFromGitHub {
# FIXME: back to NixOS org once they fix it
owner = "vcunat";
repo = "nix";
rev = "p/jq-1.8.0"; # just a tiny test-only patch atop 2.29.0
# see https://github.com/NixOS/nix/pull/13371
hash = "sha256-F2ZODsET4cBsgsyOi8Sg/quESU0DnrYri0hYniqu37k=";
};
};
nixComponents_2_29 =
(nixDependencies.callPackage ./modular/packages.nix rec {
version = "2.29.0";
inherit (self.nix_2_24.meta) maintainers teams;
otherSplices = generateSplicesForNixComponents "nixComponents_2_29";
src = fetchFromGitHub {
# FIXME: back to NixOS org once they fix it
owner = "vcunat";
repo = "nix";
rev = "p/jq-1.8.0"; # just a tiny test-only patch atop 2.29.0
# see https://github.com/NixOS/nix/pull/13371
hash = "sha256-F2ZODsET4cBsgsyOi8Sg/quESU0DnrYri0hYniqu37k=";
};
}).appendPatches
[ ./patches/ghsa-g948-229j-48j3-2.29.patch ];
nix_2_29 = addTests "nix_2_29" self.nixComponents_2_29.nix-everything;

View File

@ -27,9 +27,7 @@ mkMesonLibrary (finalAttrs: {
[
brotli
]
++ lib.optional (lib.versionAtLeast version "2.27") [
libblake3
]
++ lib.optional (lib.versionAtLeast version "2.27") libblake3
++ [
libsodium
openssl

View File

@ -0,0 +1,436 @@
From b0fab9f90b397a2b02f41df5f467ae3cf8b91c3c Mon Sep 17 00:00:00 2001
From: Eelco Dolstra <edolstra@gmail.com>
Date: Thu, 19 Jun 2025 16:20:34 +0200
Subject: [PATCH] Fixes for GHSA-g948-229j-48j3
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Squashed commit of the following:
commit 04fff3a637d455cbb1d75937a235950e43008db9
Author: Eelco Dolstra <edolstra@gmail.com>
Date: Thu Jun 12 12:30:32 2025 +0200
Chown structured attr files safely
commit 5417ad445e414c649d0cfc71a05661c7bf8f3ef5
Author: Eelco Dolstra <edolstra@gmail.com>
Date: Thu Jun 12 12:14:04 2025 +0200
Replace 'bool sync' with an enum for clarity
And drop writeFileAndSync().
commit 7ae0141f328d8e8e1094be24665789c05f974ba6
Author: Eelco Dolstra <edolstra@gmail.com>
Date: Thu Jun 12 11:35:28 2025 +0200
Drop guessOrInventPathFromFD()
No need to do hacky stuff like that when we already know the original path.
commit 45b05098bd019da7c57cd4227a89bfd0fa65bb08
Author: Eelco Dolstra <edolstra@gmail.com>
Date: Thu Jun 12 11:15:58 2025 +0200
Tweak comment
commit 0af15b31209d1b7ec8addfae9a1a6b60d8f35848
Author: Raito Bezarius <raito@lix.systems>
Date: Thu Mar 27 12:22:26 2025 +0100
libstore: ensure that temporary directory is always 0o000 before deletion
In the case the deletion fails, we should ensure that the temporary
directory cannot be used for nefarious purposes.
Change-Id: I498a2dd0999a74195d13642f44a5de1e69d46120
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit 2c20fa37b15cfa03ac6a1a6a47cdb2ed66c0827e
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 12:42:55 2025 +0100
libutil: ensure that `_deletePath` does NOT use absolute paths with dirfds
When calling `_deletePath` with a parent file descriptor, `openat` is
made effective by using relative paths to the directory file descriptor.
To avoid the problem, the signature is changed to resist misuse with an
assert in the prologue of the function.
Change-Id: I6b3fc766bad2afe54dc27d47d1df3873e188de96
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit d3c370bbcae48bb825ce19fd0f73bb4eefd2c9ea
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:07:47 2025 +0100
libstore: ensure that `passAsFile` is created in the original temp dir
This ensures that `passAsFile` data is created inside the expected
temporary build directory by `openat()` from the parent directory file
descriptor.
This avoids a TOCTOU which is part of the attack chain of CVE-????.
Change-Id: Ie5273446c4a19403088d0389ae8e3f473af8879a
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit 45d3598724f932d024ef6bc2ffb00c1bb90e6018
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:06:03 2025 +0100
libutil: writeFile variant for file descriptors
`writeFile` lose its `sync` boolean flag to make things simpler.
A new `writeFileAndSync` function is created and all call sites are
converted to it.
Change-Id: Ib871a5283a9c047db1e4fe48a241506e4aab9192
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit 732bd9b98cabf4aaf95a01fd318923de303f9996
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:05:34 2025 +0100
libstore: chown to builder variant for file descriptors
We use it immediately for the build temporary directory.
Change-Id: I180193c63a2b98721f5fb8e542c4e39c099bb947
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit 962c65f8dcd5570dd92c72370a862c7b38942e0d
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:04:59 2025 +0100
libstore: open build directory as a dirfd as well
We now keep around a proper AutoCloseFD around the temporary directory
which we plan to use for openat operations and avoiding the build
directory being swapped out while we are doing something else.
Change-Id: I18d387b0f123ebf2d20c6405cd47ebadc5505f2a
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit c9b42462b75b5a37ee6564c2b53cff186c8323da
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:04:12 2025 +0100
libutil: guess or invent a path from file descriptors
This is useful for certain error recovery paths (no pun intended) that
does not thread through the original path name.
Change-Id: I2d800740cb4f9912e64c923120d3f977c58ccb7e
Signed-off-by: Raito Bezarius <raito@lix.systems>
Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
---
src/libstore/local-store.cc | 6 +--
.../unix/build/local-derivation-goal.cc | 46 ++++++++++++++----
.../unix/build/local-derivation-goal.hh | 20 ++++++++
src/libutil/file-system.cc | 47 +++++++++++--------
src/libutil/file-system.hh | 8 +++-
5 files changed, 94 insertions(+), 33 deletions(-)
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index c6e3af456..c5489444e 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -187,7 +187,7 @@ void migrateCASchema(SQLite& db, Path schemaPath, AutoCloseFD& lockFd)
txn.commit();
}
- writeFile(schemaPath, fmt("%d", nixCASchemaVersion), 0666, true);
+ writeFile(schemaPath, fmt("%d", nixCASchemaVersion), 0666, FsSync::Yes);
lockFile(lockFd.get(), ltRead, true);
}
}
@@ -345,7 +345,7 @@ LocalStore::LocalStore(
else if (curSchema == 0) { /* new store */
curSchema = nixSchemaVersion;
openDB(*state, true);
- writeFile(schemaPath, fmt("%1%", curSchema), 0666, true);
+ writeFile(schemaPath, fmt("%1%", curSchema), 0666, FsSync::Yes);
}
else if (curSchema < nixSchemaVersion) {
@@ -394,7 +394,7 @@ LocalStore::LocalStore(
txn.commit();
}
- writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, true);
+ writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, FsSync::Yes);
lockFile(globalLock.get(), ltRead, true);
}
diff --git a/src/libstore/unix/build/local-derivation-goal.cc b/src/libstore/unix/build/local-derivation-goal.cc
index f8824e9ce..82c79f361 100644
--- a/src/libstore/unix/build/local-derivation-goal.cc
+++ b/src/libstore/unix/build/local-derivation-goal.cc
@@ -526,7 +526,14 @@ void LocalDerivationGoal::startBuilder()
} else {
tmpDir = topTmpDir;
}
- chownToBuilder(tmpDir);
+
+ /* The TOCTOU between the previous mkdir call and this open call is unavoidable due to
+ POSIX semantics.*/
+ tmpDirFd = AutoCloseFD{open(tmpDir.c_str(), O_RDONLY | O_NOFOLLOW | O_DIRECTORY)};
+ if (!tmpDirFd)
+ throw SysError("failed to open the build temporary directory descriptor '%1%'", tmpDir);
+
+ chownToBuilder(tmpDirFd.get(), tmpDir);
for (auto & [outputName, status] : initialOutputs) {
/* Set scratch path we'll actually use during the build.
@@ -1110,9 +1117,7 @@ void LocalDerivationGoal::initTmpDir() {
} else {
auto hash = hashString(HashAlgorithm::SHA256, i.first);
std::string fn = ".attr-" + hash.to_string(HashFormat::Nix32, false);
- Path p = tmpDir + "/" + fn;
- writeFile(p, rewriteStrings(i.second, inputRewrites));
- chownToBuilder(p);
+ writeBuilderFile(fn, rewriteStrings(i.second, inputRewrites));
env[i.first + "Path"] = tmpDirInSandbox + "/" + fn;
}
}
@@ -1217,11 +1222,9 @@ void LocalDerivationGoal::writeStructuredAttrs()
auto jsonSh = writeStructuredAttrsShell(json);
- writeFile(tmpDir + "/.attrs.sh", rewriteStrings(jsonSh, inputRewrites));
- chownToBuilder(tmpDir + "/.attrs.sh");
+ writeBuilderFile(".attrs.sh", rewriteStrings(jsonSh, inputRewrites));
env["NIX_ATTRS_SH_FILE"] = tmpDirInSandbox + "/.attrs.sh";
- writeFile(tmpDir + "/.attrs.json", rewriteStrings(json.dump(), inputRewrites));
- chownToBuilder(tmpDir + "/.attrs.json");
+ writeBuilderFile(".attrs.json", rewriteStrings(json.dump(), inputRewrites));
env["NIX_ATTRS_JSON_FILE"] = tmpDirInSandbox + "/.attrs.json";
}
}
@@ -1730,6 +1733,24 @@ void setupSeccomp()
#endif
}
+void LocalDerivationGoal::chownToBuilder(int fd, const Path & path)
+{
+ if (!buildUser) return;
+ if (fchown(fd, buildUser->getUID(), buildUser->getGID()) == -1)
+ throw SysError("cannot change ownership of file '%1%'", path);
+}
+
+void LocalDerivationGoal::writeBuilderFile(
+ const std::string & name,
+ std::string_view contents)
+{
+ auto path = std::filesystem::path(tmpDir) / name;
+ AutoCloseFD fd{openat(tmpDirFd.get(), name.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC | O_EXCL | O_NOFOLLOW, 0666)};
+ if (!fd)
+ throw SysError("creating file %s", path);
+ writeFile(fd, path, contents);
+ chownToBuilder(fd.get(), path);
+}
void LocalDerivationGoal::runChild()
{
@@ -3006,6 +3027,15 @@ void LocalDerivationGoal::checkOutputs(const std::map<std::string, ValidPathInfo
void LocalDerivationGoal::deleteTmpDir(bool force)
{
if (topTmpDir != "") {
+ /* As an extra precaution, even in the event of `deletePath` failing to
+ * clean up, the `tmpDir` will be chowned as if we were to move
+ * it inside the Nix store.
+ *
+ * This hardens against an attack which smuggles a file descriptor
+ * to make use of the temporary directory.
+ */
+ chmod(topTmpDir.c_str(), 0000);
+
/* Don't keep temporary directories for builtins because they
might have privileged stuff (like a copy of netrc). */
if (settings.keepFailed && !force && !drv->isBuiltin()) {
diff --git a/src/libstore/unix/build/local-derivation-goal.hh b/src/libstore/unix/build/local-derivation-goal.hh
index bf25cf2a6..69c517c4a 100644
--- a/src/libstore/unix/build/local-derivation-goal.hh
+++ b/src/libstore/unix/build/local-derivation-goal.hh
@@ -37,6 +37,11 @@ struct LocalDerivationGoal : public DerivationGoal
*/
Path topTmpDir;
+ /**
+ * The file descriptor of the temporary directory.
+ */
+ AutoCloseFD tmpDirFd;
+
/**
* The path of the temporary directory in the sandbox.
*/
@@ -232,9 +237,24 @@ struct LocalDerivationGoal : public DerivationGoal
/**
* Make a file owned by the builder.
+ *
+ * SAFETY: this function is prone to TOCTOU as it receives a path and not a descriptor.
+ * It's only safe to call in a child of a directory only visible to the owner.
*/
void chownToBuilder(const Path & path);
+ /**
+ * Make a file owned by the builder addressed by its file descriptor.
+ */
+ void chownToBuilder(int fd, const Path & path);
+
+ /**
+ * Create a file in `tmpDir` owned by the builder.
+ */
+ void writeBuilderFile(
+ const std::string & name,
+ std::string_view contents);
+
int getChildStatus() override;
/**
diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc
index 8ec38e73b..554214d66 100644
--- a/src/libutil/file-system.cc
+++ b/src/libutil/file-system.cc
@@ -247,7 +247,7 @@ void readFile(const Path & path, Sink & sink)
}
-void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
+void writeFile(const Path & path, std::string_view s, mode_t mode, FsSync sync)
{
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
// TODO
@@ -257,22 +257,29 @@ void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
, mode));
if (!fd)
throw SysError("opening file '%1%'", path);
+
+ writeFile(fd, path, s, mode, sync);
+
+ /* Close explicitly to propagate the exceptions. */
+ fd.close();
+}
+
+void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode, FsSync sync)
+{
+ assert(fd);
try {
writeFull(fd.get(), s);
+
+ if (sync == FsSync::Yes)
+ fd.fsync();
+
} catch (Error & e) {
- e.addTrace({}, "writing file '%1%'", path);
+ e.addTrace({}, "writing file '%1%'", origPath);
throw;
}
- if (sync)
- fd.fsync();
- // Explicitly close to make sure exceptions are propagated.
- fd.close();
- if (sync)
- syncParent(path);
}
-
-void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
+void writeFile(const Path & path, Source & source, mode_t mode, FsSync sync)
{
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
// TODO
@@ -296,11 +303,11 @@ void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
e.addTrace({}, "writing file '%1%'", path);
throw;
}
- if (sync)
+ if (sync == FsSync::Yes)
fd.fsync();
// Explicitly close to make sure exceptions are propagated.
fd.close();
- if (sync)
+ if (sync == FsSync::Yes)
syncParent(path);
}
@@ -318,7 +325,8 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
#ifndef _WIN32
checkInterrupt();
- std::string name(baseNameOf(path.native()));
+ std::string name(path.filename());
+ assert(name != "." && name != ".." && !name.empty());
struct stat st;
if (fstatat(parentfd, name.c_str(), &st,
@@ -359,7 +367,7 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
throw SysError("chmod '%1%'", path);
}
- int fd = openat(parentfd, path.c_str(), O_RDONLY);
+ int fd = openat(parentfd, name.c_str(), O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
if (fd == -1)
throw SysError("opening directory '%1%'", path);
AutoCloseDir dir(fdopendir(fd));
@@ -371,7 +379,7 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
checkInterrupt();
std::string childName = dirent->d_name;
if (childName == "." || childName == "..") continue;
- _deletePath(dirfd(dir.get()), path + "/" + childName, bytesFreed);
+ _deletePath(dirfd(dir.get()), path / childName, bytesFreed);
}
if (errno) throw SysError("reading directory '%1%'", path);
}
@@ -389,14 +397,13 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
static void _deletePath(const fs::path & path, uint64_t & bytesFreed)
{
- Path dir = dirOf(path.string());
- if (dir == "")
- dir = "/";
+ assert(path.is_absolute());
+ assert(path.parent_path() != path);
- AutoCloseFD dirfd = toDescriptor(open(dir.c_str(), O_RDONLY));
+ AutoCloseFD dirfd = toDescriptor(open(path.parent_path().string().c_str(), O_RDONLY));
if (!dirfd) {
if (errno == ENOENT) return;
- throw SysError("opening directory '%1%'", path);
+ throw SysError("opening directory %s", path.parent_path());
}
_deletePath(dirfd.get(), path, bytesFreed);
diff --git a/src/libutil/file-system.hh b/src/libutil/file-system.hh
index ed1112c7e..32b84456d 100644
--- a/src/libutil/file-system.hh
+++ b/src/libutil/file-system.hh
@@ -148,12 +148,16 @@ Descriptor openDirectory(const std::filesystem::path & path);
std::string readFile(const Path & path);
void readFile(const Path & path, Sink & sink);
+enum struct FsSync { Yes, No };
+
/**
* Write a string to a file.
*/
-void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, bool sync = false);
+void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
+
+void writeFile(const Path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No);
-void writeFile(const Path & path, Source & source, mode_t mode = 0666, bool sync = false);
+void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
/**
* Flush a file's parent directory to disk
--
2.44.1

View File

@ -0,0 +1,463 @@
From 787e012f26761e1455e711ab4ceedaa2c740621c Mon Sep 17 00:00:00 2001
From: Eelco Dolstra <edolstra@gmail.com>
Date: Thu, 19 Jun 2025 16:20:34 +0200
Subject: [PATCH] Fixes for GHSA-g948-229j-48j3
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Squashed commit of the following:
commit 04fff3a637d455cbb1d75937a235950e43008db9
Author: Eelco Dolstra <edolstra@gmail.com>
Date: Thu Jun 12 12:30:32 2025 +0200
Chown structured attr files safely
commit 5417ad445e414c649d0cfc71a05661c7bf8f3ef5
Author: Eelco Dolstra <edolstra@gmail.com>
Date: Thu Jun 12 12:14:04 2025 +0200
Replace 'bool sync' with an enum for clarity
And drop writeFileAndSync().
commit 7ae0141f328d8e8e1094be24665789c05f974ba6
Author: Eelco Dolstra <edolstra@gmail.com>
Date: Thu Jun 12 11:35:28 2025 +0200
Drop guessOrInventPathFromFD()
No need to do hacky stuff like that when we already know the original path.
commit 45b05098bd019da7c57cd4227a89bfd0fa65bb08
Author: Eelco Dolstra <edolstra@gmail.com>
Date: Thu Jun 12 11:15:58 2025 +0200
Tweak comment
commit 0af15b31209d1b7ec8addfae9a1a6b60d8f35848
Author: Raito Bezarius <raito@lix.systems>
Date: Thu Mar 27 12:22:26 2025 +0100
libstore: ensure that temporary directory is always 0o000 before deletion
In the case the deletion fails, we should ensure that the temporary
directory cannot be used for nefarious purposes.
Change-Id: I498a2dd0999a74195d13642f44a5de1e69d46120
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit 2c20fa37b15cfa03ac6a1a6a47cdb2ed66c0827e
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 12:42:55 2025 +0100
libutil: ensure that `_deletePath` does NOT use absolute paths with dirfds
When calling `_deletePath` with a parent file descriptor, `openat` is
made effective by using relative paths to the directory file descriptor.
To avoid the problem, the signature is changed to resist misuse with an
assert in the prologue of the function.
Change-Id: I6b3fc766bad2afe54dc27d47d1df3873e188de96
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit d3c370bbcae48bb825ce19fd0f73bb4eefd2c9ea
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:07:47 2025 +0100
libstore: ensure that `passAsFile` is created in the original temp dir
This ensures that `passAsFile` data is created inside the expected
temporary build directory by `openat()` from the parent directory file
descriptor.
This avoids a TOCTOU which is part of the attack chain of CVE-????.
Change-Id: Ie5273446c4a19403088d0389ae8e3f473af8879a
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit 45d3598724f932d024ef6bc2ffb00c1bb90e6018
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:06:03 2025 +0100
libutil: writeFile variant for file descriptors
`writeFile` lose its `sync` boolean flag to make things simpler.
A new `writeFileAndSync` function is created and all call sites are
converted to it.
Change-Id: Ib871a5283a9c047db1e4fe48a241506e4aab9192
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit 732bd9b98cabf4aaf95a01fd318923de303f9996
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:05:34 2025 +0100
libstore: chown to builder variant for file descriptors
We use it immediately for the build temporary directory.
Change-Id: I180193c63a2b98721f5fb8e542c4e39c099bb947
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit 962c65f8dcd5570dd92c72370a862c7b38942e0d
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:04:59 2025 +0100
libstore: open build directory as a dirfd as well
We now keep around a proper AutoCloseFD around the temporary directory
which we plan to use for openat operations and avoiding the build
directory being swapped out while we are doing something else.
Change-Id: I18d387b0f123ebf2d20c6405cd47ebadc5505f2a
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit c9b42462b75b5a37ee6564c2b53cff186c8323da
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:04:12 2025 +0100
libutil: guess or invent a path from file descriptors
This is useful for certain error recovery paths (no pun intended) that
does not thread through the original path name.
Change-Id: I2d800740cb4f9912e64c923120d3f977c58ccb7e
Signed-off-by: Raito Bezarius <raito@lix.systems>
Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
---
src/libstore/local-store.cc | 6 +--
.../unix/build/local-derivation-goal.cc | 46 ++++++++++++++----
.../unix/build/local-derivation-goal.hh | 20 ++++++++
src/libutil/file-content-address.cc | 2 +-
src/libutil/file-system.cc | 47 +++++++++++--------
src/libutil/file-system.hh | 14 ++++--
6 files changed, 99 insertions(+), 36 deletions(-)
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 9a7a941b6..c0c808e0a 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -116,7 +116,7 @@ LocalStore::LocalStore(
state->stmts = std::make_unique<State::Stmts>();
/* Create missing state directories if they don't already exist. */
- createDirs(realStoreDir);
+ createDirs(realStoreDir.get());
if (readOnly) {
experimentalFeatureSettings.require(Xp::ReadOnlyLocalStore);
} else {
@@ -248,7 +248,7 @@ LocalStore::LocalStore(
else if (curSchema == 0) { /* new store */
curSchema = nixSchemaVersion;
openDB(*state, true);
- writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, true);
+ writeFile(schemaPath, fmt("%1%", curSchema), 0666, FsSync::Yes);
}
else if (curSchema < nixSchemaVersion) {
@@ -299,7 +299,7 @@ LocalStore::LocalStore(
txn.commit();
}
- writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, true);
+ writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, FsSync::Yes);
lockFile(globalLock.get(), ltRead, true);
}
diff --git a/src/libstore/unix/build/local-derivation-goal.cc b/src/libstore/unix/build/local-derivation-goal.cc
index 5b9bc0bb0..80309e332 100644
--- a/src/libstore/unix/build/local-derivation-goal.cc
+++ b/src/libstore/unix/build/local-derivation-goal.cc
@@ -559,7 +559,14 @@ void LocalDerivationGoal::startBuilder()
} else {
tmpDir = topTmpDir;
}
- chownToBuilder(tmpDir);
+
+ /* The TOCTOU between the previous mkdir call and this open call is unavoidable due to
+ POSIX semantics.*/
+ tmpDirFd = AutoCloseFD{open(tmpDir.c_str(), O_RDONLY | O_NOFOLLOW | O_DIRECTORY)};
+ if (!tmpDirFd)
+ throw SysError("failed to open the build temporary directory descriptor '%1%'", tmpDir);
+
+ chownToBuilder(tmpDirFd.get(), tmpDir);
for (auto & [outputName, status] : initialOutputs) {
/* Set scratch path we'll actually use during the build.
@@ -1157,9 +1164,7 @@ void LocalDerivationGoal::initTmpDir()
} else {
auto hash = hashString(HashAlgorithm::SHA256, i.first);
std::string fn = ".attr-" + hash.to_string(HashFormat::Nix32, false);
- Path p = tmpDir + "/" + fn;
- writeFile(p, rewriteStrings(i.second, inputRewrites));
- chownToBuilder(p);
+ writeBuilderFile(fn, rewriteStrings(i.second, inputRewrites));
env[i.first + "Path"] = tmpDirInSandbox + "/" + fn;
}
}
@@ -1264,11 +1269,9 @@ void LocalDerivationGoal::writeStructuredAttrs()
auto jsonSh = writeStructuredAttrsShell(json);
- writeFile(tmpDir + "/.attrs.sh", rewriteStrings(jsonSh, inputRewrites));
- chownToBuilder(tmpDir + "/.attrs.sh");
+ writeBuilderFile(".attrs.sh", rewriteStrings(jsonSh, inputRewrites));
env["NIX_ATTRS_SH_FILE"] = tmpDirInSandbox + "/.attrs.sh";
- writeFile(tmpDir + "/.attrs.json", rewriteStrings(json.dump(), inputRewrites));
- chownToBuilder(tmpDir + "/.attrs.json");
+ writeBuilderFile(".attrs.json", rewriteStrings(json.dump(), inputRewrites));
env["NIX_ATTRS_JSON_FILE"] = tmpDirInSandbox + "/.attrs.json";
}
}
@@ -1779,6 +1782,24 @@ void setupSeccomp()
#endif
}
+void LocalDerivationGoal::chownToBuilder(int fd, const Path & path)
+{
+ if (!buildUser) return;
+ if (fchown(fd, buildUser->getUID(), buildUser->getGID()) == -1)
+ throw SysError("cannot change ownership of file '%1%'", path);
+}
+
+void LocalDerivationGoal::writeBuilderFile(
+ const std::string & name,
+ std::string_view contents)
+{
+ auto path = std::filesystem::path(tmpDir) / name;
+ AutoCloseFD fd{openat(tmpDirFd.get(), name.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC | O_EXCL | O_NOFOLLOW, 0666)};
+ if (!fd)
+ throw SysError("creating file %s", path);
+ writeFile(fd, path, contents);
+ chownToBuilder(fd.get(), path);
+}
void LocalDerivationGoal::runChild()
{
@@ -3038,6 +3059,15 @@ void LocalDerivationGoal::checkOutputs(const std::map<std::string, ValidPathInfo
void LocalDerivationGoal::deleteTmpDir(bool force)
{
if (topTmpDir != "") {
+ /* As an extra precaution, even in the event of `deletePath` failing to
+ * clean up, the `tmpDir` will be chowned as if we were to move
+ * it inside the Nix store.
+ *
+ * This hardens against an attack which smuggles a file descriptor
+ * to make use of the temporary directory.
+ */
+ chmod(topTmpDir.c_str(), 0000);
+
/* Don't keep temporary directories for builtins because they
might have privileged stuff (like a copy of netrc). */
if (settings.keepFailed && !force && !drv->isBuiltin()) {
diff --git a/src/libstore/unix/build/local-derivation-goal.hh b/src/libstore/unix/build/local-derivation-goal.hh
index 1ea247661..74a1e1c50 100644
--- a/src/libstore/unix/build/local-derivation-goal.hh
+++ b/src/libstore/unix/build/local-derivation-goal.hh
@@ -37,6 +37,11 @@ struct LocalDerivationGoal : public DerivationGoal
*/
Path topTmpDir;
+ /**
+ * The file descriptor of the temporary directory.
+ */
+ AutoCloseFD tmpDirFd;
+
/**
* The path of the temporary directory in the sandbox.
*/
@@ -244,9 +249,24 @@ struct LocalDerivationGoal : public DerivationGoal
/**
* Make a file owned by the builder.
+ *
+ * SAFETY: this function is prone to TOCTOU as it receives a path and not a descriptor.
+ * It's only safe to call in a child of a directory only visible to the owner.
*/
void chownToBuilder(const Path & path);
+ /**
+ * Make a file owned by the builder addressed by its file descriptor.
+ */
+ void chownToBuilder(int fd, const Path & path);
+
+ /**
+ * Create a file in `tmpDir` owned by the builder.
+ */
+ void writeBuilderFile(
+ const std::string & name,
+ std::string_view contents);
+
int getChildStatus() override;
/**
diff --git a/src/libutil/file-content-address.cc b/src/libutil/file-content-address.cc
index 69301d9c8..2b6839346 100644
--- a/src/libutil/file-content-address.cc
+++ b/src/libutil/file-content-address.cc
@@ -93,7 +93,7 @@ void restorePath(
{
switch (method) {
case FileSerialisationMethod::Flat:
- writeFile(path, source, 0666, startFsync);
+ writeFile(path, source, 0666, startFsync ? FsSync::Yes : FsSync::No);
break;
case FileSerialisationMethod::NixArchive:
restorePath(path, source, startFsync);
diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc
index 6fe93b63a..b3183f495 100644
--- a/src/libutil/file-system.cc
+++ b/src/libutil/file-system.cc
@@ -258,7 +258,7 @@ void readFile(const Path & path, Sink & sink)
}
-void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
+void writeFile(const Path & path, std::string_view s, mode_t mode, FsSync sync)
{
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
// TODO
@@ -268,22 +268,29 @@ void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
, mode));
if (!fd)
throw SysError("opening file '%1%'", path);
+
+ writeFile(fd, path, s, mode, sync);
+
+ /* Close explicitly to propagate the exceptions. */
+ fd.close();
+}
+
+void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode, FsSync sync)
+{
+ assert(fd);
try {
writeFull(fd.get(), s);
+
+ if (sync == FsSync::Yes)
+ fd.fsync();
+
} catch (Error & e) {
- e.addTrace({}, "writing file '%1%'", path);
+ e.addTrace({}, "writing file '%1%'", origPath);
throw;
}
- if (sync)
- fd.fsync();
- // Explicitly close to make sure exceptions are propagated.
- fd.close();
- if (sync)
- syncParent(path);
}
-
-void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
+void writeFile(const Path & path, Source & source, mode_t mode, FsSync sync)
{
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
// TODO
@@ -307,11 +314,11 @@ void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
e.addTrace({}, "writing file '%1%'", path);
throw;
}
- if (sync)
+ if (sync == FsSync::Yes)
fd.fsync();
// Explicitly close to make sure exceptions are propagated.
fd.close();
- if (sync)
+ if (sync == FsSync::Yes)
syncParent(path);
}
@@ -374,7 +381,8 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
#ifndef _WIN32
checkInterrupt();
- std::string name(baseNameOf(path.native()));
+ std::string name(path.filename());
+ assert(name != "." && name != ".." && !name.empty());
struct stat st;
if (fstatat(parentfd, name.c_str(), &st,
@@ -415,7 +423,7 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
throw SysError("chmod %1%", path);
}
- int fd = openat(parentfd, path.c_str(), O_RDONLY);
+ int fd = openat(parentfd, name.c_str(), O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
if (fd == -1)
throw SysError("opening directory %1%", path);
AutoCloseDir dir(fdopendir(fd));
@@ -427,7 +435,7 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
checkInterrupt();
std::string childName = dirent->d_name;
if (childName == "." || childName == "..") continue;
- _deletePath(dirfd(dir.get()), path + "/" + childName, bytesFreed);
+ _deletePath(dirfd(dir.get()), path / childName, bytesFreed);
}
if (errno) throw SysError("reading directory %1%", path);
}
@@ -445,14 +453,13 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
static void _deletePath(const fs::path & path, uint64_t & bytesFreed)
{
- Path dir = dirOf(path.string());
- if (dir == "")
- dir = "/";
+ assert(path.is_absolute());
+ assert(path.parent_path() != path);
- AutoCloseFD dirfd = toDescriptor(open(dir.c_str(), O_RDONLY));
+ AutoCloseFD dirfd = toDescriptor(open(path.parent_path().string().c_str(), O_RDONLY));
if (!dirfd) {
if (errno == ENOENT) return;
- throw SysError("opening directory '%1%'", path);
+ throw SysError("opening directory %s", path.parent_path());
}
_deletePath(dirfd.get(), path, bytesFreed);
diff --git a/src/libutil/file-system.hh b/src/libutil/file-system.hh
index 204907339..b2db8869e 100644
--- a/src/libutil/file-system.hh
+++ b/src/libutil/file-system.hh
@@ -194,21 +194,27 @@ std::string readFile(const Path & path);
std::string readFile(const std::filesystem::path & path);
void readFile(const Path & path, Sink & sink);
+enum struct FsSync { Yes, No };
+
/**
* Write a string to a file.
*/
-void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, bool sync = false);
-static inline void writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode = 0666, bool sync = false)
+void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
+
+static inline void writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No)
{
return writeFile(path.string(), s, mode, sync);
}
-void writeFile(const Path & path, Source & source, mode_t mode = 0666, bool sync = false);
-static inline void writeFile(const std::filesystem::path & path, Source & source, mode_t mode = 0666, bool sync = false)
+void writeFile(const Path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No);
+
+static inline void writeFile(const std::filesystem::path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No)
{
return writeFile(path.string(), source, mode, sync);
}
+void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
+
/**
* Flush a path's parent directory to disk.
*/
--
2.49.0

View File

@ -0,0 +1,454 @@
From 24c1aa735a40d3bf5361755fa10ac0e577a55eed Mon Sep 17 00:00:00 2001
From: Eelco Dolstra <edolstra@gmail.com>
Date: Thu, 19 Jun 2025 16:20:34 +0200
Subject: [PATCH] Fixes for GHSA-g948-229j-48j3
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Squashed commit of the following:
commit 04fff3a637d455cbb1d75937a235950e43008db9
Author: Eelco Dolstra <edolstra@gmail.com>
Date: Thu Jun 12 12:30:32 2025 +0200
Chown structured attr files safely
commit 5417ad445e414c649d0cfc71a05661c7bf8f3ef5
Author: Eelco Dolstra <edolstra@gmail.com>
Date: Thu Jun 12 12:14:04 2025 +0200
Replace 'bool sync' with an enum for clarity
And drop writeFileAndSync().
commit 7ae0141f328d8e8e1094be24665789c05f974ba6
Author: Eelco Dolstra <edolstra@gmail.com>
Date: Thu Jun 12 11:35:28 2025 +0200
Drop guessOrInventPathFromFD()
No need to do hacky stuff like that when we already know the original path.
commit 45b05098bd019da7c57cd4227a89bfd0fa65bb08
Author: Eelco Dolstra <edolstra@gmail.com>
Date: Thu Jun 12 11:15:58 2025 +0200
Tweak comment
commit 0af15b31209d1b7ec8addfae9a1a6b60d8f35848
Author: Raito Bezarius <raito@lix.systems>
Date: Thu Mar 27 12:22:26 2025 +0100
libstore: ensure that temporary directory is always 0o000 before deletion
In the case the deletion fails, we should ensure that the temporary
directory cannot be used for nefarious purposes.
Change-Id: I498a2dd0999a74195d13642f44a5de1e69d46120
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit 2c20fa37b15cfa03ac6a1a6a47cdb2ed66c0827e
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 12:42:55 2025 +0100
libutil: ensure that `_deletePath` does NOT use absolute paths with dirfds
When calling `_deletePath` with a parent file descriptor, `openat` is
made effective by using relative paths to the directory file descriptor.
To avoid the problem, the signature is changed to resist misuse with an
assert in the prologue of the function.
Change-Id: I6b3fc766bad2afe54dc27d47d1df3873e188de96
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit d3c370bbcae48bb825ce19fd0f73bb4eefd2c9ea
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:07:47 2025 +0100
libstore: ensure that `passAsFile` is created in the original temp dir
This ensures that `passAsFile` data is created inside the expected
temporary build directory by `openat()` from the parent directory file
descriptor.
This avoids a TOCTOU which is part of the attack chain of CVE-????.
Change-Id: Ie5273446c4a19403088d0389ae8e3f473af8879a
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit 45d3598724f932d024ef6bc2ffb00c1bb90e6018
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:06:03 2025 +0100
libutil: writeFile variant for file descriptors
`writeFile` lose its `sync` boolean flag to make things simpler.
A new `writeFileAndSync` function is created and all call sites are
converted to it.
Change-Id: Ib871a5283a9c047db1e4fe48a241506e4aab9192
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit 732bd9b98cabf4aaf95a01fd318923de303f9996
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:05:34 2025 +0100
libstore: chown to builder variant for file descriptors
We use it immediately for the build temporary directory.
Change-Id: I180193c63a2b98721f5fb8e542c4e39c099bb947
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit 962c65f8dcd5570dd92c72370a862c7b38942e0d
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:04:59 2025 +0100
libstore: open build directory as a dirfd as well
We now keep around a proper AutoCloseFD around the temporary directory
which we plan to use for openat operations and avoiding the build
directory being swapped out while we are doing something else.
Change-Id: I18d387b0f123ebf2d20c6405cd47ebadc5505f2a
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit c9b42462b75b5a37ee6564c2b53cff186c8323da
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:04:12 2025 +0100
libutil: guess or invent a path from file descriptors
This is useful for certain error recovery paths (no pun intended) that
does not thread through the original path name.
Change-Id: I2d800740cb4f9912e64c923120d3f977c58ccb7e
Signed-off-by: Raito Bezarius <raito@lix.systems>
Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
---
src/libstore/local-store.cc | 4 +-
.../unix/build/local-derivation-goal.cc | 46 ++++++++++++++----
.../nix/store/build/local-derivation-goal.hh | 20 ++++++++
src/libutil/file-content-address.cc | 2 +-
src/libutil/file-system.cc | 47 +++++++++++--------
src/libutil/include/nix/util/file-system.hh | 14 ++++--
6 files changed, 98 insertions(+), 35 deletions(-)
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index f3bee6953..eddc87ef9 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -249,7 +249,7 @@ LocalStore::LocalStore(
else if (curSchema == 0) { /* new store */
curSchema = nixSchemaVersion;
openDB(*state, true);
- writeFile(schemaPath, fmt("%1%", curSchema), 0666, true);
+ writeFile(schemaPath, fmt("%1%", curSchema), 0666, FsSync::Yes);
}
else if (curSchema < nixSchemaVersion) {
@@ -300,7 +300,7 @@ LocalStore::LocalStore(
txn.commit();
}
- writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, true);
+ writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, FsSync::Yes);
lockFile(globalLock.get(), ltRead, true);
}
diff --git a/src/libstore/unix/build/local-derivation-goal.cc b/src/libstore/unix/build/local-derivation-goal.cc
index 9edb6fb0f..a0442d0b8 100644
--- a/src/libstore/unix/build/local-derivation-goal.cc
+++ b/src/libstore/unix/build/local-derivation-goal.cc
@@ -567,7 +567,14 @@ void LocalDerivationGoal::startBuilder()
} else {
tmpDir = topTmpDir;
}
- chownToBuilder(tmpDir);
+
+ /* The TOCTOU between the previous mkdir call and this open call is unavoidable due to
+ POSIX semantics.*/
+ tmpDirFd = AutoCloseFD{open(tmpDir.c_str(), O_RDONLY | O_NOFOLLOW | O_DIRECTORY)};
+ if (!tmpDirFd)
+ throw SysError("failed to open the build temporary directory descriptor '%1%'", tmpDir);
+
+ chownToBuilder(tmpDirFd.get(), tmpDir);
for (auto & [outputName, status] : initialOutputs) {
/* Set scratch path we'll actually use during the build.
@@ -1159,9 +1166,7 @@ void LocalDerivationGoal::initTmpDir()
} else {
auto hash = hashString(HashAlgorithm::SHA256, i.first);
std::string fn = ".attr-" + hash.to_string(HashFormat::Nix32, false);
- Path p = tmpDir + "/" + fn;
- writeFile(p, rewriteStrings(i.second, inputRewrites));
- chownToBuilder(p);
+ writeBuilderFile(fn, rewriteStrings(i.second, inputRewrites));
env[i.first + "Path"] = tmpDirInSandbox + "/" + fn;
}
}
@@ -1266,11 +1271,9 @@ void LocalDerivationGoal::writeStructuredAttrs()
auto jsonSh = writeStructuredAttrsShell(json);
- writeFile(tmpDir + "/.attrs.sh", rewriteStrings(jsonSh, inputRewrites));
- chownToBuilder(tmpDir + "/.attrs.sh");
+ writeBuilderFile(".attrs.sh", rewriteStrings(jsonSh, inputRewrites));
env["NIX_ATTRS_SH_FILE"] = tmpDirInSandbox + "/.attrs.sh";
- writeFile(tmpDir + "/.attrs.json", rewriteStrings(json.dump(), inputRewrites));
- chownToBuilder(tmpDir + "/.attrs.json");
+ writeBuilderFile(".attrs.json", rewriteStrings(json.dump(), inputRewrites));
env["NIX_ATTRS_JSON_FILE"] = tmpDirInSandbox + "/.attrs.json";
}
}
@@ -1781,6 +1784,24 @@ void setupSeccomp()
#endif
}
+void LocalDerivationGoal::chownToBuilder(int fd, const Path & path)
+{
+ if (!buildUser) return;
+ if (fchown(fd, buildUser->getUID(), buildUser->getGID()) == -1)
+ throw SysError("cannot change ownership of file '%1%'", path);
+}
+
+void LocalDerivationGoal::writeBuilderFile(
+ const std::string & name,
+ std::string_view contents)
+{
+ auto path = std::filesystem::path(tmpDir) / name;
+ AutoCloseFD fd{openat(tmpDirFd.get(), name.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC | O_EXCL | O_NOFOLLOW, 0666)};
+ if (!fd)
+ throw SysError("creating file %s", path);
+ writeFile(fd, path, contents);
+ chownToBuilder(fd.get(), path);
+}
void LocalDerivationGoal::runChild()
{
@@ -3000,6 +3021,15 @@ void LocalDerivationGoal::checkOutputs(const std::map<std::string, ValidPathInfo
void LocalDerivationGoal::deleteTmpDir(bool force)
{
if (topTmpDir != "") {
+ /* As an extra precaution, even in the event of `deletePath` failing to
+ * clean up, the `tmpDir` will be chowned as if we were to move
+ * it inside the Nix store.
+ *
+ * This hardens against an attack which smuggles a file descriptor
+ * to make use of the temporary directory.
+ */
+ chmod(topTmpDir.c_str(), 0000);
+
/* Don't keep temporary directories for builtins because they
might have privileged stuff (like a copy of netrc). */
if (settings.keepFailed && !force && !drv->isBuiltin()) {
diff --git a/src/libstore/unix/include/nix/store/build/local-derivation-goal.hh b/src/libstore/unix/include/nix/store/build/local-derivation-goal.hh
index 795286a01..fb62e3ca4 100644
--- a/src/libstore/unix/include/nix/store/build/local-derivation-goal.hh
+++ b/src/libstore/unix/include/nix/store/build/local-derivation-goal.hh
@@ -37,6 +37,11 @@ struct LocalDerivationGoal : public DerivationGoal
*/
Path topTmpDir;
+ /**
+ * The file descriptor of the temporary directory.
+ */
+ AutoCloseFD tmpDirFd;
+
/**
* The path of the temporary directory in the sandbox.
*/
@@ -239,9 +244,24 @@ struct LocalDerivationGoal : public DerivationGoal
/**
* Make a file owned by the builder.
+ *
+ * SAFETY: this function is prone to TOCTOU as it receives a path and not a descriptor.
+ * It's only safe to call in a child of a directory only visible to the owner.
*/
void chownToBuilder(const Path & path);
+ /**
+ * Make a file owned by the builder addressed by its file descriptor.
+ */
+ void chownToBuilder(int fd, const Path & path);
+
+ /**
+ * Create a file in `tmpDir` owned by the builder.
+ */
+ void writeBuilderFile(
+ const std::string & name,
+ std::string_view contents);
+
int getChildStatus() override;
/**
diff --git a/src/libutil/file-content-address.cc b/src/libutil/file-content-address.cc
index 142bc70d5..d95781691 100644
--- a/src/libutil/file-content-address.cc
+++ b/src/libutil/file-content-address.cc
@@ -93,7 +93,7 @@ void restorePath(
{
switch (method) {
case FileSerialisationMethod::Flat:
- writeFile(path, source, 0666, startFsync);
+ writeFile(path, source, 0666, startFsync ? FsSync::Yes : FsSync::No);
break;
case FileSerialisationMethod::NixArchive:
restorePath(path, source, startFsync);
diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc
index 9ce3682f1..204a63c4e 100644
--- a/src/libutil/file-system.cc
+++ b/src/libutil/file-system.cc
@@ -298,7 +298,7 @@ void readFile(const Path & path, Sink & sink)
}
-void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
+void writeFile(const Path & path, std::string_view s, mode_t mode, FsSync sync)
{
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
// TODO
@@ -308,22 +308,29 @@ void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
, mode));
if (!fd)
throw SysError("opening file '%1%'", path);
+
+ writeFile(fd, path, s, mode, sync);
+
+ /* Close explicitly to propagate the exceptions. */
+ fd.close();
+}
+
+void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode, FsSync sync)
+{
+ assert(fd);
try {
writeFull(fd.get(), s);
+
+ if (sync == FsSync::Yes)
+ fd.fsync();
+
} catch (Error & e) {
- e.addTrace({}, "writing file '%1%'", path);
+ e.addTrace({}, "writing file '%1%'", origPath);
throw;
}
- if (sync)
- fd.fsync();
- // Explicitly close to make sure exceptions are propagated.
- fd.close();
- if (sync)
- syncParent(path);
}
-
-void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
+void writeFile(const Path & path, Source & source, mode_t mode, FsSync sync)
{
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
// TODO
@@ -347,11 +354,11 @@ void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
e.addTrace({}, "writing file '%1%'", path);
throw;
}
- if (sync)
+ if (sync == FsSync::Yes)
fd.fsync();
// Explicitly close to make sure exceptions are propagated.
fd.close();
- if (sync)
+ if (sync == FsSync::Yes)
syncParent(path);
}
@@ -414,7 +421,8 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
#ifndef _WIN32
checkInterrupt();
- std::string name(baseNameOf(path.native()));
+ std::string name(path.filename());
+ assert(name != "." && name != ".." && !name.empty());
struct stat st;
if (fstatat(parentfd, name.c_str(), &st,
@@ -455,7 +463,7 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
throw SysError("chmod %1%", path);
}
- int fd = openat(parentfd, path.c_str(), O_RDONLY);
+ int fd = openat(parentfd, name.c_str(), O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
if (fd == -1)
throw SysError("opening directory %1%", path);
AutoCloseDir dir(fdopendir(fd));
@@ -467,7 +475,7 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
checkInterrupt();
std::string childName = dirent->d_name;
if (childName == "." || childName == "..") continue;
- _deletePath(dirfd(dir.get()), path + "/" + childName, bytesFreed);
+ _deletePath(dirfd(dir.get()), path / childName, bytesFreed);
}
if (errno) throw SysError("reading directory %1%", path);
}
@@ -485,14 +493,13 @@ static void _deletePath(Descriptor parentfd, const fs::path & path, uint64_t & b
static void _deletePath(const fs::path & path, uint64_t & bytesFreed)
{
- Path dir = dirOf(path.string());
- if (dir == "")
- dir = "/";
+ assert(path.is_absolute());
+ assert(path.parent_path() != path);
- AutoCloseFD dirfd = toDescriptor(open(dir.c_str(), O_RDONLY));
+ AutoCloseFD dirfd = toDescriptor(open(path.parent_path().string().c_str(), O_RDONLY));
if (!dirfd) {
if (errno == ENOENT) return;
- throw SysError("opening directory '%1%'", path);
+ throw SysError("opening directory %s", path.parent_path());
}
_deletePath(dirfd.get(), path, bytesFreed);
diff --git a/src/libutil/include/nix/util/file-system.hh b/src/libutil/include/nix/util/file-system.hh
index e6b1cfef3..9a0057bbe 100644
--- a/src/libutil/include/nix/util/file-system.hh
+++ b/src/libutil/include/nix/util/file-system.hh
@@ -193,21 +193,27 @@ std::string readFile(const Path & path);
std::string readFile(const std::filesystem::path & path);
void readFile(const Path & path, Sink & sink);
+enum struct FsSync { Yes, No };
+
/**
* Write a string to a file.
*/
-void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, bool sync = false);
-static inline void writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode = 0666, bool sync = false)
+void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
+
+static inline void writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No)
{
return writeFile(path.string(), s, mode, sync);
}
-void writeFile(const Path & path, Source & source, mode_t mode = 0666, bool sync = false);
-static inline void writeFile(const std::filesystem::path & path, Source & source, mode_t mode = 0666, bool sync = false)
+void writeFile(const Path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No);
+
+static inline void writeFile(const std::filesystem::path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No)
{
return writeFile(path.string(), source, mode, sync);
}
+void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
+
/**
* Flush a path's parent directory to disk.
*/
--
2.44.1

View File

@ -0,0 +1,449 @@
From 01619fbe2dc06b79609b95b6f95ddbf4e871e762 Mon Sep 17 00:00:00 2001
From: Eelco Dolstra <edolstra@gmail.com>
Date: Thu, 19 Jun 2025 16:20:34 +0200
Subject: [PATCH] Fixes for GHSA-g948-229j-48j3
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Squashed commit of the following:
commit 04fff3a637d455cbb1d75937a235950e43008db9
Author: Eelco Dolstra <edolstra@gmail.com>
Date: Thu Jun 12 12:30:32 2025 +0200
Chown structured attr files safely
commit 5417ad445e414c649d0cfc71a05661c7bf8f3ef5
Author: Eelco Dolstra <edolstra@gmail.com>
Date: Thu Jun 12 12:14:04 2025 +0200
Replace 'bool sync' with an enum for clarity
And drop writeFileAndSync().
commit 7ae0141f328d8e8e1094be24665789c05f974ba6
Author: Eelco Dolstra <edolstra@gmail.com>
Date: Thu Jun 12 11:35:28 2025 +0200
Drop guessOrInventPathFromFD()
No need to do hacky stuff like that when we already know the original path.
commit 45b05098bd019da7c57cd4227a89bfd0fa65bb08
Author: Eelco Dolstra <edolstra@gmail.com>
Date: Thu Jun 12 11:15:58 2025 +0200
Tweak comment
commit 0af15b31209d1b7ec8addfae9a1a6b60d8f35848
Author: Raito Bezarius <raito@lix.systems>
Date: Thu Mar 27 12:22:26 2025 +0100
libstore: ensure that temporary directory is always 0o000 before deletion
In the case the deletion fails, we should ensure that the temporary
directory cannot be used for nefarious purposes.
Change-Id: I498a2dd0999a74195d13642f44a5de1e69d46120
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit 2c20fa37b15cfa03ac6a1a6a47cdb2ed66c0827e
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 12:42:55 2025 +0100
libutil: ensure that `_deletePath` does NOT use absolute paths with dirfds
When calling `_deletePath` with a parent file descriptor, `openat` is
made effective by using relative paths to the directory file descriptor.
To avoid the problem, the signature is changed to resist misuse with an
assert in the prologue of the function.
Change-Id: I6b3fc766bad2afe54dc27d47d1df3873e188de96
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit d3c370bbcae48bb825ce19fd0f73bb4eefd2c9ea
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:07:47 2025 +0100
libstore: ensure that `passAsFile` is created in the original temp dir
This ensures that `passAsFile` data is created inside the expected
temporary build directory by `openat()` from the parent directory file
descriptor.
This avoids a TOCTOU which is part of the attack chain of CVE-????.
Change-Id: Ie5273446c4a19403088d0389ae8e3f473af8879a
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit 45d3598724f932d024ef6bc2ffb00c1bb90e6018
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:06:03 2025 +0100
libutil: writeFile variant for file descriptors
`writeFile` lose its `sync` boolean flag to make things simpler.
A new `writeFileAndSync` function is created and all call sites are
converted to it.
Change-Id: Ib871a5283a9c047db1e4fe48a241506e4aab9192
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit 732bd9b98cabf4aaf95a01fd318923de303f9996
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:05:34 2025 +0100
libstore: chown to builder variant for file descriptors
We use it immediately for the build temporary directory.
Change-Id: I180193c63a2b98721f5fb8e542c4e39c099bb947
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit 962c65f8dcd5570dd92c72370a862c7b38942e0d
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:04:59 2025 +0100
libstore: open build directory as a dirfd as well
We now keep around a proper AutoCloseFD around the temporary directory
which we plan to use for openat operations and avoiding the build
directory being swapped out while we are doing something else.
Change-Id: I18d387b0f123ebf2d20c6405cd47ebadc5505f2a
Signed-off-by: Raito Bezarius <raito@lix.systems>
commit c9b42462b75b5a37ee6564c2b53cff186c8323da
Author: Raito Bezarius <raito@lix.systems>
Date: Wed Mar 26 01:04:12 2025 +0100
libutil: guess or invent a path from file descriptors
This is useful for certain error recovery paths (no pun intended) that
does not thread through the original path name.
Change-Id: I2d800740cb4f9912e64c923120d3f977c58ccb7e
Signed-off-by: Raito Bezarius <raito@lix.systems>
Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
---
src/libstore/local-store.cc | 4 +-
src/libstore/unix/build/derivation-builder.cc | 66 ++++++++++++++++---
src/libutil/file-content-address.cc | 2 +-
src/libutil/file-system.cc | 47 +++++++------
src/libutil/include/nix/util/file-system.hh | 14 ++--
5 files changed, 98 insertions(+), 35 deletions(-)
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 76fadba86..1ab3ed13a 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -247,7 +247,7 @@ LocalStore::LocalStore(ref<const Config> config)
else if (curSchema == 0) { /* new store */
curSchema = nixSchemaVersion;
openDB(*state, true);
- writeFile(schemaPath, fmt("%1%", curSchema), 0666, true);
+ writeFile(schemaPath, fmt("%1%", curSchema), 0666, FsSync::Yes);
}
else if (curSchema < nixSchemaVersion) {
@@ -298,7 +298,7 @@ LocalStore::LocalStore(ref<const Config> config)
txn.commit();
}
- writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, true);
+ writeFile(schemaPath, fmt("%1%", nixSchemaVersion), 0666, FsSync::Yes);
lockFile(globalLock.get(), ltRead, true);
}
diff --git a/src/libstore/unix/build/derivation-builder.cc b/src/libstore/unix/build/derivation-builder.cc
index 58e8d8ba6..856bc81c3 100644
--- a/src/libstore/unix/build/derivation-builder.cc
+++ b/src/libstore/unix/build/derivation-builder.cc
@@ -129,6 +129,11 @@ private:
*/
Path topTmpDir;
+ /**
+ * The file descriptor of the temporary directory.
+ */
+ AutoCloseFD tmpDirFd;
+
/**
* The path of the temporary directory in the sandbox.
*/
@@ -325,9 +330,24 @@ private:
/**
* Make a file owned by the builder.
+ *
+ * SAFETY: this function is prone to TOCTOU as it receives a path and not a descriptor.
+ * It's only safe to call in a child of a directory only visible to the owner.
*/
void chownToBuilder(const Path & path);
+ /**
+ * Make a file owned by the builder addressed by its file descriptor.
+ */
+ void chownToBuilder(int fd, const Path & path);
+
+ /**
+ * Create a file in `tmpDir` owned by the builder.
+ */
+ void writeBuilderFile(
+ const std::string & name,
+ std::string_view contents);
+
/**
* Run the builder's process.
*/
@@ -895,7 +915,14 @@ void DerivationBuilderImpl::startBuilder()
} else {
tmpDir = topTmpDir;
}
- chownToBuilder(tmpDir);
+
+ /* The TOCTOU between the previous mkdir call and this open call is unavoidable due to
+ POSIX semantics.*/
+ tmpDirFd = AutoCloseFD{open(tmpDir.c_str(), O_RDONLY | O_NOFOLLOW | O_DIRECTORY)};
+ if (!tmpDirFd)
+ throw SysError("failed to open the build temporary directory descriptor '%1%'", tmpDir);
+
+ chownToBuilder(tmpDirFd.get(), tmpDir);
for (auto & [outputName, status] : initialOutputs) {
/* Set scratch path we'll actually use during the build.
@@ -1469,9 +1496,7 @@ void DerivationBuilderImpl::initTmpDir()
} else {
auto hash = hashString(HashAlgorithm::SHA256, i.first);
std::string fn = ".attr-" + hash.to_string(HashFormat::Nix32, false);
- Path p = tmpDir + "/" + fn;
- writeFile(p, rewriteStrings(i.second, inputRewrites));
- chownToBuilder(p);
+ writeBuilderFile(fn, rewriteStrings(i.second, inputRewrites));
env[i.first + "Path"] = tmpDirInSandbox + "/" + fn;
}
}
@@ -1580,11 +1605,9 @@ void DerivationBuilderImpl::writeStructuredAttrs()
auto jsonSh = StructuredAttrs::writeShell(json);
- writeFile(tmpDir + "/.attrs.sh", rewriteStrings(jsonSh, inputRewrites));
- chownToBuilder(tmpDir + "/.attrs.sh");
+ writeBuilderFile(".attrs.sh", rewriteStrings(jsonSh, inputRewrites));
env["NIX_ATTRS_SH_FILE"] = tmpDirInSandbox + "/.attrs.sh";
- writeFile(tmpDir + "/.attrs.json", rewriteStrings(json.dump(), inputRewrites));
- chownToBuilder(tmpDir + "/.attrs.json");
+ writeBuilderFile(".attrs.json", rewriteStrings(json.dump(), inputRewrites));
env["NIX_ATTRS_JSON_FILE"] = tmpDirInSandbox + "/.attrs.json";
}
}
@@ -1838,6 +1861,24 @@ void setupSeccomp()
#endif
}
+void DerivationBuilderImpl::chownToBuilder(int fd, const Path & path)
+{
+ if (!buildUser) return;
+ if (fchown(fd, buildUser->getUID(), buildUser->getGID()) == -1)
+ throw SysError("cannot change ownership of file '%1%'", path);
+}
+
+void DerivationBuilderImpl::writeBuilderFile(
+ const std::string & name,
+ std::string_view contents)
+{
+ auto path = std::filesystem::path(tmpDir) / name;
+ AutoCloseFD fd{openat(tmpDirFd.get(), name.c_str(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC | O_EXCL | O_NOFOLLOW, 0666)};
+ if (!fd)
+ throw SysError("creating file %s", path);
+ writeFile(fd, path, contents);
+ chownToBuilder(fd.get(), path);
+}
void DerivationBuilderImpl::runChild()
{
@@ -3043,6 +3084,15 @@ void DerivationBuilderImpl::checkOutputs(const std::map<std::string, ValidPathIn
void DerivationBuilderImpl::deleteTmpDir(bool force)
{
if (topTmpDir != "") {
+ /* As an extra precaution, even in the event of `deletePath` failing to
+ * clean up, the `tmpDir` will be chowned as if we were to move
+ * it inside the Nix store.
+ *
+ * This hardens against an attack which smuggles a file descriptor
+ * to make use of the temporary directory.
+ */
+ chmod(topTmpDir.c_str(), 0000);
+
/* Don't keep temporary directories for builtins because they
might have privileged stuff (like a copy of netrc). */
if (settings.keepFailed && !force && !drv.isBuiltin()) {
diff --git a/src/libutil/file-content-address.cc b/src/libutil/file-content-address.cc
index 142bc70d5..d95781691 100644
--- a/src/libutil/file-content-address.cc
+++ b/src/libutil/file-content-address.cc
@@ -93,7 +93,7 @@ void restorePath(
{
switch (method) {
case FileSerialisationMethod::Flat:
- writeFile(path, source, 0666, startFsync);
+ writeFile(path, source, 0666, startFsync ? FsSync::Yes : FsSync::No);
break;
case FileSerialisationMethod::NixArchive:
restorePath(path, source, startFsync);
diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc
index 90ec5eda5..aeee49e9b 100644
--- a/src/libutil/file-system.cc
+++ b/src/libutil/file-system.cc
@@ -303,7 +303,7 @@ void readFile(const Path & path, Sink & sink, bool memory_map)
}
-void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
+void writeFile(const Path & path, std::string_view s, mode_t mode, FsSync sync)
{
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
// TODO
@@ -313,22 +313,29 @@ void writeFile(const Path & path, std::string_view s, mode_t mode, bool sync)
, mode));
if (!fd)
throw SysError("opening file '%1%'", path);
+
+ writeFile(fd, path, s, mode, sync);
+
+ /* Close explicitly to propagate the exceptions. */
+ fd.close();
+}
+
+void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode, FsSync sync)
+{
+ assert(fd);
try {
writeFull(fd.get(), s);
+
+ if (sync == FsSync::Yes)
+ fd.fsync();
+
} catch (Error & e) {
- e.addTrace({}, "writing file '%1%'", path);
+ e.addTrace({}, "writing file '%1%'", origPath);
throw;
}
- if (sync)
- fd.fsync();
- // Explicitly close to make sure exceptions are propagated.
- fd.close();
- if (sync)
- syncParent(path);
}
-
-void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
+void writeFile(const Path & path, Source & source, mode_t mode, FsSync sync)
{
AutoCloseFD fd = toDescriptor(open(path.c_str(), O_WRONLY | O_TRUNC | O_CREAT
// TODO
@@ -352,11 +359,11 @@ void writeFile(const Path & path, Source & source, mode_t mode, bool sync)
e.addTrace({}, "writing file '%1%'", path);
throw;
}
- if (sync)
+ if (sync == FsSync::Yes)
fd.fsync();
// Explicitly close to make sure exceptions are propagated.
fd.close();
- if (sync)
+ if (sync == FsSync::Yes)
syncParent(path);
}
@@ -419,7 +426,8 @@ static void _deletePath(Descriptor parentfd, const std::filesystem::path & path,
#ifndef _WIN32
checkInterrupt();
- std::string name(baseNameOf(path.native()));
+ std::string name(path.filename());
+ assert(name != "." && name != ".." && !name.empty());
struct stat st;
if (fstatat(parentfd, name.c_str(), &st,
@@ -460,7 +468,7 @@ static void _deletePath(Descriptor parentfd, const std::filesystem::path & path,
throw SysError("chmod %1%", path);
}
- int fd = openat(parentfd, path.c_str(), O_RDONLY);
+ int fd = openat(parentfd, name.c_str(), O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
if (fd == -1)
throw SysError("opening directory %1%", path);
AutoCloseDir dir(fdopendir(fd));
@@ -472,7 +480,7 @@ static void _deletePath(Descriptor parentfd, const std::filesystem::path & path,
checkInterrupt();
std::string childName = dirent->d_name;
if (childName == "." || childName == "..") continue;
- _deletePath(dirfd(dir.get()), path + "/" + childName, bytesFreed);
+ _deletePath(dirfd(dir.get()), path / childName, bytesFreed);
}
if (errno) throw SysError("reading directory %1%", path);
}
@@ -490,14 +498,13 @@ static void _deletePath(Descriptor parentfd, const std::filesystem::path & path,
static void _deletePath(const std::filesystem::path & path, uint64_t & bytesFreed)
{
- Path dir = dirOf(path.string());
- if (dir == "")
- dir = "/";
+ assert(path.is_absolute());
+ assert(path.parent_path() != path);
- AutoCloseFD dirfd = toDescriptor(open(dir.c_str(), O_RDONLY));
+ AutoCloseFD dirfd = toDescriptor(open(path.parent_path().string().c_str(), O_RDONLY));
if (!dirfd) {
if (errno == ENOENT) return;
- throw SysError("opening directory '%1%'", path);
+ throw SysError("opening directory %s", path.parent_path());
}
_deletePath(dirfd.get(), path, bytesFreed);
diff --git a/src/libutil/include/nix/util/file-system.hh b/src/libutil/include/nix/util/file-system.hh
index b8fa4cfa0..a9a6e43bf 100644
--- a/src/libutil/include/nix/util/file-system.hh
+++ b/src/libutil/include/nix/util/file-system.hh
@@ -175,21 +175,27 @@ std::string readFile(const Path & path);
std::string readFile(const std::filesystem::path & path);
void readFile(const Path & path, Sink & sink, bool memory_map = true);
+enum struct FsSync { Yes, No };
+
/**
* Write a string to a file.
*/
-void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, bool sync = false);
-static inline void writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode = 0666, bool sync = false)
+void writeFile(const Path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
+
+static inline void writeFile(const std::filesystem::path & path, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No)
{
return writeFile(path.string(), s, mode, sync);
}
-void writeFile(const Path & path, Source & source, mode_t mode = 0666, bool sync = false);
-static inline void writeFile(const std::filesystem::path & path, Source & source, mode_t mode = 0666, bool sync = false)
+void writeFile(const Path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No);
+
+static inline void writeFile(const std::filesystem::path & path, Source & source, mode_t mode = 0666, FsSync sync = FsSync::No)
{
return writeFile(path.string(), source, mode, sync);
}
+void writeFile(AutoCloseFD & fd, const Path & origPath, std::string_view s, mode_t mode = 0666, FsSync sync = FsSync::No);
+
/**
* Flush a path's parent directory to disk.
*/
--
2.44.1

View File

@ -5234,6 +5234,8 @@ self: super: with self; {
flask-wtf = callPackage ../development/python-modules/flask-wtf { };
flask-xml-rpc-re = callPackage ../development/python-modules/flask-xml-rpc-re { };
flatbencode = callPackage ../development/python-modules/flatbencode { };
flatbuffers = callPackage ../development/python-modules/flatbuffers { inherit (pkgs) flatbuffers; };
@ -10208,6 +10210,8 @@ self: super: with self; {
ninja = callPackage ../development/python-modules/ninja { inherit (pkgs) ninja; };
nipap = callPackage ../development/python-modules/nipap { };
nipreps-versions = callPackage ../development/python-modules/nipreps-versions { };
nipy = callPackage ../development/python-modules/nipy { };
@ -13145,6 +13149,8 @@ self: super: with self; {
pynina = callPackage ../development/python-modules/pynina { };
pynipap = callPackage ../development/python-modules/pynipap { };
pynisher = callPackage ../development/python-modules/pynisher { };
pynitrokey = callPackage ../development/python-modules/pynitrokey { };