summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorJonas Rebmann <jre@pengutronix.de>2026-09-24 15:44:03 +0200
committerMark Brown <broonie@kernel.org>2026-09-24 21:58:08 +0100
commitc79bbeadabc07e9a4c68ca16a3744a2264d6fbae (patch)
treede824283e6cef4d68a57421c6f5f26fb128cbfba /tools
parenta73c71e1f25a4f7d6266a6c1cc5e3c903b52cc6a (diff)
spi: spidev_test: rewrite unescape() to stay in bounds
unescape() could read the source buffer out of bounds for inputs like "\\x" and could write the destination buffer out of bounds due to lack of checking against the len parameter. For better readability and consistency, rewrite it as a simplified version of unescape_string() in string_helpers.h. This includes rearranging src and dst parameters. Signed-off-by: Jonas Rebmann <jre@pengutronix.de> Link: https://patch.msgid.link/20260924-spi-sun4i-spidev_test-v7-13-126e31a07fdc@pengutronix.de Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'tools')
-rw-r--r--tools/spi/spidev_test.c38
1 files changed, 21 insertions, 17 deletions
diff --git a/tools/spi/spidev_test.c b/tools/spi/spidev_test.c
index 61951ed1c908..5bd3159f61a7 100644
--- a/tools/spi/spidev_test.c
+++ b/tools/spi/spidev_test.c
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <fcntl.h>
@@ -100,28 +101,31 @@ static void hex_dump(const void *src, size_t length, size_t line_size,
* Unescape - process hexadecimal escape character
* converts shell input "\x23" -> 0x23
*/
-static int unescape(char *_dst, char *_src, size_t len)
+static int unescape(char *src, char *dst, size_t size)
{
- int ret = 0;
- int match;
- char *src = _src;
- char *dst = _dst;
+ char *out = dst;
unsigned int ch;
- while (*src) {
- if (*src == '\\' && *(src+1) == 'x') {
- match = sscanf(src + 2, "%2x", &ch);
- if (!match)
- pabort("malformed input string");
+ while (*src && size--) {
+ if (src[0] == '\\' && src[1] != '\0') {
+ src++;
+
+ if (src[0] == 'x' &&
+ isxdigit((unsigned char)src[1]) &&
+ isxdigit((unsigned char)src[2]) &&
+ sscanf(&src[1], "%2x", &ch)) {
+ *out++ = (unsigned char)ch;
+ src += 3;
+ continue;
+ }
- src += 4;
- *dst++ = (unsigned char)ch;
- } else {
- *dst++ = *src++;
+ *out++ = '\\';
+ if (!size--)
+ break;
}
- ret++;
+ *out++ = *src++;
}
- return ret;
+ return out - dst;
}
static void transfer(int fd, uint8_t const * const tx, uint8_t const * const rx, size_t len)
@@ -455,7 +459,7 @@ static void transfer_escaped_string(int fd, char *str)
pabort("can't allocate rx buffer");
}
- size = unescape((char *)tx, str, size);
+ size = unescape(str, (char *)tx, size);
transfer(fd, tx, rx, size);
free(rx);
free(tx);