Skip to content

Commit 42de2bc

Browse files
authored
cc-wrapper hardeningFlags tests: add tests for pacret, shadowstack (NixOS#331596)
2 parents 354946b + a9edd09 commit 42de2bc

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

pkgs/test/cc-wrapper/hardening.nix

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
, runCommand
44
, runCommandWith
55
, runCommandCC
6+
, bintools
67
, hello
78
, debian-devscripts
89
}:
@@ -130,6 +131,56 @@ let
130131
'';
131132

132133
brokenIf = cond: drv: if cond then drv.overrideAttrs (old: { meta = old.meta or {} // { broken = true; }; }) else drv;
134+
overridePlatforms = platforms: drv: drv.overrideAttrs (old: { meta = old.meta or {} // { inherit platforms; }; });
135+
136+
instructionPresenceTest = label: mnemonicPattern: testBin: expectFailure: runCommand "${label}-instr-test" {
137+
nativeBuildInputs = [
138+
bintools
139+
];
140+
buildInputs = [
141+
testBin
142+
];
143+
} ''
144+
touch $out
145+
if $OBJDUMP -d \
146+
--no-addresses \
147+
--no-show-raw-insn \
148+
"$(PATH=$HOST_PATH type -P test-bin)" \
149+
| grep -E '${mnemonicPattern}' > /dev/null ; then
150+
echo "Found ${label} instructions" >&2
151+
${lib.optionalString expectFailure "exit 1"}
152+
else
153+
echo "Did not find ${label} instructions" >&2
154+
${lib.optionalString (!expectFailure) "exit 1"}
155+
fi
156+
'';
157+
158+
pacRetTest = testBin: expectFailure: overridePlatforms [ "aarch64-linux" ] (
159+
instructionPresenceTest "pacret" "\\bpaciasp\\b" testBin expectFailure
160+
);
161+
162+
elfNoteTest = label: pattern: testBin: expectFailure: runCommand "${label}-elf-note-test" {
163+
nativeBuildInputs = [
164+
bintools
165+
];
166+
buildInputs = [
167+
testBin
168+
];
169+
} ''
170+
touch $out
171+
if $READELF -n "$(PATH=$HOST_PATH type -P test-bin)" \
172+
| grep -E '${pattern}' > /dev/null ; then
173+
echo "Found ${label} note" >&2
174+
${lib.optionalString expectFailure "exit 1"}
175+
else
176+
echo "Did not find ${label} note" >&2
177+
${lib.optionalString (!expectFailure) "exit 1"}
178+
fi
179+
'';
180+
181+
shadowStackTest = testBin: expectFailure: brokenIf stdenv.hostPlatform.isMusl (overridePlatforms [ "x86_64-linux" ] (
182+
elfNoteTest "shadowstack" "\\bSHSTK\\b" testBin expectFailure
183+
));
133184

134185
in nameDrvAfterAttrName ({
135186
bindNowExplicitEnabled = brokenIf stdenv.hostPlatform.isStatic (checkTestBin (f2exampleWithStdEnv stdenv {
@@ -204,6 +255,14 @@ in nameDrvAfterAttrName ({
204255
ignoreStackClashProtection = false;
205256
});
206257

258+
pacRetExplicitEnabled = pacRetTest (helloWithStdEnv stdenv {
259+
hardeningEnable = [ "pacret" ];
260+
}) false;
261+
262+
shadowStackExplicitEnabled = shadowStackTest (f1exampleWithStdEnv stdenv {
263+
hardeningEnable = [ "shadowstack" ];
264+
}) false;
265+
207266
bindNowExplicitDisabled = checkTestBin (f2exampleWithStdEnv stdenv {
208267
hardeningDisable = [ "bindnow" ];
209268
}) {
@@ -271,6 +330,14 @@ in nameDrvAfterAttrName ({
271330
expectFailure = true;
272331
};
273332

333+
pacRetExplicitDisabled = pacRetTest (helloWithStdEnv stdenv {
334+
hardeningDisable = [ "pacret" ];
335+
}) true;
336+
337+
shadowStackExplicitDisabled = shadowStackTest (f1exampleWithStdEnv stdenv {
338+
hardeningDisable = [ "shadowstack" ];
339+
}) true;
340+
274341
# most flags can't be "unsupported" by compiler alone and
275342
# binutils doesn't have an accessible hardeningUnsupportedFlags
276343
# mechanism, so can only test a couple of flags through altered
@@ -472,4 +539,12 @@ in {
472539
ignoreStackClashProtection = false;
473540
expectFailure = true;
474541
};
542+
543+
allExplicitDisabledPacRet = pacRetTest (helloWithStdEnv stdenv {
544+
hardeningDisable = [ "all" ];
545+
}) true;
546+
547+
allExplicitDisabledShadowStack = shadowStackTest (f1exampleWithStdEnv stdenv {
548+
hardeningDisable = [ "all" ];
549+
}) true;
475550
}))

0 commit comments

Comments
 (0)