Skip to content

Wrong characters in etc."xyz".source causes system crash / unbootable system #130935

@ctheune

Description

@ctheune

Describe the bug

Incorrect input to the source attribute for environment.etc files can cause a system crash and make a system unbootable.

To Reproduce
Steps to reproduce the behavior:

  1. create an etc file with a source path that includes a newline (and possibly other whitespace is dangerous here as well) via:
    environment.etc."example.conf".source = (
        pkgs.writeText "example.conf" "my example" + "\n" + "more config");
  1. nixos-rebuild
  2. watch your system go down in flames

Expected behavior

This should trigger an error during the evaluation. I think "sources" in etc.nix must consist of proper paths (the types.path type is quite naive) and in this case for the etc derivation (there's also a "Use toXML" not there) we also trust that this is actually reasonably well quoted for bash word splitting.

We could fix this immediate issue by prohibiting newlines in paths, but I haven't been able to check for the whole chain of bash quoting here and we might need to prohibit other characters, too. I'm not sure whether all of this needs fixing in types.path or whether shell quoting at the appropriate places in the derivation would be needed as well.

Screenshots
If applicable, add screenshots to help explain your problem.

Here's what a dry-activate looks like:
Screenshot 2021-07-21 at 16 01 04

Additional context

The original that made me find this was:

    environment.etc."ceph/ceph.conf".source = (
        pkgs.writeText "ceph.conf" 
        cfg.config + "\n"
        + cfg.client.config);

I thought the operator precedence was + before parameter binding, but it turns out I was wrong. So this example really is:

    environment.etc."ceph/ceph.conf".source = (
        (pkgs.writeText "ceph.conf" 
        cfg.config) + "\n"
        + cfg.client.config);

But I expected it to be (and this then works properly):

    environment.etc."ceph/ceph.conf".source = (
        pkgs.writeText "ceph.conf" 
        (cfg.config + "\n"
        + cfg.client.config));

This results in the "etc" derivation record the content of the client config as source path, which looks quite funny:

("sources","/nix/store/cp12kkzly00bmykrlry2ihc0py02iz9y-nix-phps /nix/store/8vzivf5zby0dacmm9s3rj7jrdvf96rw3-etc-bashrc /nix/store/g28l15mbdbig59n102zd0ardsfisiw32-binfmt_nixos.conf 
/nix/store/j9p8xsfbzfi3fjzjq3npa0fp2grxanw7-etc-ceph.client.admin.keyring /nix/store/fmvadclsh0svrmyl7jmnldvkjak8flx6-ceph.conf\n[mon]\nadmin socket = /run/ceph/$cluster-$name.asok\n\nmon 
addr = 172.20.4.6:6789,172.20.4.51:6789,172.20.4.40:6789\nmon data = 
/srv/ceph/mon/$cluster-$id\nmon osd allow primary affinity = true\n
mon pg warn max per osd = 3000\n\nosd pool default size = 3\n
osd pool default min size = 2\nosd pool default pg num = 64\n
osd pool default pgp num = 64\n\n[mon.cartman02]\nhost = cartman02\n
mon addr = 172.20.4.6:6789\npublic addr = 172.20.4.6:6789\ncluster addr = 172.20.8.4:6789\n /nix/store/2r74xqz5xj1lv642j7cr7a7qx6jq92s6-crontab
 /nix/store/zhn865282k7m51g8sa85y6bs2qs530fs-dbus-1 /nix/store/gzs0sknys6a2li8iw8xb

And that then results in the etc hierarchy not being properly built and systemd missing the units.

Notify maintainers

Metadata
Please run nix-shell -p nix-info --run "nix-info -m" and paste the result.

Maintainer information:

# a list of nixpkgs attributes affected by the problem
attribute:
# a list of nixos modules affected by the problem
module:

Metadata

Metadata

Assignees

No one assigned

    Labels

    0.kind: bugSomething is broken6.topic: nixosIssues or PRs affecting NixOS modules, or package usability issues specific to NixOS

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions