mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2025-01-09 16:01:19 +01:00
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:
parent
a7da6b679e
commit
a6db6c48bf
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=56096
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user