[PATCH BlueZ v2 1/2] lib: Fix out-of-bounds write when concatenating commands

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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     | 27 +++++++++++++++++++--------
 lib/bluetooth/hci_lib.h |  2 +-
 2 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/lib/bluetooth/hci.c b/lib/bluetooth/hci.c
index f9feaf185..fa5a454e5 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,16 @@ 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 +650,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 baf3d3e12..2cb660786 100644
--- a/lib/bluetooth/hci_lib.h
+++ b/lib/bluetooth/hci_lib.h
@@ -146,7 +146,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.2





[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux