Line data Source code
1 : /* $OpenBSD: syscall_mi.h,v 1.19 2018/04/12 17:13:44 deraadt Exp $ */
2 :
3 : /*
4 : * Copyright (c) 1982, 1986, 1989, 1993
5 : * The Regents of the University of California. All rights reserved.
6 : *
7 : * Redistribution and use in source and binary forms, with or without
8 : * modification, are permitted provided that the following conditions
9 : * are met:
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * 2. Redistributions in binary form must reproduce the above copyright
13 : * notice, this list of conditions and the following disclaimer in the
14 : * documentation and/or other materials provided with the distribution.
15 : * 3. Neither the name of the University nor the names of its contributors
16 : * may be used to endorse or promote products derived from this software
17 : * without specific prior written permission.
18 : *
19 : * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 : * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 : * SUCH DAMAGE.
30 : *
31 : * @(#)kern_xxx.c 8.2 (Berkeley) 11/14/93
32 : */
33 :
34 : #include <sys/param.h>
35 : #include <sys/pledge.h>
36 : #include <uvm/uvm_extern.h>
37 :
38 : #ifdef KTRACE
39 : #include <sys/ktrace.h>
40 : #endif
41 :
42 :
43 : /*
44 : * The MD setup for a system call has been done; here's the MI part.
45 : */
46 : static inline int
47 0 : mi_syscall(struct proc *p, register_t code, const struct sysent *callp,
48 : register_t *argp, register_t retval[2])
49 : {
50 0 : uint64_t tval;
51 60 : int lock = !(callp->sy_flags & SY_NOLOCK);
52 : int error, pledged;
53 0 : vaddr_t sp = PROC_STACK(p);
54 :
55 : /* refresh the thread's cache of the process's creds */
56 0 : refreshcreds(p);
57 :
58 : #ifdef SYSCALL_DEBUG
59 : KERNEL_LOCK();
60 : scdebug_call(p, code, argp);
61 : KERNEL_UNLOCK();
62 : #endif
63 : #ifdef KTRACE
64 120 : if (KTRPOINT(p, KTR_SYSCALL)) {
65 0 : KERNEL_LOCK();
66 0 : ktrsyscall(p, code, callp->sy_argsize, argp);
67 0 : KERNEL_UNLOCK();
68 0 : }
69 : #endif
70 :
71 0 : if (p->p_vmspace->vm_map.serial != p->p_spserial ||
72 0 : p->p_spstart == 0 || sp < p->p_spstart || sp >= p->p_spend) {
73 0 : KERNEL_LOCK();
74 :
75 0 : if (!uvm_map_check_stack_range(p, sp)) {
76 0 : printf("syscall [%s]%d/%d sp %lx not inside %lx-%lx\n",
77 0 : p->p_p->ps_comm, p->p_p->ps_pid, p->p_tid,
78 0 : sp, p->p_spstart, p->p_spend);
79 :
80 0 : p->p_sitrapno = 0;
81 0 : p->p_sicode = SEGV_ACCERR;
82 0 : p->p_sigval.sival_ptr = (void *)PROC_PC(p);
83 0 : psignal(p, SIGSEGV);
84 0 : KERNEL_UNLOCK();
85 0 : return (EPERM);
86 : }
87 0 : KERNEL_UNLOCK();
88 0 : }
89 0 : if (lock)
90 60 : KERNEL_LOCK();
91 0 : pledged = (p->p_p->ps_flags & PS_PLEDGE);
92 60 : if (pledged && (error = pledge_syscall(p, code, &tval))) {
93 0 : if (!lock)
94 0 : KERNEL_LOCK();
95 0 : error = pledge_fail(p, error, tval);
96 0 : KERNEL_UNLOCK();
97 0 : return (error);
98 : }
99 0 : error = (*callp->sy_call)(p, argp, retval);
100 0 : if (lock)
101 90 : KERNEL_UNLOCK();
102 :
103 0 : return (error);
104 0 : }
105 :
106 : /*
107 : * Finish MI stuff on return, after the registers have been set
108 : */
109 : static inline void
110 0 : mi_syscall_return(struct proc *p, register_t code, int error,
111 : const register_t retval[2])
112 : {
113 : #ifdef SYSCALL_DEBUG
114 : KERNEL_LOCK();
115 : scdebug_ret(p, code, error, retval);
116 : KERNEL_UNLOCK();
117 : #endif
118 :
119 0 : userret(p);
120 :
121 : #ifdef KTRACE
122 84 : if (KTRPOINT(p, KTR_SYSRET)) {
123 0 : KERNEL_LOCK();
124 0 : ktrsysret(p, code, error, retval);
125 0 : KERNEL_UNLOCK();
126 0 : }
127 : #endif
128 0 : }
129 :
130 : /*
131 : * Finish MI stuff for a new process/thread to return
132 : */
133 : static inline void
134 0 : mi_child_return(struct proc *p)
135 : {
136 : #if defined(SYSCALL_DEBUG) || defined(KTRACE)
137 0 : int code = (p->p_flag & P_THREAD) ? SYS___tfork :
138 0 : (p->p_p->ps_flags & PS_PPWAIT) ? SYS_vfork : SYS_fork;
139 : const register_t child_retval[2] = { 0, 1 };
140 : #endif
141 :
142 : #ifdef SYSCALL_DEBUG
143 : KERNEL_LOCK();
144 : scdebug_ret(p, code, 0, child_retval);
145 : KERNEL_UNLOCK();
146 : #endif
147 :
148 0 : userret(p);
149 :
150 : #ifdef KTRACE
151 0 : if (KTRPOINT(p, KTR_SYSRET)) {
152 0 : KERNEL_LOCK();
153 0 : ktrsysret(p, code, 0, child_retval);
154 0 : KERNEL_UNLOCK();
155 0 : }
156 : #endif
157 0 : }
158 :
159 : /*
160 : * Do the specific processing necessary for an AST
161 : */
162 : static inline void
163 0 : mi_ast(struct proc *p, int resched)
164 : {
165 0 : if (p->p_flag & P_OWEUPC) {
166 0 : KERNEL_LOCK();
167 0 : ADDUPROF(p);
168 0 : KERNEL_UNLOCK();
169 0 : }
170 0 : if (resched)
171 0 : preempt();
172 :
173 : /*
174 : * XXX could move call to userret() here, but
175 : * hppa calls ast() in syscall return and sh calls
176 : * it after userret()
177 : */
178 0 : }
|