mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02: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
					
				
					 3 changed files with 19 additions and 10 deletions
				
			
		| 
						 | 
				
			
			@ -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.
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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]);
 | 
			
		||||
	}
 | 
			
		||||
	hex[j++] = ' ';
 | 
			
		||||
			hex[j++] = hex_asc_hi(data[i]);
 | 
			
		||||
			hex[j++] = hex_asc_lo(data[i]);
 | 
			
		||||
		}
 | 
			
		||||
		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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue