xlat: add PR_SPEC_INDIRECT_BRANCH to pr_spec_cmds

* xlat/pr_spec_cmds.in (PR_SPEC_INDIRECT_BRANCH): New constant,
introduced by Linux commit v4.20-rc5~4^2~3.
* prctl.c (SYS_FUNC(prctl)) <case PR_GET_SPECULATION_CTRL, case
PR_SET_SPECULATION_CTRL>: Add PR_SPEC_INDIRECT_BRANCH handling.
* tests/prctl-spec-inject.c (main): Add PR_SPEC_INDIRECT_BRANCH decoding
checks, update expected output.
* NEWS: Mention this.

Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
This commit is contained in:
Eugene Syromyatnikov 2018-12-14 17:25:24 +01:00 committed by Dmitry V. Levin
parent c065838680
commit 38ea49ad11
4 changed files with 37 additions and 20 deletions

2
NEWS
View File

@ -24,7 +24,7 @@ Noteworthy changes in release ?.?? (????-??-??)
* Enhanced error diagnostics when the first exec fails. * Enhanced error diagnostics when the first exec fails.
* Added %net as a short form of %network in syscall specifications. * Added %net as a short form of %network in syscall specifications.
* Updated lists of ABS_*, BPF_*, FAN_*, IFA_*, IFLA_*, KVM_CAP_*, NETLINK_*, * Updated lists of ABS_*, BPF_*, FAN_*, IFA_*, IFLA_*, KVM_CAP_*, NETLINK_*,
NTF_*, REL_*, SOL_*, TCA_*, and V4L2_* constants. NTF_*, PR_SPEC_*, REL_*, SOL_*, TCA_*, and V4L2_* constants.
* Enhanced manual page. * Enhanced manual page.
* Bug fixes * Bug fixes

View File

@ -221,6 +221,7 @@ SYS_FUNC(prctl)
switch (arg2) { switch (arg2) {
case PR_SPEC_STORE_BYPASS: case PR_SPEC_STORE_BYPASS:
case PR_SPEC_INDIRECT_BRANCH:
tcp->auxstr = sprintflags("", tcp->auxstr = sprintflags("",
pr_spec_get_store_bypass_flags, pr_spec_get_store_bypass_flags,
(kernel_ulong_t) tcp->u_rval); (kernel_ulong_t) tcp->u_rval);
@ -393,6 +394,7 @@ SYS_FUNC(prctl)
switch (arg2) { switch (arg2) {
case PR_SPEC_STORE_BYPASS: case PR_SPEC_STORE_BYPASS:
case PR_SPEC_INDIRECT_BRANCH:
printxval64(pr_spec_set_store_bypass_flags, arg3, printxval64(pr_spec_set_store_bypass_flags, arg3,
"PR_SPEC_???"); "PR_SPEC_???");
break; break;

View File

@ -40,6 +40,15 @@ main(int argc, char **argv)
(kernel_ulong_t) 0xdeadfacebadc0dedULL; (kernel_ulong_t) 0xdeadfacebadc0dedULL;
static const kernel_ulong_t bogus_arg3 = static const kernel_ulong_t bogus_arg3 =
(kernel_ulong_t) 0xdecafeedbeefda7eULL; (kernel_ulong_t) 0xdecafeedbeefda7eULL;
static const struct {
long arg;
const char *str;
} spec_strs[] = {
{ 0, "PR_SPEC_STORE_BYPASS" },
{ 1, "PR_SPEC_INDIRECT_BRANCH" },
};
static const struct { static const struct {
long arg; long arg;
const char *str; const char *str;
@ -78,8 +87,8 @@ main(int argc, char **argv)
injected_val = strtol(argv[1], NULL, 0); injected_val = strtol(argv[1], NULL, 0);
/* PR_GET_SPECULATION_CTRL */ /* PR_GET_SPECULATION_CTRL */
rc = do_prctl(52, 1, bogus_arg3); rc = do_prctl(52, 2, bogus_arg3);
printf("prctl(PR_GET_SPECULATION_CTRL, 0x1 /* PR_SPEC_??? */) " printf("prctl(PR_GET_SPECULATION_CTRL, 0x2 /* PR_SPEC_??? */) "
"= %s (INJECTED)\n", sprintrc(rc)); "= %s (INJECTED)\n", sprintrc(rc));
rc = do_prctl(52, bogus_arg2, bogus_arg3); rc = do_prctl(52, bogus_arg2, bogus_arg3);
@ -87,24 +96,26 @@ main(int argc, char **argv)
"= %s (INJECTED)\n", "= %s (INJECTED)\n",
(unsigned long long) bogus_arg2, sprintrc(rc)); (unsigned long long) bogus_arg2, sprintrc(rc));
rc = do_prctl(52, 0, bogus_arg3); for (unsigned c = 0; c < ARRAY_SIZE(spec_strs); c++) {
rc = do_prctl(52, spec_strs[c].arg, bogus_arg3);
for (unsigned i = 0; i < ARRAY_SIZE(get_strs); i++) { for (unsigned i = 0; i < ARRAY_SIZE(get_strs); i++) {
if (get_strs[i].arg == rc) { if (get_strs[i].arg == rc) {
str = get_strs[i].str; str = get_strs[i].str;
break; break;
}
} }
} if (!str)
if (!str) error_msg_and_fail("Unknown return value: %ld", rc);
error_msg_and_fail("Unknown return value: %ld", rc);
printf("prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS) " printf("prctl(PR_GET_SPECULATION_CTRL, %s) = %s%s (INJECTED)\n",
"= %s%s (INJECTED)\n", sprintrc(rc), str); spec_strs[c].str, sprintrc(rc), str);
}
/* PR_SET_SPECULATION_CTRL*/ /* PR_SET_SPECULATION_CTRL*/
rc = do_prctl(53, 1, bogus_arg3); rc = do_prctl(53, 2, bogus_arg3);
printf("prctl(PR_SET_SPECULATION_CTRL, 0x1 /* PR_SPEC_??? */, %#llx) " printf("prctl(PR_SET_SPECULATION_CTRL, 0x2 /* PR_SPEC_??? */, %#llx) "
"= %s (INJECTED)\n", "= %s (INJECTED)\n",
(unsigned long long) bogus_arg3, sprintrc(rc)); (unsigned long long) bogus_arg3, sprintrc(rc));
@ -115,11 +126,13 @@ main(int argc, char **argv)
(unsigned long long) bogus_arg3, (unsigned long long) bogus_arg3,
sprintrc(rc)); sprintrc(rc));
for (unsigned i = 0; i < ARRAY_SIZE(set_strs); i++) { for (unsigned c = 0; c < ARRAY_SIZE(spec_strs); c++) {
rc = do_prctl(53, 0, set_strs[i].arg); for (unsigned i = 0; i < ARRAY_SIZE(set_strs); i++) {
printf("prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS" rc = do_prctl(53, spec_strs[c].arg, set_strs[i].arg);
", %s) = %s (INJECTED)\n", printf("prctl(PR_SET_SPECULATION_CTRL, %s"
set_strs[i].str, sprintrc(rc)); ", %s) = %s (INJECTED)\n",
spec_strs[c].str, set_strs[i].str, sprintrc(rc));
}
} }
puts("+++ exited with 0 +++"); puts("+++ exited with 0 +++");

View File

@ -1 +1,3 @@
#value_indexed
PR_SPEC_STORE_BYPASS 0 PR_SPEC_STORE_BYPASS 0
PR_SPEC_INDIRECT_BRANCH 1