From 1794308d463f6fc05c5fef7192f55882ba6252ce Mon Sep 17 00:00:00 2001 From: Kalesh Singh Date: Tue, 30 Apr 2024 13:42:47 -0700 Subject: [PATCH] ANDROID: 16K: Fix show maps CFI failure If the kernel is built CONFIG_CFI_CLANG=y, reading smaps may cause a panic. This is due to a failed CFI check; which is triggered becuase the signature of the function pointer for printing smaps padding VMAs does not match exactly with that for show_smap(). Fix this by casting the function pointer to the expected type based on whether printing maps or smaps padding. Bug: 330117029 Bug: 327600007 Bug: 330767927 Bug: 328266487 Bug: 329803029 Change-Id: I65564a547dacbc4131f8557344c8c96e51f90cd5 Signed-off-by: Kalesh Singh --- fs/proc/task_mmu.c | 4 ++-- include/linux/pgsize_migration.h | 6 ++---- mm/pgsize_migration.c | 10 ++++++++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 1416772416cb..9f09aa1127e0 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -355,7 +355,7 @@ static int show_map(struct seq_file *m, void *v) if (vma_pages(vma)) show_map_vma(m, vma); - show_map_pad_vma(vma, pad_vma, m, show_map_vma); + show_map_pad_vma(vma, pad_vma, m, show_map_vma, false); return 0; } @@ -894,7 +894,7 @@ static int show_smap(struct seq_file *m, void *v) show_smap_vma_flags(m, vma); show_pad: - show_map_pad_vma(vma, pad_vma, m, (show_pad_vma_fn)((void*)show_smap)); + show_map_pad_vma(vma, pad_vma, m, show_smap, true); return 0; } diff --git a/include/linux/pgsize_migration.h b/include/linux/pgsize_migration.h index 5c47ec28ea7d..fbfb1b9b9196 100644 --- a/include/linux/pgsize_migration.h +++ b/include/linux/pgsize_migration.h @@ -43,8 +43,6 @@ #define VM_PAD_MASK (VM_TOTAL_PAD_PAGES << VM_PAD_SHIFT) #define VMA_PAD_START(vma) (vma->vm_end - (vma_pad_pages(vma) << PAGE_SHIFT)) -typedef void (*show_pad_vma_fn)(struct seq_file *m, struct vm_area_struct *vma); - #if PAGE_SIZE == SZ_4K && defined(CONFIG_64BIT) extern void vma_set_pad_pages(struct vm_area_struct *vma, unsigned long nr_pages); @@ -60,7 +58,7 @@ extern struct vm_area_struct *get_data_vma(struct vm_area_struct *vma); extern void show_map_pad_vma(struct vm_area_struct *vma, struct vm_area_struct *pad, - struct seq_file *m, show_pad_vma_fn func); + struct seq_file *m, void *func, bool smaps); extern void split_pad_vma(struct vm_area_struct *vma, struct vm_area_struct *new, unsigned long addr, int new_below); @@ -92,7 +90,7 @@ static inline struct vm_area_struct *get_data_vma(struct vm_area_struct *vma) static inline void show_map_pad_vma(struct vm_area_struct *vma, struct vm_area_struct *pad, - struct seq_file *m, show_pad_vma_fn func) + struct seq_file *m, void *func, bool smaps) { } diff --git a/mm/pgsize_migration.c b/mm/pgsize_migration.c index 8b31cdb54383..a972b9ba921c 100644 --- a/mm/pgsize_migration.c +++ b/mm/pgsize_migration.c @@ -20,6 +20,9 @@ #include #include +typedef void (*show_pad_maps_fn) (struct seq_file *m, struct vm_area_struct *vma); +typedef int (*show_pad_smaps_fn) (struct seq_file *m, void *v); + #ifdef CONFIG_64BIT #if PAGE_SIZE == SZ_4K DEFINE_STATIC_KEY_TRUE(pgsize_migration_enabled); @@ -303,7 +306,7 @@ struct vm_area_struct *get_data_vma(struct vm_area_struct *vma) * and @pad. */ void show_map_pad_vma(struct vm_area_struct *vma, struct vm_area_struct *pad, - struct seq_file *m, show_pad_vma_fn func) + struct seq_file *m, void *func, bool smaps) { if (!pad) return; @@ -320,7 +323,10 @@ void show_map_pad_vma(struct vm_area_struct *vma, struct vm_area_struct *pad, */ BUG_ON(!vma); - func(m, pad); + if (smaps) + ((show_pad_smaps_fn)func)(m, pad); + else + ((show_pad_maps_fn)func)(m, pad); kfree(pad); kfree(vma);