From 454074149593d8df9b1a65f6c78d3b1f9edf4b90 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 14 Dec 2022 11:10:53 -0800 Subject: [PATCH] Update GDB examples for CHERI GDB 12. --- src/exercises/adapt-c/answers.md | 102 +++++++++--------- .../buffer-overflow-global/answers.md | 23 ++-- .../buffer-overflow-stack/answers.md | 38 ++++--- src/exercises/cheri-allocator/answers.md | 56 +++++----- src/exercises/cheri-tags/answers.md | 15 +-- src/exercises/cheriabi/answers.md | 1 - src/exercises/pointer-revocation/answers.md | 2 +- src/exercises/subobject-bounds/answers.md | 35 ++++-- 8 files changed, 143 insertions(+), 129 deletions(-) diff --git a/src/exercises/adapt-c/answers.md b/src/exercises/adapt-c/answers.md index 16e2b345..a3bece27 100644 --- a/src/exercises/adapt-c/answers.md +++ b/src/exercises/adapt-c/answers.md @@ -2,7 +2,7 @@ 2. Example output: ``` - # ./tools/ccc riscv64 -o /build/cat-cheri ./src/exercises/adapt-c/cat/cat.c ./src/exercises/adapt-c/cat/methods.c + # ./tools/ccc riscv64 -o /build/cat-baseline ./src/exercises/adapt-c/cat/cat.c ./src/exercises/adapt-c/cat/methods.c Running: /output/sdk/bin/clang -target riscv64-unknown-freebsd -march=rv64gc -mabi=lp64d -mno-relax --sysroot=/output/sdk/sysroot-riscv64-purecap -g -O2 -fuse-ld=lld -Wall -Wcheri -o /build/cat-cheri ./src/exercises/adapt-c/cat/cat.c ./src/exercises/adapt-c/cat/methods.c # ./tools/ccc riscv64-purecap -o /build/cat-cheri ./src/exercises/adapt-c/cat/cat.c ./src/exercises/adapt-c/cat/methods.c Running: /output/sdk/bin/clang -target riscv64-unknown-freebsd -march=rv64gcxcheri -mabi=l64pc128d -mno-relax --sysroot=/output/sdk/sysroot-riscv64-purecap -g -O2 -fuse-ld=lld -Wall -Wcheri -o /build/cat-cheri ./src/exercises/adapt-c/cat/cat.c ./src/exercises/adapt-c/cat/methods.c @@ -54,23 +54,26 @@ Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (write) pending. (gdb) r /etc/hostid - Starting program: /buildroot/cat-cheri /etc/hostid - - Breakpoint 1, write (fd=1, buf=0x40810000, nbytes=37) at /source/cheribsd/lib/libc/sys/write.c:49 - 49 /source/cheribsd/lib/libc/sys/write.c: No such file or directory. - (gdb) info register ca0 ca1 ca2 + Starting program: /root/cat-cheri /etc/hostid + + Breakpoint 1, write (fd=, buf=, nbytes=) at /usr/home/john/work/cheri/git/cheribsd/lib/libc/sys/write.c:48 + 48 __libc_interposing[INTERPOS_write])(fd, buf, nbytes)); + ``` + Even though the debugger believes that the function arguments are + optimized out, from the CHERI-RISC-V calling conventions we know that + the arguments are in the ca0, ca1, and ca2 registers: + ``` + (gdb) info registers ca0 ca1 ca2 ca0 0x1 0x1 - ca1 0x40810000 0x40810000 + ca1 0x40802000 0x40802000 ca2 0x25 0x25 - (gdb) (gdb) disassemble Dump of assembler code for function write: - => 0x0000000040295dc4 <+0>: auipc a3,0xc2 - 0x0000000040295dc8 <+4>: lc ca3,1532(a3) # 0x403583c0 <_CHERI_CAPABILITY_TABLE_+2464> - 0x0000000040295dcc <+8>: lc ca5,496(a3) - 0x0000000040295dd0 <+12>: cjr ca5 + => 0x000000004027fa98 <+0>: auipcc ca3,0xb7 + 0x000000004027fa9c <+4>: clc ca3,-424(ca3) + 0x000000004027faa0 <+8>: clc ca5,496(ca3) + 0x000000004027faa4 <+12>: cjr ca5 End of assembler dump. - (gdb) ``` We can see that `write()` was called to write to `stdout` (`ca0`) 37 bytes (`ca2`) from a buffer with an untagged capability (`ca1`). The `write()` libc @@ -82,15 +85,14 @@ 4 _write.S: No such file or directory. (gdb) disassemble Dump of assembler code for function _write: - => 0x0000000040299130 <+0>: li t0,4 - 0x0000000040299132 <+2>: ecall - 0x0000000040299136 <+6>: bnez t0,0x4029913e <_write+14> - 0x000000004029913a <+10>: cret - 0x000000004029913e <+14>: auipc t1,0xffffd - 0x0000000040299142 <+18>: cincoffset ct1,ct1,-846 - 0x0000000040299146 <+22>: cjr ct1 + => 0x0000000040282f40 <+0>: li t0,4 + 0x0000000040282f42 <+2>: ecall + 0x0000000040282f46 <+6>: bnez t0,0x40282f4e <_write+14> + 0x0000000040282f4a <+10>: cret + 0x0000000040282f4e <+14>: auipcc ct1,0xffffd + 0x0000000040282f52 <+18>: cincoffset ct1,ct1,-1166 + 0x0000000040282f56 <+22>: cjr ct1 End of assembler dump. - (gdb) ``` `write()` jumped to `_write()`, a system call wrapper written in assembly, that uses the `ecall` instruction to make a system call. Let's see what is @@ -145,43 +147,45 @@ ``` # gdb-run.sh ./cat-cheri -n /etc/hostid (...) - Starting program: /buildroot/cat-cheri -n /etc/hostid - - Program received signal SIGPROT, CHERI protection violation - Capability tag fault caused by register cs2. - verbose_cat (file=) at ./src/exercises/adapt-c/cat/methods.c:87 - 87 ./src/exercises/adapt-c/cat/methods.c: No such file or directory. - - Thread 1 (LWP 100043 of process 808): - #0 verbose_cat (file=) at ./src/exercises/adapt-c/cat/methods.c:87 - #1 do_cat (file=, verbose=) at ./src/exercises/adapt-c/cat/methods.c:214 - #2 0x0000000000102f1a in scanfiles (argv=, verbose=) at ./src/exercises/adapt-c/cat/cat.c:172 - #3 0x0000000000102d8c in main (argc=, argv=) at ./src/exercises/adapt-c/cat/cat.c:128 - (gdb) + Starting program: /root/cat-cheri -n /etc/hostid + + Program received signal SIGPROT, CHERI protection violation. + Capability tag fault caused by register cs4. + verbose_cat (file=) at cat/methods.c:87 + 87 for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) { + + Thread 1 (LWP 100061 of process 2694): + #0 verbose_cat (file=) at cat/methods.c:87 + #1 do_cat (file=, verbose=) at cat/methods.c:214 + #2 0x0000000000102dca in scanfiles (argv=0x3fbfdff7c0 [rwRW,0x3fbfdff7a0-0x3fbfdff7e0], verbose=) at cat/cat.c:172 + #3 0x0000000000102c52 in main (argc=3, argv=0x0) at cat/cat.c:128 ``` - `gdb` says that `cs2` triggered a CHERI exception: + `gdb` says that `cs4` triggered a CHERI exception: ``` - (gdb) info register cs2 - cs2 0x4037a400 0x4037a400 - (gdb) + (gdb) info register cs4 + cs4 0x403545d0 0x403545d0 ``` - `cs2` holds an untagged capability and the program tries to load a word using - `cs2` which violates CHERI restrictions: + `cs4` holds an untagged capability and the program tries to load a word using + `cs4` which violates CHERI restrictions: ``` (gdb) disassemble $pcc,+4 - Dump of assembler code from 0x103094 to 0x103098: - => 0x0000000000103094 : lw a0,16(s2) + Dump of assembler code from 0x102f7e to 0x102f82: + => 0x0000000000102f7e : clw a0,16(cs4) End of assembler dump. - (gdb) ``` - Looking at the above backtrace, we can correlate this output with the source - code and see that `cs2` holds a value of - the `fp` variable: + Looking at the values of local variables, we can see that `cs4` holds the + value of the `fp` variable: ``` - (gdb) p fp - $1 = (FILE *) 0x4037a400 + (gdb) info locals + fp = 0x403545d0 + gobble = 0 + line = 0 + prev = 10 + ch = + wch = ``` - It means that for some reason `fp` became an invalid capability. + It means that for some reason `fp` holds an invalid (NULL-derived) + capability. 7. When compiling `cat-cheri`, the compiler printed: diff --git a/src/exercises/buffer-overflow-global/answers.md b/src/exercises/buffer-overflow-global/answers.md index 178c2666..fbc3b5ec 100644 --- a/src/exercises/buffer-overflow-global/answers.md +++ b/src/exercises/buffer-overflow-global/answers.md @@ -14,22 +14,15 @@ ``` Program received signal SIGPROT, CHERI protection violation Capability bounds fault caused by register ca4. - fill_buf ( - buf=0x104060 [rwRW,0x104060-0x1040e0] 'b' , - len=128) at src/exercises/buffer-overflow-global/buffer-overflow-global.c:11 - 11 in src/exercises/buffer-overflow-global/buffer-overflow-global.c + fill_buf (buf=0x104160 [rwRW,0x104160-0x1041e0] 'b' , "c", len=128) at buffer-overflow-global.c:15 + 15 buf[i] = 'b'; (gdb) info reg ca4 - ca4 0xf17d00000439806400000000001040e0 0x1040e0 [rwRW,0x104060-0x1040e0] + ca4 0xf17d00000479816400000000001041e0 0x1041e0 [rwRW,0x104160-0x1041e0] (gdb) x/i $pcc - => 0x101cc8 : sb a3,0(a4) + => 0x101d2c : csb a3,0(ca4) ``` The array has been incremented beyond the end of the allocation as out of bounds store has been attempted (`Capability bounds fault`). - *Note:* due to deficiencies in the current GDB implementation, the - instruction incorrectly decodes as `sb` rather than correctly as: - ``` - 1cc8: 23 00 d7 00 csb a3, 0(ca4) - ``` 5. Expected output: ``` @@ -40,13 +33,13 @@ To see why this occurs, examine the bounds of the buffer in `fill_buf`. ``` (gdb) b fill_buf - Breakpoint 1 at 0x1cc2: file src/exercises/buffer-overflow-global/buffer-overflow-global.c, line 11. + Breakpoint 1 at 0x101d26: file buffer-overflow-global.c, line 15. (gdb) r Starting program: /root/buffer-overflow-global-cheri + c = c - Breakpoint 1, fill_buf (buf=0x105000 [rwRW,0x105000-0x205800] "", - len=1048577) at src/exercises/buffer-overflow-global/buffer-overflow-global.c:11 - 11 src/exercises/buffer-overflow-global/buffer-overflow-global.c: No such file or directory. + Breakpoint 1, fill_buf (buf=0x105000 [rwRW,0x105000-0x205800] "", len=1048577) at buffer-overflow-global.c:15 + 15 buf[i] = 'b'; ``` This indicates that buffer has been allocated (1024 * 1026) bytes. This is due to the padding required to ensure that the bounds of `buffer` diff --git a/src/exercises/buffer-overflow-stack/answers.md b/src/exercises/buffer-overflow-stack/answers.md index d0e9e0a8..c2d9699c 100644 --- a/src/exercises/buffer-overflow-stack/answers.md +++ b/src/exercises/buffer-overflow-stack/answers.md @@ -21,24 +21,22 @@ Program received signal SIGPROT, CHERI protection violation Capability bounds fault caused by register ca0. - 0x0000000000101ce8 in write_buf (buf=, ix=) at ./buffer-overflow-stack.c:13 + 0x0000000000101cf0 in write_buf (buf=, ix=) at buffer-overflow-stack.c:13 13 buf[ix] = 'b'; - Thread 1 (LWP 100044 of process 838): - #0 0x0000000000101ce8 in write_buf (buf=, ix=) at ./buffer-overflow-stack.c:13 - #1 0x0000000000101d72 in main () at ./buffer-overflow-stack.c:31 + Thread 1 (LWP 100055 of process 829): + #0 0x0000000000101cf0 in write_buf (buf=, ix=) at buffer-overflow-stack.c:13 + #1 0x0000000000101d7a in main () at buffer-overflow-stack.c:31 (gdb) disass Dump of assembler code for function write_buf: - 0x0000000000101ce0 <+0>: cincoffset ca0,ca0,a1 - 0x0000000000101ce4 <+4>: li a1,98 - => 0x0000000000101ce8 <+8>: sb a1,0(a0) - 0x0000000000101cec <+12>: ret + 0x0000000000101ce8 <+0>: cincoffset ca0,ca0,a1 + 0x0000000000101cec <+4>: li a1,98 + => 0x0000000000101cf0 <+8>: csb a1,0(ca0) + 0x0000000000101cf4 <+12>: cret End of assembler dump. ``` - *Note:* due to deficiencies in the current GDB implementation, the faulting - instruction incorrectly decodes as `sb` rather than correctly as `csb a1, - 0(ca0)`. Asking `gdb` about the registers with `info registers` and focusing + Asking `gdb` about the registers with `info registers` and focusing on the ones involved here, we see ``` a0 0x3fffdfff50 274875809616 @@ -55,20 +53,20 @@ `disass`embling, we see (eliding irrelevant instructions): ``` (gdb) up - #1 0x0000000000101d72 in main () at ./buffer-overflow-stack.c:31 + #1 0x0000000000101d7a in main () at buffer-overflow-stack.c:31 31 write_buf(lower, sizeof(lower)); (gdb) disass Dump of assembler code for function main: - 0x0000000000101cf0 <+0>: cincoffset csp,csp,-144 + 0x0000000000101cf8 <+0>: cincoffset csp,csp,-144 - 0x0000000000101d0c <+28>: cincoffset ca0,csp,48 - 0x0000000000101d10 <+32>: csetbounds cs0,ca0,16 + 0x0000000000101d14 <+28>: cincoffset ca0,csp,48 + 0x0000000000101d18 <+32>: csetbounds cs0,ca0,16 - 0x0000000000101d64 <+116>: li a1,16 - 0x0000000000101d66 <+118>: cmove ca0,cs0 - 0x0000000000101d6a <+122>: auipc ra,0x0 - 0x0000000000101d6e <+126>: jalr -138(ra) # 0x101ce0 - => 0x0000000000101d72 <+130>: lbu a0,0(s1) + 0x0000000000101d6c <+116>: li a1,16 + 0x0000000000101d6e <+118>: cmove ca0,cs0 + 0x0000000000101d72 <+122>: auipcc cra,0x0 + 0x0000000000101d76 <+126>: cjalr -138(cra) + => 0x0000000000101d7a <+130>: clbu a0,0(cs1) ``` The compiler has arranged for `main` to allocate 144 bytes on the stack by decrementing the *capability stack pointer* register (`csp`) by 144 bytes. diff --git a/src/exercises/cheri-allocator/answers.md b/src/exercises/cheri-allocator/answers.md index 47eda4e3..34072c36 100644 --- a/src/exercises/cheri-allocator/answers.md +++ b/src/exercises/cheri-allocator/answers.md @@ -7,23 +7,26 @@ a later call to `alloc_allocate()`: ``` -Starting program: /opt/cheri-exercises/cheri-allocator-cheri +Starting program: /root/cheri-allocator Allocator initialised Allocating memory -Allocation returned 0x104830 -Preparing to overflow 0x104830 -Overflowed allocation 0x104830 -Freeing allocation 0x104830 -Allocation 0x104830 freed +Allocation returned 0x104550 +Preparing to overflow 0x104550 +Overflowed allocation 0x104550 +Freeing allocation 0x104550 +Allocation 0x104550 freed Allocating memory -Allocation returned 0x104830 +Allocation returned 0x104550 Allocating memory -Allocation returned 0x1048c0 +Allocation returned 0x1045e0 Allocating memory -Program received signal SIGPROT, CHERI protection violation -Capability tag fault caused by register ca2. -0x0000000000102374 in alloc_allocate () +Program received signal SIGPROT, CHERI protection violation. +Capability tag fault caused by register ca0. +alloc_allocate () at cheri-allocator.c:83 +83 alloc_nextfree = alloc->a_next; +(gdb) p alloc +$1 = (struct alloc_storage *) 0x4141414141414141 [,0x4141402800000000-0x414142a000000000] (invalid,sealed) ``` 3. When compiling for CHERI C, use `cheri_bounds_set()` to set bounds on the @@ -42,16 +45,16 @@ Capability tag fault caused by register ca2. violation exception on overflow: ``` -Starting program: /opt/cheri-exercises/cheri-allocator-cheri +Starting program: /root/cheri-allocator Allocator initialised Allocating memory -Allocation returned 0x104840 -Preparing to overflow 0x104840 +Allocation returned 0x104550 +Preparing to overflow 0x104550 -Program received signal SIGPROT, CHERI protection violation +Program received signal SIGPROT, CHERI protection violation. Capability bounds fault caused by register ca3. -memset (dst0=0x1048c0 [rwRW,0x104840-0x1048c0], c0=65, - length=15) at /home/rnw24/cheri/cheribsd/lib/libc/string/memset.c:94 +memset (dst0=0x1045d0 [rwRW,0x104550-0x1045d0], c0=65, length=15) at /usr/home/john/work/cheri/git/cheribsd/lib/libc/string/memset.c:94 +94 *dst++ = VAL; ``` ## Reaching allocator metadata @@ -60,18 +63,21 @@ memset (dst0=0x1048c0 [rwRW,0x104840-0x1048c0], c0=65, due to reaching outside the bounds of the passed memory allocation: ``` -Starting program: /opt/cheri-exercises/cheri-allocator-cheri +Starting program: /root/cheri-allocator Allocator initialised Allocating memory -Allocation returned 0x1046e0 -Freeing allocation 0x1046e0 +Allocation returned 0x104420 +Freeing allocation 0x104420 -Program received signal SIGPROT, CHERI protection violation -Capability bounds fault caused by register ca3. -0x00000000001022fe in alloc_free () +Program received signal SIGPROT, CHERI protection violation. +Capability bounds fault caused by register cfp. +alloc_free (ptr=) at cheri-allocator.c:106 +106 alloc->a_next = alloc_nextfree; (gdb) bt -#0 0x00000000001022fe in alloc_free () -#1 0x0000000000101f52 in main () +#0 alloc_free (ptr=) at cheri-allocator.c:106 +#1 main () at cheri-allocator.c:137 +(gdb) p alloc +$1 = (struct alloc_storage *) 0x104410 [rwRW,0x104420-0x1044a0] ``` 7. We need to create a new capability, derived from `alloc_array` but with the diff --git a/src/exercises/cheri-tags/answers.md b/src/exercises/cheri-tags/answers.md index 40efbaed..062840ff 100644 --- a/src/exercises/cheri-tags/answers.md +++ b/src/exercises/cheri-tags/answers.md @@ -34,18 +34,19 @@ We can ask `gdb` to print out the faulting instruction: ``` (gdb) x/i $pcc - => 0x101d7c : lbu a0,0(s1) + => 0x101d84 : clbu a1,0(cs1) ``` - *Note:* due to deficiencies in the current GDB implementation, the faulting - instruction incorrectly decodes as `lbu` with integer operands rather than - correctly as `clbu a0, 0(cs1)`. - We can also ask `gdb` for more information about the signal we received: ``` (gdb) p $_siginfo - $1 = {si_signo = 34, si_errno = 0, si_code = 2, si_pid = 0, si_uid = 0, si_status = 0, si_addr = 0x101d7c , si_value = {sival_int = 0, sival_ptr = 0x0}, _reason = {_fault = {si_trapno = 28, si_capreg = 9}, _timer = {si_timerid = 28, si_overrun = 9}, _mesgq = {si_mqd = 28}, _poll = {si_band = 38654705692}, __spare__ = {__spare1__ = 38654705692, __spare2__ = {0, 0, 0, 0, 0, 0, 0}}}} - + $1 = {si_signo = 34, si_errno = 0, si_code = 2, si_pid = 0, si_uid = 0, + si_status = 0, + si_addr = 0x101d84 [rxR,0x100000-0x104120] (invalid), si_value = { + sival_int = 0, sival_ptr = 0x0}, _reason = {_fault = {si_trapno = 28, + si_capreg = 9}, _timer = {si_timerid = 28, si_overrun = 9}, _mesgq = { + si_mqd = 28}, _poll = {si_band = 38654705692}, __spare__ = { + __spare1__ = 38654705692, __spare2__ = {0, 0, 0, 0, 0, 0, 0}}}} ``` As said, `si_signo = 34` is `SIGPROT`, for which `si_code = 2` is `PROT_CHERI_TAG`, indicating a missing (clear) tag as an input to a diff --git a/src/exercises/cheriabi/answers.md b/src/exercises/cheriabi/answers.md index 362cee50..4d761544 100644 --- a/src/exercises/cheriabi/answers.md +++ b/src/exercises/cheriabi/answers.md @@ -138,7 +138,6 @@ ca0 0xd17d00000785b9b40000003fbfdff9b0 0x3fbfdff9b0 [rwRW,0x3fbfdff9b0-0x3fbfdffe10] pcc 0x4010f040 0x4010f040 ddc 0x0 0x0 - cap_valid 0x80800003 2155872259 ``` 6. In baseline programs, the stack is bounded only by operating system measures diff --git a/src/exercises/pointer-revocation/answers.md b/src/exercises/pointer-revocation/answers.md index df94599c..14f9fc80 100644 --- a/src/exercises/pointer-revocation/answers.md +++ b/src/exercises/pointer-revocation/answers.md @@ -36,7 +36,7 @@ Capability permission fault caused by register ca2. 0x0000000000102140 in main () (gdb) x/i 0x0000000000102140 -=> 0x102140 : lc ca2,32(a2) +=> 0x102140 : clc ca2,32(ca2) (gdb) p $ca2 $1 = (void *) 0x41200040 [,0x41200040-0x41200080] diff --git a/src/exercises/subobject-bounds/answers.md b/src/exercises/subobject-bounds/answers.md index afef8165..9b1e026a 100644 --- a/src/exercises/subobject-bounds/answers.md +++ b/src/exercises/subobject-bounds/answers.md @@ -17,16 +17,15 @@ structure. 3. Example session: ``` - (gdb) f fill_buf - No registers. (gdb) b fill_buf - Breakpoint 1 at 0x1b3a: file src/exercises/buffer-overflow-subobject/buffer-overflow-subobject.c, line 13. + Breakpoint 1 at 0x1bae: file buffer-overflow-subobject.c, line 17. (gdb) r Starting program: /root/buffer-overflow-subobject-cheri + b.i = c - Breakpoint 1, fill_buf (buf=0x103e50 [rwRW,0x103e50-0x103ed4] "", len=128) - at src/exercises/buffer-overflow-subobject/buffer-overflow-subobject.c:13 - 13 src/exercises/buffer-overflow-subobject/buffer-overflow-subobject.c: No such file or directory. + Breakpoint 1, fill_buf (buf=0x103f50 [rwRW,0x103f50-0x103fd4] "", len=128) + at buffer-overflow-subobject.c:17 + 17 buf[i] = 'b'; ``` The bounds are `132` bytes corresponding to the size of the underlying object. @@ -40,19 +39,33 @@ structure. 6. Example session: ``` (gdb) b fill_buf - Breakpoint 1 at 0x1b3a: file src/exercises/buffer-overflow-subobject/buffer-overflow-subobject.c, line 13. + Breakpoint 1 at 0x1bae: file buffer-overflow-subobject.c, line 17. (gdb) r - Starting program: /root/buffer-overflow-subobject-cheri-subobject + Starting program: /root/buffer-overflow-subobject-cheri + b.i = c - Breakpoint 1, fill_buf (buf=0x103e50 [rwRW,0x103e50-0x103ed0] "", len=128) - at src/exercises/buffer-overflow-subobject/buffer-overflow-subobject.c:13 - 13 src/exercises/buffer-overflow-subobject/buffer-overflow-subobject.c: No such file or directory. + Breakpoint 1, fill_buf (buf=0x103f50 [rwRW,0x103f50-0x103fd0] "", len=128) at buffer-overflow-subobject.c:17 + 17 buf[i] = 'b'; ``` The pointer to the buffer is now bounded to the array rather than the object. Investigating further will reveal that the compiler has inserted a bounds-setting instruction prior to the call to `fill_buf` in `main`, that is, when the pointer to `b.buffer` is materialized. + ``` + (gdb) up + #1 0x0000000000101c0c in main () at buffer-overflow-subobject.c:26 + 26 fill_buf(b.buffer, sizeof(b.buffer)); + (gdb) disassemble + Dump of assembler code for function main: + 0x0000000000101bc0 <+0>: cincoffset csp,csp,-64 + ... + 0x0000000000101bfc <+60>: csetbounds ca0,cs1,128 + 0x0000000000101c00 <+64>: li a1,128 + 0x0000000000101c04 <+68>: auipcc cra,0x0 + 0x0000000000101c08 <+72>: cjalr -92(cra) + => 0x0000000000101c0c <+76>: clw a0,128(cs1) + ``` ## Deliberately Using Larger Bounds