modinfo: fix module parsing with kernel >= 2.6.37
display() function returns the length of the value we are displaying + 1. As a consequence, if we have field=value\0field=value\0field=value in the binary, then the second occurence will be skipped as ptr will miss the first character of the following field. Example trying to list aliases from ixgbe.ko on a 3.2 kernel. - In the module we have: alias=pci:v00008086d00001560sv*sd*bc*sc*i*\0 alias=pci:v00008086d0000154Asv*sd*bc*sc*i*\0 alias=pci:v00008086d00001557sv*sd*bc*sc*i*\0 alias=pci:v00008086d0000154Fsv*sd*bc*sc*i*\0 alias=pci:v00008086d0000154Dsv*sd*bc*sc*i*\0 ... - Using modinfo -F alias ixgbe returns: alias: pci:v00008086d00001560sv*sd*bc*sc*i* alias: pci:v00008086d00001557sv*sd*bc*sc*i* alias: pci:v00008086d0000154Dsv*sd*bc*sc*i* ... This problem appeared with kernel commit "modules: no need to align .modinfo strings" b6472776816af1ed52848c93d26e3edb3b17adab in 2.6.37. Fix this by not trusting display() return value but increment ptr by strlen(ptr) (the same way as depmod.c does). Signed-off-by: David Marchand <david.marchand@6wind.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
		
				
					committed by
					
						
						Denys Vlasenko
					
				
			
			
				
	
			
			
			
						parent
						
							03e17bfa8d
						
					
				
				
					commit
					7d16964c3e
				
			@@ -34,14 +34,14 @@ struct modinfo_env {
 | 
			
		||||
	int tags;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int display(const char *data, const char *pattern, int flag)
 | 
			
		||||
static void display(const char *data, const char *pattern, int flag)
 | 
			
		||||
{
 | 
			
		||||
	if (flag) {
 | 
			
		||||
		int n = printf("%s:", pattern);
 | 
			
		||||
		while (n++ < 16)
 | 
			
		||||
			bb_putchar(' ');
 | 
			
		||||
	}
 | 
			
		||||
	return printf("%s%c", data, (option_mask32 & OPT_0) ? '\0' : '\n');
 | 
			
		||||
	printf("%s%c", data, (option_mask32 & OPT_0) ? '\0' : '\n');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void modinfo(const char *path, const char *version,
 | 
			
		||||
@@ -104,7 +104,8 @@ static void modinfo(const char *path, const char *version,
 | 
			
		||||
				/* field prefixes are 0x80 or 0x00 */
 | 
			
		||||
				if ((ptr[-1] & 0x7F) == '\0') {
 | 
			
		||||
					ptr += length + 1;
 | 
			
		||||
					ptr += display(ptr, pattern, (1<<j) != tags);
 | 
			
		||||
					display(ptr, pattern, (1<<j) != tags);
 | 
			
		||||
					ptr += strlen(ptr);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			++ptr;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user