Bug Summary

File:amd64/amd64/ptrace_machdep.c
Warning:line 85, column 11
Copies out a struct with uncleared padding (>= 4 bytes)

Annotated Source Code

1/*-
2 * Copyright (c) 2011 Konstantin Belousov <[email protected]>
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 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: releng/11.0/sys/amd64/amd64/ptrace_machdep.c 285011 2015-07-01 16:37:03Z kib $")__asm__(".ident\t\"" "$FreeBSD: releng/11.0/sys/amd64/amd64/ptrace_machdep.c 285011 2015-07-01 16:37:03Z kib $"
"\"")
;
30
31#include "opt_compat.h"
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/malloc.h>
36#include <sys/proc.h>
37#include <sys/ptrace.h>
38#include <sys/sysent.h>
39#include <vm/vm.h>
40#include <vm/pmap.h>
41#include <machine/md_var.h>
42#include <machine/pcb.h>
43#include <machine/frame.h>
44#include <machine/vmparam.h>
45
46static int
47cpu_ptrace_xstate(struct thread *td, int req, void *addr, int data)
48{
49 struct ptrace_xstate_info info;
50 char *savefpu;
51 int error;
52
53 if (!use_xsave)
6
Assuming 'use_xsave' is not equal to 0
7
Taking false branch
54 return (EOPNOTSUPP45);
55
56 switch (req) {
8
Control jumps to 'case 68:' at line 78
57 case PT_GETXSTATE_OLD(64 + 2):
58 fpugetregs(td);
59 savefpu = (char *)(get_pcb_user_save_td(td) + 1);
60 error = copyout(savefpu, addr,
61 cpu_max_ext_state_size - sizeof(struct savefpu));
62 break;
63
64 case PT_SETXSTATE_OLD(64 + 3):
65 if (data > cpu_max_ext_state_size - sizeof(struct savefpu)) {
66 error = EINVAL22;
67 break;
68 }
69 savefpu = malloc(data, M_TEMP, M_WAITOK0x0002);
70 error = copyin(addr, savefpu, data);
71 if (error == 0) {
72 fpugetregs(td);
73 error = fpusetxstate(td, savefpu, data);
74 }
75 free(savefpu, M_TEMP);
76 break;
77
78 case PT_GETXSTATE_INFO(64 + 4):
79 if (data != sizeof(info)) {
9
Taking false branch
80 error = EINVAL22;
81 break;
82 }
83 info.xsave_len = cpu_max_ext_state_size;
84 info.xsave_mask = xsave_mask;
85 error = copyout(&info, addr, data);
10
Copies out a struct with uncleared padding (>= 4 bytes)
86 break;
87
88 case PT_GETXSTATE(64 + 5):
89 fpugetregs(td);
90 savefpu = (char *)(get_pcb_user_save_td(td));
91 error = copyout(savefpu, addr, cpu_max_ext_state_size);
92 break;
93
94 case PT_SETXSTATE(64 + 6):
95 if (data < sizeof(struct savefpu) ||
96 data > cpu_max_ext_state_size) {
97 error = EINVAL22;
98 break;
99 }
100 savefpu = malloc(data, M_TEMP, M_WAITOK0x0002);
101 error = copyin(addr, savefpu, data);
102 if (error == 0)
103 error = fpusetregs(td, (struct savefpu *)savefpu,
104 savefpu + sizeof(struct savefpu), data -
105 sizeof(struct savefpu));
106 free(savefpu, M_TEMP);
107 break;
108
109 default:
110 error = EINVAL22;
111 break;
112 }
113
114 return (error);
115}
116
117static void
118cpu_ptrace_setbase(struct thread *td, int req, register_t r)
119{
120
121 if (req == PT_SETFSBASE(64 + 8)) {
122 td->td_pcb->pcb_fsbase = r;
123 td->td_frame->tf_fs = _ufssel;
124 } else {
125 td->td_pcb->pcb_gsbase = r;
126 td->td_frame->tf_gs = _ugssel;
127 }
128 set_pcb_flags(td->td_pcb, PCB_FULL_IRET0x01);
129}
130
131#ifdef COMPAT_FREEBSD321
132#define PT_I386_GETXMMREGS(64 + 0) (PT_FIRSTMACH64 + 0)
133#define PT_I386_SETXMMREGS(64 + 1) (PT_FIRSTMACH64 + 1)
134
135static int
136cpu32_ptrace(struct thread *td, int req, void *addr, int data)
137{
138 struct savefpu *fpstate;
139 uint32_t r;
140 int error;
141
142 switch (req) {
143 case PT_I386_GETXMMREGS(64 + 0):
144 fpugetregs(td);
145 error = copyout(get_pcb_user_save_td(td), addr,
146 sizeof(*fpstate));
147 break;
148
149 case PT_I386_SETXMMREGS(64 + 1):
150 fpugetregs(td);
151 fpstate = get_pcb_user_save_td(td);
152 error = copyin(addr, fpstate, sizeof(*fpstate));
153 fpstate->sv_env.en_mxcsr &= cpu_mxcsr_mask;
154 break;
155
156 case PT_GETXSTATE_OLD(64 + 2):
157 case PT_SETXSTATE_OLD(64 + 3):
158 case PT_GETXSTATE_INFO(64 + 4):
159 case PT_GETXSTATE(64 + 5):
160 case PT_SETXSTATE(64 + 6):
161 error = cpu_ptrace_xstate(td, req, addr, data);
162 break;
163
164 case PT_GETFSBASE(64 + 7):
165 case PT_GETGSBASE(64 + 9):
166 if (!SV_PROC_FLAG(td->td_proc, SV_ILP32)((td->td_proc)->p_sysent->sv_flags & (0x000100))) {
167 error = EINVAL22;
168 break;
169 }
170 r = req == PT_GETFSBASE(64 + 7) ? td->td_pcb->pcb_fsbase :
171 td->td_pcb->pcb_gsbase;
172 error = copyout(&r, addr, sizeof(r));
173 break;
174
175 case PT_SETFSBASE(64 + 8):
176 case PT_SETGSBASE(64 + 10):
177 if (!SV_PROC_FLAG(td->td_proc, SV_ILP32)((td->td_proc)->p_sysent->sv_flags & (0x000100))) {
178 error = EINVAL22;
179 break;
180 }
181 error = copyin(addr, &r, sizeof(r));
182 if (error != 0)
183 break;
184 cpu_ptrace_setbase(td, req, r);
185 break;
186
187 default:
188 error = EINVAL22;
189 break;
190 }
191
192 return (error);
193}
194#endif
195
196int
197cpu_ptrace(struct thread *td, int req, void *addr, int data)
198{
199 register_t *r, rv;
200 int error;
201
202#ifdef COMPAT_FREEBSD321
203 if (SV_CURPROC_FLAG(SV_ILP32)((((__curthread())->td_proc))->p_sysent->sv_flags &
(0x000100))
)
1
Taking false branch
204 return (cpu32_ptrace(td, req, addr, data));
205#endif
206
207 /* Support old values of PT_GETXSTATE_OLD and PT_SETXSTATE_OLD. */
208 if (req == PT_FIRSTMACH64 + 0)
2
Taking false branch
209 req = PT_GETXSTATE_OLD(64 + 2);
210 if (req == PT_FIRSTMACH64 + 1)
3
Taking false branch
211 req = PT_SETXSTATE_OLD(64 + 3);
212
213 switch (req) {
4
Control jumps to 'case 68:' at line 216
214 case PT_GETXSTATE_OLD(64 + 2):
215 case PT_SETXSTATE_OLD(64 + 3):
216 case PT_GETXSTATE_INFO(64 + 4):
217 case PT_GETXSTATE(64 + 5):
218 case PT_SETXSTATE(64 + 6):
219 error = cpu_ptrace_xstate(td, req, addr, data);
5
Calling 'cpu_ptrace_xstate'
220 break;
221
222 case PT_GETFSBASE(64 + 7):
223 case PT_GETGSBASE(64 + 9):
224 r = req == PT_GETFSBASE(64 + 7) ? &td->td_pcb->pcb_fsbase :
225 &td->td_pcb->pcb_gsbase;
226 error = copyout(r, addr, sizeof(*r));
227 break;
228
229 case PT_SETFSBASE(64 + 8):
230 case PT_SETGSBASE(64 + 10):
231 error = copyin(addr, &rv, sizeof(rv));
232 if (error != 0)
233 break;
234 if (rv >= td->td_proc->p_sysent->sv_maxuser) {
235 error = EINVAL22;
236 break;
237 }
238 cpu_ptrace_setbase(td, req, rv);
239 break;
240
241 default:
242 error = EINVAL22;
243 break;
244 }
245
246 return (error);
247}