Skip to content

Commit a9edd09

Browse files
committed
cc-wrapper hardeningFlags tests: add tests for pacret & shadowstack
1 parent b94e45e commit a9edd09

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 {
@@ -197,6 +248,14 @@ in nameDrvAfterAttrName ({
197248
ignoreStackClashProtection = false;
198249
});
199250

251+
pacRetExplicitEnabled = pacRetTest (helloWithStdEnv stdenv {
252+
hardeningEnable = [ "pacret" ];
253+
}) false;
254+
255+
shadowStackExplicitEnabled = shadowStackTest (f1exampleWithStdEnv stdenv {
256+
hardeningEnable = [ "shadowstack" ];
257+
}) false;
258+
200259
bindNowExplicitDisabled = checkTestBin (f2exampleWithStdEnv stdenv {
201260
hardeningDisable = [ "bindnow" ];
202261
}) {
@@ -264,6 +323,14 @@ in nameDrvAfterAttrName ({
264323
expectFailure = true;
265324
};
266325

326+
pacRetExplicitDisabled = pacRetTest (helloWithStdEnv stdenv {
327+
hardeningDisable = [ "pacret" ];
328+
}) true;
329+
330+
shadowStackExplicitDisabled = shadowStackTest (f1exampleWithStdEnv stdenv {
331+
hardeningDisable = [ "shadowstack" ];
332+
}) true;
333+
267334
# most flags can't be "unsupported" by compiler alone and
268335
# binutils doesn't have an accessible hardeningUnsupportedFlags
269336
# mechanism, so can only test a couple of flags through altered
@@ -465,4 +532,12 @@ in {
465532
ignoreStackClashProtection = false;
466533
expectFailure = true;
467534
};
535+
536+
allExplicitDisabledPacRet = pacRetTest (helloWithStdEnv stdenv {
537+
hardeningDisable = [ "all" ];
538+
}) true;
539+
540+
allExplicitDisabledShadowStack = shadowStackTest (f1exampleWithStdEnv stdenv {
541+
hardeningDisable = [ "all" ];
542+
}) true;
468543
}))

0 commit comments

Comments
 (0)