powerpc: Only worry about the lower 32 bits of SP in a 32-bit process

Summary:
Running a 32-bit process on a 64-bit POWER CPU may still use all 64-bits
in calculations, while ignoring the upper 32 bits for addressing
storage.  It so happens that some processes end up with r1 (SP) having
bit 31 set in some cases (33-bit address).  Writing out to this 33-bit
address obviosly fails.  Since the CPU ignores the upper bits, we should
as well.

sendsig() and cpu_fetch_syscall_args() appear to be the only functions
that actually rely on userspace register values for copy in/out, and
cpu_fetch_syscall_args() doesn't seem to be bitten in practice yet.

Reviewed By: luporl
Differential Revision: https://reviews.freebsd.org/D20896
This commit is contained in:
Justin Hibbits 2019-07-11 03:29:25 +00:00
parent 46a7f2ebd4
commit 9ac516a6f1

View File

@ -144,6 +144,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
#endif
size_t sfpsize;
caddr_t sfp, usfp;
register_t sp;
int oonstack, rndfsize;
int sig;
int code;
@ -155,7 +156,6 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
psp = p->p_sigacts;
mtx_assert(&psp->ps_mtx, MA_OWNED);
tf = td->td_frame;
oonstack = sigonstack(tf->fixreg[1]);
/*
* Fill siginfo structure.
@ -173,6 +173,8 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
sfp = (caddr_t)&sf32;
sfpsize = sizeof(sf32);
rndfsize = roundup(sizeof(sf32), 16);
sp = (uint32_t)tf->fixreg[1];
oonstack = sigonstack(sp);
/*
* Save user context
@ -203,6 +205,8 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
#else
rndfsize = roundup(sizeof(sf), 16);
#endif
sp = tf->fixreg[1];
oonstack = sigonstack(sp);
/*
* Save user context
@ -232,7 +236,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
usfp = (void *)(((uintptr_t)td->td_sigstk.ss_sp +
td->td_sigstk.ss_size - rndfsize) & ~0xFul);
} else {
usfp = (void *)((tf->fixreg[1] - rndfsize) & ~0xFul);
usfp = (void *)((sp - rndfsize) & ~0xFul);
}
/*