Skip to content

Commit 6b6f6c2

Browse files
committed
Replace printf with private RawSerial
printf uses a globally modifiable `stdio_uart` object that can be used for arbitrary code execution in secure boxes. Replace the use of printf with a private RawSerial object. Fixes #2
1 parent 39822cb commit 6b6f6c2

File tree

3 files changed

+30
-6
lines changed

3 files changed

+30
-6
lines changed

source/client_a.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
struct box_context {
2424
uint32_t number;
25+
RawSerial * pc;
2526
};
2627

2728
static const UvisorBoxAclItem acl[] = {
@@ -55,7 +56,7 @@ static void box_async_runner(const void *)
5556
while (1) {
5657
uint32_t ret;
5758
int status = rpc_fncall_wait(result, UVISOR_WAIT_FOREVER, &ret);
58-
printf("%c: %s '0x%08x'\n", (char) uvisor_box_id_self() + '0', (ret == 0) ? "Wrote" : "Failed to write", (unsigned int) number);
59+
uvisor_ctx->pc->printf("%c: %s '0x%08x'\n", (char) uvisor_box_id_self() + '0', (ret == 0) ? "Wrote" : "Failed to write", (unsigned int) number);
5960
/* FIXME: Add better error handling. */
6061
if (!status) {
6162
break;
@@ -71,14 +72,21 @@ static void box_sync_runner(const void *)
7172
while (1) {
7273
/* Synchronous access to the number. */
7374
const uint32_t number = secure_number_get_number();
74-
printf("%c: Read '0x%08x'\n", (char) uvisor_box_id_self() + '0', (unsigned int) number);
75+
uvisor_ctx->pc->printf("%c: Read '0x%08x'\n", (char) uvisor_box_id_self() + '0', (unsigned int) number);
7576

7677
Thread::wait(7000);
7778
}
7879
}
7980

8081
static void client_a_main(const void *)
8182
{
83+
/* Allocate serial port to ensure that code in this secure box won't touch
84+
* the handle in the default security context when printing. */
85+
uvisor_ctx->pc = new RawSerial(USBTX, USBRX);
86+
if (!uvisor_ctx->pc) {
87+
return;
88+
}
89+
8290
srand(uvisor_box_id_self());
8391
new Thread(box_sync_runner, NULL);
8492
new Thread(box_async_runner, NULL);

source/client_b.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
struct box_context {
2424
uint32_t number;
25+
RawSerial * pc;
2526
};
2627

2728
static const UvisorBoxAclItem acl[] = {
@@ -44,6 +45,13 @@ static uint32_t get_a_number()
4445

4546
static void client_b_main(const void *)
4647
{
48+
/* Allocate serial port to ensure that code in this secure box won't touch
49+
* the handle in the default security context when printing. */
50+
uvisor_ctx->pc = new RawSerial(USBTX, USBRX);
51+
if (!uvisor_ctx->pc) {
52+
return;
53+
}
54+
4755
/* The entire box code runs in its main thread. */
4856
while (1) {
4957
uvisor_rpc_result_t result;
@@ -57,15 +65,15 @@ static void client_b_main(const void *)
5765
while (1) {
5866
uint32_t ret;
5967
int status = rpc_fncall_wait(result, UVISOR_WAIT_FOREVER, &ret);
60-
printf("%c: %s '0x%08x'\n", (char) uvisor_box_id_self() + '0', (ret == 0) ? "Wrote" : "Failed to write", (unsigned int) number);
68+
uvisor_ctx->pc->printf("%c: %s '0x%08x'\n", (char) uvisor_box_id_self() + '0', (ret == 0) ? "Wrote" : "Failed to write", (unsigned int) number);
6169
if (!status) {
6270
break;
6371
}
6472
}
6573

6674
/* Synchronous access to the number. */
6775
number = secure_number_get_number();
68-
printf("%c: Read '0x%08x'\n", (char) uvisor_box_id_self() + '0', (unsigned int) number);
76+
uvisor_ctx->pc->printf("%c: Read '0x%08x'\n", (char) uvisor_box_id_self() + '0', (unsigned int) number);
6977

7078
Thread::wait(3000);
7179
}

source/secure_number.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct box_context {
2424
int trusted_id;
2525
int previous_box_caller;
2626
int caller_id;
27+
RawSerial * pc;
2728
};
2829

2930
static const UvisorBoxAclItem acl[] = {
@@ -81,7 +82,7 @@ static int set_number(uint32_t number)
8182
static const char * trusted_namespace = "client_a";
8283
if (memcmp(name, trusted_namespace, sizeof(*trusted_namespace)) == 0) {
8384
uvisor_ctx->trusted_id = id;
84-
printf("Trusted client a has box id %u\n", id);
85+
uvisor_ctx->pc->printf("Trusted client a has box id %u\n", id);
8586
} else {
8687
return 1;
8788
}
@@ -102,6 +103,13 @@ static int set_number(uint32_t number)
102103

103104
static void number_store_main(const void *)
104105
{
106+
/* Allocate serial port to ensure that code in this secure box won't touch
107+
* the handle in the default security context when printing. */
108+
uvisor_ctx->pc = new RawSerial(USBTX, USBRX);
109+
if (!uvisor_ctx->pc) {
110+
return;
111+
}
112+
105113
/* Today we only allow client a to write to the number. */
106114
uvisor_ctx->trusted_id = -1;
107115

@@ -118,7 +126,7 @@ static void number_store_main(const void *)
118126
status = rpc_fncall_waitfor(my_fn_array, 2, &uvisor_ctx->caller_id, UVISOR_WAIT_FOREVER);
119127

120128
if (status) {
121-
printf("Failure is not an option.\r\n");
129+
uvisor_ctx->pc->printf("Failure is not an option.\r\n");
122130
uvisor_error(USER_NOT_ALLOWED);
123131
}
124132
}

0 commit comments

Comments
 (0)