Commit 6b8bafd46a1395f37027b1038b9c97e1e436c930

Authored by Ji Luo
1 parent 6ef6024906

MA-13738 [Trusty] Fix null pointer error

Print the func name instead of null buffer.

Test: boot on imx8qm_mek.

Change-Id: I883a9cebb2981b7e2451c00ed27000baf40097bf
Signed-off-by: Ji Luo <ji.luo@nxp.com>

Showing 1 changed file with 1 additions and 1 deletions Inline Diff

lib/trusty/ql-tipc/rpmb_proxy.c
1 /* 1 /*
2 * Copyright (C) 2016 The Android Open Source Project 2 * Copyright (C) 2016 The Android Open Source Project
3 * 3 *
4 * Permission is hereby granted, free of charge, to any person 4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation 5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without 6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy, 7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies 8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is 9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions: 10 * furnished to do so, subject to the following conditions:
11 * 11 *
12 * The above copyright notice and this permission notice shall be 12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software. 13 * included in all copies or substantial portions of the Software.
14 * 14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE. 22 * SOFTWARE.
23 */ 23 */
24 24
25 #include <trusty/rpmb.h> 25 #include <trusty/rpmb.h>
26 #include <trusty/trusty_ipc.h> 26 #include <trusty/trusty_ipc.h>
27 #include <trusty/util.h> 27 #include <trusty/util.h>
28 #include <interface/storage/storage.h> 28 #include <interface/storage/storage.h>
29 29
30 #define LOCAL_LOG 0 30 #define LOCAL_LOG 0
31 31
32 static bool initialized; 32 static bool initialized;
33 /* Address of rpmb device */ 33 /* Address of rpmb device */
34 static void *proxy_rpmb; 34 static void *proxy_rpmb;
35 struct trusty_ipc_chan proxy_chan; 35 struct trusty_ipc_chan proxy_chan;
36 36
37 struct storage_msg req_msg; 37 struct storage_msg req_msg;
38 static uint8_t req_buf[4096]; 38 static uint8_t req_buf[4096];
39 static uint8_t read_buf[4096]; 39 static uint8_t read_buf[4096];
40 40
41 /* 41 /*
42 * Read RPMB request from storage service. Writes message to @msg 42 * Read RPMB request from storage service. Writes message to @msg
43 * and @req. 43 * and @req.
44 * 44 *
45 * @chan: proxy ipc channel 45 * @chan: proxy ipc channel
46 * @msg: address of storage message header 46 * @msg: address of storage message header
47 * @req: address of storage message request 47 * @req: address of storage message request
48 * @req_len: length of req in bytes 48 * @req_len: length of req in bytes
49 */ 49 */
50 static int proxy_read_request(struct trusty_ipc_chan *chan, 50 static int proxy_read_request(struct trusty_ipc_chan *chan,
51 struct storage_msg *msg, void *req, 51 struct storage_msg *msg, void *req,
52 size_t req_len) 52 size_t req_len)
53 { 53 {
54 int rc; 54 int rc;
55 55
56 struct trusty_ipc_iovec req_iovs[2] = { 56 struct trusty_ipc_iovec req_iovs[2] = {
57 { .base = msg, .len = sizeof(*msg) }, 57 { .base = msg, .len = sizeof(*msg) },
58 { .base = req, .len = req_len }, 58 { .base = req, .len = req_len },
59 }; 59 };
60 rc = trusty_ipc_recv(chan, req_iovs, 2, false); 60 rc = trusty_ipc_recv(chan, req_iovs, 2, false);
61 if (rc < 0) { 61 if (rc < 0) {
62 /* recv message failed */ 62 /* recv message failed */
63 trusty_error("%s: failed (%d) to recv request\n", __func__, rc); 63 trusty_error("%s: failed (%d) to recv request\n", __func__, rc);
64 return rc; 64 return rc;
65 } 65 }
66 66
67 if ((size_t)rc < sizeof(*msg)) { 67 if ((size_t)rc < sizeof(*msg)) {
68 /* malformed message */ 68 /* malformed message */
69 trusty_error("%s: malformed request (%zu)\n", __func__, (size_t)rc); 69 trusty_error("%s: malformed request (%zu)\n", __func__, (size_t)rc);
70 return TRUSTY_ERR_GENERIC; 70 return TRUSTY_ERR_GENERIC;
71 } 71 }
72 72
73 return rc - sizeof(*msg); /* return payload size */ 73 return rc - sizeof(*msg); /* return payload size */
74 } 74 }
75 75
76 /* 76 /*
77 * Send RPMB response to storage service 77 * Send RPMB response to storage service
78 * 78 *
79 * @chan: proxy ipc channel 79 * @chan: proxy ipc channel
80 * @msg: address of storage message header 80 * @msg: address of storage message header
81 * @resp: address of storage message response 81 * @resp: address of storage message response
82 * @resp_len: length of resp in bytes 82 * @resp_len: length of resp in bytes
83 */ 83 */
84 static int proxy_send_response(struct trusty_ipc_chan *chan, 84 static int proxy_send_response(struct trusty_ipc_chan *chan,
85 struct storage_msg *msg, void *resp, 85 struct storage_msg *msg, void *resp,
86 size_t resp_len) 86 size_t resp_len)
87 { 87 {
88 struct trusty_ipc_iovec resp_iovs[2] = { 88 struct trusty_ipc_iovec resp_iovs[2] = {
89 { .base = msg, .len = sizeof(*msg) }, 89 { .base = msg, .len = sizeof(*msg) },
90 { .base = resp, .len = resp_len } 90 { .base = resp, .len = resp_len }
91 }; 91 };
92 92
93 msg->cmd |= STORAGE_RESP_BIT; 93 msg->cmd |= STORAGE_RESP_BIT;
94 return trusty_ipc_send(chan, resp_iovs, resp ? 2 : 1, false); 94 return trusty_ipc_send(chan, resp_iovs, resp ? 2 : 1, false);
95 } 95 }
96 96
97 /* 97 /*
98 * Executes the RPMB request at @r, sends response to storage service. 98 * Executes the RPMB request at @r, sends response to storage service.
99 * 99 *
100 * @chan: proxy ipc channel 100 * @chan: proxy ipc channel
101 * @msg: address of storage message header 101 * @msg: address of storage message header
102 * @r: address of storage message request 102 * @r: address of storage message request
103 * @req_len: length of resp in bytes 103 * @req_len: length of resp in bytes
104 */ 104 */
105 static int proxy_handle_rpmb(struct trusty_ipc_chan *chan, 105 static int proxy_handle_rpmb(struct trusty_ipc_chan *chan,
106 struct storage_msg *msg, const void *r, 106 struct storage_msg *msg, const void *r,
107 size_t req_len) 107 size_t req_len)
108 { 108 {
109 int rc; 109 int rc;
110 size_t exp_len; 110 size_t exp_len;
111 const void *write_data = NULL; 111 const void *write_data = NULL;
112 const void *rel_write_data = NULL; 112 const void *rel_write_data = NULL;
113 const struct storage_rpmb_send_req *req = r; 113 const struct storage_rpmb_send_req *req = r;
114 114
115 if (req_len < sizeof(req)) { 115 if (req_len < sizeof(req)) {
116 msg->result = STORAGE_ERR_NOT_VALID; 116 msg->result = STORAGE_ERR_NOT_VALID;
117 goto err_response; 117 goto err_response;
118 } 118 }
119 119
120 exp_len = sizeof(*req) + req->reliable_write_size + req->write_size; 120 exp_len = sizeof(*req) + req->reliable_write_size + req->write_size;
121 if (req_len != exp_len) { 121 if (req_len != exp_len) {
122 trusty_error( 122 trusty_error(
123 "%s: malformed rpmb request: invalid length (%zu != %zu)\n", 123 "%s: malformed rpmb request: invalid length (%zu != %zu)\n",
124 __func__, req_len, exp_len); 124 __func__, req_len, exp_len);
125 msg->result = STORAGE_ERR_NOT_VALID; 125 msg->result = STORAGE_ERR_NOT_VALID;
126 goto err_response; 126 goto err_response;
127 } 127 }
128 128
129 if (req->reliable_write_size) { 129 if (req->reliable_write_size) {
130 if ((req->reliable_write_size % MMC_BLOCK_SIZE) != 0) { 130 if ((req->reliable_write_size % MMC_BLOCK_SIZE) != 0) {
131 trusty_error("%s: invalid reliable write size %u\n", __func__, 131 trusty_error("%s: invalid reliable write size %u\n", __func__,
132 req->reliable_write_size); 132 req->reliable_write_size);
133 msg->result = STORAGE_ERR_NOT_VALID; 133 msg->result = STORAGE_ERR_NOT_VALID;
134 goto err_response; 134 goto err_response;
135 } 135 }
136 rel_write_data = req->payload; 136 rel_write_data = req->payload;
137 } 137 }
138 138
139 if (req->write_size) { 139 if (req->write_size) {
140 if ((req->write_size % MMC_BLOCK_SIZE) != 0) { 140 if ((req->write_size % MMC_BLOCK_SIZE) != 0) {
141 trusty_error("%: invalid write size %u\n", __func__, 141 trusty_error("%: invalid write size %u\n", __func__,
142 req->write_size); 142 req->write_size);
143 msg->result = STORAGE_ERR_NOT_VALID; 143 msg->result = STORAGE_ERR_NOT_VALID;
144 goto err_response; 144 goto err_response;
145 } 145 }
146 write_data = req->payload + req->reliable_write_size; 146 write_data = req->payload + req->reliable_write_size;
147 } 147 }
148 148
149 if (req->read_size) { 149 if (req->read_size) {
150 if (req->read_size % MMC_BLOCK_SIZE != 0 || 150 if (req->read_size % MMC_BLOCK_SIZE != 0 ||
151 req->read_size > sizeof(read_buf)) { 151 req->read_size > sizeof(read_buf)) {
152 trusty_error("%s: invalid read size %u\n", __func__, 152 trusty_error("%s: invalid read size %u\n", __func__,
153 req->read_size); 153 req->read_size);
154 msg->result = STORAGE_ERR_NOT_VALID; 154 msg->result = STORAGE_ERR_NOT_VALID;
155 goto err_response; 155 goto err_response;
156 } 156 }
157 } 157 }
158 158
159 /* execute rpmb command */ 159 /* execute rpmb command */
160 rc = rpmb_storage_send(proxy_rpmb, 160 rc = rpmb_storage_send(proxy_rpmb,
161 rel_write_data, req->reliable_write_size, 161 rel_write_data, req->reliable_write_size,
162 write_data, req->write_size, 162 write_data, req->write_size,
163 read_buf, req->read_size); 163 read_buf, req->read_size);
164 if (rc) { 164 if (rc) {
165 trusty_error("%s: rpmb_storage_send failed: %d\n", __func__, rc); 165 trusty_error("%s: rpmb_storage_send failed: %d\n", __func__, rc);
166 msg->result = STORAGE_ERR_GENERIC; 166 msg->result = STORAGE_ERR_GENERIC;
167 goto err_response; 167 goto err_response;
168 } 168 }
169 169
170 if (msg->flags & STORAGE_MSG_FLAG_POST_COMMIT) { 170 if (msg->flags & STORAGE_MSG_FLAG_POST_COMMIT) {
171 /* 171 /*
172 * Nothing todo for post msg commit request as MMC_IOC_MULTI_CMD 172 * Nothing todo for post msg commit request as MMC_IOC_MULTI_CMD
173 * is fully synchronous in this implementation. 173 * is fully synchronous in this implementation.
174 */ 174 */
175 } 175 }
176 176
177 msg->result = STORAGE_NO_ERROR; 177 msg->result = STORAGE_NO_ERROR;
178 return proxy_send_response(chan, msg, read_buf, req->read_size); 178 return proxy_send_response(chan, msg, read_buf, req->read_size);
179 179
180 err_response: 180 err_response:
181 return proxy_send_response(chan, msg, NULL, 0); 181 return proxy_send_response(chan, msg, NULL, 0);
182 } 182 }
183 183
184 /* 184 /*
185 * Handles storage request. 185 * Handles storage request.
186 * 186 *
187 * @chan: proxy ipc channel 187 * @chan: proxy ipc channel
188 * @msg: address of storage message header 188 * @msg: address of storage message header
189 * @req: address of storage message request 189 * @req: address of storage message request
190 * @req_len: length of resp in bytes 190 * @req_len: length of resp in bytes
191 */ 191 */
192 static int proxy_handle_req(struct trusty_ipc_chan *chan, 192 static int proxy_handle_req(struct trusty_ipc_chan *chan,
193 struct storage_msg *msg, const void *req, 193 struct storage_msg *msg, const void *req,
194 size_t req_len) 194 size_t req_len)
195 { 195 {
196 int rc; 196 int rc;
197 197
198 if (msg->flags & STORAGE_MSG_FLAG_PRE_COMMIT) { 198 if (msg->flags & STORAGE_MSG_FLAG_PRE_COMMIT) {
199 /* nothing to do */ 199 /* nothing to do */
200 } 200 }
201 201
202 switch (msg->cmd) { 202 switch (msg->cmd) {
203 case STORAGE_RPMB_SEND: 203 case STORAGE_RPMB_SEND:
204 rc = proxy_handle_rpmb(chan, msg, req, req_len); 204 rc = proxy_handle_rpmb(chan, msg, req, req_len);
205 break; 205 break;
206 206
207 case STORAGE_FILE_DELETE: 207 case STORAGE_FILE_DELETE:
208 case STORAGE_FILE_OPEN: 208 case STORAGE_FILE_OPEN:
209 case STORAGE_FILE_CLOSE: 209 case STORAGE_FILE_CLOSE:
210 case STORAGE_FILE_WRITE: 210 case STORAGE_FILE_WRITE:
211 case STORAGE_FILE_READ: 211 case STORAGE_FILE_READ:
212 case STORAGE_FILE_GET_SIZE: 212 case STORAGE_FILE_GET_SIZE:
213 case STORAGE_FILE_SET_SIZE: 213 case STORAGE_FILE_SET_SIZE:
214 /* Bulk filesystem is not supported */ 214 /* Bulk filesystem is not supported */
215 msg->result = STORAGE_ERR_UNIMPLEMENTED; 215 msg->result = STORAGE_ERR_UNIMPLEMENTED;
216 rc = proxy_send_response(chan, msg, NULL, 0); 216 rc = proxy_send_response(chan, msg, NULL, 0);
217 break; 217 break;
218 218
219 default: 219 default:
220 msg->result = STORAGE_ERR_UNIMPLEMENTED; 220 msg->result = STORAGE_ERR_UNIMPLEMENTED;
221 rc = proxy_send_response(chan, msg, NULL, 0); 221 rc = proxy_send_response(chan, msg, NULL, 0);
222 } 222 }
223 223
224 return rc; 224 return rc;
225 } 225 }
226 226
227 /* 227 /*
228 * Invalidates @chan on hangup event 228 * Invalidates @chan on hangup event
229 * 229 *
230 * @chan: proxy ipc channel 230 * @chan: proxy ipc channel
231 */ 231 */
232 static int proxy_on_disconnect(struct trusty_ipc_chan *chan) 232 static int proxy_on_disconnect(struct trusty_ipc_chan *chan)
233 { 233 {
234 trusty_assert(chan); 234 trusty_assert(chan);
235 235
236 trusty_debug("%s: closed by peer\n", __func__); 236 trusty_debug("%s: closed by peer\n", __func__);
237 chan->handle = INVALID_IPC_HANDLE; 237 chan->handle = INVALID_IPC_HANDLE;
238 return TRUSTY_EVENT_HANDLED; 238 return TRUSTY_EVENT_HANDLED;
239 } 239 }
240 240
241 /* 241 /*
242 * Handles received storage message on message event 242 * Handles received storage message on message event
243 * 243 *
244 * @chan: proxy ipc channel 244 * @chan: proxy ipc channel
245 */ 245 */
246 static int proxy_on_message(struct trusty_ipc_chan *chan) 246 static int proxy_on_message(struct trusty_ipc_chan *chan)
247 { 247 {
248 int rc; 248 int rc;
249 249
250 trusty_assert(chan); 250 trusty_assert(chan);
251 251
252 /* read request */ 252 /* read request */
253 rc = proxy_read_request(chan, &req_msg, req_buf, sizeof(req_buf)); 253 rc = proxy_read_request(chan, &req_msg, req_buf, sizeof(req_buf));
254 if (rc < 0) { 254 if (rc < 0) {
255 trusty_error("%s: failed (%d) to read request\n", __func__, rc); 255 trusty_error("%s: failed (%d) to read request\n", __func__, rc);
256 trusty_ipc_close(chan); 256 trusty_ipc_close(chan);
257 return rc; 257 return rc;
258 } 258 }
259 259
260 /* handle it and send reply */ 260 /* handle it and send reply */
261 rc = proxy_handle_req(chan, &req_msg, req_buf, rc); 261 rc = proxy_handle_req(chan, &req_msg, req_buf, rc);
262 if (rc < 0) { 262 if (rc < 0) {
263 trusty_error("%s: failed (%d) to handle request\n", __func__, rc); 263 trusty_error("%s: failed (%d) to handle request\n", __func__, rc);
264 trusty_ipc_close(chan); 264 trusty_ipc_close(chan);
265 return rc; 265 return rc;
266 } 266 }
267 267
268 return TRUSTY_EVENT_HANDLED; 268 return TRUSTY_EVENT_HANDLED;
269 } 269 }
270 270
271 static struct trusty_ipc_ops proxy_ops = { 271 static struct trusty_ipc_ops proxy_ops = {
272 .on_message = proxy_on_message, 272 .on_message = proxy_on_message,
273 .on_disconnect = proxy_on_disconnect, 273 .on_disconnect = proxy_on_disconnect,
274 }; 274 };
275 275
276 /* 276 /*
277 * Initialize RPMB storage proxy 277 * Initialize RPMB storage proxy
278 */ 278 */
279 int rpmb_storage_proxy_init(struct trusty_ipc_dev *dev, void *rpmb_dev) 279 int rpmb_storage_proxy_init(struct trusty_ipc_dev *dev, void *rpmb_dev)
280 { 280 {
281 int rc; 281 int rc;
282 282
283 trusty_assert(dev); 283 trusty_assert(dev);
284 trusty_assert(!initialized); 284 trusty_assert(!initialized);
285 285
286 /* attach rpmb device */ 286 /* attach rpmb device */
287 proxy_rpmb = rpmb_dev; 287 proxy_rpmb = rpmb_dev;
288 288
289 /* init ipc channel */ 289 /* init ipc channel */
290 trusty_ipc_chan_init(&proxy_chan, dev); 290 trusty_ipc_chan_init(&proxy_chan, dev);
291 291
292 /* connect to proxy service and wait for connect to complete */ 292 /* connect to proxy service and wait for connect to complete */
293 rc = trusty_ipc_connect(&proxy_chan, STORAGE_DISK_PROXY_PORT, true); 293 rc = trusty_ipc_connect(&proxy_chan, STORAGE_DISK_PROXY_PORT, true);
294 if (rc < 0) { 294 if (rc < 0) {
295 trusty_error("%s: failed (%d) to connect to '%s'\n", __func__, rc, 295 trusty_error("%s: failed (%d) to connect to '%s'\n", __func__, rc,
296 STORAGE_DISK_PROXY_PORT); 296 STORAGE_DISK_PROXY_PORT);
297 return rc; 297 return rc;
298 } 298 }
299 299
300 /* override default ops */ 300 /* override default ops */
301 proxy_chan.ops = &proxy_ops; 301 proxy_chan.ops = &proxy_ops;
302 302
303 do { 303 do {
304 /* Check for RPMB events */ 304 /* Check for RPMB events */
305 rc = trusty_ipc_poll_for_event(proxy_chan.dev); 305 rc = trusty_ipc_poll_for_event(proxy_chan.dev);
306 if (rc < 0) { 306 if (rc < 0) {
307 trusty_error("%s: failed (%d) to get rpmb event\n", __func__, rc); 307 trusty_error("%s: failed (%d) to get rpmb event\n", __func__, rc);
308 return rc; 308 return rc;
309 } 309 }
310 310
311 if (proxy_chan.handle == INVALID_IPC_HANDLE) { 311 if (proxy_chan.handle == INVALID_IPC_HANDLE) {
312 trusty_error("%s: unexpected proxy channel close\n"); 312 trusty_error("%s: unexpected proxy channel close\n", __func__);
313 return TRUSTY_ERR_CHANNEL_CLOSED; 313 return TRUSTY_ERR_CHANNEL_CLOSED;
314 } 314 }
315 } 315 }
316 while (rc != TRUSTY_EVENT_NONE); 316 while (rc != TRUSTY_EVENT_NONE);
317 317
318 /* mark as initialized */ 318 /* mark as initialized */
319 initialized = true; 319 initialized = true;
320 320
321 return TRUSTY_ERR_NONE; 321 return TRUSTY_ERR_NONE;
322 } 322 }
323 323
324 void rpmb_storage_proxy_shutdown(struct trusty_ipc_dev *dev) 324 void rpmb_storage_proxy_shutdown(struct trusty_ipc_dev *dev)
325 { 325 {
326 trusty_assert(initialized); 326 trusty_assert(initialized);
327 327
328 /* close channel */ 328 /* close channel */
329 trusty_ipc_close(&proxy_chan); 329 trusty_ipc_close(&proxy_chan);
330 330
331 initialized = false; 331 initialized = false;
332 } 332 }
333 333