Demonstrate pointer injection
This exercise demonstrates how CHERI's pointer provenance validity prevents injected pointer values from being dereferenced. In this example code, a pointer is injected via pipe IPC, and then dereferenced.
- Compile
long-over-pipe.c
with a RISC-V target and a binary name oflong-over-pipe-riscv
, and with a CHERI-RISC-V target and a binary name oflong-over-pipe-cheri
.
/*
* SPDX-License-Identifier: BSD-2-Clause-DARPA-SSITH-ECATS-HR0011-18-C-0016
* Copyright (c) 2020 SRI International
*/
#include <err.h>
#include <stdio.h>
#include <unistd.h>
int
main(void)
{
int fds[2];
pid_t pid;
long val;
if (pipe(fds) == -1)
err(1, "pipe");
if ((pid = fork()) == -1)
err(1, "fork");
if (pid == 0) {
val = 42;
if (write(fds[0], &val, sizeof(val)) != sizeof(val))
err(1, "write");
} else {
if (read(fds[1], &val, sizeof(val)) != sizeof(val))
err(1, "read");
printf("received %ld\n", val);
}
return 0;
}
- Run the two binaries, which both send long integers over pipe IPC, and print the sent and received values.
- Compile
ptr-over-pipe.c
with a RISC-V target and a binary name ofptr-over-pipe-riscv
, and with a CHERI-RISC-V target and a binary name ofptr-over-pipe-cheri
.
/*
* SPDX-License-Identifier: BSD-2-Clause-DARPA-SSITH-ECATS-HR0011-18-C-0016
* Copyright (c) 2020 SRI International
*/
#include <err.h>
#include <stdio.h>
#include <unistd.h>
const char hello[] = "Hello world!";
int
main(void)
{
int fds[2];
pid_t pid;
const char *ptr;
if (pipe(fds) == -1)
err(1, "pipe");
if ((pid = fork()) == -1)
err(1, "fork");
if (pid == 0) {
ptr = hello;
if (write(fds[0], &ptr, sizeof(ptr)) != sizeof(ptr))
err(1, "write");
} else {
if (read(fds[1], &ptr, sizeof(ptr)) != sizeof(ptr))
err(1, "read");
printf("received %s\n", ptr);
}
return 0;
}
- Run the two binaries, which both send pointers over pipe IPC, and then dereference the received copy to print a string.
- Why does dereferencing the received pointer in a CHERI binary fail?