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>
This commit is contained in:
Jonas Rebmann 2026-09-24 15:44:03 +02:00 committed by Mark Brown
parent a73c71e1f2
commit c79bbeadab
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -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++;
src += 4;
*dst++ = (unsigned char)ch;
} else {
*dst++ = *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;
}
*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);