Don't use fuword() and suword() on struct members of type int. This
happens to work on 32-bit platforms as sizeof(long)=sizeof(int), but wrecks all kinds of havoc (garbage reads, corrupting writes and misaligned loads/stores) on 64-bit architectures. The fix for now is to use fuword32() and suword32() and change the type of the applicable int fields to int32. This is to make it explicit that we depend on these fields being 32-bit. We may want to revisit this later. Reviewed by: deischen
This commit is contained in:
parent
19acf030a2
commit
4e4422d4d4
@ -1012,8 +1012,8 @@ thread_export_context(struct thread *td)
|
||||
|
||||
/* Exports clock ticks in kernel mode */
|
||||
addr = (caddr_t)(&td->td_mailbox->tm_sticks);
|
||||
temp = fuword(addr) + td->td_usticks;
|
||||
if (suword(addr, temp)) {
|
||||
temp = fuword32(addr) + td->td_usticks;
|
||||
if (suword32(addr, temp)) {
|
||||
error = EFAULT;
|
||||
goto bad;
|
||||
}
|
||||
@ -1167,7 +1167,7 @@ thread_update_usr_ticks(struct thread *td, int user)
|
||||
addr = (caddr_t)&tmbx->tm_sticks;
|
||||
}
|
||||
if (uticks) {
|
||||
if (suword(addr, uticks+fuword(addr))) {
|
||||
if (suword32(addr, uticks+fuword32(addr))) {
|
||||
PROC_LOCK(p);
|
||||
psignal(p, SIGSEGV);
|
||||
PROC_UNLOCK(p);
|
||||
@ -1576,7 +1576,7 @@ thread_user_enter(struct proc *p, struct thread *td)
|
||||
KASSERT(ku, ("%s: no upcall owned", __func__));
|
||||
KASSERT((ku->ku_owner == td), ("%s: wrong owner", __func__));
|
||||
KASSERT(!TD_CAN_UNBIND(td), ("%s: can unbind", __func__));
|
||||
ku->ku_mflags = fuword((void *)&ku->ku_mailbox->km_flags);
|
||||
ku->ku_mflags = fuword32((void *)&ku->ku_mailbox->km_flags);
|
||||
tmbx = (void *)fuword((void *)&ku->ku_mailbox->km_curthread);
|
||||
if ((tmbx == NULL) || (tmbx == (void *)-1)) {
|
||||
td->td_mailbox = NULL;
|
||||
|
@ -1012,8 +1012,8 @@ thread_export_context(struct thread *td)
|
||||
|
||||
/* Exports clock ticks in kernel mode */
|
||||
addr = (caddr_t)(&td->td_mailbox->tm_sticks);
|
||||
temp = fuword(addr) + td->td_usticks;
|
||||
if (suword(addr, temp)) {
|
||||
temp = fuword32(addr) + td->td_usticks;
|
||||
if (suword32(addr, temp)) {
|
||||
error = EFAULT;
|
||||
goto bad;
|
||||
}
|
||||
@ -1167,7 +1167,7 @@ thread_update_usr_ticks(struct thread *td, int user)
|
||||
addr = (caddr_t)&tmbx->tm_sticks;
|
||||
}
|
||||
if (uticks) {
|
||||
if (suword(addr, uticks+fuword(addr))) {
|
||||
if (suword32(addr, uticks+fuword32(addr))) {
|
||||
PROC_LOCK(p);
|
||||
psignal(p, SIGSEGV);
|
||||
PROC_UNLOCK(p);
|
||||
@ -1576,7 +1576,7 @@ thread_user_enter(struct proc *p, struct thread *td)
|
||||
KASSERT(ku, ("%s: no upcall owned", __func__));
|
||||
KASSERT((ku->ku_owner == td), ("%s: wrong owner", __func__));
|
||||
KASSERT(!TD_CAN_UNBIND(td), ("%s: can unbind", __func__));
|
||||
ku->ku_mflags = fuword((void *)&ku->ku_mailbox->km_flags);
|
||||
ku->ku_mflags = fuword32((void *)&ku->ku_mailbox->km_flags);
|
||||
tmbx = (void *)fuword((void *)&ku->ku_mailbox->km_curthread);
|
||||
if ((tmbx == NULL) || (tmbx == (void *)-1)) {
|
||||
td->td_mailbox = NULL;
|
||||
|
@ -58,8 +58,8 @@ struct kse_thr_mailbox {
|
||||
unsigned int tm_flags; /* Thread flags */
|
||||
struct kse_thr_mailbox *tm_next; /* Next thread in list */
|
||||
void *tm_udata; /* For use by the UTS */
|
||||
unsigned int tm_uticks;
|
||||
unsigned int tm_sticks;
|
||||
uint32_t tm_uticks;
|
||||
uint32_t tm_sticks;
|
||||
siginfo_t tm_syncsig;
|
||||
int tm_spare[8];
|
||||
};
|
||||
@ -75,7 +75,7 @@ struct kse_mailbox {
|
||||
struct kse_thr_mailbox *km_curthread; /* Currently running thread */
|
||||
struct kse_thr_mailbox *km_completed; /* Threads back from kernel */
|
||||
sigset_t km_sigscaught; /* Caught signals */
|
||||
unsigned int km_flags; /* KSE flags */
|
||||
uint32_t km_flags; /* KSE flags */
|
||||
kse_func_t *km_func; /* UTS function */
|
||||
stack_t km_stack; /* UTS context */
|
||||
void *km_udata; /* For use by the UTS */
|
||||
|
Loading…
Reference in New Issue
Block a user