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>
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,
/* 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;