x86: Allow users to change PSL_RF via ptrace(PT_SETREGS...)
Debuggers may need to change PSL_RF. Note that tf_eflags is already stored in the signal context during signal handling and PSL_RF previously could be modified via sigreturn, so this change should not provide any new ability to userspace. For background see the thread at: http://lists.freebsd.org/pipermail/freebsd-i386/2007-September/005910.html Reviewed by: jhb, kib Sponsored by: DARPA, AFRL
This commit is contained in:
parent
e4e01d9cec
commit
3d271aaab0
@ -486,17 +486,7 @@ sys_sigreturn(td, uap)
|
||||
/*
|
||||
* Don't allow users to change privileged or reserved flags.
|
||||
*/
|
||||
/*
|
||||
* XXX do allow users to change the privileged flag PSL_RF.
|
||||
* The cpu sets PSL_RF in tf_rflags for faults. Debuggers
|
||||
* should sometimes set it there too. tf_rflags is kept in
|
||||
* the signal context during signal handling and there is no
|
||||
* other place to remember it, so the PSL_RF bit may be
|
||||
* corrupted by the signal handler without us knowing.
|
||||
* Corruption of the PSL_RF bit at worst causes one more or
|
||||
* one less debugger trap, so allowing it is fairly harmless.
|
||||
*/
|
||||
if (!EFL_SECURE(rflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
|
||||
if (!EFL_SECURE(rflags, regs->tf_rflags)) {
|
||||
uprintf("pid %d (%s): sigreturn rflags = 0x%lx\n", p->p_pid,
|
||||
td->td_name, rflags);
|
||||
return (EINVAL);
|
||||
|
@ -719,7 +719,7 @@ ofreebsd32_sigreturn(struct thread *td, struct ofreebsd32_sigreturn_args *uap)
|
||||
return (error);
|
||||
scp = ≻
|
||||
eflags = scp->sc_eflags;
|
||||
if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
|
||||
if (!EFL_SECURE(eflags, regs->tf_rflags)) {
|
||||
return (EINVAL);
|
||||
}
|
||||
if (!CS_SECURE(scp->sc_cs)) {
|
||||
@ -787,17 +787,7 @@ freebsd4_freebsd32_sigreturn(td, uap)
|
||||
/*
|
||||
* Don't allow users to change privileged or reserved flags.
|
||||
*/
|
||||
/*
|
||||
* XXX do allow users to change the privileged flag PSL_RF.
|
||||
* The cpu sets PSL_RF in tf_eflags for faults. Debuggers
|
||||
* should sometimes set it there too. tf_eflags is kept in
|
||||
* the signal context during signal handling and there is no
|
||||
* other place to remember it, so the PSL_RF bit may be
|
||||
* corrupted by the signal handler without us knowing.
|
||||
* Corruption of the PSL_RF bit at worst causes one more or
|
||||
* one less debugger trap, so allowing it is fairly harmless.
|
||||
*/
|
||||
if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
|
||||
if (!EFL_SECURE(eflags, regs->tf_rflags)) {
|
||||
uprintf("pid %d (%s): freebsd4_freebsd32_sigreturn eflags = 0x%x\n",
|
||||
td->td_proc->p_pid, td->td_name, eflags);
|
||||
return (EINVAL);
|
||||
@ -873,17 +863,7 @@ freebsd32_sigreturn(td, uap)
|
||||
/*
|
||||
* Don't allow users to change privileged or reserved flags.
|
||||
*/
|
||||
/*
|
||||
* XXX do allow users to change the privileged flag PSL_RF.
|
||||
* The cpu sets PSL_RF in tf_eflags for faults. Debuggers
|
||||
* should sometimes set it there too. tf_eflags is kept in
|
||||
* the signal context during signal handling and there is no
|
||||
* other place to remember it, so the PSL_RF bit may be
|
||||
* corrupted by the signal handler without us knowing.
|
||||
* Corruption of the PSL_RF bit at worst causes one more or
|
||||
* one less debugger trap, so allowing it is fairly harmless.
|
||||
*/
|
||||
if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
|
||||
if (!EFL_SECURE(eflags, regs->tf_rflags)) {
|
||||
uprintf("pid %d (%s): freebsd32_sigreturn eflags = 0x%x\n",
|
||||
td->td_proc->p_pid, td->td_name, eflags);
|
||||
return (EINVAL);
|
||||
|
@ -587,17 +587,7 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
|
||||
*/
|
||||
#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
|
||||
eflags = frame.sf_sc.sc_eflags;
|
||||
/*
|
||||
* XXX do allow users to change the privileged flag PSL_RF. The
|
||||
* cpu sets PSL_RF in tf_eflags for faults. Debuggers should
|
||||
* sometimes set it there too. tf_eflags is kept in the signal
|
||||
* context during signal handling and there is no other place
|
||||
* to remember it, so the PSL_RF bit may be corrupted by the
|
||||
* signal handler without us knowing. Corruption of the PSL_RF
|
||||
* bit at worst causes one more or one less debugger trap, so
|
||||
* allowing it is fairly harmless.
|
||||
*/
|
||||
if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF))
|
||||
if (!EFLAGS_SECURE(eflags, regs->tf_rflags))
|
||||
return(EINVAL);
|
||||
|
||||
/*
|
||||
@ -689,17 +679,7 @@ linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
|
||||
*/
|
||||
#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
|
||||
eflags = context->sc_eflags;
|
||||
/*
|
||||
* XXX do allow users to change the privileged flag PSL_RF. The
|
||||
* cpu sets PSL_RF in tf_eflags for faults. Debuggers should
|
||||
* sometimes set it there too. tf_eflags is kept in the signal
|
||||
* context during signal handling and there is no other place
|
||||
* to remember it, so the PSL_RF bit may be corrupted by the
|
||||
* signal handler without us knowing. Corruption of the PSL_RF
|
||||
* bit at worst causes one more or one less debugger trap, so
|
||||
* allowing it is fairly harmless.
|
||||
*/
|
||||
if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF))
|
||||
if (!EFLAGS_SECURE(eflags, regs->tf_rflags))
|
||||
return(EINVAL);
|
||||
|
||||
/*
|
||||
|
@ -842,17 +842,7 @@ osigreturn(td, uap)
|
||||
/*
|
||||
* Don't allow users to change privileged or reserved flags.
|
||||
*/
|
||||
/*
|
||||
* XXX do allow users to change the privileged flag PSL_RF.
|
||||
* The cpu sets PSL_RF in tf_eflags for faults. Debuggers
|
||||
* should sometimes set it there too. tf_eflags is kept in
|
||||
* the signal context during signal handling and there is no
|
||||
* other place to remember it, so the PSL_RF bit may be
|
||||
* corrupted by the signal handler without us knowing.
|
||||
* Corruption of the PSL_RF bit at worst causes one more or
|
||||
* one less debugger trap, so allowing it is fairly harmless.
|
||||
*/
|
||||
if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
|
||||
if (!EFL_SECURE(eflags, regs->tf_eflags)) {
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
@ -968,17 +958,7 @@ freebsd4_sigreturn(td, uap)
|
||||
/*
|
||||
* Don't allow users to change privileged or reserved flags.
|
||||
*/
|
||||
/*
|
||||
* XXX do allow users to change the privileged flag PSL_RF.
|
||||
* The cpu sets PSL_RF in tf_eflags for faults. Debuggers
|
||||
* should sometimes set it there too. tf_eflags is kept in
|
||||
* the signal context during signal handling and there is no
|
||||
* other place to remember it, so the PSL_RF bit may be
|
||||
* corrupted by the signal handler without us knowing.
|
||||
* Corruption of the PSL_RF bit at worst causes one more or
|
||||
* one less debugger trap, so allowing it is fairly harmless.
|
||||
*/
|
||||
if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
|
||||
if (!EFL_SECURE(eflags, regs->tf_eflags)) {
|
||||
uprintf("pid %d (%s): freebsd4_sigreturn eflags = 0x%x\n",
|
||||
td->td_proc->p_pid, td->td_name, eflags);
|
||||
return (EINVAL);
|
||||
@ -1082,17 +1062,7 @@ sys_sigreturn(td, uap)
|
||||
/*
|
||||
* Don't allow users to change privileged or reserved flags.
|
||||
*/
|
||||
/*
|
||||
* XXX do allow users to change the privileged flag PSL_RF.
|
||||
* The cpu sets PSL_RF in tf_eflags for faults. Debuggers
|
||||
* should sometimes set it there too. tf_eflags is kept in
|
||||
* the signal context during signal handling and there is no
|
||||
* other place to remember it, so the PSL_RF bit may be
|
||||
* corrupted by the signal handler without us knowing.
|
||||
* Corruption of the PSL_RF bit at worst causes one more or
|
||||
* one less debugger trap, so allowing it is fairly harmless.
|
||||
*/
|
||||
if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
|
||||
if (!EFL_SECURE(eflags, regs->tf_eflags)) {
|
||||
uprintf("pid %d (%s): sigreturn eflags = 0x%x\n",
|
||||
td->td_proc->p_pid, td->td_name, eflags);
|
||||
return (EINVAL);
|
||||
|
@ -113,7 +113,7 @@ struct vm86context {
|
||||
} pmap[VM86_PMAPSIZE];
|
||||
};
|
||||
|
||||
#define VM_USERCHANGE (PSL_USERCHANGE | PSL_RF)
|
||||
#define VM_USERCHANGE (PSL_USERCHANGE)
|
||||
#define VME_USERCHANGE (VM_USERCHANGE | PSL_VIP | PSL_VIF)
|
||||
|
||||
struct vm86_kernel {
|
||||
|
@ -684,17 +684,7 @@ linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
|
||||
*/
|
||||
#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
|
||||
eflags = frame.sf_sc.sc_eflags;
|
||||
/*
|
||||
* XXX do allow users to change the privileged flag PSL_RF. The
|
||||
* cpu sets PSL_RF in tf_eflags for faults. Debuggers should
|
||||
* sometimes set it there too. tf_eflags is kept in the signal
|
||||
* context during signal handling and there is no other place
|
||||
* to remember it, so the PSL_RF bit may be corrupted by the
|
||||
* signal handler without us knowing. Corruption of the PSL_RF
|
||||
* bit at worst causes one more or one less debugger trap, so
|
||||
* allowing it is fairly harmless.
|
||||
*/
|
||||
if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF))
|
||||
if (!EFLAGS_SECURE(eflags, regs->tf_eflags))
|
||||
return(EINVAL);
|
||||
|
||||
/*
|
||||
@ -785,17 +775,7 @@ linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
|
||||
*/
|
||||
#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
|
||||
eflags = context->sc_eflags;
|
||||
/*
|
||||
* XXX do allow users to change the privileged flag PSL_RF. The
|
||||
* cpu sets PSL_RF in tf_eflags for faults. Debuggers should
|
||||
* sometimes set it there too. tf_eflags is kept in the signal
|
||||
* context during signal handling and there is no other place
|
||||
* to remember it, so the PSL_RF bit may be corrupted by the
|
||||
* signal handler without us knowing. Corruption of the PSL_RF
|
||||
* bit at worst causes one more or one less debugger trap, so
|
||||
* allowing it is fairly harmless.
|
||||
*/
|
||||
if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF))
|
||||
if (!EFLAGS_SECURE(eflags, regs->tf_eflags))
|
||||
return(EINVAL);
|
||||
|
||||
/*
|
||||
|
@ -773,17 +773,7 @@ osigreturn(td, uap)
|
||||
/*
|
||||
* Don't allow users to change privileged or reserved flags.
|
||||
*/
|
||||
/*
|
||||
* XXX do allow users to change the privileged flag PSL_RF.
|
||||
* The cpu sets PSL_RF in tf_eflags for faults. Debuggers
|
||||
* should sometimes set it there too. tf_eflags is kept in
|
||||
* the signal context during signal handling and there is no
|
||||
* other place to remember it, so the PSL_RF bit may be
|
||||
* corrupted by the signal handler without us knowing.
|
||||
* Corruption of the PSL_RF bit at worst causes one more or
|
||||
* one less debugger trap, so allowing it is fairly harmless.
|
||||
*/
|
||||
if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
|
||||
if (!EFL_SECURE(eflags, regs->tf_eflags)) {
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
@ -899,17 +889,7 @@ freebsd4_sigreturn(td, uap)
|
||||
/*
|
||||
* Don't allow users to change privileged or reserved flags.
|
||||
*/
|
||||
/*
|
||||
* XXX do allow users to change the privileged flag PSL_RF.
|
||||
* The cpu sets PSL_RF in tf_eflags for faults. Debuggers
|
||||
* should sometimes set it there too. tf_eflags is kept in
|
||||
* the signal context during signal handling and there is no
|
||||
* other place to remember it, so the PSL_RF bit may be
|
||||
* corrupted by the signal handler without us knowing.
|
||||
* Corruption of the PSL_RF bit at worst causes one more or
|
||||
* one less debugger trap, so allowing it is fairly harmless.
|
||||
*/
|
||||
if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
|
||||
if (!EFL_SECURE(eflags, regs->tf_eflags)) {
|
||||
uprintf("pid %d (%s): freebsd4_sigreturn eflags = 0x%x\n",
|
||||
td->td_proc->p_pid, td->td_name, eflags);
|
||||
return (EINVAL);
|
||||
@ -1013,17 +993,7 @@ sys_sigreturn(td, uap)
|
||||
/*
|
||||
* Don't allow users to change privileged or reserved flags.
|
||||
*/
|
||||
/*
|
||||
* XXX do allow users to change the privileged flag PSL_RF.
|
||||
* The cpu sets PSL_RF in tf_eflags for faults. Debuggers
|
||||
* should sometimes set it there too. tf_eflags is kept in
|
||||
* the signal context during signal handling and there is no
|
||||
* other place to remember it, so the PSL_RF bit may be
|
||||
* corrupted by the signal handler without us knowing.
|
||||
* Corruption of the PSL_RF bit at worst causes one more or
|
||||
* one less debugger trap, so allowing it is fairly harmless.
|
||||
*/
|
||||
if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_eflags & ~PSL_RF)) {
|
||||
if (!EFL_SECURE(eflags, regs->tf_eflags)) {
|
||||
uprintf("pid %d (%s): sigreturn eflags = 0x%x\n",
|
||||
td->td_proc->p_pid, td->td_name, eflags);
|
||||
return (EINVAL);
|
||||
|
@ -77,8 +77,16 @@
|
||||
* is undesirable but it may as well be allowed since users can inflict
|
||||
* it on the kernel directly. Changes to PSL_AC are silently ignored on
|
||||
* 386's.
|
||||
*
|
||||
* Users are allowed to change the privileged flag PSL_RF. The cpu sets PSL_RF
|
||||
* in tf_eflags for faults. Debuggers should sometimes set it there too.
|
||||
* tf_eflags is kept in the signal context during signal handling and there is
|
||||
* no other place to remember it, so the PSL_RF bit may be corrupted by the
|
||||
* signal handler without us knowing. Corruption of the PSL_RF bit at worst
|
||||
* causes one more or one less debugger trap, so allowing it is fairly
|
||||
* harmless.
|
||||
*/
|
||||
#define PSL_USERCHANGE (PSL_C | PSL_PF | PSL_AF | PSL_Z | PSL_N | PSL_T \
|
||||
| PSL_D | PSL_V | PSL_NT | PSL_AC | PSL_ID)
|
||||
| PSL_D | PSL_V | PSL_NT | PSL_RF | PSL_AC | PSL_ID)
|
||||
|
||||
#endif /* !_MACHINE_PSL_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user