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

nixos/malloc: apply allocator settings to systemd units #62238

Merged
merged 1 commit into from May 30, 2019

Conversation

delroth
Copy link
Contributor

@delroth delroth commented May 30, 2019

Motivation for this change

#62236

This PR uses systemd's system.conf/user.conf "DefaultEnvironment" feature to set the allocator's LD_PRELOAD near-globally.

I've only tested this with Scudo, not with Graphene, so no idea if it's going to break Graphene allocator systems further than they are already. With this PR, I see almost all processes on my system using the configured allocator. The only exceptions are:

  • chromium (but that's expected, they have their own allocator I imagine)
  • sddm-helper and 1-2 /bin/sh processes it spawns. Haven't looked into what's going on there, but I don't particularly care much either.

@GrahamcOfBorg test hardened

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 nix-review --run "nix-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.

This uses systemd's system.conf/user.conf "DefaultEnvironment" feature
to set the allocator's LD_PRELOAD near-globally.
@delroth
Copy link
Contributor Author

delroth commented May 30, 2019

@GrahamcOfBorg test hardened

@joachifm joachifm merged commit b0500aa into NixOS:master May 30, 2019
@joachifm
Copy link
Contributor

Thank you

@Izorkin
Copy link
Contributor

Izorkin commented May 30, 2019

After this PR error worked authorization by openssh client. Used hardened profile.
Error:

client: must succeed: ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil server true
server# [   15.777066] sshd[768]: Connection from 192.168.1.1 port 58912 on 192.168.1.2 port 22
server# [   15.914535] audit: type=1326 audit(1559221065.244:34): auid=4294967295 uid=498 gid=65534 ses=4294967295 subj==unconfined pid=769 comm="sshd" exe="/nix/store/bcnhzyllllhww9k8c9p3wv2rrxd03lhs-openssh-7.9p1/bin/sshd" sig=31 arch=c000003e syscall=10 compat=0 ip=0x7781139ec4b7 code=0x0
client# Connection reset by 192.168.1.2 port 22
client: exit status 255
client: output:
(0.06 seconds)
error: command `ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i privkey.snakeoil server true' did not succeed (exit code 255)

Checked with this script:

import ./make-test.nix ({ pkgs, ... }:

let inherit (import ./ssh-keys.nix pkgs)
      snakeOilPrivateKey snakeOilPublicKey;
in {
  name = "openssh";
  meta = with pkgs.stdenv.lib.maintainers; {
    maintainers = [ aszlig eelco ];
  };

  nodes = {

    server =
      { ... }:

      {
        nix.useSandbox = false;
        imports = [ ../modules/profiles/hardened.nix ];
        services.openssh = { enable = true; startWhenNeeded = false; };
        security.pam.services.sshd.limits =
          [ { domain = "*"; item = "memlock"; type = "-"; value = 1024; } ];
        users.users.root.openssh.authorizedKeys.keys = [
          snakeOilPublicKey
        ];
      };

    client =
      { ... }: { };

  };

  testScript = ''
    startAll;

    my $key=`${pkgs.openssh}/bin/ssh-keygen -t ed25519 -f key -N ""`;

    $server->waitForUnit("sshd");

    subtest "manual-authkey", sub {
      $server->succeed("mkdir -m 700 /root/.ssh");
      $server->copyFileFromHost("key.pub", "/root/.ssh/authorized_keys");

      $client->succeed("mkdir -m 700 /root/.ssh");
      $client->copyFileFromHost("key", "/root/.ssh/id_ed25519");
      $client->succeed("chmod 600 /root/.ssh/id_ed25519");

      $client->waitForUnit("network.target");
      $client->succeed("ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server 'echo hello world' >&2");
      $client->succeed("ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no server 'ulimit -l' | grep 1024");
    };

    subtest "configured-authkey", sub {
      $client->succeed("cat ${snakeOilPrivateKey} > privkey.snakeoil");
      $client->succeed("chmod 600 privkey.snakeoil");
      $client->succeed("ssh -o UserKnownHostsFile=/dev/null" .
                       " -o StrictHostKeyChecking=no -i privkey.snakeoil" .
                       " server true");
    };

  '';
})

@Izorkin
Copy link
Contributor

Izorkin commented May 30, 2019

This variant is no better?

  environment.etc."ld-nix.so.preload".text = ''
    ${pkgs.jemalloc}/lib/libjemalloc.so
  '';

Example. With ld-nix.so.preload:

sudo lsof -p `pgrep vsftpd` | grep malloc                                                                                                                                                                 
vsftpd  17274 root  mem    REG     0,26   625688 1293183 /nix/store/dzwh7cvw7d3x3mizzyypa741saxpjp4s-malloc-provider-jemalloc/lib/libjemalloc.so

With environment.variables.LD_PRELOAD and systemd.extraConfig library not loaded.

@joachifm
Copy link
Contributor

That variant was mentioned in #59955 (comment)
I think your example shows that ld-nix.so.preload in fact is more robust, perhaps it'd be better to use that approach instead.

@Izorkin
Copy link
Contributor

Izorkin commented May 31, 2019

I used this method:

  environment.etc."ld-nix.so.preload".text = ''
    ${pkgs.jemalloc}/lib/libjemalloc.so
  '';

and

  systemd.services.mysql = with pkgs; {
    environment = {
      LD_PRELOAD = "${pkgs.jemalloc450}/lib/libjemalloc.so";
    };
  ...

before this PR #60187

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