Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix infinite recursion caused by the unnecessary inspection of options #51541

Merged
merged 1 commit into from Dec 24, 2018
Merged

fix infinite recursion caused by the unnecessary inspection of options #51541

merged 1 commit into from Dec 24, 2018

Conversation

msteen
Copy link
Contributor

@msteen msteen commented Dec 5, 2018

Motivation for this change

When you have a NixOS configuration like the following:

{ config, ... }:

{
  boot.loader.grub.device = "nodev";
  fileSystems."/" = {
    device = "nodev";
    options = [ "uid=${toString config.users.users.root.uid}" ];
  };
  fileSystems."/foo" = {
    device = "nodev";
  };
}

And you test it like so:

NIXOS_CONFIG=debug-fs-user-recursion.nix nix-instantiate --eval \
  --expr '(import <nixpkgs/nixos> { }).config.services.rpcbind.enable'

You will get infinite recursion:

  1. rpcbind.nix defines users.extraUsers.rpc
  2. nfs.nix sets services.rpcbind.enable depending on config.boot.supportedFilesystems
  3. filesystems.nix defines boot.supportedFilesystems based on toposort fsBefore (attrValues config.fileSystems)
  4. utils.nix defines fsBefore and uses config.fileSystems.<name>.options to do so
  5. this file defines fileSystems."/".options to refer to config.users.users (extraUsers is an alias for users)
  6. causing infinite recursion

The original check had this:

((any (x: elem x [ "bind" "move" ]) b.options) && (a.mountPoint == b.device))

However any file system type that allows a device to be what is also valid in a mount point (i.e. normal directories), like "bind" and "move" do, are the only ones that will ever pass the a.mountPoint == b.device condition. Hence the precondition any (x: elem x [ "bind" "move" ]) b.options should be unnecessary. Removing the precondition solves the infinite recursion issue.

Then to address # FIXME: it's incorrect to simply use hasPrefix here: "/dev/a" is not a parent of "/dev/ab", we could just ensure that the prefix check always end with a "/", such that hasPrefix only succeeds if its an actual parent, like so:

hasPrefix "${a.mountPoint}${optionalString (!(hasSuffix "/" a.mountPoint)) "/"}" b.mountPoint
Things done
  • Tested using sandboxing (nix.useSandbox on NixOS, or option sandbox in nix.conf on non-NixOS)
  • Built on platform(s)
    • NixOS
    • macOS
    • other Linux distributions
  • Tested via one or more NixOS test(s) if existing and applicable for the change (look inside nixos/tests)
  • Tested compilation of all pkgs that depend on this change using nix-shell -p nox --run "nox-review wip"
  • Tested execution of all binary files (usually in ./result/bin/)
  • Determined the impact on package closure size (by running nix path-info -S before and after)
  • Assured whether relevant documentation is up to date
  • Fits CONTRIBUTING.md.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants