180708Sjake/*- 280708Sjake * Copyright (c) 2001 Jake Burkholder. 380708Sjake * All rights reserved. 480708Sjake * 580708Sjake * Redistribution and use in source and binary forms, with or without 680708Sjake * modification, are permitted provided that the following conditions 780708Sjake * are met: 880708Sjake * 1. Redistributions of source code must retain the above copyright 980708Sjake * notice, this list of conditions and the following disclaimer. 1080708Sjake * 2. Redistributions in binary form must reproduce the above copyright 1180708Sjake * notice, this list of conditions and the following disclaimer in the 1280708Sjake * documentation and/or other materials provided with the distribution. 1380708Sjake * 1481337Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1580708Sjake * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1680708Sjake * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1781337Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1880708Sjake * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1980708Sjake * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2080708Sjake * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2180708Sjake * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2280708Sjake * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2380708Sjake * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2480708Sjake * SUCH DAMAGE. 2580708Sjake * 2680708Sjake * $FreeBSD$ 2780708Sjake */ 2880708Sjake 29223692Sjonathan#include "opt_capsicum.h" 30223692Sjonathan 3180708Sjake#include <sys/param.h> 3288782Sjake#include <sys/systm.h> 33223692Sjonathan#include <sys/capability.h> 34114029Sjhb#include <sys/lock.h> 3588782Sjake#include <sys/malloc.h> 36114029Sjhb#include <sys/mutex.h> 3780708Sjake#include <sys/proc.h> 3880708Sjake#include <sys/sysproto.h> 3980708Sjake 40140485Sjhb#include <machine/md_var.h> 4188782Sjake#include <machine/utrap.h> 4288782Sjake#include <machine/sysarch.h> 4388782Sjake 4495744Sjakestatic int sparc_sigtramp_install(struct thread *td, char *args); 4588782Sjakestatic int sparc_utrap_install(struct thread *td, char *args); 4688782Sjake 4780708Sjake#ifndef _SYS_SYSPROTO_H_ 4883088Sobrienstruct sysarch_args { 4980708Sjake int op; 5080708Sjake char *parms; 5180708Sjake}; 5280708Sjake#endif 5380708Sjake 5480708Sjakeint 5583366Sjuliansysarch(struct thread *td, struct sysarch_args *uap) 5680708Sjake{ 5788782Sjake int error; 5888782Sjake 59223692Sjonathan#ifdef CAPABILITY_MODE 60223692Sjonathan /* 61223692Sjonathan * When adding new operations, add a new case statement here to 62223692Sjonathan * explicitly indicate whether or not the operation is safe to 63223692Sjonathan * perform in capability mode. 64223692Sjonathan */ 65223692Sjonathan if (IN_CAPABILITY_MODE(td)) { 66223692Sjonathan switch (uap->op) { 67223692Sjonathan case SPARC_SIGTRAMP_INSTALL: 68223692Sjonathan case SPARC_UTRAP_INSTALL: 69223692Sjonathan break; 70223692Sjonathan 71223692Sjonathan default: 72223692Sjonathan return (ECAPMODE); 73223692Sjonathan } 74223692Sjonathan } 75223692Sjonathan#endif 76223692Sjonathan 77114029Sjhb mtx_lock(&Giant); 7888782Sjake switch (uap->op) { 7995744Sjake case SPARC_SIGTRAMP_INSTALL: 8095744Sjake error = sparc_sigtramp_install(td, uap->parms); 8195744Sjake break; 8288782Sjake case SPARC_UTRAP_INSTALL: 8388782Sjake error = sparc_utrap_install(td, uap->parms); 8488782Sjake break; 8588782Sjake default: 8688782Sjake error = EINVAL; 8788782Sjake break; 8888782Sjake } 89114029Sjhb mtx_unlock(&Giant); 9088782Sjake return (error); 9180708Sjake} 9288782Sjake 9388782Sjakestatic int 9495744Sjakesparc_sigtramp_install(struct thread *td, char *args) 9595744Sjake{ 9695744Sjake struct sparc_sigtramp_install_args sia; 9795744Sjake struct proc *p; 9895744Sjake int error; 9995744Sjake 10095744Sjake p = td->td_proc; 10195744Sjake if ((error = copyin(args, &sia, sizeof(sia))) != 0) 10295744Sjake return (error); 10395744Sjake if (sia.sia_old != NULL) { 10495744Sjake if (suword(sia.sia_old, (long)p->p_md.md_sigtramp) != 0) 10595744Sjake return (EFAULT); 10695744Sjake } 10795744Sjake p->p_md.md_sigtramp = sia.sia_new; 10895744Sjake return (0); 10995744Sjake} 11095744Sjake 11195744Sjakestatic int 11288782Sjakesparc_utrap_install(struct thread *td, char *args) 11388782Sjake{ 11488782Sjake struct sparc_utrap_install_args uia; 11588782Sjake struct sparc_utrap_args ua; 11688782Sjake struct md_utrap *ut; 11788782Sjake int error; 11888782Sjake int i; 11988782Sjake 12088782Sjake ut = td->td_proc->p_md.md_utrap; 12188782Sjake if ((error = copyin(args, &uia, sizeof(uia))) != 0) 12288782Sjake return (error); 12388782Sjake if (uia.num < 0 || uia.num > UT_MAX || 12488782Sjake (uia.handlers == NULL && uia.num > 0)) 12588782Sjake return (EINVAL); 12688782Sjake for (i = 0; i < uia.num; i++) { 12788782Sjake if ((error = copyin(&uia.handlers[i], &ua, sizeof(ua))) != 0) 12888782Sjake return (error); 12988782Sjake if (ua.type != UTH_NOCHANGE && 13088782Sjake (ua.type < 0 || ua.type >= UT_MAX)) 13188782Sjake return (EINVAL); 13288782Sjake if (ua.old_deferred != NULL) { 13388782Sjake if ((error = suword(ua.old_deferred, 0)) != 0) 13488782Sjake return (error); 13588782Sjake } 13688782Sjake if (ua.old_precise != NULL) { 13788782Sjake error = suword(ua.old_precise, 13888782Sjake ut != NULL ? (long)ut->ut_precise[ua.type] : 0); 13988782Sjake if (error != 0) 14088782Sjake return (error); 14188782Sjake } 14288782Sjake if (ua.type != UTH_NOCHANGE) { 14388782Sjake if (ut == NULL) { 144140485Sjhb ut = utrap_alloc(); 14588782Sjake td->td_proc->p_md.md_utrap = ut; 14688782Sjake } 14788782Sjake ut->ut_precise[ua.type] = ua.new_precise; 14888782Sjake } 14988782Sjake } 15088782Sjake return (0); 15188782Sjake} 152