klp-post-link.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Read the intermediate KLP reloc/symbol representations created by klp diff
  4. * and convert them to the proper format required by livepatch. This needs to
  5. * run last to avoid linker wreckage. Linkers don't tend to handle the "two
  6. * rela sections for a single base section" case very well, nor do they like
  7. * SHN_LIVEPATCH.
  8. *
  9. * This is the final tool in the livepatch module generation pipeline:
  10. *
  11. * kernel builds -> objtool klp diff -> module link -> objtool klp post-link
  12. */
  13. #include <fcntl.h>
  14. #include <gelf.h>
  15. #include <objtool/objtool.h>
  16. #include <objtool/warn.h>
  17. #include <objtool/klp.h>
  18. #include <objtool/util.h>
  19. #include <linux/livepatch_external.h>
  20. static int fix_klp_relocs(struct elf *elf)
  21. {
  22. struct section *symtab, *klp_relocs;
  23. klp_relocs = find_section_by_name(elf, KLP_RELOCS_SEC);
  24. if (!klp_relocs)
  25. return 0;
  26. symtab = find_section_by_name(elf, ".symtab");
  27. if (!symtab) {
  28. ERROR("missing .symtab");
  29. return -1;
  30. }
  31. for (int i = 0; i < sec_size(klp_relocs) / sizeof(struct klp_reloc); i++) {
  32. struct klp_reloc *klp_reloc;
  33. unsigned long klp_reloc_off;
  34. struct section *sec, *tmp, *klp_rsec;
  35. unsigned long offset;
  36. struct reloc *reloc;
  37. char sym_modname[64];
  38. char rsec_name[SEC_NAME_LEN];
  39. u64 addend;
  40. struct symbol *sym, *klp_sym;
  41. klp_reloc_off = i * sizeof(*klp_reloc);
  42. klp_reloc = klp_relocs->data->d_buf + klp_reloc_off;
  43. /*
  44. * Read __klp_relocs[i]:
  45. */
  46. /* klp_reloc.sec_offset */
  47. reloc = find_reloc_by_dest(elf, klp_relocs,
  48. klp_reloc_off + offsetof(struct klp_reloc, offset));
  49. if (!reloc) {
  50. ERROR("malformed " KLP_RELOCS_SEC " section");
  51. return -1;
  52. }
  53. sec = reloc->sym->sec;
  54. offset = reloc_addend(reloc);
  55. /* klp_reloc.sym */
  56. reloc = find_reloc_by_dest(elf, klp_relocs,
  57. klp_reloc_off + offsetof(struct klp_reloc, sym));
  58. if (!reloc) {
  59. ERROR("malformed " KLP_RELOCS_SEC " section");
  60. return -1;
  61. }
  62. klp_sym = reloc->sym;
  63. addend = reloc_addend(reloc);
  64. /* symbol format: .klp.sym.modname.sym_name,sympos */
  65. if (sscanf(klp_sym->name + strlen(KLP_SYM_PREFIX), "%55[^.]", sym_modname) != 1)
  66. ERROR("can't find modname in klp symbol '%s'", klp_sym->name);
  67. /*
  68. * Create the KLP rela:
  69. */
  70. /* section format: .klp.rela.sec_objname.section_name */
  71. if (snprintf_check(rsec_name, SEC_NAME_LEN,
  72. KLP_RELOC_SEC_PREFIX "%s.%s",
  73. sym_modname, sec->name))
  74. return -1;
  75. klp_rsec = find_section_by_name(elf, rsec_name);
  76. if (!klp_rsec) {
  77. klp_rsec = elf_create_section(elf, rsec_name, 0,
  78. elf_rela_size(elf),
  79. SHT_RELA, elf_addr_size(elf),
  80. SHF_ALLOC | SHF_INFO_LINK | SHF_RELA_LIVEPATCH);
  81. if (!klp_rsec)
  82. return -1;
  83. klp_rsec->sh.sh_link = symtab->idx;
  84. klp_rsec->sh.sh_info = sec->idx;
  85. klp_rsec->base = sec;
  86. }
  87. tmp = sec->rsec;
  88. sec->rsec = klp_rsec;
  89. if (!elf_create_reloc(elf, sec, offset, klp_sym, addend, klp_reloc->type))
  90. return -1;
  91. sec->rsec = tmp;
  92. /*
  93. * Fix up the corresponding KLP symbol:
  94. */
  95. klp_sym->sym.st_shndx = SHN_LIVEPATCH;
  96. if (!gelf_update_sym(symtab->data, klp_sym->idx, &klp_sym->sym)) {
  97. ERROR_ELF("gelf_update_sym");
  98. return -1;
  99. }
  100. /*
  101. * Disable the original non-KLP reloc by converting it to R_*_NONE:
  102. */
  103. reloc = find_reloc_by_dest(elf, sec, offset);
  104. sym = reloc->sym;
  105. sym->sym.st_shndx = SHN_LIVEPATCH;
  106. set_reloc_type(elf, reloc, 0);
  107. if (!gelf_update_sym(symtab->data, sym->idx, &sym->sym)) {
  108. ERROR_ELF("gelf_update_sym");
  109. return -1;
  110. }
  111. }
  112. return 0;
  113. }
  114. /*
  115. * This runs on the livepatch module after all other linking has been done. It
  116. * converts the intermediate __klp_relocs section into proper KLP relocs to be
  117. * processed by livepatch. This needs to run last to avoid linker wreckage.
  118. * Linkers don't tend to handle the "two rela sections for a single base
  119. * section" case very well, nor do they appreciate SHN_LIVEPATCH.
  120. */
  121. int cmd_klp_post_link(int argc, const char **argv)
  122. {
  123. struct elf *elf;
  124. argc--;
  125. argv++;
  126. if (argc != 1) {
  127. fprintf(stderr, "%d\n", argc);
  128. fprintf(stderr, "usage: objtool link <file.ko>\n");
  129. return -1;
  130. }
  131. elf = elf_open_read(argv[0], O_RDWR);
  132. if (!elf)
  133. return -1;
  134. if (fix_klp_relocs(elf))
  135. return -1;
  136. if (elf_write(elf))
  137. return -1;
  138. return elf_close(elf);
  139. }