version.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Module version support
  4. *
  5. * Copyright (C) 2008 Rusty Russell
  6. */
  7. #include <linux/module.h>
  8. #include <linux/string.h>
  9. #include <linux/printk.h>
  10. #include "internal.h"
  11. int check_version(const struct load_info *info,
  12. const char *symname,
  13. struct module *mod,
  14. const s32 *crc)
  15. {
  16. Elf_Shdr *sechdrs = info->sechdrs;
  17. unsigned int versindex = info->index.vers;
  18. unsigned int i, num_versions;
  19. struct modversion_info *versions;
  20. /* Exporting module didn't supply crcs? OK, we're already tainted. */
  21. if (!crc)
  22. return 1;
  23. /* No versions at all? modprobe --force does this. */
  24. if (versindex == 0)
  25. return try_to_force_load(mod, symname) == 0;
  26. versions = (void *)sechdrs[versindex].sh_addr;
  27. num_versions = sechdrs[versindex].sh_size
  28. / sizeof(struct modversion_info);
  29. for (i = 0; i < num_versions; i++) {
  30. u32 crcval;
  31. if (strcmp(versions[i].name, symname) != 0)
  32. continue;
  33. crcval = *crc;
  34. if (versions[i].crc == crcval)
  35. return 1;
  36. pr_debug("Found checksum %X vs module %lX\n",
  37. crcval, versions[i].crc);
  38. goto bad_version;
  39. }
  40. /* Broken toolchain. Warn once, then let it go.. */
  41. pr_warn_once("%s: no symbol version for %s\n", info->name, symname);
  42. return 1;
  43. bad_version:
  44. pr_warn("%s: disagrees about version of symbol %s\n", info->name, symname);
  45. return 0;
  46. }
  47. int check_modstruct_version(const struct load_info *info,
  48. struct module *mod)
  49. {
  50. struct find_symbol_arg fsa = {
  51. .name = "module_layout",
  52. .gplok = true,
  53. };
  54. /*
  55. * Since this should be found in kernel (which can't be removed), no
  56. * locking is necessary -- use preempt_disable() to placate lockdep.
  57. */
  58. preempt_disable();
  59. if (!find_symbol(&fsa)) {
  60. preempt_enable();
  61. BUG();
  62. }
  63. preempt_enable();
  64. return check_version(info, "module_layout", mod, fsa.crc);
  65. }
  66. /* First part is kernel version, which we ignore if module has crcs. */
  67. int same_magic(const char *amagic, const char *bmagic,
  68. bool has_crcs)
  69. {
  70. if (has_crcs) {
  71. amagic += strcspn(amagic, " ");
  72. bmagic += strcspn(bmagic, " ");
  73. }
  74. return strcmp(amagic, bmagic) == 0;
  75. }
  76. /*
  77. * Generate the signature for all relevant module structures here.
  78. * If these change, we don't want to try to parse the module.
  79. */
  80. void module_layout(struct module *mod,
  81. struct modversion_info *ver,
  82. struct kernel_param *kp,
  83. struct kernel_symbol *ks,
  84. struct tracepoint * const *tp)
  85. {
  86. }
  87. EXPORT_SYMBOL(module_layout);