Skip to content

Commit fa8eb2f

Browse files
committed
app: Add runtime safety checks for AT host
Various functions like: * check_idle_timer() * in_at_mode_*() * is_idle_*() * is_open_*() are designed to tolerate NULL for either context or pipe pointer. This is because sm_at_host_get_current(), sm_at_host_get_pipe() and sm_at_host_get_current_pipe() are designed to return NULL when there is no context or pipe to point to. However, few of those mentioned were not properly handling the NULL, especially the internal check_idle_timer() caused NULL pointer dereference if context was destroyed just before URC message was send to that pipe. Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
1 parent cc886f7 commit fa8eb2f

1 file changed

Lines changed: 17 additions & 9 deletions

File tree

app/src/sm_at_host.c

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,9 @@ struct sm_at_host_ctx *sm_at_host_get_urc_ctx(void)
335335

336336
struct modem_pipe *sm_at_host_get_pipe(struct sm_at_host_ctx *ctx)
337337
{
338+
if (!sm_at_ctx_check(ctx)) {
339+
return NULL;
340+
}
338341
return ctx ? atomic_ptr_get(&ctx->pipe) : NULL;
339342
}
340343

@@ -385,6 +388,9 @@ static bool sm_at_ctx_check(struct sm_at_host_ctx *ctx)
385388

386389
static void check_idle_timer(struct sm_at_host_ctx *ctx, bool reschedule)
387390
{
391+
if (!ctx) {
392+
return;
393+
}
388394
if (reschedule || k_timer_remaining_ticks(&ctx->idle_timer) == 0) {
389395
k_timeout_t delay = ctx->echo_enabled && (reschedule || ctx->at_cmd_len != 0)
390396
? K_MSEC(CONFIG_SM_URC_DELAY_WITH_INCOMPLETE_ECHO_MS)
@@ -1016,11 +1022,13 @@ static int sm_at_send_internal(struct sm_at_host_ctx *ctx, const uint8_t *data,
10161022
sys_slist_append(&ctx->buffered_urcs, &msg->node);
10171023
}
10181024
}
1019-
if (!is_idle(ctx)) {
1020-
LOG_DBG("AT command in progress, delaying URC processing");
1021-
check_idle_timer(ctx, false);
1022-
} else {
1023-
sm_at_host_event_notify(ctx, SM_EVENT_URC);
1025+
if (ctx) {
1026+
if (!is_idle(ctx)) {
1027+
LOG_DBG("AT command in progress, delaying URC processing");
1028+
check_idle_timer(ctx, false);
1029+
} else {
1030+
sm_at_host_event_notify(ctx, SM_EVENT_URC);
1031+
}
10241032
}
10251033
return 0;
10261034
}
@@ -1506,20 +1514,20 @@ bool in_at_mode_pipe(struct modem_pipe *pipe)
15061514
{
15071515
struct sm_at_host_ctx *ctx = sm_at_host_get_ctx_from(pipe);
15081516

1509-
return in_at_mode_ctx(ctx);
1517+
return ctx ? in_at_mode_ctx(ctx) : false;
15101518
}
15111519

15121520
bool is_idle_ctx(struct sm_at_host_ctx *ctx)
15131521
{
1514-
return (in_at_mode_ctx(ctx) &&
1522+
return (sm_at_ctx_check(ctx) && in_at_mode_ctx(ctx) &&
15151523
k_timer_remaining_ticks(&ctx->idle_timer) == 0);
15161524
}
15171525

15181526
bool is_idle_pipe(struct modem_pipe *pipe)
15191527
{
15201528
struct sm_at_host_ctx *ctx = sm_at_host_get_ctx_from(pipe);
15211529

1522-
return is_idle_ctx(ctx);
1530+
return ctx ? is_idle_ctx(ctx) : false;
15231531
}
15241532

15251533
bool is_open_pipe(struct modem_pipe *pipe)
@@ -1529,7 +1537,7 @@ bool is_open_pipe(struct modem_pipe *pipe)
15291537

15301538
bool is_open_ctx(struct sm_at_host_ctx *ctx)
15311539
{
1532-
return sm_at_host_get_pipe(ctx);
1540+
return ctx ? is_open_pipe(sm_at_host_get_pipe(ctx)) : false;
15331541
}
15341542

15351543
void exit_datamode_handler(int result)

0 commit comments

Comments
 (0)