How do i fake sudo?(Help packaging a kernel driver)

Hello I am trying to package maccel
This is what I’ve come up with so far (Most of this is from the nix wiki)

{
  stdenv,
  pkgs,
  lib,
  fetchFromGitHub,
  kernel,
  kmod,
}:
stdenv.mkDerivation rec {
  pname = "maccel";
  version = "0.2.1";

  src = fetchFromGitHub {
    owner = "Gnarus-G";
    repo = "maccel";
    rev = "v${version}";
    hash = "sha256-j6rxNGhRRah6RkZc0KORJfwSgpSQONMK2LgZ5WBMWxA=";
  };

  sourceRoot = "source/";
  hardeningDisable = ["pic" "format"]; # 1
  nativeBuildInputs = [kernel.moduleBuildDependencies pkgs.sudo]; # 2
  makeFlags = [
    "KERNELRELEASE=${kernel.modDirVersion}" # 3
    "KDIR=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build" # 4
    "MODULEDIR=${kernel.dev}/lib/modules/"
    "INSTALL_MOD_PATH=$(out)" # 5
  ];

  meta = {
    description = "Mouse acceleration driver and kernel module for Linux.";
    homepage = "https://github.com/Gnarus-G/maccel";
    license = lib.licenses.gpl2;
    platforms = lib.platforms.linux;
  };
}

This returns the error

sudo: The "no new privileges" flag is set, which prevents sudo from running as root.

The Makefile extensively uses sudo, I do not know how to proceed.
Maybe fork the repo and remove all sudo usages?I think it would work but it would be a pain to maintain.
Or maybe try to “fake” sudo

none of the sudo usage is needed for non-imperative installs. you should be able to just remove it. something like this should work for patching the makefile

  prePatch = ''
    substituteInPlace Makefile \
      --replace "sudo" ""
  '';

depending on how much needs to be changed apart from that a patch-file might make more sense in the end.

An alternative is to add a fake “sudo” to nativeBuildInputs which just execs its arguments without privilege escalation:

pkgs.runCommand "sudo" { } ''exec "$@"''

pkgs should never be used as a package expression argument, btw, list out the attributes under pkgs instead!

See Package parameters and overrides with callPackage — nix.dev documentation for more context.

1 Like

Thank you that seems to work! :smiley:
Now I’ve hit another issue

{
  stdenv,
  pkgs,
  lib,
  fetchFromGitHub,
  kernel,
  kmod,
}:
stdenv.mkDerivation rec {
  pname = "maccel";
  version = "0.2.1";

  src = fetchFromGitHub {
    owner = "Gnarus-G";
    repo = "maccel";
    rev = "v${version}";
    hash = "sha256-j6rxNGhRRah6RkZc0KORJfwSgpSQONMK2LgZ5WBMWxA=";
  };

  sourceRoot = "source/";
  hardeningDisable = ["pic" "format"];
  prePatch = ''
    substituteInPlace Makefile \
      --replace "sudo" ""
  '';
  nativeBuildInputs = [
    kernel.moduleBuildDependencies
    pkgs.klibcShrunk
  ];
  makeFlags = [
    "KDIR=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build"
    "MODULEDIR=$out/lib/modules/${kernel.modDirVersion}/kernel/drivers/usb"
    "DRIVERDIR=${src}/driver/"
    "CC=${stdenv.cc.targetPrefix}gcc"
  ];
  meta = {
    description = "Mouse acceleration driver and kernel module for Linux.";
    homepage = "https://github.com/Gnarus-G/maccel";
    license = lib.licenses.gpl2;
    platforms = lib.platforms.linux;
  };
}

It tries to create files in DRIVERDIR folder but it cannot as DRIVIERDIR points to the source.

I tried copying the files to $NIX_BUILD_TOP ( which i think is writable?)

  preBuild = ''
    mkdir -p $NIX_BUILD_TOP/src
    cp -r ${src} $NIX_BUILD_TOP/src/
    cp -r ${kernel.dev}/lib $NIX_BUILD_TOP/
  '';
  makeFlags = [
    "KDIR=$NIX_BUILD_TOP/lib/modules/${kernel.modDirVersion}/build"
    "MODULEDIR=$out/lib/modules/${kernel.modDirVersion}/kernel/drivers/usb"
    "DRIVERDIR=$NIX_BUILD_TOP/src/driver/"
    "CC=${stdenv.cc.targetPrefix}gcc"
  ];

but now make tries to enter /build/source

maccel> make CC=gcc EXTRA_CFLAGS= -C IX_BUILD_TOP/lib/modules/6.12.5/build M=IX_BUILD_TOP/src/driver/
maccel> make[1]: Entering directory '/build/source'
maccel> make[1]: *** IX_BUILD_TOP/lib/modules/6.12.5/build: No such file or directory.  Stop.

You’re in the source dir by default after unpackPhase, just use $(pwd).

You generally never want to reference src anywhere except a custom unpackPhase.

2 Likes

I tried to use that initially but i wasn’t able to get it to work

 nativeBuildInputs = [
    kernel.moduleBuildDependencies
    pkgs.klibcShrunk
    (pkgs.runCommand "sudo" {} ''exec "$@"'')
  ];

The above returns

sudo> building '/nix/store/63qnzji6ryxlmfmhp03sm8hv18malzs6-sudo.drv'
error: builder for '/nix/store/63qnzji6ryxlmfmhp03sm8hv18malzs6-sudo.drv' failed to produce output path for output 'out' at '/nix/store/63qnzji6ryxlmfmhp03sm8hv18malzs6-sudo.drv.chroot/root/nix/store/w24x6ylyxrknnkxzy8kkgjnhvwn4qgq8-sudo'

Whats the correct way to use the snippet you provided?

Ah sorry, I don’t know what I was thinking. This needs to be writeShellScriptBin of course:

    (writeShellScriptBin "sudo" ''exec "$@"'')