forked from mirrors/linux
		
	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
	
	 Steven Rostedt (Red Hat)
						Steven Rostedt (Red Hat)