Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/signal: Report minimum signal frame size to userspace via AT_MINSIGSTKSZ

Implement the AT_MINSIGSTKSZ AUXV entry, allowing userspace to
dynamically size stack allocations in a manner forward-compatible with
new processor state saved in the signal frame

For now these statically find the maximum signal frame size rather than
doing any runtime testing of features to minimise the size.

glibc 2.34 will take advantage of this, as will applications that use
use _SC_MINSIGSTKSZ and _SC_SIGSTKSZ.

Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
References: 94b07c1f8c39 ("arm64: signal: Report signal frame size to userspace via auxv")
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20220307182734.289289-2-npiggin@gmail.com

authored by

Nicholas Piggin and committed by
Michael Ellerman
2896b2df 2f82ec19

+47 -2
+13 -1
arch/powerpc/include/asm/elf.h
··· 160 160 * even if DLINFO_ARCH_ITEMS goes to zero or is undefined. 161 161 * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes 162 162 */ 163 - #define ARCH_DLINFO \ 163 + #define COMMON_ARCH_DLINFO \ 164 164 do { \ 165 165 /* Handle glibc compatibility. */ \ 166 166 NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \ ··· 171 171 NEW_AUX_ENT(AT_UCACHEBSIZE, 0); \ 172 172 VDSO_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long)current->mm->context.vdso);\ 173 173 ARCH_DLINFO_CACHE_GEOMETRY; \ 174 + } while (0) 175 + 176 + #define ARCH_DLINFO \ 177 + do { \ 178 + COMMON_ARCH_DLINFO; \ 179 + NEW_AUX_ENT(AT_MINSIGSTKSZ, get_min_sigframe_size()); \ 180 + } while (0) 181 + 182 + #define COMPAT_ARCH_DLINFO \ 183 + do { \ 184 + COMMON_ARCH_DLINFO; \ 185 + NEW_AUX_ENT(AT_MINSIGSTKSZ, get_min_sigframe_size_compat()); \ 174 186 } while (0) 175 187 176 188 /* Relocate the kernel image to @final_address */
+5
arch/powerpc/include/asm/signal.h
··· 9 9 struct pt_regs; 10 10 void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags); 11 11 12 + unsigned long get_min_sigframe_size_32(void); 13 + unsigned long get_min_sigframe_size_64(void); 14 + unsigned long get_min_sigframe_size(void); 15 + unsigned long get_min_sigframe_size_compat(void); 16 + 12 17 #endif /* _ASM_POWERPC_SIGNAL_H */
+3 -1
arch/powerpc/include/uapi/asm/auxvec.h
··· 48 48 #define AT_L3_CACHESIZE 46 49 49 #define AT_L3_CACHEGEOMETRY 47 50 50 51 - #define AT_VECTOR_SIZE_ARCH 14 /* entries in ARCH_DLINFO */ 51 + #define AT_MINSIGSTKSZ 51 /* stack needed for signal delivery */ 52 + 53 + #define AT_VECTOR_SIZE_ARCH 15 /* entries in ARCH_DLINFO */ 52 54 53 55 #endif
+15
arch/powerpc/kernel/signal.c
··· 141 141 142 142 int show_unhandled_signals = 1; 143 143 144 + unsigned long get_min_sigframe_size(void) 145 + { 146 + if (IS_ENABLED(CONFIG_PPC64)) 147 + return get_min_sigframe_size_64(); 148 + else 149 + return get_min_sigframe_size_32(); 150 + } 151 + 152 + #ifdef CONFIG_COMPAT 153 + unsigned long get_min_sigframe_size_compat(void) 154 + { 155 + return get_min_sigframe_size_32(); 156 + } 157 + #endif 158 + 144 159 /* 145 160 * Allocate space for the signal frame 146 161 */
+6
arch/powerpc/kernel/signal_32.c
··· 233 233 int abigap[56]; 234 234 }; 235 235 236 + unsigned long get_min_sigframe_size_32(void) 237 + { 238 + return max(sizeof(struct rt_sigframe) + __SIGNAL_FRAMESIZE + 16, 239 + sizeof(struct sigframe) + __SIGNAL_FRAMESIZE); 240 + } 241 + 236 242 /* 237 243 * Save the current user registers on the user stack. 238 244 * We only save the altivec/spe registers if the process has used
+5
arch/powerpc/kernel/signal_64.c
··· 66 66 char abigap[USER_REDZONE_SIZE]; 67 67 } __attribute__ ((aligned (16))); 68 68 69 + unsigned long get_min_sigframe_size_64(void) 70 + { 71 + return sizeof(struct rt_sigframe) + __SIGNAL_FRAMESIZE; 72 + } 73 + 69 74 /* 70 75 * This computes a quad word aligned pointer inside the vmx_reserve array 71 76 * element. For historical reasons sigcontext might not be quad word aligned,