1717
1818const uintptr_t MAX_WALK_SIZE = 0x100000 ;
1919const intptr_t MAX_INTERPRETER_FRAME_SIZE = 0x1000 ;
20+ const intptr_t MAX_FRAME_SIZE_WORDS = StackWalkValidation::MAX_FRAME_SIZE / sizeof (void *); // 0x8000 = 32768 words
2021
2122static ucontext_t empty_ucontext{};
2223
@@ -187,11 +188,19 @@ int StackWalker::walkDwarf(void* ucontext, const void** callchain, int max_depth
187188 pc = (const char *)pc + (f.fp_off >> 1 );
188189 } else {
189190 if (f.fp_off != DW_SAME_FP && f.fp_off < MAX_FRAME_SIZE && f.fp_off > -MAX_FRAME_SIZE) {
190- fp = (uintptr_t )SafeAccess::load ((void **)(sp + f.fp_off ));
191+ uintptr_t fp_addr = sp + f.fp_off ;
192+ if (!aligned (fp_addr)) {
193+ break ;
194+ }
195+ fp = (uintptr_t )SafeAccess::load ((void **)fp_addr);
191196 }
192197
193198 if (EMPTY_FRAME_SIZE > 0 || f.pc_off != DW_LINK_REGISTER) {
194- pc = stripPointer (SafeAccess::load ((void **)(sp + f.pc_off )));
199+ uintptr_t pc_addr = sp + f.pc_off ;
200+ if (!aligned (pc_addr)) {
201+ break ;
202+ }
203+ pc = stripPointer (SafeAccess::load ((void **)pc_addr));
195204 } else if (depth == 1 ) {
196205 pc = (const void *)frame.link ();
197206 } else {
@@ -245,6 +254,10 @@ __attribute__((no_sanitize("address"))) int StackWalker::walkVM(void* ucontext,
245254
246255 const void * pc = anchor->lastJavaPC ();
247256 if (pc == NULL ) {
257+ // Verify alignment before dereferencing sp as pointer
258+ if (!aligned (sp)) {
259+ return 0 ;
260+ }
248261 pc = ((const void **)sp)[-1 ];
249262 }
250263
@@ -334,6 +347,12 @@ __attribute__((no_sanitize("address"))) int StackWalker::walkVM(void* ucontext,
334347 }
335348
336349 if (nm->isNMethod ()) {
350+ // Check if deoptimization is in progress before walking compiled frames
351+ if (vm_thread != NULL && vm_thread->inDeopt ()) {
352+ fillFrame (frames[depth++], BCI_ERROR, " break_deopt_compiled" );
353+ break ;
354+ }
355+
337356 int level = nm->level ();
338357 FrameTypeId type = details && level >= 1 && level <= 3 ? FRAME_C1_COMPILED : FRAME_JIT_COMPILED;
339358 fillFrame (frames[depth++], type, 0 , nm->method ()->id ());
@@ -360,7 +379,21 @@ __attribute__((no_sanitize("address"))) int StackWalker::walkVM(void* ucontext,
360379 // Handle situations when sp is temporarily changed in the compiled code
361380 frame.adjustSP (nm->entry (), pc, sp);
362381
363- sp += nm->frameSize () * sizeof (void *);
382+ // Validate NMethod metadata before using frameSize()
383+ int frame_size = nm->frameSize ();
384+ if (frame_size <= 0 || frame_size > MAX_FRAME_SIZE_WORDS) {
385+ fillFrame (frames[depth++], BCI_ERROR, " break_invalid_framesize" );
386+ break ;
387+ }
388+
389+ sp += frame_size * sizeof (void *);
390+
391+ // Verify alignment before dereferencing sp as pointer (secondary defense)
392+ if (!aligned (sp)) {
393+ fillFrame (frames[depth++], BCI_ERROR, " break_misaligned_sp" );
394+ break ;
395+ }
396+
364397 fp = ((uintptr_t *)sp)[-FRAME_PC_SLOT - 1 ];
365398 pc = ((const void **)sp)[-FRAME_PC_SLOT];
366399 continue ;
@@ -407,7 +440,7 @@ __attribute__((no_sanitize("address"))) int StackWalker::walkVM(void* ucontext,
407440 sp = frame.senderSP ();
408441 fp = *(uintptr_t *)fp;
409442 } else {
410- pc = stripPointer (*( void **)sp);
443+ pc = stripPointer (SafeAccess::load (( void **)sp) );
411444 sp = frame.senderSP ();
412445 }
413446 continue ;
@@ -455,7 +488,21 @@ __attribute__((no_sanitize("address"))) int StackWalker::walkVM(void* ucontext,
455488 }
456489
457490 if (depth > 1 && nm->frameSize () > 0 ) {
458- sp += nm->frameSize () * sizeof (void *);
491+ // Validate NMethod metadata before using frameSize()
492+ int frame_size = nm->frameSize ();
493+ if (frame_size <= 0 || frame_size > MAX_FRAME_SIZE_WORDS) {
494+ fillFrame (frames[depth++], BCI_ERROR, " break_invalid_framesize" );
495+ break ;
496+ }
497+
498+ sp += frame_size * sizeof (void *);
499+
500+ // Verify alignment before dereferencing sp as pointer (secondary defense)
501+ if (!aligned (sp)) {
502+ fillFrame (frames[depth++], BCI_ERROR, " break_misaligned_sp" );
503+ break ;
504+ }
505+
459506 fp = ((uintptr_t *)sp)[-FRAME_PC_SLOT - 1 ];
460507 pc = ((const void **)sp)[-FRAME_PC_SLOT];
461508 continue ;
@@ -572,7 +619,12 @@ __attribute__((no_sanitize("address"))) int StackWalker::walkVM(void* ucontext,
572619 }
573620
574621 if (EMPTY_FRAME_SIZE > 0 || f.pc_off != DW_LINK_REGISTER) {
575- pc = stripPointer (*(void **)(sp + f.pc_off ));
622+ // Verify alignment before dereferencing sp + offset
623+ uintptr_t pc_addr = sp + f.pc_off ;
624+ if (!aligned (pc_addr)) {
625+ break ;
626+ }
627+ pc = stripPointer (SafeAccess::load ((void **)pc_addr));
576628 } else if (depth == 1 ) {
577629 pc = (const void *)frame.link ();
578630 } else {
0 commit comments