diff mbox series

[12/20] create-diff-object: Extend patchability verification: STN_UNDEF

Message ID 20190821082056.91090-13-wipawel@amazon.de (mailing list archive)
State Superseded
Headers show
Series livepatch-build-tools: new features and fixes | expand

Commit Message

Wieczorkiewicz, Pawel Aug. 21, 2019, 8:20 a.m. UTC
During verification check if all sections do not contain any entries
with undefined symbols (STN_UNDEF). This situation can happen when a
section is copied over from its original object to a patched object,
but various symbols related to the section are not copied along.
This scenario happens typically during stacked hotpatches creation
(between 2 different hotpatch modules).

Signed-off-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
Reviewed-by: Martin Pohlack <mpohlack@amazon.de>
Reviewed-by: Bjoern Doebel <doebel@amazon.de>
Reviewed-by: Norbert Manthey <nmanthey@amazon.de>
Reviewed-by: Andra-Irina Paraschiv <andraprs@amazon.com>
---
 create-diff-object.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

Comments

Ross Lagerwall Aug. 22, 2019, 1:57 p.m. UTC | #1
On 8/21/19 9:20 AM, Pawel Wieczorkiewicz wrote:
> During verification check if all sections do not contain any entries
> with undefined symbols (STN_UNDEF). This situation can happen when a
> section is copied over from its original object to a patched object,
> but various symbols related to the section are not copied along.
> This scenario happens typically during stacked hotpatches creation
> (between 2 different hotpatch modules).
> 
> Signed-off-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
> Reviewed-by: Martin Pohlack <mpohlack@amazon.de>
> Reviewed-by: Bjoern Doebel <doebel@amazon.de>
> Reviewed-by: Norbert Manthey <nmanthey@amazon.de>
> Reviewed-by: Andra-Irina Paraschiv <andraprs@amazon.com>
> ---
Reviewed-by: Ross Lagerwall <ross.lagerwall@citrix.com>

Thanks
diff mbox series

Patch

diff --git a/create-diff-object.c b/create-diff-object.c
index 4e0f3be..1c84f81 100644
--- a/create-diff-object.c
+++ b/create-diff-object.c
@@ -1536,6 +1536,61 @@  static void kpatch_print_changes(struct kpatch_elf *kelf)
 	}
 }
 
+static inline int get_section_entry_size(const struct section *sec,
+					 struct kpatch_elf *kelf)
+{
+	int entry_size;
+
+	/*
+	 * Base sections typically do not define fixed size elements.
+	 * Detect section's element size in case it's a special section.
+	 * Otherwise, skip it due to an unknown sh_entsize.
+	 */
+	entry_size = sec->sh.sh_entsize;
+	if (entry_size == 0) {
+		struct special_section *special;
+
+		/* Find special section group_size. */
+		for (special = special_sections; special->name; special++) {
+			if (!strcmp(sec->name, special->name))
+				return special->group_size(kelf, 0);
+		}
+        }
+
+	return entry_size;
+}
+
+static int kpatch_section_has_undef_symbols(struct kpatch_elf *kelf,
+					    const struct section *sec)
+{
+	int offset, entry_size;
+	struct rela *rela;
+	size_t d_size;
+
+	entry_size = get_section_entry_size(sec, kelf);
+	if (entry_size == 0)
+		return false;
+
+	d_size = sec->base->data->d_size;
+	for (offset = 0; offset < d_size; offset += entry_size) {
+		list_for_each_entry(rela, &sec->relas, list) {
+			if (rela->offset < offset ||
+			    rela->offset >= offset + entry_size) {
+				continue;
+			}
+
+			if ((GELF_R_SYM(rela->rela.r_info) == STN_UNDEF) ||
+			    (!rela->sym->include && rela->sym->status == SAME)) {
+				log_normal("section %s has an entry with an undefined symbol: %s\n",
+					   sec->name, rela->sym->name ?: "none");
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
 static void kpatch_verify_patchability(struct kpatch_elf *kelf)
 {
 	struct section *sec;
@@ -1568,6 +1623,17 @@  static void kpatch_verify_patchability(struct kpatch_elf *kelf)
 					errs++;
 				}
 			}
+
+			/* Check if a RELA section does not contain any entries with
+			 * undefined symbols (STN_UNDEF). This situation can happen
+			 * when a section is copied over from its original object to
+			 * a patched object, but various symbols related to the section
+			 * are not copied along.
+			 */
+			if (is_rela_section(sec)) {
+				if (kpatch_section_has_undef_symbols(kelf, sec))
+					errs++;
+			}
 		}
 
 		/*