54dc0a
From 85344cf524cccc7b8e10bf04ed38a0f586bffd10 Mon Sep 17 00:00:00 2001
54dc0a
From: Sumanth Korikkar <sumanthk@linux.ibm.com>
54dc0a
Date: Tue, 21 Feb 2023 15:28:21 +0100
54dc0a
Subject: [PATCH] support ubsan for kpatch
54dc0a
54dc0a
ubsan generates .data..Lubsan_data* sections as follows:
54dc0a
54dc0a
1. int main(int argc, char **argv) {
54dc0a
        int arr[100];
54dc0a
        arr[101] = 1;
54dc0a
        printf("arr[101] = %d", arr[101]);
54dc0a
        return 0;
54dc0a
}
54dc0a
54dc0a
2. 1a:   50 10 b0 ac          st      %r1,172(%r11)
54dc0a
      int arr[100];
54dc0a
      arr[101] = 1;
54dc0a
1e:   a7 39 00 65             lghi    %r3,101
54dc0a
22:   c0 20 00 00 00 00       larl    %r2,22 <main+0x22>
54dc0a
            24: R_390_PC32DBL       .data..Lubsan_data1+0x2
54dc0a
28:   c0 e5 00 00 00 00       brasl   %r14,28 <main+0x28>
54dc0a
            2a: R_390_PLT32DBL      __ubsan_handle_out_of_bounds+0x2
54dc0a
54dc0a
3. 0000000000000000 <.data..Lubsan_data1>:
54dc0a
0: R_390_64     .rodata              <=== source_location.location->file_name
54dc0a
8: 00 00 00 04  .long   0x00000004   <=== source_location.location->line
54dc0a
c: 00 00 00 05  .long   0x00000005   <=== source_location.location->column
54dc0a
54dc0a
10: R_390_64    .data..Lubsan_type0   <== source_location->array_type
54dc0a
18: R_390_64    .data..Lubsan_type1   <=== source_location->index_type
54dc0a
54dc0a
4. Avoid correlating the *.data.Lubsan* sections. This means
54dc0a
   included function points to new *.data.Lubsan* sections.
54dc0a
54dc0a
Signed-off-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
54dc0a
---
54dc0a
 kpatch-build/create-diff-object.c | 13 +++++++++++++
54dc0a
 kpatch-build/kpatch-elf.c         | 12 ++++++++++++
54dc0a
 kpatch-build/kpatch-elf.h         |  1 +
54dc0a
 kpatch-build/lookup.c             |  3 ++-
54dc0a
 4 files changed, 28 insertions(+), 1 deletion(-)
54dc0a
54dc0a
diff --git a/kpatch-build/create-diff-object.c b/kpatch-build/create-diff-object.c
54dc0a
index 707b0a9..454783a 100644
54dc0a
--- a/kpatch-build/create-diff-object.c
54dc0a
+++ b/kpatch-build/create-diff-object.c
54dc0a
@@ -1036,6 +1036,9 @@ static void kpatch_correlate_sections(struct list_head *seclist_orig,
54dc0a
 			    sec_patched->twin)
54dc0a
 				continue;
54dc0a
 
54dc0a
+			if (is_ubsan_sec(sec_orig->name))
54dc0a
+				continue;
54dc0a
+
54dc0a
 			if (is_special_static(is_rela_section(sec_orig) ?
54dc0a
 					      sec_orig->base->secsym :
54dc0a
 					      sec_orig->secsym))
54dc0a
@@ -1072,6 +1075,9 @@ static void kpatch_correlate_symbols(struct list_head *symlist_orig,
54dc0a
 			    sym_orig->type != sym_patched->type || sym_patched->twin)
54dc0a
 				continue;
54dc0a
 
54dc0a
+			if (is_ubsan_sec(sym_orig->name))
54dc0a
+				continue;
54dc0a
+
54dc0a
 			if (is_special_static(sym_orig))
54dc0a
 				continue;
54dc0a
 
54dc0a
@@ -1547,6 +1553,13 @@ static void kpatch_replace_sections_syms(struct kpatch_elf *kelf)
54dc0a
 			if (rela->sym->type != STT_SECTION || !rela->sym->sec)
54dc0a
 				continue;
54dc0a
 
54dc0a
+			/*
54dc0a
+			 * UBSAN data will be taken wholesale, no need to
54dc0a
+			 * replace section symbols.
54dc0a
+			 */
54dc0a
+			if (is_ubsan_sec(rela->sym->name))
54dc0a
+				continue;
54dc0a
+
54dc0a
 			/*
54dc0a
 			 * These sections don't have symbols associated with
54dc0a
 			 * them:
54dc0a
diff --git a/kpatch-build/kpatch-elf.c b/kpatch-build/kpatch-elf.c
54dc0a
index c7d12ec..405e0d3 100644
54dc0a
--- a/kpatch-build/kpatch-elf.c
54dc0a
+++ b/kpatch-build/kpatch-elf.c
54dc0a
@@ -587,6 +587,18 @@ bool is_local_sym(struct symbol *sym)
54dc0a
 	return sym->bind == STB_LOCAL;
54dc0a
 }
54dc0a
 
54dc0a
+bool is_ubsan_sec(const char *name) {
54dc0a
+	if (!strncmp(name, ".data.rel.local..Lubsan_data", 28) ||
54dc0a
+		!strncmp(name, ".data..Lubsan_type", 18) ||
54dc0a
+		!strncmp(name, ".Lubsan_data", 12) ||
54dc0a
+		!strncmp(name, ".data..Lubsan_data", 18) ||
54dc0a
+		!strncmp(name, ".rela.data..Lubsan_data", 23) ||
54dc0a
+		!strncmp(name, ".rela.data.rel.local..Lubsan_data", 33))
54dc0a
+		return true;
54dc0a
+	else
54dc0a
+		return false;
54dc0a
+}
54dc0a
+
54dc0a
 void print_strtab(char *buf, size_t size)
54dc0a
 {
54dc0a
 	size_t i;
54dc0a
diff --git a/kpatch-build/kpatch-elf.h b/kpatch-build/kpatch-elf.h
54dc0a
index cd2900c..187b1d1 100644
54dc0a
--- a/kpatch-build/kpatch-elf.h
54dc0a
+++ b/kpatch-build/kpatch-elf.h
54dc0a
@@ -170,6 +170,7 @@ bool is_null_sym(struct symbol *sym);
54dc0a
 bool is_file_sym(struct symbol *sym);
54dc0a
 bool is_local_func_sym(struct symbol *sym);
54dc0a
 bool is_local_sym(struct symbol *sym);
54dc0a
+bool is_ubsan_sec(const char *name);
54dc0a
 
54dc0a
 void print_strtab(char *buf, size_t size);
54dc0a
 void kpatch_create_shstrtab(struct kpatch_elf *kelf);
54dc0a
diff --git a/kpatch-build/lookup.c b/kpatch-build/lookup.c
54dc0a
index f2596b1..2ccc181 100644
54dc0a
--- a/kpatch-build/lookup.c
54dc0a
+++ b/kpatch-build/lookup.c
54dc0a
@@ -84,7 +84,8 @@ static bool maybe_discarded_sym(const char *name)
54dc0a
 	    !strncmp(name, "__func_stack_frame_non_standard_", 32) ||
54dc0a
 	    strstr(name, "__addressable_") ||
54dc0a
 	    strstr(name, "__UNIQUE_ID_") ||
54dc0a
-	    !strncmp(name, ".L.str", 6))
54dc0a
+	    !strncmp(name, ".L.str", 6) ||
54dc0a
+	    is_ubsan_sec(name))
54dc0a
 		return true;
54dc0a
 
54dc0a
 	return false;
54dc0a
-- 
54dc0a
2.37.3
54dc0a