mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 21:38:32 +08:00
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: Steven Rostedt <rostedt@goodmis.org>
This commit is contained in:
parent
36aabfff50
commit
6d2289f3fa
@ -25,8 +25,6 @@ trace_seq_init(struct trace_seq *s)
|
|||||||
s->full = 0;
|
s->full = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_MEMHEX_BYTES 8
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Currently only defined when tracing is enabled.
|
* Currently only defined when tracing is enabled.
|
||||||
*/
|
*/
|
||||||
|
@ -43,7 +43,6 @@ do { \
|
|||||||
|
|
||||||
#define SEQ_PUT_HEX_FIELD_RET(s, x) \
|
#define SEQ_PUT_HEX_FIELD_RET(s, x) \
|
||||||
do { \
|
do { \
|
||||||
BUILD_BUG_ON(sizeof(x) > MAX_MEMHEX_BYTES); \
|
|
||||||
if (!trace_seq_putmem_hex(s, &(x), sizeof(x))) \
|
if (!trace_seq_putmem_hex(s, &(x), sizeof(x))) \
|
||||||
return TRACE_TYPE_PARTIAL_LINE; \
|
return TRACE_TYPE_PARTIAL_LINE; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -291,6 +291,7 @@ int trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(trace_seq_putmem);
|
EXPORT_SYMBOL_GPL(trace_seq_putmem);
|
||||||
|
|
||||||
|
#define MAX_MEMHEX_BYTES 8U
|
||||||
#define HEX_CHARS (MAX_MEMHEX_BYTES*2 + 1)
|
#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];
|
unsigned char hex[HEX_CHARS];
|
||||||
const unsigned char *data = mem;
|
const unsigned char *data = mem;
|
||||||
|
unsigned int start_len;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
if (s->full)
|
if (s->full)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
while (len) {
|
||||||
|
start_len = min(len, HEX_CHARS - 1);
|
||||||
#ifdef __BIG_ENDIAN
|
#ifdef __BIG_ENDIAN
|
||||||
for (i = 0, j = 0; i < len; i++) {
|
for (i = 0, j = 0; i < start_len; i++) {
|
||||||
#else
|
#else
|
||||||
for (i = len-1, j = 0; i >= 0; i--) {
|
for (i = start_len-1, j = 0; i >= 0; i--) {
|
||||||
#endif
|
#endif
|
||||||
hex[j++] = hex_asc_hi(data[i]);
|
hex[j++] = hex_asc_hi(data[i]);
|
||||||
hex[j++] = hex_asc_lo(data[i]);
|
hex[j++] = hex_asc_lo(data[i]);
|
||||||
}
|
}
|
||||||
hex[j++] = ' ';
|
if (WARN_ON_ONCE(j == 0 || j/2 > len))
|
||||||
|
break;
|
||||||
|
|
||||||
return trace_seq_putmem(s, hex, j);
|
/* j increments twice per loop */
|
||||||
|
len -= j / 2;
|
||||||
|
hex[j++] = ' ';
|
||||||
|
|
||||||
|
cnt += trace_seq_putmem(s, hex, j);
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(trace_seq_putmem_hex);
|
EXPORT_SYMBOL_GPL(trace_seq_putmem_hex);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user