Skip to content

Commit

Permalink
Revert "UBUNTU: SAUCE: modpost: support arbitrary symbol length in mo…
Browse files Browse the repository at this point in the history
…dversion"

This reverts commit 47d27f2.

We need to revert this to avoid regressing any modules used in Jammy.

Signed-off-by: Ian May <[email protected]>
  • Loading branch information
ianmay81 authored and jacobmartin0 committed Dec 9, 2024
1 parent 9a8b226 commit 7c0d52e
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 48 deletions.
5 changes: 2 additions & 3 deletions arch/powerpc/kernel/module_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,13 +347,12 @@ static unsigned long get_got_size(const Elf64_Ehdr *hdr,
static void dedotify_versions(struct modversion_info *vers,
unsigned long size)
{
struct modversion_info *end = (void *)vers + size;
struct modversion_info *end;

for (; vers < end && vers->next; vers = (void *)vers + vers->next) {
for (end = (void *)vers + size; vers < end; vers++)
if (vers->name[0] == '.') {
memmove(vers->name, vers->name+1, strlen(vers->name));
}
}
}

/*
Expand Down
8 changes: 3 additions & 5 deletions include/linux/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,9 @@
#define MODULE_NAME_LEN MAX_PARAM_PREFIX_LEN

struct modversion_info {
/* Offset of the next modversion entry in relation to this one. */
u32 next;
u32 crc;
char name[]; /* Flexible array member */
} __packed;
unsigned long crc;
char name[MODULE_NAME_LEN];
};

struct module;
struct exception_table_entry;
Expand Down
22 changes: 12 additions & 10 deletions kernel/module/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,32 @@ int check_version(const struct load_info *info,
{
Elf_Shdr *sechdrs = info->sechdrs;
unsigned int versindex = info->index.vers;
struct modversion_info *versions, *end;
u32 crcval;
unsigned int i, num_versions;
struct modversion_info *versions;

/* Exporting module didn't supply crcs? OK, we're already tainted. */
if (!crc)
return 1;
crcval = *crc;

/* No versions at all? modprobe --force does this. */
if (versindex == 0)
return try_to_force_load(mod, symname) == 0;

versions = (void *)sechdrs[versindex].sh_addr;
end = (void *)versions + sechdrs[versindex].sh_size;
num_versions = sechdrs[versindex].sh_size
/ sizeof(struct modversion_info);

for (; versions < end && versions->next;
versions = (void *)versions + versions->next) {
if (strcmp(versions->name, symname) != 0)
for (i = 0; i < num_versions; i++) {
u32 crcval;

if (strcmp(versions[i].name, symname) != 0)
continue;

if (versions->crc == crcval)
crcval = *crc;
if (versions[i].crc == crcval)
return 1;
pr_debug("Found checksum %X vs module %X\n",
crcval, versions->crc);
pr_debug("Found checksum %X vs module %lX\n",
crcval, versions[i].crc);
goto bad_version;
}

Expand Down
9 changes: 4 additions & 5 deletions scripts/export_report.pl
Original file line number Diff line number Diff line change
Expand Up @@ -116,19 +116,18 @@ sub collectcfiles {
while ( <$module> ) {
chomp;
if ($state == 0) {
$state = 1 if ($_ =~ /static const char ____versions/);
$state = 1 if ($_ =~ /static const struct modversion_info/);
next;
}
if ($state == 1) {
$state = 2 if ($_ =~ /__used __section\("__versions"\)/);
$state = 2 if ($_ =~ /__attribute__\(\(section\("__versions"\)\)\)/);
next;
}
if ($state == 2) {
if ( $_ !~ /\\0"/ ) {
last if ($_ =~ /;/);
if ( $_ !~ /0x[0-9a-f]+,/ ) {
next;
}
my $sym = (split /(["\\])/,)[2];
my $sym = (split /([,"])/,)[4];
my ($module, $value, $symbol, $gpl) = @{$SYMBOL{$sym}};
$SYMBOL{ $sym } = [ $module, $value+1, $symbol, $gpl];
push(@{$MODULE{$thismod}} , $sym);
Expand Down
35 changes: 10 additions & 25 deletions scripts/mod/modpost.c
Original file line number Diff line number Diff line change
Expand Up @@ -1906,17 +1906,13 @@ static void add_exported_symbols(struct buffer *buf, struct module *mod)
static void add_versions(struct buffer *b, struct module *mod)
{
struct symbol *s;
unsigned int name_len;
unsigned int name_len_padded;
unsigned int tmp;
unsigned char *tmp_view = (unsigned char *)&tmp;

if (!modversions)
return;

buf_printf(b, "\n");
buf_printf(b, "static const char ____versions[]\n");
buf_printf(b, "__used __section(\"__versions\") =\n");
buf_printf(b, "static const struct modversion_info ____versions[]\n");
buf_printf(b, "__used __section(\"__versions\") = {\n");

list_for_each_entry(s, &mod->unresolved_symbols, list) {
if (!s->module)
Expand All @@ -1926,27 +1922,16 @@ static void add_versions(struct buffer *b, struct module *mod)
s->name, mod->name);
continue;
}
name_len = strlen(s->name);
name_len_padded = (name_len + 1 + 3) & ~3;

/* Offset to next entry */
tmp = 8 + name_len_padded;
tmp = TO_NATIVE(tmp);
buf_printf(b, "\t\"\\x%02x\\x%02x\\x%02x\\x%02x",
tmp_view[0], tmp_view[1], tmp_view[2], tmp_view[3]);

tmp = TO_NATIVE(s->crc);
buf_printf(b, "\\x%02x\\x%02x\\x%02x\\x%02x\"\n",
tmp_view[0], tmp_view[1], tmp_view[2], tmp_view[3]);

buf_printf(b, "\t\"%s", s->name);
for (; name_len < name_len_padded; name_len++)
buf_printf(b, "\\0");
buf_printf(b, "\"\n");
if (strlen(s->name) >= MODULE_NAME_LEN) {
error("too long symbol \"%s\" [%s.ko]\n",
s->name, mod->name);
break;
}
buf_printf(b, "\t{ %#8x, \"%s\" },\n",
s->crc, s->name);
}

/* Always end with a NULL entry */
buf_printf(b, "\t\"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\";\n");
buf_printf(b, "};\n");
}

static void add_depends(struct buffer *b, struct module *mod)
Expand Down

0 comments on commit 7c0d52e

Please sign in to comment.