svn commit: r258135 - in head/sys: amd64/amd64 amd64/ia32 amd64/linux32 i386/i386 i386/include i386/linux pc98/pc98 x86/include
Ed Maste
emaste at FreeBSD.org
Thu Nov 14 15:37:22 UTC 2013
Author: emaste
Date: Thu Nov 14 15:37:20 2013
New Revision: 258135
URL: http://svnweb.freebsd.org/changeset/base/258135
Log:
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
Modified:
head/sys/amd64/amd64/machdep.c
head/sys/amd64/ia32/ia32_signal.c
head/sys/amd64/linux32/linux32_sysvec.c
head/sys/i386/i386/machdep.c
head/sys/i386/include/vm86.h
head/sys/i386/linux/linux_sysvec.c
head/sys/pc98/pc98/machdep.c
head/sys/x86/include/psl.h
Modified: head/sys/amd64/amd64/machdep.c
==============================================================================
--- head/sys/amd64/amd64/machdep.c Thu Nov 14 15:14:27 2013 (r258134)
+++ head/sys/amd64/amd64/machdep.c Thu Nov 14 15:37:20 2013 (r258135)
@@ -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);
Modified: head/sys/amd64/ia32/ia32_signal.c
==============================================================================
--- head/sys/amd64/ia32/ia32_signal.c Thu Nov 14 15:14:27 2013 (r258134)
+++ head/sys/amd64/ia32/ia32_signal.c Thu Nov 14 15:37:20 2013 (r258135)
@@ -719,7 +719,7 @@ ofreebsd32_sigreturn(struct thread *td,
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);
Modified: head/sys/amd64/linux32/linux32_sysvec.c
==============================================================================
--- head/sys/amd64/linux32/linux32_sysvec.c Thu Nov 14 15:14:27 2013 (r258134)
+++ head/sys/amd64/linux32/linux32_sysvec.c Thu Nov 14 15:37:20 2013 (r258135)
@@ -587,17 +587,7 @@ linux_sigreturn(struct thread *td, struc
*/
#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, st
*/
#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);
/*
Modified: head/sys/i386/i386/machdep.c
==============================================================================
--- head/sys/i386/i386/machdep.c Thu Nov 14 15:14:27 2013 (r258134)
+++ head/sys/i386/i386/machdep.c Thu Nov 14 15:37:20 2013 (r258135)
@@ -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);
Modified: head/sys/i386/include/vm86.h
==============================================================================
--- head/sys/i386/include/vm86.h Thu Nov 14 15:14:27 2013 (r258134)
+++ head/sys/i386/include/vm86.h Thu Nov 14 15:37:20 2013 (r258135)
@@ -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 {
Modified: head/sys/i386/linux/linux_sysvec.c
==============================================================================
--- head/sys/i386/linux/linux_sysvec.c Thu Nov 14 15:14:27 2013 (r258134)
+++ head/sys/i386/linux/linux_sysvec.c Thu Nov 14 15:37:20 2013 (r258135)
@@ -684,17 +684,7 @@ linux_sigreturn(struct thread *td, struc
*/
#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, st
*/
#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);
/*
Modified: head/sys/pc98/pc98/machdep.c
==============================================================================
--- head/sys/pc98/pc98/machdep.c Thu Nov 14 15:14:27 2013 (r258134)
+++ head/sys/pc98/pc98/machdep.c Thu Nov 14 15:37:20 2013 (r258135)
@@ -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);
Modified: head/sys/x86/include/psl.h
==============================================================================
--- head/sys/x86/include/psl.h Thu Nov 14 15:14:27 2013 (r258134)
+++ head/sys/x86/include/psl.h Thu Nov 14 15:37:20 2013 (r258135)
@@ -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_ */
More information about the svn-src-head
mailing list