-
-
Notifications
You must be signed in to change notification settings - Fork 18.3k
Shipping Security Updates #10851
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
Closed
Closed
Shipping Security Updates #10851
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
ad1572c
Extract all imports out of pkgsWithOvverrides.
nbp c2134e1
Add pkgsWithPackages function, and split pkgs expression.
nbp e0efe6c
Move the fix-point from pkgsWithOverridesWithPackages to pkgs, and ad…
nbp 187776f
Add maybeApplyAbiCompatiblePatches, as well as the quickfixPackages a…
nbp c40639d
Add applyAbiCompatiblePatches function.
nbp 9f6ccac
Add a flag for buildfarms, to turn off the abiCompatiblePatches while…
nbp 0b4d9b1
Add a static analysis to report security issues.
nbp 2cc9534
Add a test case to verify that security fixes are correctly applied.
nbp ca70916
Add test cases to ensure that the onefix, and abifix are keeping the …
nbp 8729a70
Add security test cases as release blockers.
nbp 9b88a3b
Make patchUpdatedDependencies lazier, to accept loops with override f…
nbp 847405c
Security Static Analysis: forceNativeDrv and lowPrio are not changing…
nbp File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # Check that evaluating all the packages, with the abi patching mechanism | ||
| # with no fixes is effectively a no-op. | ||
|
|
||
| with import ./lib.nix; | ||
|
|
||
| assert builtins.trace "Found ${builtins.toString (builtins.length pkgsDrvs)} packages." true; | ||
| assert builtins.length pkgsDrvs == builtins.length abifixDrvs; | ||
| assert lib.all lib.id (zipPkgs pkgsDrvs abifixDrvs); | ||
| true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,201 @@ | ||
| let | ||
| testDrv = stdenv: name: rec { | ||
| inherit name; | ||
| buildInputs = [ ]; | ||
| buildCommand = '' | ||
| mkdir -p $out | ||
| touch $out/installed | ||
| echo ${name} >> $out/installed | ||
| touch $out/dependency | ||
| echo $out >> $out/dependency | ||
| ''; | ||
|
|
||
| meta = with stdenv.lib; { | ||
| homepage = https://nixos.org/; | ||
| description = "Test case"; | ||
| longDescription = "Test case"; | ||
| license = licenses.mit; | ||
| maintainers = [ maintainers.pierron ]; | ||
| platforms = platforms.all; | ||
| }; | ||
| }; | ||
|
|
||
| testDrvWithDep = stdenv: name: dep: | ||
| let drv = testDrv stdenv name; in drv // { | ||
| buildInputs = [ dep ]; | ||
| buildCommand = drv.buildCommand + '' | ||
| cat ${dep}/installed >> $out/installed | ||
| cat ${dep}/dependency >> $out/dependency | ||
| ''; | ||
| }; | ||
|
|
||
| testPkg = stdenv: name: | ||
| stdenv.mkDerivation (testDrv stdenv name); | ||
|
|
||
| testPkgWithDep = stdenv: name: dep: | ||
| stdenv.mkDerivation (testDrvWithDep stdenv name dep); | ||
|
|
||
| pkgTestDead = { stdenv, name ? "dead-1.0.0" }: | ||
| testPkg stdenv name; | ||
| pkgTestBeef = { stdenv, name ? "beef-1.0.0", test-dead }: | ||
| testPkgWithDep stdenv name test-dead; | ||
| pkgTestAte = { stdenv, name ? "ate-1.0.0", test-beef }: | ||
| testPkgWithDep stdenv name test-beef; | ||
| pkgTestBad = { stdenv, name ? "bad-1.0.0", test-ate }: | ||
| testPkgWithDep stdenv name test-ate; | ||
| pkgTestFood = { stdenv, name ? "food-1.0.0", test-bad }: | ||
| testPkgWithDep stdenv name test-bad; | ||
|
|
||
| originalPackages = { | ||
| adapters = import ../../../pkgs/stdenv/adapters.nix; | ||
| builders = import ../../../pkgs/build-support/trivial-builders.nix; | ||
| stdenv = import ../../../pkgs/top-level/stdenv.nix; | ||
| all = import ../../../pkgs/top-level/all-packages.nix; | ||
| aliases = import ../../../pkgs/top-level/aliases.nix; | ||
| }; | ||
|
|
||
| defaultPackages = originalPackages // { | ||
| all = top: self: pkgs: originalPackages.all top self pkgs // ( | ||
| let callPackage = top.lib.callPackageWith pkgs; in { | ||
| test-dead = callPackage pkgTestDead { }; | ||
| test-beef = callPackage pkgTestBeef { }; | ||
| test-ate = callPackage pkgTestAte { }; | ||
| test-bad = callPackage pkgTestBad { }; | ||
| test-food = callPackage pkgTestFood { }; | ||
| }); | ||
| }; | ||
|
|
||
| # Only change the foo package which is used explicitly by bar, and | ||
| # indirectly by baz. | ||
| quickfixPackages = originalPackages // { | ||
| all = top: self: pkgs: originalPackages.all top self pkgs // ( | ||
| let callPackage = top.lib.callPackageWith pkgs; in { | ||
| test-dead = callPackage pkgTestDead { }; | ||
| test-beef = callPackage pkgTestBeef { name = "beef-1.0.2"; }; | ||
| test-ate = callPackage pkgTestAte { }; | ||
| test-bad = callPackage pkgTestBad { name = "bad-1.0.51"; }; | ||
| test-food = callPackage pkgTestFood { }; | ||
| }); | ||
| }; | ||
|
|
||
| withoutFix = import ../../../. { | ||
| inherit defaultPackages; | ||
| quickfixPackages = null; | ||
| }; | ||
|
|
||
| withFix = import ../../../. { | ||
| inherit defaultPackages quickfixPackages; | ||
| }; | ||
| in | ||
|
|
||
| withoutFix.stdenv.mkDerivation { | ||
| name = "check-quickfix"; | ||
| buildInputs = []; | ||
| buildCommand = '' | ||
| length() { | ||
| local arg="$1"; | ||
| echo ''${#arg}; | ||
| } | ||
| set -x; | ||
|
|
||
| : Check that fixes are correctly applies. | ||
| test ${withoutFix.test-dead} = ${withFix.test-dead} | ||
| test \! ${withoutFix.test-beef} = ${withFix.test-beef} # recompiled | ||
| test \! ${withoutFix.test-ate } = ${withFix.test-ate } # patched | ||
| test \! ${withoutFix.test-bad } = ${withFix.test-bad } # recompiled & patched | ||
| test \! ${withoutFix.test-food} = ${withFix.test-food} # patched | ||
|
|
||
| : Check output paths have identical length. | ||
| test $(length ${withoutFix.test-dead}) -eq $(length ${withFix.test-dead}) | ||
| test $(length ${withoutFix.test-beef}) -eq $(length ${withFix.test-beef}) | ||
| test $(length ${withoutFix.test-ate }) -eq $(length ${withFix.test-ate }) | ||
| test $(length ${withoutFix.test-bad }) -eq $(length ${withFix.test-bad }) # renamed | ||
| test $(length ${withoutFix.test-food}) -eq $(length ${withFix.test-food}) | ||
|
|
||
| : Check compiled packages names. | ||
| grep -q "dead-1.0.0" ${withoutFix.test-dead}/installed | ||
| grep -q "beef-1.0.0" ${withoutFix.test-beef}/installed | ||
| grep -q "ate-1.0.0" ${withoutFix.test-ate }/installed | ||
| grep -q "bad-1.0.0" ${withoutFix.test-bad }/installed | ||
| grep -q "food-1.0.0" ${withoutFix.test-food}/installed | ||
|
|
||
| grep -q "dead-1.0.0" ${withoutFix.test-beef}/installed | ||
| grep -q "beef-1.0.0" ${withoutFix.test-ate }/installed | ||
| grep -q "ate-1.0.0" ${withoutFix.test-bad }/installed | ||
| grep -q "bad-1.0.0" ${withoutFix.test-food}/installed | ||
|
|
||
| grep -q "dead-1.0.0" ${withoutFix.test-ate }/installed | ||
| grep -q "beef-1.0.0" ${withoutFix.test-bad }/installed | ||
| grep -q "ate-1.0.0" ${withoutFix.test-food}/installed | ||
|
|
||
| grep -q "dead-1.0.0" ${withoutFix.test-bad }/installed | ||
| grep -q "beef-1.0.0" ${withoutFix.test-food}/installed | ||
|
|
||
| grep -q "dead-1.0.0" ${withoutFix.test-food}/installed | ||
|
|
||
| grep -q "dead-1.0.0" ${withFix.test-dead}/installed | ||
| grep -q "beef-1.0.2" ${withFix.test-beef}/installed | ||
| grep -q "ate-1.0.0" ${withFix.test-ate }/installed | ||
| grep -q "bad-1.0.51" ${withFix.test-bad }/installed # not renamed | ||
| grep -q "food-1.0.0" ${withFix.test-food}/installed | ||
|
|
||
| grep -q "dead-1.0.0" ${withFix.test-beef}/installed | ||
| grep -q "beef-1.0.0" ${withFix.test-ate }/installed # not updated | ||
| grep -q "ate-1.0.0" ${withFix.test-bad }/installed | ||
| grep -q "bad-1.0.0" ${withFix.test-food}/installed # not updated | ||
|
|
||
| grep -q "dead-1.0.0" ${withFix.test-ate }/installed | ||
| grep -q "beef-1.0.0" ${withFix.test-bad }/installed # not updated | ||
| grep -q "ate-1.0.0" ${withFix.test-food}/installed | ||
|
|
||
| grep -q "dead-1.0.0" ${withFix.test-bad }/installed | ||
| grep -q "beef-1.0.0" ${withFix.test-food}/installed # not updated | ||
|
|
||
| grep -q "dead-1.0.0" ${withFix.test-food}/installed | ||
|
|
||
| : Check dependencies hashes. | ||
| grep -q ${withoutFix.test-dead} ${withoutFix.test-dead}/dependency | ||
| grep -q ${withoutFix.test-beef} ${withoutFix.test-beef}/dependency | ||
| grep -q ${withoutFix.test-ate } ${withoutFix.test-ate }/dependency | ||
| grep -q ${withoutFix.test-bad } ${withoutFix.test-bad }/dependency | ||
| grep -q ${withoutFix.test-food} ${withoutFix.test-food}/dependency | ||
|
|
||
| grep -q ${withoutFix.test-dead} ${withoutFix.test-beef}/dependency | ||
| grep -q ${withoutFix.test-beef} ${withoutFix.test-ate }/dependency | ||
| grep -q ${withoutFix.test-ate } ${withoutFix.test-bad }/dependency | ||
| grep -q ${withoutFix.test-bad } ${withoutFix.test-food}/dependency | ||
|
|
||
| grep -q ${withoutFix.test-dead} ${withoutFix.test-ate }/dependency | ||
| grep -q ${withoutFix.test-beef} ${withoutFix.test-bad }/dependency | ||
| grep -q ${withoutFix.test-ate } ${withoutFix.test-food}/dependency | ||
|
|
||
| grep -q ${withoutFix.test-dead} ${withoutFix.test-bad }/dependency | ||
| grep -q ${withoutFix.test-beef} ${withoutFix.test-food}/dependency | ||
|
|
||
| grep -q ${withoutFix.test-dead} ${withoutFix.test-food}/dependency | ||
|
|
||
| grep -q ${withFix.test-dead} ${withFix.test-dead}/dependency | ||
| grep -q ${withFix.test-beef} ${withFix.test-beef}/dependency # recompiled | ||
| grep -q ${withFix.test-ate } ${withFix.test-ate }/dependency | ||
| grep -q ${withFix.test-bad } ${withFix.test-bad }/dependency # recompiled | ||
| grep -q ${withFix.test-food} ${withFix.test-food}/dependency | ||
|
|
||
| grep -q ${withFix.test-dead} ${withFix.test-beef}/dependency | ||
| grep -q ${withFix.test-beef} ${withFix.test-ate }/dependency # patched | ||
| grep -q ${withFix.test-ate } ${withFix.test-bad }/dependency | ||
| grep -q ${withFix.test-bad } ${withFix.test-food}/dependency # patched | ||
|
|
||
| grep -q ${withFix.test-dead} ${withFix.test-ate }/dependency | ||
| grep -q ${withFix.test-beef} ${withFix.test-bad }/dependency # patched | ||
| grep -q ${withFix.test-ate } ${withFix.test-food}/dependency | ||
|
|
||
| grep -q ${withFix.test-dead} ${withFix.test-bad }/dependency | ||
| grep -q ${withFix.test-beef} ${withFix.test-food}/dependency # patched | ||
|
|
||
| grep -q ${withFix.test-dead} ${withFix.test-food}/dependency | ||
|
|
||
| mkdir -p $out | ||
| echo success > $out/result | ||
| set +x | ||
| ''; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| { nixpkgs, pkgs }: | ||
|
|
||
| with pkgs; | ||
|
|
||
| let | ||
| nixCommand = name: command: | ||
| runCommand name { buildInputs = [ nix ]; } '' | ||
| datadir="${nix}/share" | ||
| export TEST_ROOT=$(pwd)/test-tmp | ||
| export NIX_BUILD_HOOK= | ||
| export NIX_CONF_DIR=$TEST_ROOT/etc | ||
| export NIX_DB_DIR=$TEST_ROOT/db | ||
| export NIX_LOCALSTATE_DIR=$TEST_ROOT/var | ||
| export NIX_LOG_DIR=$TEST_ROOT/var/log/nix | ||
| export NIX_MANIFESTS_DIR=$TEST_ROOT/var/nix/manifests | ||
| export NIX_STATE_DIR=$TEST_ROOT/var/nix | ||
| export NIX_STORE_DIR=$TEST_ROOT/store | ||
| export PAGER=cat | ||
| cacheDir=$TEST_ROOT/binary-cache | ||
| nix-store --init | ||
|
|
||
| cd ${nixpkgs}/pkgs/test/security | ||
| ${command} | ||
| touch $out | ||
| ''; | ||
| in | ||
|
|
||
| { | ||
| check-quickfix = import ./check-quickfix.nix; | ||
| onefix-noop = nixCommand "onefix-noop" '' | ||
| nix-instantiate --timeout 60 ./onefix-noop.nix --eval-only | ||
| ''; | ||
| abifix-noop = nixCommand "abifix-noop" '' | ||
| nix-instantiate --timeout 60 ./abifix-noop.nix --eval-only | ||
| ''; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| let | ||
| lib = import ../../../lib; | ||
| in | ||
|
|
||
| with lib; | ||
|
|
||
| rec { | ||
| inherit lib; | ||
|
|
||
| originalPackages = { | ||
| adapters = import ../../../pkgs/stdenv/adapters.nix; | ||
| builders = import ../../../pkgs/build-support/trivial-builders.nix; | ||
| stdenv = import ../../../pkgs/top-level/stdenv.nix; | ||
| all = import ../../../pkgs/top-level/all-packages.nix; | ||
| aliases = import ../../../pkgs/top-level/aliases.nix; | ||
| }; | ||
|
|
||
| pkgs = import ../../../. { | ||
| defaultPackages = originalPackages; | ||
| quickfixPackages = null; | ||
| doPatchWithDependencies = false; | ||
| } // { recurseForDerivations = true; }; | ||
|
|
||
| onefix = import ../../../. { | ||
| defaultPackages = originalPackages; | ||
| quickfixPackages = originalPackages; | ||
| doPatchWithDependencies = false; | ||
| } // { recurseForDerivations = true; }; | ||
|
|
||
| abifix = import ../../../. { | ||
| defaultPackages = originalPackages; | ||
| quickfixPackages = originalPackages; | ||
| doPatchWithDependencies = true; | ||
| } // { recurseForDerivations = true; }; | ||
|
|
||
| # This is the same as the `collectWithPath` function of Nixpkgs's library, | ||
| # except that it uses `tryEval` to ignore invalid evaluations, such as | ||
| # broken and unfree packages. | ||
| # | ||
| # Example: | ||
| # maybeCollectWithPath (x: x ? outPath) | ||
| # { a = { outPath = "a/"; }; b = { outPath = "b/"; }; } | ||
| # => [ { path = ["a"]; value = { outPath = "a/"; }; } | ||
| # { path = ["b"]; value = { outPath = "b/"; }; } | ||
| # ] | ||
| # | ||
| maybeCollectWithPath = pred: attrs: with lib; | ||
| let | ||
| collectInternal = path: attrs: | ||
| # assert __trace (["maybeCollectWithPath::"] ++ path) true; | ||
| addErrorContext "while collecting derivations under ${concatStringsSep "." path}:" ( | ||
| if pred attrs then | ||
| [ { path = concatStringsSep "." path; value = attrs; } ] | ||
| else if isAttrs attrs && attrs.recurseForDerivations or false then | ||
| concatMap (name: maybeCollectInternal (path ++ [name]) attrs.${name}) | ||
| (attrNames attrs) | ||
| else | ||
| []); | ||
|
|
||
| maybeCollectInternal = path: attrs: | ||
| # Some evaluation of isAttrs might raise an assertion while | ||
| # evaluating Nixpkgs, tryEval is used to work-around this issue. | ||
| let res = builtins.tryEval (collectInternal path attrs); in | ||
| if res.success then res.value | ||
| else []; | ||
|
|
||
| in | ||
| maybeCollectInternal [] attrs; | ||
|
|
||
| # Collect all derivations. | ||
| collectDerivations = with lib; pkgs: | ||
| maybeCollectWithPath (drv: isDerivation drv && drv.outPath != "") pkgs; | ||
|
|
||
| pkgsDrvs = collectDerivations pkgs; | ||
| onefixDrvs = collectDerivations onefix; | ||
| abifixDrvs = collectDerivations abifix; | ||
|
|
||
| # Zip all packages collected so far, and verify that they are equal. | ||
| zipPkgs = | ||
| lib.zipListsWith | ||
| (p: o: p.path == o.path && p.value.outPath == o.value.outPath); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| with import ./lib.nix; | ||
|
|
||
| assert builtins.trace "Found ${builtins.toString (builtins.length pkgsDrvs)} packages." true; | ||
| assert builtins.length pkgsDrvs == builtins.length onefixDrvs; | ||
| assert lib.all lib.id (zipPkgs pkgsDrvs onefixDrvs); | ||
| true |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This testcase is incomplete. You don't test that package that depends on
test-foodortest-ateisn't recompiled.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@danbst, Note that
test-badis recompiled with the patched version oftest-ate, and not the recompiled version oftest-ate. This is verified by the line 148, which checks that the dependency names inherited fromtest-ateisbeef-1.0.0instead ofbeef-1.0.2.I guess, for testing what you suggest we should copy the
dependencyfile from the latest added hash of theinstalledfile, and check that the names are the original one, and not the patched one.With this method, recompiled package depending on
test-food/test-atewould get the renamed version oftest-bad/test-beef, and non recompiled package depending ontest-food/test-atewould get the original version oftest-bad/test-beef.Note, the way the current patching mechanism is made also guarantee that adding the above test should work, because it only works on one package at a time, thus by recursion inference, all should work out of the box.