Skip to content

Commit 1d9e35c

Browse files
Stephen CraneAndroid (Google) Code Review
authored andcommitted
Merge changes Iecc0d468,I928ddebc,Iade322a2 into sc-qpr1-dev
* changes: [storageproxyd] Dump binary buffers to log instead of stderr storageproxyd: Add logging of failed RPMB transactions storageproxyd: Add file handle param to debug buffer print
2 parents d638319 + f647221 commit 1d9e35c

1 file changed

Lines changed: 165 additions & 13 deletions

File tree

trusty/storage/proxy/rpmb.c

Lines changed: 165 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616

1717
#include <errno.h>
1818
#include <fcntl.h>
19+
#include <scsi/scsi.h>
20+
#include <scsi/scsi_proto.h>
1921
#include <scsi/sg.h>
22+
#include <stdbool.h>
2023
#include <stdint.h>
2124
#include <stdio.h>
2225
#include <stdlib.h>
@@ -104,21 +107,62 @@ static enum dev_type dev_type = UNKNOWN_RPMB;
104107

105108
static const char* UFS_WAKE_LOCK_NAME = "ufs_seq_wakelock";
106109

107-
#ifdef RPMB_DEBUG
108-
109-
static void print_buf(const char* prefix, const uint8_t* buf, size_t size) {
110+
/**
111+
* log_buf - Log a byte buffer to the android log.
112+
* @priority: One of ANDROID_LOG_* priority levels from android_LogPriority in
113+
* android/log.h
114+
* @prefix: A null-terminated string that identifies this buffer. Must be less
115+
* than 128 bytes.
116+
* @buf: Buffer to dump.
117+
* @size: Length of @buf in bytes.
118+
*/
119+
#define LOG_BUF_SIZE 256
120+
static int log_buf(int priority, const char* prefix, const uint8_t* buf, size_t size) {
121+
int rc;
110122
size_t i;
123+
char line[LOG_BUF_SIZE] = {0};
124+
char* cur = line;
111125

112-
printf("%s @%p [%zu]", prefix, buf, size);
126+
rc = snprintf(line, LOG_BUF_SIZE, "%s @%p [%zu]", prefix, buf, size);
127+
if (rc < 0 || rc >= LOG_BUF_SIZE) {
128+
goto err;
129+
}
130+
cur += rc;
113131
for (i = 0; i < size; i++) {
114-
if (i && i % 32 == 0) printf("\n%*s", (int)strlen(prefix), "");
115-
printf(" %02x", buf[i]);
132+
if (i % 32 == 0) {
133+
/*
134+
* Flush the line out to the log after we have printed 32 bytes
135+
* (also flushes the header line on the first iteration and sets up
136+
* for printing the buffer itself)
137+
*/
138+
LOG_PRI(priority, LOG_TAG, "%s", line);
139+
memset(line, 0, LOG_BUF_SIZE);
140+
cur = line;
141+
/* Shift output over by the length of the prefix */
142+
rc = snprintf(line, LOG_BUF_SIZE, "%*s", (int)strlen(prefix), "");
143+
if (rc < 0 || rc >= LOG_BUF_SIZE) {
144+
goto err;
145+
}
146+
cur += rc;
147+
}
148+
rc = snprintf(cur, LOG_BUF_SIZE - (cur - line), "%02x ", buf[i]);
149+
if (rc < 0 || rc >= LOG_BUF_SIZE - (cur - line)) {
150+
goto err;
151+
}
152+
cur += rc;
116153
}
117-
printf("\n");
118-
fflush(stdout);
119-
}
154+
LOG_PRI(priority, LOG_TAG, "%s", line);
120155

121-
#endif
156+
return 0;
157+
158+
err:
159+
if (rc < 0) {
160+
return rc;
161+
} else {
162+
ALOGE("log_buf prefix was too long");
163+
return -1;
164+
}
165+
}
122166

123167
static void set_sg_io_hdr(sg_io_hdr_t* io_hdrp, int dxfer_direction, unsigned char cmd_len,
124168
unsigned char mx_sb_len, unsigned int dxfer_len, void* dxferp,
@@ -135,6 +179,111 @@ static void set_sg_io_hdr(sg_io_hdr_t* io_hdrp, int dxfer_direction, unsigned ch
135179
io_hdrp->timeout = TIMEOUT;
136180
}
137181

182+
/* Returns false if the sense data was valid and no errors were present */
183+
static bool check_scsi_sense(const uint8_t* sense_buf, size_t len) {
184+
uint8_t response_code = 0;
185+
uint8_t sense_key = 0;
186+
uint8_t additional_sense_code = 0;
187+
uint8_t additional_sense_code_qualifier = 0;
188+
uint8_t additional_length = 0;
189+
190+
if (!sense_buf || len == 0) {
191+
ALOGE("Invalid SCSI sense buffer, length: %zu\n", len);
192+
return false;
193+
}
194+
195+
response_code = 0x7f & sense_buf[0];
196+
197+
if (response_code < 0x70 || response_code > 0x73) {
198+
ALOGE("Invalid SCSI sense response code: %hhu\n", response_code);
199+
return false;
200+
}
201+
202+
if (response_code >= 0x72) {
203+
/* descriptor format, SPC-6 4.4.2 */
204+
if (len > 1) {
205+
sense_key = 0xf & sense_buf[1];
206+
}
207+
if (len > 2) {
208+
additional_sense_code = sense_buf[2];
209+
}
210+
if (len > 3) {
211+
additional_sense_code_qualifier = sense_buf[3];
212+
}
213+
if (len > 7) {
214+
additional_length = sense_buf[7];
215+
}
216+
} else {
217+
/* fixed format, SPC-6 4.4.3 */
218+
if (len > 2) {
219+
sense_key = 0xf & sense_buf[2];
220+
}
221+
if (len > 7) {
222+
additional_length = sense_buf[7];
223+
}
224+
if (len > 12) {
225+
additional_sense_code = sense_buf[12];
226+
}
227+
if (len > 13) {
228+
additional_sense_code_qualifier = sense_buf[13];
229+
}
230+
}
231+
232+
switch (sense_key) {
233+
case NO_SENSE:
234+
case 0x0f: /* COMPLETED, not present in kernel headers */
235+
ALOGD("SCSI success with sense data: key=%hhu, asc=%hhu, ascq=%hhu\n", sense_key,
236+
additional_sense_code, additional_sense_code_qualifier);
237+
return true;
238+
}
239+
240+
ALOGE("Unexpected SCSI sense data: key=%hhu, asc=%hhu, ascq=%hhu\n", sense_key,
241+
additional_sense_code, additional_sense_code_qualifier);
242+
log_buf(ANDROID_LOG_ERROR, "sense buffer: ", sense_buf, len);
243+
return false;
244+
}
245+
246+
static void check_sg_io_hdr(const sg_io_hdr_t* io_hdrp) {
247+
if (io_hdrp->status == 0 && io_hdrp->host_status == 0 && io_hdrp->driver_status == 0) {
248+
return;
249+
}
250+
251+
if (io_hdrp->status & 0x01) {
252+
ALOGE("SG_IO received unknown status, LSB is set: %hhu", io_hdrp->status);
253+
}
254+
255+
if (io_hdrp->masked_status != GOOD && io_hdrp->sb_len_wr > 0) {
256+
bool sense_error = check_scsi_sense(io_hdrp->sbp, io_hdrp->sb_len_wr);
257+
if (sense_error) {
258+
ALOGE("Unexpected SCSI sense. masked_status: %hhu, host_status: %hu, driver_status: "
259+
"%hu\n",
260+
io_hdrp->masked_status, io_hdrp->host_status, io_hdrp->driver_status);
261+
return;
262+
}
263+
}
264+
265+
switch (io_hdrp->masked_status) {
266+
case GOOD:
267+
break;
268+
case CHECK_CONDITION:
269+
/* handled by check_sg_sense above */
270+
break;
271+
default:
272+
ALOGE("SG_IO failed with masked_status: %hhu, host_status: %hu, driver_status: %hu\n",
273+
io_hdrp->masked_status, io_hdrp->host_status, io_hdrp->driver_status);
274+
return;
275+
}
276+
277+
if (io_hdrp->host_status != 0) {
278+
ALOGE("SG_IO failed with host_status: %hu, driver_status: %hu\n", io_hdrp->host_status,
279+
io_hdrp->driver_status);
280+
}
281+
282+
if (io_hdrp->resid != 0) {
283+
ALOGE("SG_IO resid was non-zero: %d\n", io_hdrp->resid);
284+
}
285+
}
286+
138287
static int send_mmc_rpmb_req(int mmc_fd, const struct storage_rpmb_send_req* req) {
139288
struct {
140289
struct mmc_ioc_multi_cmd multi;
@@ -153,7 +302,7 @@ static int send_mmc_rpmb_req(int mmc_fd, const struct storage_rpmb_send_req* req
153302
mmc_ioc_cmd_set_data((*cmd), write_buf);
154303
#ifdef RPMB_DEBUG
155304
ALOGI("opcode: 0x%x, write_flag: 0x%x\n", cmd->opcode, cmd->write_flag);
156-
print_buf("request: ", write_buf, req->reliable_write_size);
305+
log_buf(ANDROID_LOG_INFO, "request: ", write_buf, req->reliable_write_size);
157306
#endif
158307
write_buf += req->reliable_write_size;
159308
mmc.multi.num_of_cmds++;
@@ -169,7 +318,7 @@ static int send_mmc_rpmb_req(int mmc_fd, const struct storage_rpmb_send_req* req
169318
mmc_ioc_cmd_set_data((*cmd), write_buf);
170319
#ifdef RPMB_DEBUG
171320
ALOGI("opcode: 0x%x, write_flag: 0x%x\n", cmd->opcode, cmd->write_flag);
172-
print_buf("request: ", write_buf, req->write_size);
321+
log_buf(ANDROID_LOG_INFO, "request: ", write_buf, req->write_size);
173322
#endif
174323
write_buf += req->write_size;
175324
mmc.multi.num_of_cmds++;
@@ -225,6 +374,7 @@ static int send_ufs_rpmb_req(int sg_fd, const struct storage_rpmb_send_req* req)
225374
ALOGE("%s: ufs ioctl failed: %d, %s\n", __func__, rc, strerror(errno));
226375
goto err_op;
227376
}
377+
check_sg_io_hdr(&io_hdr);
228378
write_buf += req->reliable_write_size;
229379
}
230380

@@ -239,6 +389,7 @@ static int send_ufs_rpmb_req(int sg_fd, const struct storage_rpmb_send_req* req)
239389
ALOGE("%s: ufs ioctl failed: %d, %s\n", __func__, rc, strerror(errno));
240390
goto err_op;
241391
}
392+
check_sg_io_hdr(&io_hdr);
242393
write_buf += req->write_size;
243394
}
244395

@@ -252,6 +403,7 @@ static int send_ufs_rpmb_req(int sg_fd, const struct storage_rpmb_send_req* req)
252403
if (rc < 0) {
253404
ALOGE("%s: ufs ioctl failed: %d, %s\n", __func__, rc, strerror(errno));
254405
}
406+
check_sg_io_hdr(&io_hdr);
255407
}
256408

257409
err_op:
@@ -353,7 +505,7 @@ int rpmb_send(struct storage_msg* msg, const void* r, size_t req_len) {
353505
goto err_response;
354506
}
355507
#ifdef RPMB_DEBUG
356-
if (req->read_size) print_buf("response: ", read_buf, req->read_size);
508+
if (req->read_size) log_buf(ANDROID_LOG_INFO, "response: ", read_buf, req->read_size);
357509
#endif
358510

359511
if (msg->flags & STORAGE_MSG_FLAG_POST_COMMIT) {

0 commit comments

Comments
 (0)