6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
28
29 #include <sys/types.h>
30 #include <sys/sysmacros.h>
31 #include <sys/param.h>
32 #include <sys/vmparam.h>
33 #include <sys/systm.h>
34 #include <sys/cred.h>
35 #include <sys/user.h>
36 #include <sys/proc.h>
37 #include <sys/conf.h>
38 #include <sys/tuneable.h>
39 #include <sys/cpuvar.h>
40 #include <sys/archsystm.h>
41 #include <sys/vmem.h>
42 #include <vm/seg_kmem.h>
43 #include <sys/errno.h>
44 #include <sys/cmn_err.h>
45 #include <sys/debug.h>
291 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
292 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
293 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
294 };
295
296 uchar_t bcd_to_byte[256] = { /* CSTYLED */
297 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
298 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0,
299 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, 0, 0, 0, 0, 0,
300 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0,
301 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 0, 0, 0, 0, 0, 0,
302 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 0, 0, 0, 0, 0, 0,
303 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 0, 0, 0, 0, 0, 0,
304 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, 0, 0, 0, 0,
305 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 0, 0, 0, 0, 0, 0,
306 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
307 };
308
309 /*
310 * Hot-patch a single instruction in the kernel's text.
311 * If you want to patch multiple instructions you must
312 * arrange to do it so that all intermediate stages are
313 * sane -- we don't stop other cpus while doing this.
314 * Size must be 1, 2, or 4 bytes with iaddr aligned accordingly.
315 */
316 void
317 hot_patch_kernel_text(caddr_t iaddr, uint32_t new_instr, uint_t size)
318 {
319 caddr_t vaddr;
320 page_t **ppp;
321 uintptr_t off = (uintptr_t)iaddr & PAGEOFFSET;
322
323 vaddr = vmem_alloc(heap_arena, PAGESIZE, VM_SLEEP);
324
325 (void) as_pagelock(&kas, &ppp, iaddr - off, PAGESIZE, S_WRITE);
326
327 hat_devload(kas.a_hat, vaddr, PAGESIZE,
328 hat_getpfnum(kas.a_hat, iaddr - off),
329 PROT_READ | PROT_WRITE, HAT_LOAD_LOCK | HAT_LOAD_NOCONSIST);
330
331 switch (size) {
332 case 1:
333 *(uint8_t *)(vaddr + off) = new_instr;
334 break;
335 case 2:
336 *(uint16_t *)(vaddr + off) = new_instr;
337 break;
338 case 4:
339 *(uint32_t *)(vaddr + off) = new_instr;
340 break;
341 default:
342 panic("illegal hot-patch");
343 }
344
345 membar_enter();
346 sync_icache(vaddr + off, size);
347 sync_icache(iaddr, size);
348 as_pageunlock(&kas, ppp, iaddr - off, PAGESIZE, S_WRITE);
349 hat_unload(kas.a_hat, vaddr, PAGESIZE, HAT_UNLOAD_UNLOCK);
350 vmem_free(heap_arena, vaddr, PAGESIZE);
351 }
352
353 /*
354 * Routine to report an attempt to execute non-executable data. If the
355 * address executed lies in the stack, explicitly say so.
356 */
357 void
358 report_stack_exec(proc_t *p, caddr_t addr)
359 {
360 if (!noexec_user_stack_log)
361 return;
362
363 if (addr < p->p_usrstack && addr >= (p->p_usrstack - p->p_stksize)) {
364 cmn_err(CE_NOTE, "%s[%d] attempt to execute code "
365 "on stack by uid %d", p->p_user.u_comm,
366 p->p_pid, crgetruid(p->p_cred));
367 } else {
368 cmn_err(CE_NOTE, "%s[%d] attempt to execute non-executable "
369 "data at 0x%p by uid %d", p->p_user.u_comm,
370 p->p_pid, (void *) addr, crgetruid(p->p_cred));
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * Copyright 2019 Joyent, Inc.
28 */
29
30 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
31 /* All Rights Reserved */
32
33 #include <sys/types.h>
34 #include <sys/sysmacros.h>
35 #include <sys/param.h>
36 #include <sys/vmparam.h>
37 #include <sys/systm.h>
38 #include <sys/cred.h>
39 #include <sys/user.h>
40 #include <sys/proc.h>
41 #include <sys/conf.h>
42 #include <sys/tuneable.h>
43 #include <sys/cpuvar.h>
44 #include <sys/archsystm.h>
45 #include <sys/vmem.h>
46 #include <vm/seg_kmem.h>
47 #include <sys/errno.h>
48 #include <sys/cmn_err.h>
49 #include <sys/debug.h>
295 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
296 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
297 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
298 };
299
300 uchar_t bcd_to_byte[256] = { /* CSTYLED */
301 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
302 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0,
303 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, 0, 0, 0, 0, 0,
304 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0,
305 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 0, 0, 0, 0, 0, 0,
306 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 0, 0, 0, 0, 0, 0,
307 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 0, 0, 0, 0, 0, 0,
308 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 0, 0, 0, 0, 0, 0,
309 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 0, 0, 0, 0, 0, 0,
310 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
311 };
312
313 /*
314 * Hot-patch a single instruction in the kernel's text.
315 *
316 * If you want to patch multiple instructions you must arrange to do it so that
317 * all intermediate stages are sane -- we don't stop other cpus while doing
318 * this.
319 *
320 * Size must be 1, 2, or 4 bytes with iaddr aligned accordingly.
321 *
322 * The instruction itself might straddle a page boundary, so we have to account
323 * for that.
324 */
325 void
326 hot_patch_kernel_text(caddr_t iaddr, uint32_t new_instr, uint_t size)
327 {
328 const uintptr_t pageoff = (uintptr_t)iaddr & PAGEOFFSET;
329 const boolean_t straddles = (pageoff + size > PAGESIZE);
330 const size_t mapsize = straddles ? PAGESIZE * 2 : PAGESIZE;
331 caddr_t ipageaddr = iaddr - pageoff;
332 caddr_t vaddr;
333 page_t **ppp;
334
335 vaddr = vmem_alloc(heap_arena, mapsize, VM_SLEEP);
336
337 (void) as_pagelock(&kas, &ppp, ipageaddr, mapsize, S_WRITE);
338
339 hat_devload(kas.a_hat, vaddr, PAGESIZE,
340 hat_getpfnum(kas.a_hat, ipageaddr), PROT_READ | PROT_WRITE,
341 HAT_LOAD_LOCK | HAT_LOAD_NOCONSIST);
342
343 if (straddles) {
344 hat_devload(kas.a_hat, vaddr + PAGESIZE, PAGESIZE,
345 hat_getpfnum(kas.a_hat, ipageaddr + PAGESIZE),
346 PROT_READ | PROT_WRITE, HAT_LOAD_LOCK | HAT_LOAD_NOCONSIST);
347 }
348
349 switch (size) {
350 case 1:
351 *(uint8_t *)(vaddr + pageoff) = new_instr;
352 break;
353 case 2:
354 *(uint16_t *)(vaddr + pageoff) = new_instr;
355 break;
356 case 4:
357 *(uint32_t *)(vaddr + pageoff) = new_instr;
358 break;
359 default:
360 panic("illegal hot-patch");
361 }
362
363 membar_enter();
364 sync_icache(vaddr + pageoff, size);
365 sync_icache(iaddr, size);
366 as_pageunlock(&kas, ppp, ipageaddr, mapsize, S_WRITE);
367 hat_unload(kas.a_hat, vaddr, mapsize, HAT_UNLOAD_UNLOCK);
368 vmem_free(heap_arena, vaddr, mapsize);
369 }
370
371 /*
372 * Routine to report an attempt to execute non-executable data. If the
373 * address executed lies in the stack, explicitly say so.
374 */
375 void
376 report_stack_exec(proc_t *p, caddr_t addr)
377 {
378 if (!noexec_user_stack_log)
379 return;
380
381 if (addr < p->p_usrstack && addr >= (p->p_usrstack - p->p_stksize)) {
382 cmn_err(CE_NOTE, "%s[%d] attempt to execute code "
383 "on stack by uid %d", p->p_user.u_comm,
384 p->p_pid, crgetruid(p->p_cred));
385 } else {
386 cmn_err(CE_NOTE, "%s[%d] attempt to execute non-executable "
387 "data at 0x%p by uid %d", p->p_user.u_comm,
388 p->p_pid, (void *) addr, crgetruid(p->p_cred));
|