modpost: add strict white-listing when referencing sections.

Prints a warning when a section references a section outside a strict
white-list.  This will be useful to print a warning if __ex_table
references a non-executable section.

Signed-off-by: Quentin Casasnovas <quentin.casasnovas@oracle.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Quentin Casasnovas 2015-04-13 20:41:04 +09:30 committed by Rusty Russell
parent cc9e605dc6
commit 050e57fd59
1 changed files with 19 additions and 15 deletions

View File

@ -925,7 +925,8 @@ enum mismatch {
struct sectioncheck { struct sectioncheck {
const char *fromsec[20]; const char *fromsec[20];
const char *tosec[20]; const char *bad_tosec[20];
const char *good_tosec[20];
enum mismatch mismatch; enum mismatch mismatch;
const char *symbol_white_list[20]; const char *symbol_white_list[20];
}; };
@ -936,19 +937,19 @@ static const struct sectioncheck sectioncheck[] = {
*/ */
{ {
.fromsec = { TEXT_SECTIONS, NULL }, .fromsec = { TEXT_SECTIONS, NULL },
.tosec = { ALL_INIT_SECTIONS, NULL }, .bad_tosec = { ALL_INIT_SECTIONS, NULL },
.mismatch = TEXT_TO_ANY_INIT, .mismatch = TEXT_TO_ANY_INIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
{ {
.fromsec = { DATA_SECTIONS, NULL }, .fromsec = { DATA_SECTIONS, NULL },
.tosec = { ALL_XXXINIT_SECTIONS, NULL }, .bad_tosec = { ALL_XXXINIT_SECTIONS, NULL },
.mismatch = DATA_TO_ANY_INIT, .mismatch = DATA_TO_ANY_INIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
{ {
.fromsec = { DATA_SECTIONS, NULL }, .fromsec = { DATA_SECTIONS, NULL },
.tosec = { INIT_SECTIONS, NULL }, .bad_tosec = { INIT_SECTIONS, NULL },
.mismatch = DATA_TO_ANY_INIT, .mismatch = DATA_TO_ANY_INIT,
.symbol_white_list = { .symbol_white_list = {
"*_template", "*_timer", "*_sht", "*_ops", "*_template", "*_timer", "*_sht", "*_ops",
@ -957,54 +958,54 @@ static const struct sectioncheck sectioncheck[] = {
}, },
{ {
.fromsec = { TEXT_SECTIONS, NULL }, .fromsec = { TEXT_SECTIONS, NULL },
.tosec = { ALL_EXIT_SECTIONS, NULL }, .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
.mismatch = TEXT_TO_ANY_EXIT, .mismatch = TEXT_TO_ANY_EXIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
{ {
.fromsec = { DATA_SECTIONS, NULL }, .fromsec = { DATA_SECTIONS, NULL },
.tosec = { ALL_EXIT_SECTIONS, NULL }, .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
.mismatch = DATA_TO_ANY_EXIT, .mismatch = DATA_TO_ANY_EXIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
/* Do not reference init code/data from meminit code/data */ /* Do not reference init code/data from meminit code/data */
{ {
.fromsec = { ALL_XXXINIT_SECTIONS, NULL }, .fromsec = { ALL_XXXINIT_SECTIONS, NULL },
.tosec = { INIT_SECTIONS, NULL }, .bad_tosec = { INIT_SECTIONS, NULL },
.mismatch = XXXINIT_TO_SOME_INIT, .mismatch = XXXINIT_TO_SOME_INIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
/* Do not reference exit code/data from memexit code/data */ /* Do not reference exit code/data from memexit code/data */
{ {
.fromsec = { ALL_XXXEXIT_SECTIONS, NULL }, .fromsec = { ALL_XXXEXIT_SECTIONS, NULL },
.tosec = { EXIT_SECTIONS, NULL }, .bad_tosec = { EXIT_SECTIONS, NULL },
.mismatch = XXXEXIT_TO_SOME_EXIT, .mismatch = XXXEXIT_TO_SOME_EXIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
/* Do not use exit code/data from init code */ /* Do not use exit code/data from init code */
{ {
.fromsec = { ALL_INIT_SECTIONS, NULL }, .fromsec = { ALL_INIT_SECTIONS, NULL },
.tosec = { ALL_EXIT_SECTIONS, NULL }, .bad_tosec = { ALL_EXIT_SECTIONS, NULL },
.mismatch = ANY_INIT_TO_ANY_EXIT, .mismatch = ANY_INIT_TO_ANY_EXIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
/* Do not use init code/data from exit code */ /* Do not use init code/data from exit code */
{ {
.fromsec = { ALL_EXIT_SECTIONS, NULL }, .fromsec = { ALL_EXIT_SECTIONS, NULL },
.tosec = { ALL_INIT_SECTIONS, NULL }, .bad_tosec = { ALL_INIT_SECTIONS, NULL },
.mismatch = ANY_EXIT_TO_ANY_INIT, .mismatch = ANY_EXIT_TO_ANY_INIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
}, },
{ {
.fromsec = { ALL_PCI_INIT_SECTIONS, NULL }, .fromsec = { ALL_PCI_INIT_SECTIONS, NULL },
.tosec = { INIT_SECTIONS, NULL }, .bad_tosec = { INIT_SECTIONS, NULL },
.mismatch = ANY_INIT_TO_ANY_EXIT, .mismatch = ANY_INIT_TO_ANY_EXIT,
.symbol_white_list = { NULL }, .symbol_white_list = { NULL },
}, },
/* Do not export init/exit functions or data */ /* Do not export init/exit functions or data */
{ {
.fromsec = { "__ksymtab*", NULL }, .fromsec = { "__ksymtab*", NULL },
.tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL }, .bad_tosec = { INIT_SECTIONS, EXIT_SECTIONS, NULL },
.mismatch = EXPORT_TO_INIT_EXIT, .mismatch = EXPORT_TO_INIT_EXIT,
.symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL }, .symbol_white_list = { DEFAULT_SYMBOL_WHITE_LIST, NULL },
} }
@ -1018,9 +1019,12 @@ static const struct sectioncheck *section_mismatch(
const struct sectioncheck *check = &sectioncheck[0]; const struct sectioncheck *check = &sectioncheck[0];
for (i = 0; i < elems; i++) { for (i = 0; i < elems; i++) {
if (match(fromsec, check->fromsec) && if (match(fromsec, check->fromsec)) {
match(tosec, check->tosec)) if (check->bad_tosec[0] && match(tosec, check->bad_tosec))
return check; return check;
if (check->good_tosec[0] && !match(tosec, check->good_tosec))
return check;
}
check++; check++;
} }
return NULL; return NULL;