summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2013-11-25 15:58:48 +0000
committeremaste <emaste@FreeBSD.org>2013-11-25 15:58:48 +0000
commitb0519089ed0efd8b8d92d24e9d972cfdb513232a (patch)
tree1700a610df043601614f2bd2a345a3bca0ec7cd6
parent79f55b704935cf6e1a4f60d33d1ce87bcf710f08 (diff)
downloadFreeBSD-src-b0519089ed0efd8b8d92d24e9d972cfdb513232a.zip
FreeBSD-src-b0519089ed0efd8b8d92d24e9d972cfdb513232a.tar.gz
MFC r258135: 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 Approved by: re (gjb)
-rw-r--r--sys/amd64/amd64/machdep.c12
-rw-r--r--sys/amd64/ia32/ia32_signal.c26
-rw-r--r--sys/amd64/linux32/linux32_sysvec.c24
-rw-r--r--sys/i386/i386/machdep.c36
-rw-r--r--sys/i386/include/vm86.h2
-rw-r--r--sys/i386/linux/linux_sysvec.c24
-rw-r--r--sys/pc98/pc98/machdep.c36
-rw-r--r--sys/x86/include/psl.h10
8 files changed, 24 insertions, 146 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 2b2e47f..6c39e1c 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -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);
diff --git a/sys/amd64/ia32/ia32_signal.c b/sys/amd64/ia32/ia32_signal.c
index cff57f6..75a0511 100644
--- a/sys/amd64/ia32/ia32_signal.c
+++ b/sys/amd64/ia32/ia32_signal.c
@@ -719,7 +719,7 @@ ofreebsd32_sigreturn(struct thread *td, struct ofreebsd32_sigreturn_args *uap)
return (error);
scp = &sc;
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);
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
index c4b66de..c06ce11 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -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);
/*
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index ad1f0fe..ca15f27 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -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);
diff --git a/sys/i386/include/vm86.h b/sys/i386/include/vm86.h
index e33d720..2253d5c 100644
--- a/sys/i386/include/vm86.h
+++ b/sys/i386/include/vm86.h
@@ -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 {
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 71417e0..0ad6791 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -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);
/*
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index 4435186..a4887c6 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -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);
diff --git a/sys/x86/include/psl.h b/sys/x86/include/psl.h
index 12d05c5..47851e0 100644
--- a/sys/x86/include/psl.h
+++ b/sys/x86/include/psl.h
@@ -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_ */
OpenPOWER on IntegriCloud