From ba920d3edb7afb61ca1cd1c1ae57aaccba503fc2 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Mon, 25 Aug 2025 17:27:06 +0200 Subject: [PATCH] lib: Fix out-of-bounds write when concatenating commands This commit fixes the hci_commandstostr() command by writing new line character in place of trailing space when wrapping long lines. Previous approach was to append new line character to existing string, which caused buffer overflow when there was more than 9 lines in the output string. Also, the last trailing space is removed in order to return trailing-spaces-free string to the caller. --- lib/bluetooth/hci.c | 28 ++++++++++++++++++++-------- lib/bluetooth/hci_lib.h | 2 +- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/lib/bluetooth/hci.c b/lib/bluetooth/hci.c index acf63f182..44eea054b 100644 --- a/lib/bluetooth/hci.c +++ b/lib/bluetooth/hci.c @@ -604,18 +604,26 @@ char *hci_cmdtostr(unsigned int cmd) return hci_uint2str(commands_map, cmd); } -char *hci_commandstostr(uint8_t *commands, char *pref, int width) +char *hci_commandstostr(const uint8_t *commands, const char *pref, int width) { unsigned int maxwidth = width - 3; const hci_map *m; char *off, *ptr, *str; - int size = 10; + int size = 1; + int pref_len; + + if (pref) { + pref_len = strlen(pref); + } else { + pref_len = 0; + pref = ""; + } m = commands_map; while (m->str) { if (commands[m->val / 8] & (1 << (m->val % 8))) - size += strlen(m->str) + (pref ? strlen(pref) : 0) + 3; + size += pref_len + strlen(m->str) + 3; m++; } @@ -625,17 +633,17 @@ char *hci_commandstostr(uint8_t *commands, char *pref, int width) ptr = str; *ptr = '\0'; - if (pref) - ptr += sprintf(ptr, "%s", pref); - + ptr += sprintf(ptr, "%s", pref); off = ptr; m = commands_map; while (m->str) { if (commands[m->val / 8] & (1 << (m->val % 8))) { - if (strlen(off) + strlen(m->str) > maxwidth) { - ptr += sprintf(ptr, "\n%s", pref ? pref : ""); + if (ptr != str && + strlen(off) + strlen(m->str) > maxwidth) { + ptr = ptr - 1; + ptr += sprintf(ptr, "\n%s", pref); off = ptr; } ptr += sprintf(ptr, "'%s' ", m->str); @@ -643,6 +651,10 @@ char *hci_commandstostr(uint8_t *commands, char *pref, int width) m++; } + if (ptr != str) + /* Trim trailing space. */ + ptr[-1] = '\0'; + return str; } diff --git a/lib/bluetooth/hci_lib.h b/lib/bluetooth/hci_lib.h index da89de054..eeb51411a 100644 --- a/lib/bluetooth/hci_lib.h +++ b/lib/bluetooth/hci_lib.h @@ -152,7 +152,7 @@ char *hci_lmtostr(unsigned int ptype); int hci_strtolm(char *str, unsigned int *val); char *hci_cmdtostr(unsigned int cmd); -char *hci_commandstostr(uint8_t *commands, char *pref, int width); +char *hci_commandstostr(const uint8_t *commands, const char *pref, int width); char *hci_vertostr(unsigned int ver); int hci_strtover(char *str, unsigned int *ver); -- 2.47.3