1/*- 2 * Copyright (c) 2001 Jake Burkholder. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29#include "opt_capsicum.h" 30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/capability.h> 34#include <sys/lock.h> 35#include <sys/malloc.h> 36#include <sys/mutex.h> 37#include <sys/proc.h> 38#include <sys/sysproto.h> 39 40#include <machine/md_var.h> 41#include <machine/utrap.h> 42#include <machine/sysarch.h> 43 44static int sparc_sigtramp_install(struct thread *td, char *args); 45static int sparc_utrap_install(struct thread *td, char *args); 46 47#ifndef _SYS_SYSPROTO_H_ 48struct sysarch_args { 49 int op; 50 char *parms; 51}; 52#endif 53 54int 55sysarch(struct thread *td, struct sysarch_args *uap) 56{ 57 int error; 58 59#ifdef CAPABILITY_MODE 60 /* 61 * When adding new operations, add a new case statement here to 62 * explicitly indicate whether or not the operation is safe to 63 * perform in capability mode. 64 */ 65 if (IN_CAPABILITY_MODE(td)) { 66 switch (uap->op) { 67 case SPARC_SIGTRAMP_INSTALL: 68 case SPARC_UTRAP_INSTALL: 69 break; 70 71 default: 72 return (ECAPMODE); 73 } 74 } 75#endif 76 77 mtx_lock(&Giant); 78 switch (uap->op) { 79 case SPARC_SIGTRAMP_INSTALL: 80 error = sparc_sigtramp_install(td, uap->parms); 81 break; 82 case SPARC_UTRAP_INSTALL: 83 error = sparc_utrap_install(td, uap->parms); 84 break; 85 default: 86 error = EINVAL; 87 break; 88 } 89 mtx_unlock(&Giant); 90 return (error); 91} 92 93static int 94sparc_sigtramp_install(struct thread *td, char *args) 95{ 96 struct sparc_sigtramp_install_args sia; 97 struct proc *p; 98 int error; 99 100 p = td->td_proc; 101 if ((error = copyin(args, &sia, sizeof(sia))) != 0) 102 return (error); 103 if (sia.sia_old != NULL) { 104 if (suword(sia.sia_old, (long)p->p_md.md_sigtramp) != 0) 105 return (EFAULT); 106 } 107 p->p_md.md_sigtramp = sia.sia_new; 108 return (0); 109} 110 111static int 112sparc_utrap_install(struct thread *td, char *args) 113{ 114 struct sparc_utrap_install_args uia; 115 struct sparc_utrap_args ua; 116 struct md_utrap *ut; 117 int error; 118 int i; 119 120 ut = td->td_proc->p_md.md_utrap; 121 if ((error = copyin(args, &uia, sizeof(uia))) != 0) 122 return (error); 123 if (uia.num < 0 || uia.num > UT_MAX || 124 (uia.handlers == NULL && uia.num > 0)) 125 return (EINVAL); 126 for (i = 0; i < uia.num; i++) { 127 if ((error = copyin(&uia.handlers[i], &ua, sizeof(ua))) != 0) 128 return (error); 129 if (ua.type != UTH_NOCHANGE && 130 (ua.type < 0 || ua.type >= UT_MAX)) 131 return (EINVAL); 132 if (ua.old_deferred != NULL) { 133 if ((error = suword(ua.old_deferred, 0)) != 0) 134 return (error); 135 } 136 if (ua.old_precise != NULL) { 137 error = suword(ua.old_precise, 138 ut != NULL ? (long)ut->ut_precise[ua.type] : 0); 139 if (error != 0) 140 return (error); 141 } 142 if (ua.type != UTH_NOCHANGE) { 143 if (ut == NULL) { 144 ut = utrap_alloc(); 145 td->td_proc->p_md.md_utrap = ut; 146 } 147 ut->ut_precise[ua.type] = ua.new_precise; 148 } 149 } 150 return (0); 151} 152