The kernel side of per-process unaligned access control (printing, fixing &

delivering SIGBUS).  This will allow a non-superuser to control unaligned
access behaviour on a per-process basis once a userland control program
(uac) is written.

Reviewed by: obrien
Tested by:   obrien
This commit is contained in:
Andrew Gallatin 2000-01-16 07:07:33 +00:00
parent a7da6b679e
commit a6db6c48bf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=56096
7 changed files with 68 additions and 9 deletions

View File

@ -66,6 +66,8 @@ struct sysarch_args {
static int alpha_sethae(struct proc *p, char *args);
static int alpha_get_fpmask(struct proc *p, char *args);
static int alpha_set_fpmask(struct proc *p, char *args);
static int alpha_set_uac(struct proc *p, char *args);
static int alpha_get_uac(struct proc *p, char *args);
int
sysarch(p, uap)
@ -84,6 +86,12 @@ sysarch(p, uap)
case ALPHA_SET_FPMASK:
error = alpha_set_fpmask(p, uap->parms);
break;
case ALPHA_SET_UAC:
error = alpha_set_uac(p, uap->parms);
break;
case ALPHA_GET_UAC:
error = alpha_get_uac(p, uap->parms);
break;
default:
error = EINVAL;
@ -154,3 +162,43 @@ alpha_set_fpmask(struct proc *p, char *args)
error = copyout(&ua, args, sizeof(struct alpha_fpmask_args));
return (error);
}
static int
alpha_set_uac(struct proc *p, char *args)
{
int error, s;
unsigned long uac;
error = copyin(args, &uac, sizeof(uac));
if (error)
return (error);
if (p->p_pptr) {
s = splimp();
if (p->p_pptr) {
p->p_pptr->p_md.md_flags &= ~MDP_UAC_MASK;
p->p_pptr->p_md.md_flags |= uac & MDP_UAC_MASK;
} else
error = ESRCH;
splx(s);
}
return error;
}
static int
alpha_get_uac(struct proc *p, char *args)
{
int error, s;
unsigned long uac;
error = ESRCH;
if (p->p_pptr) {
s = splimp();
if (p->p_pptr) {
uac = p->p_pptr->p_md.md_flags & MDP_UAC_MASK;
error = copyout(&uac, args, sizeof(uac));
}
splx(s);
}
return error;
}

View File

@ -923,7 +923,7 @@ unaligned_fixup(va, opcode, reg, p)
int doprint, dofix, dosigbus;
int signal, size;
const char *type;
unsigned long *regptr, longdata;
unsigned long *regptr, longdata, uac;
int intdata; /* signed to get extension when storing */
struct {
const char *type; /* opcode name */
@ -950,12 +950,16 @@ unaligned_fixup(va, opcode, reg, p)
/*
* Figure out what actions to take.
*
* XXX In the future, this should have a per-process component
* as well.
*/
doprint = alpha_unaligned_print;
dofix = alpha_unaligned_fix;
dosigbus = alpha_unaligned_sigbus;
if (p)
uac = p->p_md.md_flags & MDP_UAC_MASK;
else
uac = 0;
doprint = alpha_unaligned_print && !(uac & MDP_UAC_NOPRINT);
dofix = alpha_unaligned_fix && !(uac & MDP_UAC_NOFIX);
dosigbus = alpha_unaligned_sigbus | (uac & MDP_UAC_SIGBUS);
/*
* Find out which opcode it is. Arrange to have the opcode

View File

@ -126,7 +126,7 @@ cpu_fork(p1, p2, flags)
return;
p2->p_md.md_tf = p1->p_md.md_tf;
p2->p_md.md_flags = p1->p_md.md_flags & MDP_FPUSED;
p2->p_md.md_flags = p1->p_md.md_flags & (MDP_FPUSED | MDP_UAC_MASK);
/*
* Cache the physical address of the pcb, so we can

View File

@ -50,3 +50,8 @@ struct mdproc {
#define MDP_STEP1 0x0002 /* Single step normal instruction */
#define MDP_STEP2 0x0004 /* Single step branch instruction */
#define MDP_HAEUSED 0x0008 /* Process used the HAE */
#define MDP_UAC_NOPRINT 0x0010 /* Don't print unaligned traps */
#define MDP_UAC_NOFIX 0x0020 /* Don't fixup unaligned traps */
#define MDP_UAC_SIGBUS 0x0040 /* Deliver SIGBUS upon
unalinged access */
#define MDP_UAC_MASK (MDP_UAC_NOPRINT | MDP_UAC_NOFIX | MDP_UAC_SIGBUS)

View File

@ -42,6 +42,8 @@
#define ALPHA_SETHAE 0
#define ALPHA_GET_FPMASK 1
#define ALPHA_SET_FPMASK 2
#define ALPHA_GET_UAC 3
#define ALPHA_SET_UAC 4
#ifndef _KERNEL
#include <sys/cdefs.h>

View File

@ -126,7 +126,7 @@ cpu_fork(p1, p2, flags)
return;
p2->p_md.md_tf = p1->p_md.md_tf;
p2->p_md.md_flags = p1->p_md.md_flags & MDP_FPUSED;
p2->p_md.md_flags = p1->p_md.md_flags & (MDP_FPUSED | MDP_UAC_MASK);
/*
* Cache the physical address of the pcb, so we can

View File

@ -126,7 +126,7 @@ cpu_fork(p1, p2, flags)
return;
p2->p_md.md_tf = p1->p_md.md_tf;
p2->p_md.md_flags = p1->p_md.md_flags & MDP_FPUSED;
p2->p_md.md_flags = p1->p_md.md_flags & (MDP_FPUSED | MDP_UAC_MASK);
/*
* Cache the physical address of the pcb, so we can