1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Permission is hereby granted, free of charge, to any person
5  * obtaining a copy of this software and associated documentation
6  * files (the "Software"), to deal in the Software without
7  * restriction, including without limitation the rights to use, copy,
8  * modify, merge, publish, distribute, sublicense, and/or sell copies
9  * of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be
13  * included in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
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
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 
25 #define LOG_TAG "rpmb_mock"
26 
27 #include "rpmb_protocol.h"
28 
29 #include <assert.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <getopt.h>
33 #include <log/log.h>
34 #include <openssl/hmac.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sys/socket.h>
39 #include <sys/stat.h>
40 #include <sys/types.h>
41 #include <sys/un.h>
42 #include <unistd.h>
43 
44 /* verbose is an int for getopt */
45 static int verbose = false;
46 
47 #if OPENSSL_VERSION_NUMBER < 0x10100000L
48 
HMAC_CTX_new(void)49 HMAC_CTX* HMAC_CTX_new(void) {
50     HMAC_CTX* ctx = malloc(sizeof(*ctx));
51     if (ctx != NULL) {
52         HMAC_CTX_init(ctx);
53     }
54     return ctx;
55 }
56 
HMAC_CTX_free(HMAC_CTX * ctx)57 void HMAC_CTX_free(HMAC_CTX* ctx) {
58     if (ctx != NULL) {
59         HMAC_CTX_cleanup(ctx);
60         free(ctx);
61     }
62 }
63 
64 #endif
65 
66 #define MAX_WRITE_COUNTER (0xffffffff)
67 
68 struct rpmb_data_header {
69     uint32_t write_counter;
70     uint16_t max_block;
71     uint8_t pad1;
72     uint8_t key_programmed;
73     struct rpmb_key key;
74     uint8_t pad[512 - 4 - 2 - 1 - 1 - sizeof(struct rpmb_key)];
75 };
76 
77 #define MAX_PACKET_COUNT (8)
78 
79 struct rpmb_dev_state {
80     struct rpmb_data_header header;
81     struct rpmb_packet cmd[MAX_PACKET_COUNT];
82     struct rpmb_packet res[MAX_PACKET_COUNT];
83     uint16_t cmd_count;
84     uint16_t res_count;
85     int data_fd;
86 };
87 
88 /* TODO: move to common location */
rpmb_mac(struct rpmb_key key,struct rpmb_packet * packet,size_t packet_count,struct rpmb_key * mac)89 static int rpmb_mac(struct rpmb_key key, struct rpmb_packet* packet, size_t packet_count,
90                     struct rpmb_key* mac) {
91     size_t i;
92     int hmac_ret;
93     unsigned int md_len;
94     HMAC_CTX* hmac_ctx;
95 
96     hmac_ctx = HMAC_CTX_new();
97     hmac_ret = HMAC_Init_ex(hmac_ctx, &key, sizeof(key), EVP_sha256(), NULL);
98     if (!hmac_ret) {
99         ALOGE("HMAC_Init_ex failed\n");
100         goto err;
101     }
102     for (i = 0; i < packet_count; i++) {
103         hmac_ret = HMAC_Update(hmac_ctx, packet[i].data, 284);
104         if (!hmac_ret) {
105             ALOGE("HMAC_Update failed\n");
106             goto err;
107         }
108     }
109     hmac_ret = HMAC_Final(hmac_ctx, mac->byte, &md_len);
110     if (md_len != sizeof(mac->byte)) {
111         ALOGE("bad md_len %d != %zd\n", md_len, sizeof(mac->byte));
112         exit(1);
113     }
114     if (!hmac_ret) {
115         ALOGE("HMAC_Final failed\n");
116         goto err;
117     }
118 
119 err:
120     HMAC_CTX_free(hmac_ctx);
121     return hmac_ret ? 0 : -1;
122 }
123 
rpmb_file_seek(struct rpmb_dev_state * s,uint16_t addr)124 static int rpmb_file_seek(struct rpmb_dev_state* s, uint16_t addr) {
125     int ret;
126     int pos = addr * RPMB_PACKET_DATA_SIZE + sizeof(s->header);
127     ret = lseek(s->data_fd, pos, SEEK_SET);
128     if (ret != pos) {
129         ALOGE("rpmb_dev: seek to %d failed, got %d\n", pos, ret);
130         return -1;
131     }
132     return 0;
133 }
134 
rpmb_dev_program_key(struct rpmb_dev_state * s)135 static uint16_t rpmb_dev_program_key(struct rpmb_dev_state* s) {
136     int ret;
137 
138     if (s->header.key_programmed) {
139         return RPMB_RES_WRITE_FAILURE;
140     }
141 
142     s->header.key = s->cmd[0].key_mac;
143     s->header.key_programmed = 1;
144 
145     ret = lseek(s->data_fd, 0, SEEK_SET);
146     if (ret) {
147         ALOGE("rpmb_dev: Failed to seek rpmb data file\n");
148         return RPMB_RES_WRITE_FAILURE;
149     }
150 
151     ret = write(s->data_fd, &s->header, sizeof(s->header));
152     if (ret != sizeof(s->header)) {
153         ALOGE("rpmb_dev: Failed to write rpmb key: %d, %s\n", ret, strerror(errno));
154 
155         return RPMB_RES_WRITE_FAILURE;
156     }
157 
158     return RPMB_RES_OK;
159 }
160 
rpmb_dev_get_counter(struct rpmb_dev_state * s)161 static uint16_t rpmb_dev_get_counter(struct rpmb_dev_state* s) {
162     s->res[0].write_counter = rpmb_u32(s->header.write_counter);
163 
164     return RPMB_RES_OK;
165 }
166 
rpmb_dev_data_write(struct rpmb_dev_state * s)167 static uint16_t rpmb_dev_data_write(struct rpmb_dev_state* s) {
168     uint16_t addr = rpmb_get_u16(s->cmd[0].address);
169     uint16_t block_count = s->cmd_count;
170     uint32_t write_counter;
171     int ret;
172 
173     if (s->header.write_counter == MAX_WRITE_COUNTER) {
174         if (verbose) {
175             ALOGE("rpmb_dev: Write counter expired\n");
176         }
177         return RPMB_RES_WRITE_FAILURE;
178     }
179 
180     write_counter = rpmb_get_u32(s->cmd[0].write_counter);
181     if (s->header.write_counter != write_counter) {
182         if (verbose) {
183             ALOGE("rpmb_dev: Invalid write counter %u. Expected: %u\n", write_counter,
184                   s->header.write_counter);
185         }
186         return RPMB_RES_COUNT_FAILURE;
187     }
188 
189     ret = rpmb_file_seek(s, addr);
190     if (ret) {
191         ALOGE("rpmb_dev: Failed to seek rpmb data file\n");
192         return RPMB_RES_WRITE_FAILURE;
193     }
194 
195     for (int i = 0; i < block_count; i++) {
196         ret = write(s->data_fd, s->cmd[i].data, RPMB_PACKET_DATA_SIZE);
197         if (ret != RPMB_PACKET_DATA_SIZE) {
198             ALOGE("rpmb_dev: Failed to write rpmb data file: %d, %s\n", ret, strerror(errno));
199             return RPMB_RES_WRITE_FAILURE;
200         }
201     }
202 
203     s->header.write_counter++;
204 
205     ret = lseek(s->data_fd, 0, SEEK_SET);
206     if (ret) {
207         ALOGE("rpmb_dev: Failed to seek rpmb data file\n");
208         return RPMB_RES_WRITE_FAILURE;
209     }
210 
211     ret = write(s->data_fd, &s->header.write_counter, sizeof(s->header.write_counter));
212     if (ret != sizeof(s->header.write_counter)) {
213         ALOGE("rpmb_dev: Failed to write rpmb write counter: %d, %s\n", ret, strerror(errno));
214 
215         return RPMB_RES_WRITE_FAILURE;
216     }
217 
218     s->res[0].write_counter = rpmb_u32(s->header.write_counter);
219     return RPMB_RES_OK;
220 }
221 
rpmb_dev_data_read(struct rpmb_dev_state * s)222 static uint16_t rpmb_dev_data_read(struct rpmb_dev_state* s) {
223     uint16_t addr;
224     uint16_t block_count;
225     int ret;
226 
227     addr = rpmb_get_u16(s->cmd[0].address);
228     block_count = s->res_count;
229 
230     rpmb_file_seek(s, addr);
231 
232     for (int i = 0; i < block_count; i++) {
233         ret = read(s->data_fd, s->res[i].data, RPMB_PACKET_DATA_SIZE);
234         if (ret != 0 && ret != RPMB_PACKET_DATA_SIZE) {
235             ALOGE("rpmb_dev: Failed to read rpmb data file: %d, %s\n", ret, strerror(errno));
236             return RPMB_RES_READ_FAILURE;
237         }
238     }
239 
240     return RPMB_RES_OK;
241 }
242 
243 struct rpmb_dev_cmd {
244     uint16_t (*func)(struct rpmb_dev_state* s);
245     uint16_t resp;
246     bool key_mac_is_key;
247     bool check_mac;
248     bool check_result_read;
249     bool check_key_programmed;
250     bool check_addr;
251     bool multi_packet_cmd;
252     bool multi_packet_res;
253     bool res_mac;
254 };
255 
256 static struct rpmb_dev_cmd rpmb_dev_cmd_table[] = {
257         [RPMB_REQ_PROGRAM_KEY] =
258                 {
259                         .func = rpmb_dev_program_key,
260                         .resp = RPMB_RESP_PROGRAM_KEY,
261                         .key_mac_is_key = true,
262                         .check_result_read = true,
263                 },
264         [RPMB_REQ_GET_COUNTER] =
265                 {
266                         .func = rpmb_dev_get_counter,
267                         .resp = RPMB_RESP_GET_COUNTER,
268                         .check_key_programmed = true,
269                         .res_mac = true,
270                 },
271         [RPMB_REQ_DATA_WRITE] =
272                 {
273                         .func = rpmb_dev_data_write,
274                         .resp = RPMB_RESP_DATA_WRITE,
275                         .check_mac = true,
276                         .check_result_read = true,
277                         .check_key_programmed = true,
278                         .check_addr = true,
279                         .multi_packet_cmd = true,
280                         .res_mac = true,
281                 },
282         [RPMB_REQ_DATA_READ] =
283                 {
284                         .func = rpmb_dev_data_read,
285                         .resp = RPMB_RESP_DATA_READ,
286                         .check_key_programmed = true,
287                         .check_addr = true,
288                         .multi_packet_res = true,
289                         .res_mac = true,
290                 },
291 };
292 
293 #define countof(arr) (sizeof(arr) / sizeof(arr[0]))
294 
rpmb_dev_process_cmd(struct rpmb_dev_state * s)295 static void rpmb_dev_process_cmd(struct rpmb_dev_state* s) {
296     assert(s->cmd_count > 0);
297     assert(s->res_count > 0);
298     uint16_t req_resp = rpmb_get_u16(s->cmd[0].req_resp);
299     uint16_t addr = rpmb_get_u16(s->cmd[0].address);
300     uint16_t sub_req;
301     uint16_t cmd_index = req_resp < countof(rpmb_dev_cmd_table) ? req_resp : 0;
302     struct rpmb_dev_cmd* cmd = &rpmb_dev_cmd_table[cmd_index];
303     uint16_t result = RPMB_RES_GENERAL_FAILURE;
304     struct rpmb_key mac;
305     uint16_t block_count = 0;
306 
307     if (cmd->check_result_read) {
308         sub_req = rpmb_get_u16(s->cmd[s->cmd_count - 1].req_resp);
309         if (sub_req != RPMB_REQ_RESULT_READ) {
310             if (verbose) {
311                 ALOGE("rpmb_dev: Request %d, missing result read request, got %d, cmd_count %d\n",
312                       req_resp, sub_req, s->cmd_count);
313             }
314             goto err;
315         }
316         assert(s->cmd_count > 1);
317         s->cmd_count--;
318     }
319 
320     if (cmd->check_mac) {
321         if (rpmb_mac(s->header.key, s->cmd, s->cmd_count, &mac) != 0) {
322             ALOGE("rpmb_dev: failed to caclulate mac\n");
323             goto err;
324         }
325     } else if (cmd->key_mac_is_key) {
326         mac = s->cmd[s->cmd_count - 1].key_mac;
327     } else {
328         memset(mac.byte, 0, sizeof(mac.byte));
329     }
330 
331     if (memcmp(&mac, s->cmd[s->cmd_count - 1].key_mac.byte, sizeof(mac))) {
332         if (verbose) {
333             ALOGE("rpmb_dev: Request %d, invalid MAC, cmd_count %d\n", req_resp, s->cmd_count);
334         }
335         if (cmd->check_mac) {
336             result = RPMB_RES_AUTH_FAILURE;
337         }
338         goto err;
339     }
340 
341     if (cmd->multi_packet_cmd) {
342         block_count = s->cmd_count;
343     }
344     if (cmd->multi_packet_res) {
345         block_count = s->res_count;
346     }
347 
348     if (cmd->check_addr && (addr + block_count > s->header.max_block + 1)) {
349         if (verbose) {
350             ALOGE("rpmb_dev: Request %d, invalid addr: 0x%x count 0x%x, Out of bounds. Max addr "
351                   "0x%x\n",
352                   req_resp, addr, block_count, s->header.max_block + 1);
353         }
354         result = RPMB_RES_ADDR_FAILURE;
355         goto err;
356     }
357     if (!cmd->check_addr && addr) {
358         if (verbose) {
359             ALOGE("rpmb_dev: Request %d, invalid addr: 0x%x != 0\n", req_resp, addr);
360         }
361         goto err;
362     }
363 
364     for (int i = 1; i < s->cmd_count; i++) {
365         sub_req = rpmb_get_u16(s->cmd[i].req_resp);
366         if (sub_req != req_resp) {
367             if (verbose) {
368                 ALOGE("rpmb_dev: Request %d, sub-request mismatch, %d, at %d\n", req_resp, i,
369                       sub_req);
370             }
371             goto err;
372         }
373     }
374     if (!cmd->multi_packet_cmd && s->cmd_count != 1) {
375         if (verbose) {
376             ALOGE("rpmb_dev: Request %d, bad cmd count %d, expected 1\n", req_resp, s->cmd_count);
377         }
378         goto err;
379     }
380     if (!cmd->multi_packet_res && s->res_count != 1) {
381         if (verbose) {
382             ALOGE("rpmb_dev: Request %d, bad res count %d, expected 1\n", req_resp, s->res_count);
383         }
384         goto err;
385     }
386 
387     if (cmd->check_key_programmed && !s->header.key_programmed) {
388         if (verbose) {
389             ALOGE("rpmb_dev: Request %d, key is not programmed\n", req_resp);
390         }
391         s->res[0].result = rpmb_u16(RPMB_RES_NO_AUTH_KEY);
392         return;
393     }
394 
395     if (!cmd->func) {
396         if (verbose) {
397             ALOGE("rpmb_dev: Unsupported request: %d\n", req_resp);
398         }
399         goto err;
400     }
401 
402     result = cmd->func(s);
403 
404 err:
405     if (s->header.write_counter == MAX_WRITE_COUNTER) {
406         result |= RPMB_RES_WRITE_COUNTER_EXPIRED;
407     }
408 
409     for (int i = 0; i < s->res_count; i++) {
410         s->res[i].nonce = s->cmd[0].nonce;
411         s->res[i].address = rpmb_u16(addr);
412         s->res[i].block_count = rpmb_u16(block_count);
413         s->res[i].result = rpmb_u16(result);
414         s->res[i].req_resp = rpmb_u16(cmd->resp);
415     }
416     if (cmd->res_mac) {
417         rpmb_mac(s->header.key, s->res, s->res_count, &s->res[s->res_count - 1].key_mac);
418     }
419 }
420 
421 /*
422  * Receives data until one of the following is true:
423  * - The buffer is full (return will be len)
424  * - The connection closed (return > 0, < len)
425  * - An error occurred (return will be the negative error code from recv)
426  */
recv_until(int sock,void * dest_in,size_t len)427 ssize_t recv_until(int sock, void* dest_in, size_t len) {
428     size_t bytes_recvd = 0;
429     char* dest = dest_in;
430     while (bytes_recvd < len) {
431         ssize_t ret = recv(sock, dest, len - bytes_recvd, 0);
432         if (ret < 0) {
433             return ret;
434         }
435         dest += ret;
436         bytes_recvd += ret;
437         if (ret == 0) {
438             break;
439         }
440     }
441     return bytes_recvd;
442 }
443 
444 /*
445  * Handles an incoming connection to the rpmb daemon.
446  * Returns 0 if the client disconnects without violating the protocol.
447  * Returns a negative value if we terminated the connection abnormally.
448  *
449  * Arguments:
450  *   conn_sock - an fd to send/recv on
451  *   s - an initialized rpmb device
452  */
handle_conn(struct rpmb_dev_state * s,int conn_sock)453 int handle_conn(struct rpmb_dev_state* s, int conn_sock) {
454     int ret;
455 
456     while (true) {
457         memset(s->res, 0, sizeof(s->res));
458         ret = recv_until(conn_sock, &s->res_count, sizeof(s->res_count));
459 
460         /*
461          * Disconnected while not in the middle of anything.
462          */
463         if (ret <= 0) {
464             return 0;
465         }
466 
467         if (s->res_count > MAX_PACKET_COUNT) {
468             ALOGE("rpmb_dev: Receive count too large: %d\n", s->res_count);
469             return -1;
470         }
471         if (s->res_count <= 0) {
472             ALOGE("rpmb_dev: Receive count too small: %d\n", s->res_count);
473             return -1;
474         }
475 
476         ret = recv_until(conn_sock, &s->cmd_count, sizeof(s->cmd_count));
477         if (ret != sizeof(s->cmd_count)) {
478             ALOGE("rpmb_dev: Failed to read cmd_count");
479             return -1;
480         }
481 
482         if (s->cmd_count == 0) {
483             ALOGE("rpmb_dev: Must contain at least one command\n");
484             return -1;
485         }
486 
487         if (s->cmd_count > MAX_PACKET_COUNT) {
488             ALOGE("rpmb_dev: Command count is too large\n");
489             return -1;
490         }
491 
492         size_t cmd_size = s->cmd_count * sizeof(s->cmd[0]);
493         ret = recv_until(conn_sock, s->cmd, cmd_size);
494         if (ret != (int)cmd_size) {
495             ALOGE("rpmb_dev: Failed to read command: "
496                   "cmd_size: %zu ret: %d, %s\n",
497                   cmd_size, ret, strerror(errno));
498             return -1;
499         }
500 
501         rpmb_dev_process_cmd(s);
502 
503         size_t resp_size = sizeof(s->res[0]) * s->res_count;
504         ret = send(conn_sock, s->res, resp_size, 0);
505         if (ret != (int)resp_size) {
506             ALOGE("rpmb_dev: Failed to send response: %d, %s\n", ret, strerror(errno));
507             return -1;
508         }
509     }
510 }
511 
usage(const char * argv0)512 void usage(const char* argv0) {
513     fprintf(stderr, "Usage: %s [-d|--dev] <datafile> [--sock] <socket_path>\n", argv0);
514     fprintf(stderr, "or:    %s [-d|--dev] <datafile> [--size <size>] [--key key]\n", argv0);
515 }
516 
main(int argc,char ** argv)517 int main(int argc, char** argv) {
518     struct rpmb_dev_state s;
519     int ret;
520     int cmdres_sock;
521     struct sockaddr_un cmdres_sockaddr;
522     const char* data_file_name = NULL;
523     const char* socket_path = NULL;
524     int open_flags;
525     int init = false;
526 
527     struct option long_options[] = {{"size", required_argument, 0, 0},
528                                     {"key", required_argument, 0, 0},
529                                     {"sock", required_argument, 0, 0},
530                                     {"dev", required_argument, 0, 'd'},
531                                     {"init", no_argument, &init, true},
532                                     {"verbose", no_argument, &verbose, true},
533                                     {0, 0, 0, 0}};
534 
535     memset(&s.header, 0, sizeof(s.header));
536 
537     while (1) {
538         int c;
539         int option_index = 0;
540         c = getopt_long(argc, argv, "d:", long_options, &option_index);
541         if (c == -1) {
542             break;
543         }
544 
545         switch (c) {
546             /* long args */
547             case 0:
548                 switch (option_index) {
549                     /* size */
550                     case 0:
551                         s.header.max_block = atoi(optarg) - 1;
552                         break;
553                     /* key */
554                     case 1:
555                         for (size_t i = 0; i < sizeof(s.header.key.byte); i++) {
556                             if (!optarg) {
557                                 break;
558                             }
559                             s.header.key.byte[i] = strtol(optarg, &optarg, 16);
560                             s.header.key_programmed = 1;
561                         }
562                         break;
563                     /* sock */
564                     case 2:
565                         socket_path = optarg;
566                         break;
567                 }
568                 break;
569             /* dev */
570             case 'd':
571                 data_file_name = optarg;
572                 break;
573             default:
574                 usage(argv[0]);
575                 return EXIT_FAILURE;
576         }
577     }
578 
579     /*
580      * We always need a data file, and at exactly one of --init or --sock
581      * must be specified.
582      */
583     if (!data_file_name || (!init == !socket_path)) {
584         usage(argv[0]);
585         return EXIT_FAILURE;
586     }
587 
588     /*
589      * If the file is already initialized, exit early.
590      */
591     if (init && !access(data_file_name, F_OK)) {
592         return EXIT_SUCCESS;
593     }
594 
595     open_flags = O_RDWR | O_SYNC;
596     if (init) {
597         open_flags |= O_CREAT | O_TRUNC;
598     }
599     s.data_fd = open(data_file_name, open_flags, S_IWUSR | S_IRUSR);
600     if (s.data_fd < 0) {
601         ALOGE("rpmb_dev: Failed to open rpmb data file, %s: %s\n", data_file_name, strerror(errno));
602         return EXIT_FAILURE;
603     }
604 
605     if (init) {
606         /* Create new rpmb data file */
607         if (s.header.max_block == 0) {
608             s.header.max_block = 512 - 1;
609         }
610         ret = write(s.data_fd, &s.header, sizeof(s.header));
611         if (ret != sizeof(s.header)) {
612             ALOGE("rpmb_dev: Failed to write rpmb data file: %d, %s\n", ret, strerror(errno));
613             return EXIT_FAILURE;
614         }
615         return EXIT_SUCCESS;
616     }
617 
618     ret = read(s.data_fd, &s.header, sizeof(s.header));
619     if (ret != sizeof(s.header)) {
620         ALOGE("rpmb_dev: Failed to read rpmb data file: %d, %s\n", ret, strerror(errno));
621         return EXIT_FAILURE;
622     }
623 
624     cmdres_sock = socket(AF_UNIX, SOCK_STREAM, 0);
625     if (cmdres_sock < 0) {
626         ALOGE("rpmb_dev: Failed to create command/response socket: %s\n", strerror(errno));
627         return EXIT_FAILURE;
628     }
629 
630     cmdres_sockaddr.sun_family = AF_UNIX;
631     strncpy(cmdres_sockaddr.sun_path, socket_path, sizeof(cmdres_sockaddr.sun_path));
632 
633     ret = bind(cmdres_sock, (struct sockaddr*)&cmdres_sockaddr, sizeof(struct sockaddr_un));
634     if (ret < 0) {
635         ALOGE("rpmb_dev: Failed to bind command/response socket: %s: %s\n", socket_path,
636               strerror(errno));
637         return EXIT_FAILURE;
638     }
639 
640     ret = listen(cmdres_sock, 1);
641     if (ret < 0) {
642         ALOGE("rpmb_dev: Failed to listen on command/response socket: %s\n", strerror(errno));
643         return EXIT_FAILURE;
644     }
645 
646     while (true) {
647         int conn_sock = accept(cmdres_sock, NULL, NULL);
648         if (conn_sock < 0) {
649             ALOGE("rpmb_dev: Could not accept connection: %s\n", strerror(errno));
650             return EXIT_FAILURE;
651         }
652         ret = handle_conn(&s, conn_sock);
653         close(conn_sock);
654         if (ret) {
655             ALOGE("rpmb_dev: Connection terminated: %d", ret);
656         }
657     }
658 }
659