* [Bug testsuite/26991] FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation
2020-12-01 13:49 [Bug testsuite/26991] New: FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation vries at gcc dot gnu.org
@ 2020-12-01 13:54 ` vries at gcc dot gnu.org
2020-12-02 13:27 ` vries at gcc dot gnu.org
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: vries at gcc dot gnu.org @ 2020-12-01 13:54 UTC (permalink / raw)
To: gdb-prs
https://sourceware.org/bugzilla/show_bug.cgi?id=26991
--- Comment #1 from Tom de Vries <vries at gcc dot gnu.org> ---
With this tentative patch:
...
diff --git a/gdb/testsuite/gdb.arch/i386-mpx-call.exp
b/gdb/testsuite/gdb.arch/i386-mpx-cal
l.exp
index 41abbeebcf..5347eaecc2 100644
--- a/gdb/testsuite/gdb.arch/i386-mpx-call.exp
+++ b/gdb/testsuite/gdb.arch/i386-mpx-call.exp
@@ -138,7 +138,17 @@ proc check_bound_violation {parm parm_type is_positive} {
global u_fault
- gdb_test "continue" "$u_fault.*" "continue to a bnd violation"
+ set have_violation 0
+ gdb_test_multiple "continue" "continue to a bnd violation" {
+ -wrap -re "$u_fault.*" {
+ set have_violation 1
+ pass $gdb_test_name
+ }
+ }
+
+ if { ! $have_violation } {
+ return
+ }
set message "access only one position"
if {$is_positive == 1} {
...
we have instead just:
...
Running
/home/vries/gdb_versions/devel/src/gdb/testsuite/gdb.arch/i386-mpx-call.exp ...
FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation
FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd1: continue to a bnd violation
FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd2: continue to a bnd violation
FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd3: continue to a bnd violation
FAIL: gdb.arch/i386-mpx-call.exp: lower_bnd0: continue to a bnd violation
FAIL: gdb.arch/i386-mpx-call.exp: lower_bnd1: continue to a bnd violation
FAIL: gdb.arch/i386-mpx-call.exp: lower_bnd2: continue to a bnd violation
FAIL: gdb.arch/i386-mpx-call.exp: lower_bnd3: continue to a bnd violation
FAIL: gdb.arch/i386-mpx-call.exp: chars_up: continue to a bnd violation
FAIL: gdb.arch/i386-mpx-call.exp: chars_low: continue to a bnd violation
FAIL: gdb.arch/i386-mpx-call.exp: chars_low_adhoc_parm: continue to a bnd
violation
=== gdb Summary ===
# of expected passes 137
# of unexpected failures 11
...
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug testsuite/26991] FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation
2020-12-01 13:49 [Bug testsuite/26991] New: FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation vries at gcc dot gnu.org
2020-12-01 13:54 ` [Bug testsuite/26991] " vries at gcc dot gnu.org
@ 2020-12-02 13:27 ` vries at gcc dot gnu.org
2020-12-02 14:37 ` vries at gcc dot gnu.org
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: vries at gcc dot gnu.org @ 2020-12-02 13:27 UTC (permalink / raw)
To: gdb-prs
https://sourceware.org/bugzilla/show_bug.cgi?id=26991
--- Comment #2 from Tom de Vries <vries at gcc dot gnu.org> ---
As for the remaining failure.
Things are made complicated by the fact that bnd0.lbound and bnd0.ubound are
represented as 32-bit in -m32, while in the hardware they're actually 64-bit.
This is reflected in the types:
...
(gdb) ptype $bnd0
type = struct builtin_type_bound128 {
void *lbound;
void *ubound;
}
(gdb) ptype $bnd0raw
type = struct br128 {
uint64_t lbound;
uint64_t ubound_raw;
}
...
So, the interesting thing is always to print the raw value to see what's
actually written in the hw register.
So, before the FAIL we have:
...
(gdb) p /x $bnd0.lbound = $bnd0.ubound^M
$19 = 0xffffffff^M
(gdb) p /x $bnd0.ubound = 0^M
$20 = 0x0^M
(gdb) p /x $bnd0raw^M
$21 = {lbound = 0xffffffff, ubound_raw = 0xffffffffffffffff}^M
...
Now comparing that with the info found here (
https://www.felixcloutier.com/x86/bndmk ):
...
BND.LB ← SRCMEM.base;
IF 64-bit mode Then
BND.UB ← NOT(LEA.64_bits(SRCMEM));
ELSE
BND.UB ← Zero_Extend.64_bits(NOT(LEA.32_bits(SRCMEM)));
FI;
...
we can see that the value written into ubound_raw is not congruent with how
bndmk would write it.
Using this tentative patch:
...
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 00de4e1ccb..2ea28c68bd 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -3527,6 +3527,8 @@ i386_pseudo_register_write
raw_buf);
upper = ~upper;
+ if (size == 4)
+ upper = upper & 0xffffffff;
/* Set register bits. */
memcpy (raw_buf, &lower, 8);
...
fixes that, but not the FAIL.
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug testsuite/26991] FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation
2020-12-01 13:49 [Bug testsuite/26991] New: FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation vries at gcc dot gnu.org
2020-12-01 13:54 ` [Bug testsuite/26991] " vries at gcc dot gnu.org
2020-12-02 13:27 ` vries at gcc dot gnu.org
@ 2020-12-02 14:37 ` vries at gcc dot gnu.org
2020-12-03 14:28 ` [Bug tdep/26991] " vries at gcc dot gnu.org
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: vries at gcc dot gnu.org @ 2020-12-02 14:37 UTC (permalink / raw)
To: gdb-prs
https://sourceware.org/bugzilla/show_bug.cgi?id=26991
--- Comment #3 from Tom de Vries <vries at gcc dot gnu.org> ---
The mechanism of the test (as demonstrated on -m64) is as follows:
- use -mmpx -fcheck-pointer-bounds to generate pointer checks in the exec
- run the exec to after all mallocs are done, such that all variables are valid
- do inferior calls, similar to those already in the program
- a peculiarity about inferior calls is that the bounds (that is, the registers
bnd0-3) are reset at the start of the call, see amd64_push_dummy_call
- first two inferior calls are done (default_run and verify_default_values,
where
the memory access are done with the bounds registers set by
amd64_push_dummy_call to all-allowed
- then we try to do an inferior call with modified bounds registers.
In order to do that, we set a breakpoint at *function before doing the
inferior
call. Once we hit the breakpoint during the inferior call, the bounds
registers are set to none-allowed, and we continue expecting to run into an
bounds check sigsegv.
This doesn't work for -m32 because the abi seems different.
For -m64 we have before a regular call the bnd regs setup like this:
...
(gdb) p $bnd0
$5 = {lbound = 0x7fffffffdb70, ubound = 0x7fffffffdb83} : size 20
(gdb) p &sa
$7 = (int (*)[5]) 0x7fffffffdb70
...
by this code:
...
*x = upper (sa, sb, sc, sd, 0); /* bkpt 1. */
4006ef: 48 8d 8d 60 ff ff ff lea -0xa0(%rbp),%rcx
4006f6: 48 8d 55 80 lea -0x80(%rbp),%rdx
4006fa: 48 8d 75 a0 lea -0x60(%rbp),%rsi
4006fe: 48 8d 45 c0 lea -0x40(%rbp),%rax
400702: 41 b8 00 00 00 00 mov $0x0,%r8d
400708: 66 0f 1a 9d f0 fe ff bndmov -0x110(%rbp),%bnd3
40070f: ff
400710: 66 0f 1a 95 00 ff ff bndmov -0x100(%rbp),%bnd2
400717: ff
400718: 66 0f 1a 8d 10 ff ff bndmov -0xf0(%rbp),%bnd1
40071f: ff
400720: 66 0f 1a 85 20 ff ff bndmov -0xe0(%rbp),%bnd0
400727: ff
400728: 48 89 c7 mov %rax,%rdi
40072b: f2 e8 bb 02 00 00 bnd callq 4009ec <upper>
...
But for -m32, we have instead this (the &sa address is in bnd3, but that's just
used as temporary):
...
(gdb) p $bnd0
$1 = {lbound = 0x804c1e0, ubound = 0x804c1f3} : size 20
(gdb) p &sa
$2 = (int (*)[5]) 0xffffcdf4
(gdb) p $bnd1
$3 = {lbound = 0xffffcde0, ubound = 0xffffcdf3} : size 20
(gdb) p $bnd2
$4 = {lbound = 0x804c1e0, ubound = 0x804c1f3} : size 20
(gdb) p $bnd3
$5 = {lbound = 0xffffcdf4, ubound = 0xffffce07} : size 20
...
because the bounds are passed in the bounds table:
...
*x = upper (sa, sb, sc, sd, 0); /* bkpt 1. */
80485ed: 83 ec 20 sub $0x20,%esp
80485f0: 89 e0 mov %esp,%eax
80485f2: c7 40 10 00 00 00 00 movl $0x0,0x10(%eax)
80485f9: 8d 55 90 lea -0x70(%ebp),%edx
80485fc: 89 50 0c mov %edx,0xc(%eax)
80485ff: 8d 55 a4 lea -0x5c(%ebp),%edx
8048602: 89 50 08 mov %edx,0x8(%eax)
8048605: 8d 55 b8 lea -0x48(%ebp),%edx
8048608: 89 50 04 mov %edx,0x4(%eax)
804860b: 8d 55 cc lea -0x34(%ebp),%edx
804860e: 89 10 mov %edx,(%eax)
8048610: 8d 50 0c lea 0xc(%eax),%edx
8048613: 8b 48 0c mov 0xc(%eax),%ecx
8048616: 66 0f 1a 8d 58 ff ff bndmov -0xa8(%ebp),%bnd1
804861d: ff
804861e: 0f 1b 0c 0a bndstx %bnd1,(%edx,%ecx,1)
8048622: 8d 50 08 lea 0x8(%eax),%edx
8048625: 8b 48 08 mov 0x8(%eax),%ecx
8048628: 66 0f 1a 9d 60 ff ff bndmov -0xa0(%ebp),%bnd3
804862f: ff
8048630: 0f 1b 1c 0a bndstx %bnd3,(%edx,%ecx,1)
8048634: 8d 50 04 lea 0x4(%eax),%edx
8048637: 8b 48 04 mov 0x4(%eax),%ecx
804863a: 66 0f 1a 8d 68 ff ff bndmov -0x98(%ebp),%bnd1
8048641: ff
8048642: 0f 1b 0c 0a bndstx %bnd1,(%edx,%ecx,1)
8048646: 8b 10 mov (%eax),%edx
8048648: 66 0f 1a 9d 70 ff ff bndmov -0x90(%ebp),%bnd3
804864f: ff
8048650: 0f 1b 1c 10 bndstx %bnd3,(%eax,%edx,1)
8048654: f2 e8 e5 02 00 00 bnd call 804893f <upper>
...
So, setting the bounds registers at function entry has no effect, because the
bounds are passed in the bounds table instead.
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug tdep/26991] FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation
2020-12-01 13:49 [Bug testsuite/26991] New: FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation vries at gcc dot gnu.org
` (2 preceding siblings ...)
2020-12-02 14:37 ` vries at gcc dot gnu.org
@ 2020-12-03 14:28 ` vries at gcc dot gnu.org
2020-12-04 12:03 ` [Bug testsuite/26991] " vries at gcc dot gnu.org
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: vries at gcc dot gnu.org @ 2020-12-03 14:28 UTC (permalink / raw)
To: gdb-prs
https://sourceware.org/bugzilla/show_bug.cgi?id=26991
Tom de Vries <vries at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Component|testsuite |tdep
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug testsuite/26991] FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation
2020-12-01 13:49 [Bug testsuite/26991] New: FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation vries at gcc dot gnu.org
` (3 preceding siblings ...)
2020-12-03 14:28 ` [Bug tdep/26991] " vries at gcc dot gnu.org
@ 2020-12-04 12:03 ` vries at gcc dot gnu.org
2020-12-04 14:22 ` vries at gcc dot gnu.org
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: vries at gcc dot gnu.org @ 2020-12-04 12:03 UTC (permalink / raw)
To: gdb-prs
https://sourceware.org/bugzilla/show_bug.cgi?id=26991
Tom de Vries <vries at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Component|tdep |testsuite
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug testsuite/26991] FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation
2020-12-01 13:49 [Bug testsuite/26991] New: FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation vries at gcc dot gnu.org
` (4 preceding siblings ...)
2020-12-04 12:03 ` [Bug testsuite/26991] " vries at gcc dot gnu.org
@ 2020-12-04 14:22 ` vries at gcc dot gnu.org
2020-12-11 17:26 ` cvs-commit at gcc dot gnu.org
2020-12-11 17:29 ` vries at gcc dot gnu.org
7 siblings, 0 replies; 9+ messages in thread
From: vries at gcc dot gnu.org @ 2020-12-04 14:22 UTC (permalink / raw)
To: gdb-prs
https://sourceware.org/bugzilla/show_bug.cgi?id=26991
--- Comment #4 from Tom de Vries <vries at gcc dot gnu.org> ---
Patch posted:
https://sourceware.org/pipermail/gdb-patches/2020-December/173768.html
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug testsuite/26991] FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation
2020-12-01 13:49 [Bug testsuite/26991] New: FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation vries at gcc dot gnu.org
` (5 preceding siblings ...)
2020-12-04 14:22 ` vries at gcc dot gnu.org
@ 2020-12-11 17:26 ` cvs-commit at gcc dot gnu.org
2020-12-11 17:29 ` vries at gcc dot gnu.org
7 siblings, 0 replies; 9+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2020-12-11 17:26 UTC (permalink / raw)
To: gdb-prs
https://sourceware.org/bugzilla/show_bug.cgi?id=26991
--- Comment #5 from cvs-commit at gcc dot gnu.org <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Tom de Vries <vries@sourceware.org>:
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=346e7e192370a4d602e14466825c329ed5920c8f
commit 346e7e192370a4d602e14466825c329ed5920c8f
Author: Tom de Vries <tdevries@suse.de>
Date: Fri Dec 11 18:26:40 2020 +0100
[gdb/testsuite] Update gdb.arch/i386-mpx-call.exp for -m32
When running test-case gdb.arch/i386-mpx-call.exp with target board
unix/-m32,
we run into:
...
(gdb) continue^M
Continuing.^M
(gdb) FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd
violation
...
Let's look first for reference at -m64, where the test passes.
The test-case uses -mmpx -fcheck-pointer-bounds to generate pointer checks
in
the exec. Effectively, -fcheck-pointer-bounds modifies the calling ABI: a
call passes pointer bounds as well as arguments. The call to upper (with
four pointer arguments and an int argument, passed in 5 registers) is
modified
like this:
...
lea -0xa0(%rbp),%rcx
lea -0x80(%rbp),%rdx
lea -0x60(%rbp),%rsi
lea -0x40(%rbp),%rax
mov $0x0,%r8d
+ bndmov -0x110(%rbp),%bnd3
+ bndmov -0x100(%rbp),%bnd2
+ bndmov -0xf0(%rbp),%bnd1
+ bndmov -0xe0(%rbp),%bnd0
mov %rax,%rdi
- callq <upper>
+ bnd callq <upper>
...
passsing the four pointer bounds in bounds registers BND0-3.
The top-level mechanism of the test is as follows:
- run the exec to after all mallocs are done, such that all pointer
variables
are valid
- do inferior calls, similar to those present in the program
The inferior call mechanism doesn't differentiate between a call to a
function
compiled with -fcheck-pointer-bounds, and one without. It merely resets
the
bound registers to all-allowed state (see amd64_push_dummy_call), to make
sure
the checks don't trigger during the inferior call. [ This is the same as
what
happens when executing a call without bnd prefix when the BNDPRESERVE bit
of
the BNDCFG register is set to 0, a provision for calling an instrumented
function using a non-instrumented call. ]
First, two inferior calls are done (default_run and verify_default_values)
with the bound registers unmodified by the test. So, the memory accesses
are
performed with the bounds registers set by amd64_push_dummy_call to
all-allowed, and the bounds checks do not trigger.
Then we try to do an inferior call with modified bounds registers, set to
none-allowed. In order to do that, we set a breakpoint at *upper before
doing the inferior call. Once we hit the breakpoint during the inferior
call,
the bounds registers are set to none-allowed, and we continue expecting to
run
into an triggered bounds check, which takes the shape of a sigsegv.
Back to -m32. Here, the pointer arguments are passed in memory rather than
registers, so with -fcheck-pointer-bounds, the pointer bounds are placed in
the Bounds Table using bndstx:
...
movl $0x0,0x10(%eax)
lea -0x70(%ebp),%edx
mov %edx,0xc(%eax)
lea -0x5c(%ebp),%edx
mov %edx,0x8(%eax)
lea -0x48(%ebp),%edx
mov %edx,0x4(%eax)
lea -0x34(%ebp),%edx
mov %edx,(%eax)
lea 0xc(%eax),%edx
mov 0xc(%eax),%ecx
bndmov -0xa8(%ebp),%bnd1
bndstx %bnd1,(%edx,%ecx,1)
lea 0x8(%eax),%edx
mov 0x8(%eax),%ecx
bndmov -0xa0(%ebp),%bnd3
bndstx %bnd3,(%edx,%ecx,1)
lea 0x4(%eax),%edx
mov 0x4(%eax),%ecx
bndmov -0x98(%ebp),%bnd1
bndstx %bnd1,(%edx,%ecx,1)
mov (%eax),%edx
bndmov -0x90(%ebp),%bnd3
bndstx %bnd3,(%eax,%edx,1)
bnd call 804893f <upper>
...
Again, the bounds registers are reset at the start of the inferior call by
amd64_push_dummy_call, and modified by the test-case, but neither has any
effect. The code in upper reads the pointer bounds from the Bounds Table,
not
from the bounds registers.
Note that for a test.c with an out-of-bounds access:
...
$ cat test.c
void foo (int *a) { volatile int v = a[1]; }
int main (void) { int a; foo (&a); return 0; }
$ gcc test.c -mmpx -fcheck-pointer-bounds -g -m32
$ ./a.out
Saw a #BR! status 1 at 0x804848d
...
and inferior call foo (&a) right before "bnd call foo" (at the point that
the
bounds for a are setup in the bounds table) doesn't trigger a bounds
violation:
...
(gdb) call foo (&a)
(gdb)
...
This is because the bounds table doesn't associate a pointer with bounds,
but
rather a pair of pointer and pointer location. So, the bound is setup for
&a,
with as location the pushed argument in the frame. The inferior call
however
executes in a dummy frame, so the bound is checked for &a with as location
the
pushed argument in the dummy frame, which is different, so the bounds check
doesn't trigger.
In conclusion, this is expected behaviour.
Update the test-case to not expect to override effective pointer bounds
using
the bounds registers when the bounds passing is done via the Bounds Table.
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2020-12-11 Tom de Vries <tdevries@suse.de>
PR testsuite/26991
* gdb.arch/i386-mpx-call.exp: Don't expect to trigger bounds
violations by setting bounds registers if the bounds are passed in
the
Bounds Table.
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [Bug testsuite/26991] FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation
2020-12-01 13:49 [Bug testsuite/26991] New: FAIL: gdb.arch/i386-mpx-call.exp: upper_bnd0: continue to a bnd violation vries at gcc dot gnu.org
` (6 preceding siblings ...)
2020-12-11 17:26 ` cvs-commit at gcc dot gnu.org
@ 2020-12-11 17:29 ` vries at gcc dot gnu.org
7 siblings, 0 replies; 9+ messages in thread
From: vries at gcc dot gnu.org @ 2020-12-11 17:29 UTC (permalink / raw)
To: gdb-prs
https://sourceware.org/bugzilla/show_bug.cgi?id=26991
Tom de Vries <vries at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Target Milestone|--- |11.1
Resolution|--- |FIXED
Status|NEW |RESOLVED
--- Comment #6 from Tom de Vries <vries at gcc dot gnu.org> ---
Patch fixed test-case committed, marking resolved-fixed.
--
You are receiving this mail because:
You are on the CC list for the bug.
^ permalink raw reply [flat|nested] 9+ messages in thread