From 846db25d801c2aac7def2f9be0c66221f3dac2b1 Mon Sep 17 00:00:00 2001 From: Brennan Lamoreaux Date: Wed, 11 Dec 2024 18:55:57 +0000 Subject: [PATCH] use dynamic prefix offset instead of hardcoding In commit [1], kpatch added support for function padding, and CONFIG_CFI_CLANG, which hardcoded a value of 16 for the prefix size. In some cases, the padding around __cfi prefixed functions can vary. For example, in Photon OS 5.0, the __cfi prefix size is modified in a patch for the gcc RAP plugin [2]. Since we have read the prefix size anyways, we can use it instead of hardcoding. Ref: 1. https://github.com/dynup/kpatch/commit/3e54c63b175b68cf48654c119e62bda398d0c018 2. https://github.com/vmware/photon/blob/5.0/SPECS/linux/secure/gcc-rap-plugin-with-kcfi.patch Signed-off-by: Brennan Lamoreaux --- kpatch-build/create-diff-object.c | 6 +++--- kpatch-build/kpatch-elf.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c index 531df648..8b567f43 100644 --- a/kpatch-build/create-diff-object.c +++ b/kpatch-build/create-diff-object.c @@ -236,19 +236,19 @@ static struct rela *toc_rela(const struct rela *rela) static void kpatch_bundle_symbols(struct kpatch_elf *kelf) { struct symbol *sym; - unsigned int expected_offset; + uint64_t expected_offset; list_for_each_entry(sym, &kelf->symbols, list) { if (is_bundleable(sym)) { if (sym->pfx) - expected_offset = 16; + expected_offset = sym->pfx->sym.st_size; else if (is_gcc6_localentry_bundled_sym(kelf, sym)) expected_offset = 8; else expected_offset = 0; if (sym->sym.st_value != expected_offset) { - ERROR("symbol %s at offset %lu within section %s, expected %u", + ERROR("symbol %s at offset %lu within section %s, expected %lu", sym->name, sym->sym.st_value, sym->sec->name, expected_offset); } diff --git a/kpatch-build/kpatch-elf.c b/kpatch-build/kpatch-elf.c index 7e9d2c81..c8ab5bd3 100755 --- a/kpatch-build/kpatch-elf.c +++ b/kpatch-build/kpatch-elf.c @@ -470,7 +470,7 @@ static void kpatch_link_prefixed_functions(struct kpatch_elf *kelf) list_for_each_entry(func, &kelf->symbols, list) { if (func->type == STT_FUNC && func->sec == pfx->sec && - func->sym.st_value == pfx->sym.st_value + 16) { + func->sym.st_value == pfx->sym.st_value + pfx->sym.st_size) { /* * If a func has aliases, it's possible for