Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d2289f3 authored by Steven Rostedt (Red Hat)'s avatar Steven Rostedt (Red Hat) Committed by Steven Rostedt
Browse files

tracing: Make trace_seq_putmem_hex() more robust



Currently trace_seq_putmem_hex() can only take as a parameter a pointer
to something that is 8 bytes or less, otherwise it will overflow the
buffer. This is protected by a macro that encompasses the call to
trace_seq_putmem_hex() that has a BUILD_BUG_ON() for the variable before
it is passed in. This is not very robust and if trace_seq_putmem_hex() ever
gets used outside that macro it will cause issues.

Instead of only being able to produce a hex output of memory that is for
a single word, change it to be more robust and allow any size input.

Signed-off-by: default avatarSteven Rostedt <rostedt@goodmis.org>
parent 36aabfff
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -25,8 +25,6 @@ trace_seq_init(struct trace_seq *s)
	s->full = 0;
}

#define MAX_MEMHEX_BYTES	8

/*
 * Currently only defined when tracing is enabled.
 */
+0 −1
Original line number Diff line number Diff line
@@ -43,7 +43,6 @@ do { \

#define SEQ_PUT_HEX_FIELD_RET(s, x)			\
do {							\
	BUILD_BUG_ON(sizeof(x) > MAX_MEMHEX_BYTES);	\
	if (!trace_seq_putmem_hex(s, &(x), sizeof(x)))	\
		return TRACE_TYPE_PARTIAL_LINE;		\
} while (0)
+19 −7
Original line number Diff line number Diff line
@@ -291,6 +291,7 @@ int trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len)
}
EXPORT_SYMBOL_GPL(trace_seq_putmem);

#define MAX_MEMHEX_BYTES	8U
#define HEX_CHARS		(MAX_MEMHEX_BYTES*2 + 1)

/**
@@ -310,22 +311,33 @@ int trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
{
	unsigned char hex[HEX_CHARS];
	const unsigned char *data = mem;
	unsigned int start_len;
	int i, j;
	int cnt = 0;

	if (s->full)
		return 0;

	while (len) {
		start_len = min(len, HEX_CHARS - 1);
#ifdef __BIG_ENDIAN
	for (i = 0, j = 0; i < len; i++) {
		for (i = 0, j = 0; i < start_len; i++) {
#else
	for (i = len-1, j = 0; i >= 0; i--) {
		for (i = start_len-1, j = 0; i >= 0; i--) {
#endif
			hex[j++] = hex_asc_hi(data[i]);
			hex[j++] = hex_asc_lo(data[i]);
		}
		if (WARN_ON_ONCE(j == 0 || j/2 > len))
			break;

		/* j increments twice per loop */
		len -= j / 2;
		hex[j++] = ' ';

	return trace_seq_putmem(s, hex, j);
		cnt += trace_seq_putmem(s, hex, j);
	}
	return cnt;
}
EXPORT_SYMBOL_GPL(trace_seq_putmem_hex);