Mon Aug 10 09:38:48 2020 UTC ()
Forbid to set odd address to PC in process_write_regs() and process_set_pc().

Otherwise, address error occurs in kernel at rte instruction when returning
to the user level.

Found by tests/lib/libc/t_ptrace_*:access_regs_set_unaligned_pc_0x[137].


(rin)
diff -r1.30 -r1.31 src/sys/arch/m68k/m68k/process_machdep.c

cvs diff -r1.30 -r1.31 src/sys/arch/m68k/m68k/process_machdep.c (expand / switch to unified diff)

--- src/sys/arch/m68k/m68k/process_machdep.c 2014/01/04 00:10:02 1.30
+++ src/sys/arch/m68k/m68k/process_machdep.c 2020/08/10 09:38:48 1.31
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: process_machdep.c,v 1.30 2014/01/04 00:10:02 dsl Exp $ */ 1/* $NetBSD: process_machdep.c,v 1.31 2020/08/10 09:38:48 rin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1993 Christopher G. Demetriou 4 * Copyright (c) 1993 Christopher G. Demetriou
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -43,27 +43,27 @@ @@ -43,27 +43,27 @@
43 * Update the current register set from the passed in regs 43 * Update the current register set from the passed in regs
44 * structure. Take care to avoid clobbering special CPU 44 * structure. Take care to avoid clobbering special CPU
45 * registers or privileged bits in the PSL. 45 * registers or privileged bits in the PSL.
46 * The process is stopped at the time write_regs is called. 46 * The process is stopped at the time write_regs is called.
47 * 47 *
48 * process_sstep(proc) 48 * process_sstep(proc)
49 * Arrange for the process to trap after executing a single instruction. 49 * Arrange for the process to trap after executing a single instruction.
50 * 50 *
51 * process_set_pc(proc) 51 * process_set_pc(proc)
52 * Set the process's program counter. 52 * Set the process's program counter.
53 */ 53 */
54 54
55#include <sys/cdefs.h> 55#include <sys/cdefs.h>
56__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.30 2014/01/04 00:10:02 dsl Exp $"); 56__KERNEL_RCSID(0, "$NetBSD: process_machdep.c,v 1.31 2020/08/10 09:38:48 rin Exp $");
57 57
58#include <sys/param.h> 58#include <sys/param.h>
59#include <sys/systm.h> 59#include <sys/systm.h>
60#include <sys/kernel.h> 60#include <sys/kernel.h>
61#include <sys/proc.h> 61#include <sys/proc.h>
62#include <sys/vnode.h> 62#include <sys/vnode.h>
63#include <sys/ptrace.h> 63#include <sys/ptrace.h>
64 64
65#include <machine/frame.h> 65#include <machine/frame.h>
66#include <machine/pcb.h> 66#include <machine/pcb.h>
67#include <machine/psl.h> 67#include <machine/psl.h>
68 68
69static inline struct frame * 69static inline struct frame *
@@ -104,33 +104,30 @@ process_read_fpregs(struct lwp *l, struc @@ -104,33 +104,30 @@ process_read_fpregs(struct lwp *l, struc
104 regs->r_fpcr = frame->fpf_fpcr; 104 regs->r_fpcr = frame->fpf_fpcr;
105 regs->r_fpsr = frame->fpf_fpsr; 105 regs->r_fpsr = frame->fpf_fpsr;
106 regs->r_fpiar = frame->fpf_fpiar; 106 regs->r_fpiar = frame->fpf_fpiar;
107 107
108 return 0; 108 return 0;
109} 109}
110 110
111int 111int
112process_write_regs(struct lwp *l, const struct reg *regs) 112process_write_regs(struct lwp *l, const struct reg *regs)
113{ 113{
114 struct frame *frame = process_frame(l); 114 struct frame *frame = process_frame(l);
115 115
116 /* 116 /*
117 * in the hp300 machdep.c _write_regs, PC alignment wasn't 117 * Avoid kernel address error at rte instruction.
118 * checked. If an odd address is placed in the PC and the 
119 * program is allowed to run, it will cause an Address Error 
120 * which will be transmitted to the process by a SIGBUS. 
121 * No reasonable debugger would let this happen, but 
122 * it's not our problem. 
123 */ 118 */
 119 if (regs->r_pc & 1)
 120 return EINVAL;
124 121
125 /* 122 /*
126 * XXX 123 * XXX
127 * in hp300 machdep.c, it just cleared/set these bits 124 * in hp300 machdep.c, it just cleared/set these bits
128 * automatically. here, we barf. well-written programs 125 * automatically. here, we barf. well-written programs
129 * shouldn't munge them. 126 * shouldn't munge them.
130 */ 127 */
131 if ((regs->r_sr & PSL_USERCLR) != 0 || 128 if ((regs->r_sr & PSL_USERCLR) != 0 ||
132 (regs->r_sr & PSL_USERSET) != PSL_USERSET) 129 (regs->r_sr & PSL_USERSET) != PSL_USERSET)
133 return EPERM; 130 return EPERM;
134 131
135 memcpy(frame->f_regs, regs->r_regs, sizeof(frame->f_regs)); 132 memcpy(frame->f_regs, regs->r_regs, sizeof(frame->f_regs));
136 frame->f_sr = regs->r_sr; 133 frame->f_sr = regs->r_sr;
@@ -161,25 +158,21 @@ process_sstep(struct lwp *l, int sstep) @@ -161,25 +158,21 @@ process_sstep(struct lwp *l, int sstep)
161 frame->f_sr |= PSL_T; 158 frame->f_sr |= PSL_T;
162 else 159 else
163 frame->f_sr &= ~PSL_T; 160 frame->f_sr &= ~PSL_T;
164 161
165 return 0; 162 return 0;
166} 163}
167 164
168int 165int
169process_set_pc(struct lwp *l, void *addr) 166process_set_pc(struct lwp *l, void *addr)
170{ 167{
171 struct frame *frame = process_frame(l); 168 struct frame *frame = process_frame(l);
172 169
173 /* 170 /*
174 * in the hp300 machdep.c _set_pc, PC alignment is guaranteed 171 * Avoid kernel address error at rte instruction.
175 * by chopping off the low order bit of the new pc. 
176 * If an odd address was placed in the PC and the program 
177 * is allowed to run, it will cause an Address Error 
178 * which will be transmitted to the process by a SIGBUS. 
179 * No reasonable debugger would let this happen, but 
180 * it's not our problem. 
181 */ 172 */
 173 if ((u_int)addr & 1)
 174 return EINVAL;
182 frame->f_pc = (u_int)addr; 175 frame->f_pc = (u_int)addr;
183 176
184 return 0; 177 return 0;
185} 178}