1 /*
2  * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
3  */
4 
5 #include <fcntl.h>
6 #include <libgen.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <sys/mman.h>
11 #include <sys/stat.h>
12 #include <time.h>
13 #include <unistd.h>
14 #include <xenctrl.h>
15 #include <xenstore.h>
16 
17 #include <xen/errno.h>
18 #include <xen-tools/libs.h>
19 
20 static xc_interface *xch;
21 
show_help(void)22 void show_help(void)
23 {
24     fprintf(stderr,
25             "xen-livepatch: live patching tool\n"
26             "Usage: xen-livepatch <command> [args] [command-flags]\n"
27             " <name> An unique name of payload. Up to %d characters.\n"
28             "Commands:\n"
29             "  help                   display this help\n"
30             "  upload <name> <file>   upload file <file> with <name> name\n"
31             "  list                   list payloads uploaded.\n"
32             "  apply <name> [flags]   apply <name> patch.\n"
33             "    Supported flags:\n"
34             "      --nodeps           Disable inter-module buildid dependency check.\n"
35             "                         Check only against hypervisor buildid.\n"
36             "  revert <name>          revert name <name> patch.\n"
37             "  replace <name>         apply <name> patch and revert all others.\n"
38             "  unload <name>          unload name <name> patch.\n"
39             "  load <file> [flags]    upload and apply <file> with name as the <file> name\n"
40             "    Supported flags:\n"
41             "      --nodeps           Disable inter-module buildid dependency check.\n"
42             "                         Check only against hypervisor buildid.\n",
43             XEN_LIVEPATCH_NAME_SIZE);
44 }
45 
46 /* wrapper function */
help_func(int argc,char * argv[])47 static int help_func(int argc, char *argv[])
48 {
49     show_help();
50     return 0;
51 }
52 
state2str(unsigned int state)53 static const char *state2str(unsigned int state)
54 {
55 #define STATE(x) [LIVEPATCH_STATE_##x] = #x
56     static const char *const names[] = {
57             STATE(CHECKED),
58             STATE(APPLIED),
59     };
60 #undef STATE
61     if (state >= ARRAY_SIZE(names) || !names[state])
62         return "unknown";
63 
64     return names[state];
65 }
66 
list_func(int argc,char * argv[])67 static int list_func(int argc, char *argv[])
68 {
69     unsigned int nr, done, left, i;
70     xen_livepatch_status_t *info = NULL;
71     char *name = NULL;
72     char *metadata = NULL;
73     uint32_t *len = NULL;
74     uint32_t *metadata_len = NULL;
75     uint32_t name_total_size, metadata_total_size, name_off, metadata_off;
76     int rc = ENOMEM;
77 
78     if ( argc )
79     {
80         show_help();
81         return -1;
82     }
83     done = left = 0;
84 
85     rc = xc_livepatch_list_get_sizes(xch, &nr, &name_total_size, &metadata_total_size);
86     if ( rc )
87     {
88         rc = errno;
89         fprintf(stderr, "Failed to get list sizes.\n"
90                 "Error %d: %s\n",
91                 rc, strerror(rc));
92         return rc;
93     }
94 
95     if ( nr == 0 )
96     {
97         fprintf(stdout, "Nothing to list\n");
98         return 0;
99     }
100 
101     info = malloc(nr * sizeof(*info));
102     if ( !info )
103         return rc;
104 
105     name = malloc(name_total_size * sizeof(*name));
106     if ( !name )
107         goto error_name;
108 
109     len = malloc(nr * sizeof(*len));
110     if ( !len )
111         goto error_len;
112 
113     metadata = malloc(metadata_total_size * sizeof(*metadata) + 1);
114     if ( !metadata )
115         goto error_metadata;
116 
117     metadata_len = malloc(nr * sizeof(*metadata_len));
118     if ( !metadata_len )
119         goto error_metadata_len;
120 
121     memset(info, 'A', nr * sizeof(*info));
122     memset(name, 'B', name_total_size * sizeof(*name));
123     memset(len, 'C', nr * sizeof(*len));
124     memset(metadata, 'D', metadata_total_size * sizeof(*metadata) + 1);
125     memset(metadata_len, 'E', nr * sizeof(*metadata_len));
126     name_off = metadata_off = 0;
127 
128     rc = xc_livepatch_list(xch, nr, 0, info, name, len, name_total_size,
129                            metadata, metadata_len, metadata_total_size, &done, &left);
130     if ( rc || done != nr || left > 0)
131     {
132         rc = errno;
133         fprintf(stderr, "Failed to list %d/%d.\n"
134                 "Error %d: %s\n",
135                 left, nr, rc, strerror(rc));
136         goto error;
137     }
138 
139     fprintf(stdout," ID                                     | status     | metadata\n"
140                    "----------------------------------------+------------+---------------\n");
141 
142     for ( i = 0; i < done; i++ )
143     {
144         unsigned int j;
145         char *name_str = name + name_off;
146         char *metadata_str = metadata + metadata_off;
147 
148         printf("%-40.*s| %s", len[i], name_str, state2str(info[i].state));
149         if ( info[i].rc )
150             printf(" (%d, %s)    | ", -info[i].rc, strerror(-info[i].rc));
151         else
152             printf("    | ");
153 
154         /* Replace all '\0' with semi-colons. */
155         for ( j = 0; metadata_len[i] && j < metadata_len[i] - 1; j++ )
156             metadata_str[j] = (metadata_str[j] ?: ';');
157         printf("%.*s\n", metadata_len[i], metadata_str);
158 
159         name_off += len[i];
160         metadata_off += metadata_len[i];
161     }
162 
163 error:
164     free(metadata_len);
165 error_metadata_len:
166     free(metadata);
167 error_metadata:
168     free(len);
169 error_len:
170     free(name);
171 error_name:
172     free(info);
173     return rc;
174 }
175 #undef MAX_LEN
176 
get_name(int argc,char * argv[],char * name)177 static int get_name(int argc, char *argv[], char *name)
178 {
179     ssize_t len = strlen(argv[0]);
180     if ( len > XEN_LIVEPATCH_NAME_SIZE )
181     {
182         fprintf(stderr, "ID must be no more than %d characters.\n",
183                 XEN_LIVEPATCH_NAME_SIZE);
184         errno = EINVAL;
185         return errno;
186     }
187     /* Don't want any funny strings from the stack. */
188     memset(name, 0, XEN_LIVEPATCH_NAME_SIZE);
189     strncpy(name, argv[0], len);
190     return 0;
191 }
192 
upload_func(int argc,char * argv[])193 static int upload_func(int argc, char *argv[])
194 {
195     char *filename;
196     char name[XEN_LIVEPATCH_NAME_SIZE];
197     int fd = 0, rc;
198     struct stat buf;
199     unsigned char *fbuf;
200     ssize_t len;
201 
202     if ( argc != 2 )
203     {
204         show_help();
205         return -1;
206     }
207 
208     if ( get_name(argc, argv, name) )
209         return EINVAL;
210 
211     filename = argv[1];
212     fd = open(filename, O_RDONLY);
213     if ( fd < 0 )
214     {
215         int saved_errno = errno;
216         fprintf(stderr, "Could not open %s.\n"
217                         "Error %d: %s\n",
218                 filename, saved_errno, strerror(saved_errno));
219         return saved_errno;
220     }
221     if ( stat(filename, &buf) != 0 )
222     {
223         int saved_errno = errno;
224         fprintf(stderr, "Could not get size of %s.\n"
225                         "Error %d: %s\n",
226                 filename, saved_errno, strerror(saved_errno));
227         close(fd);
228         return saved_errno;
229     }
230 
231     len = buf.st_size;
232     fbuf = mmap(0, len, PROT_READ, MAP_PRIVATE, fd, 0);
233     if ( fbuf == MAP_FAILED )
234     {
235         int saved_errno = errno;
236         fprintf(stderr, "Could not map %s.\n"
237                         "Error %d: %s\n",
238                 filename, saved_errno, strerror(saved_errno));
239         close (fd);
240         return saved_errno;
241     }
242     printf("Uploading %s... ", filename);
243     rc = xc_livepatch_upload(xch, name, fbuf, len);
244     if ( rc )
245     {
246         rc = errno;
247         printf("failed\n");
248         fprintf(stderr, "Error %d: %s\n", rc, strerror(rc));
249     }
250     else
251         printf("completed\n");
252 
253 
254     if ( munmap( fbuf, len) )
255     {
256         fprintf(stderr, "Could not unmap %s.\n"
257                         "Error %d: %s\n",
258                 filename, errno, strerror(errno));
259     }
260     close(fd);
261 
262     return rc;
263 }
264 
265 /* These MUST match to the 'action_options[]' and 'flag_options[]' array slots. */
266 enum {
267     ACTION_APPLY = 0,
268     ACTION_REVERT = 1,
269     ACTION_UNLOAD = 2,
270     ACTION_REPLACE = 3,
271     ACTION_NUM
272 };
273 
274 struct {
275     int allow; /* State it must be in to call function. */
276     int expected; /* The state to be in after the function. */
277     const char *name;
278     const char *verb;
279     int (*function)(xc_interface *xch, char *name, uint32_t timeout, uint32_t flags);
280 } action_options[] = {
281     {   .allow = LIVEPATCH_STATE_CHECKED,
282         .expected = LIVEPATCH_STATE_APPLIED,
283         .name = "apply",
284         .verb = "Applying",
285         .function = xc_livepatch_apply,
286     },
287     {   .allow = LIVEPATCH_STATE_APPLIED,
288         .expected = LIVEPATCH_STATE_CHECKED,
289         .name = "revert",
290         .verb = "Reverting",
291         .function = xc_livepatch_revert,
292     },
293     {   .allow = LIVEPATCH_STATE_CHECKED,
294         .expected = -XEN_ENOENT,
295         .name = "unload",
296         .verb = "Unloading",
297         .function = xc_livepatch_unload,
298     },
299     {   .allow = LIVEPATCH_STATE_CHECKED,
300         .expected = LIVEPATCH_STATE_APPLIED,
301         .name = "replace",
302         .verb = "Replacing all live patches with",
303         .function = xc_livepatch_replace,
304     },
305 };
306 
307 /*
308  * This structure defines supported flag options for actions.
309  * It defines entries for each action and supports up to 32
310  * flags per action.
311  */
312 struct {
313     const char *name;
314     const uint32_t flag;
315 } flag_options[ACTION_NUM][8 * sizeof(uint32_t)] = {
316     { /* ACTION_APPLY */
317         {   .name = "--nodeps",
318             .flag = LIVEPATCH_ACTION_APPLY_NODEPS,
319         },
320     },
321     { /* ACTION_REVERT */
322     },
323     { /* ACTION_UNLOAD */
324     },
325     { /* ACTION_REPLACE */
326     }
327 };
328 
329 /*
330  * Parse user provided action flags.
331  * This function expects to only receive an array of input parameters being flags.
332  * Expected action is specified via idx paramater (index of flag_options[]).
333  */
get_flags(int argc,char * argv[],unsigned int idx,uint32_t * flags)334 static int get_flags(int argc, char *argv[], unsigned int idx, uint32_t *flags)
335 {
336     int i, j;
337 
338     if ( !flags || idx >= ARRAY_SIZE(flag_options) )
339         return -1;
340 
341     *flags = 0;
342     for ( i = 0; i < argc; i++ )
343     {
344         for ( j = 0; j < ARRAY_SIZE(flag_options[idx]); j++ )
345         {
346             if ( !flag_options[idx][j].name )
347                 goto error;
348 
349             if ( !strcmp(flag_options[idx][j].name, argv[i]) )
350             {
351                 *flags |= flag_options[idx][j].flag;
352                 break;
353             }
354         }
355 
356         if ( j == ARRAY_SIZE(flag_options[idx]) )
357             goto error;
358     }
359 
360     return 0;
361 error:
362     fprintf(stderr, "Unsupported flag: %s.\n", argv[i]);
363     errno = EINVAL;
364     return errno;
365 }
366 
367 /* The hypervisor timeout for the live patching operation is 30 msec,
368  * but it could take some time for the operation to start, so wait twice
369  * that period. */
370 #define HYPERVISOR_TIMEOUT_NS 30000000
371 #define DELAY (2 * HYPERVISOR_TIMEOUT_NS)
372 
nanosleep_retry(long ns)373 static void nanosleep_retry(long ns)
374 {
375     struct timespec req, rem;
376     int rc;
377 
378     rem.tv_sec = 0;
379     rem.tv_nsec = ns;
380 
381     do {
382         req = rem;
383         rc = nanosleep(&req, &rem);
384     } while ( rc == -1 && errno == EINTR );
385 }
386 
action_func(int argc,char * argv[],unsigned int idx)387 int action_func(int argc, char *argv[], unsigned int idx)
388 {
389     char name[XEN_LIVEPATCH_NAME_SIZE];
390     int rc;
391     xen_livepatch_status_t status;
392     uint32_t flags;
393 
394     if ( argc < 1 )
395     {
396         show_help();
397         return -1;
398     }
399 
400     if ( idx >= ARRAY_SIZE(action_options) )
401         return -1;
402 
403     if ( get_name(argc--, argv++, name) )
404         return EINVAL;
405 
406     if ( get_flags(argc, argv, idx, &flags) )
407         return EINVAL;
408 
409     /* Check initial status. */
410     rc = xc_livepatch_get(xch, name, &status);
411     if ( rc )
412     {
413         int saved_errno = errno;
414         fprintf(stderr, "Failed to get status of %s.\n"
415                         "Error %d: %s\n",
416                 name, saved_errno, strerror(saved_errno));
417         return saved_errno;
418     }
419     if ( status.rc == -XEN_EAGAIN )
420     {
421         fprintf(stderr,
422                 "Cannot execute %s.\n"
423                 "Operation already in progress.\n", action_options[idx].name);
424         return EAGAIN;
425     }
426 
427     if ( status.state == action_options[idx].expected )
428     {
429         printf("No action needed.\n");
430         return 0;
431     }
432 
433     /* Perform action. */
434     if ( action_options[idx].allow & status.state )
435     {
436         printf("%s %s... ", action_options[idx].verb, name);
437         rc = action_options[idx].function(xch, name, HYPERVISOR_TIMEOUT_NS, flags);
438         if ( rc )
439         {
440             int saved_errno = errno;
441             printf("failed\n");
442             fprintf(stderr, "Error %d: %s\n",
443                     saved_errno, strerror(saved_errno));
444             return saved_errno;
445         }
446     }
447     else
448     {
449         fprintf(stderr, "%s is in the wrong state.\n"
450                         "Current state: %s\n"
451                         "Expected state: %s\n",
452                 name, state2str(status.state),
453                 state2str(action_options[idx].allow));
454         return -1;
455     }
456 
457     nanosleep_retry(DELAY);
458     rc = xc_livepatch_get(xch, name, &status);
459 
460     if ( rc )
461         rc = -errno;
462     else if ( status.rc )
463         rc = status.rc;
464 
465     if ( rc == -XEN_EAGAIN )
466     {
467         printf("failed\n");
468         fprintf(stderr, "Operation didn't complete.\n");
469         return EAGAIN;
470     }
471 
472     if ( rc == 0 )
473         rc = status.state;
474 
475     if ( action_options[idx].expected == rc )
476         printf("completed\n");
477     else if ( rc < 0 )
478     {
479         printf("failed\n");
480         fprintf(stderr, "Error %d: %s\n", -rc, strerror(-rc));
481         return -rc;
482     }
483     else
484     {
485         printf("failed\n");
486         fprintf(stderr, "%s is in the wrong state.\n"
487                         "Current state: %s\n"
488                         "Expected state: %s\n",
489                 name, state2str(rc),
490                 state2str(action_options[idx].expected));
491         return -1;
492     }
493 
494     return 0;
495 }
496 
load_func(int argc,char * argv[])497 static int load_func(int argc, char *argv[])
498 {
499     int i, rc = ENOMEM;
500     char *upload_argv[2];
501     char **apply_argv, *path, *name, *lastdot;
502 
503     if ( argc < 1 )
504     {
505         show_help();
506         return -1;
507     }
508 
509     /* apply action has <id> [flags] input requirement, which must be constructed */
510     apply_argv = (char **) malloc(argc * sizeof(*apply_argv));
511     if ( !apply_argv )
512         return rc;
513 
514     /* <file> */
515     upload_argv[1] = argv[0];
516 
517     /* Synthesize the <id> */
518     path = strdup(argv[0]);
519 
520     name = basename(path);
521     lastdot = strrchr(name, '.');
522     if ( lastdot != NULL )
523         *lastdot = '\0';
524     upload_argv[0] = name;
525     apply_argv[0] = name;
526 
527     /* Fill in all user provided flags */
528     for ( i = 1; i < argc; i++ )
529         apply_argv[i] = argv[i];
530 
531     rc = upload_func(2 /* <id> <file> */, upload_argv);
532     if ( rc )
533         goto error;
534 
535     rc = action_func(argc, apply_argv, ACTION_APPLY);
536     if ( rc )
537         action_func(1 /* only <id> */, upload_argv, ACTION_UNLOAD);
538 
539 error:
540     free(apply_argv);
541     free(path);
542     return rc;
543 }
544 
545 /*
546  * These are also functions in action_options that are called in case
547  * none of the ones in main_options match.
548  */
549 struct {
550     const char *name;
551     int (*function)(int argc, char *argv[]);
552 } main_options[] = {
553     { "help", help_func },
554     { "list", list_func },
555     { "upload", upload_func },
556     { "load", load_func },
557 };
558 
main(int argc,char * argv[])559 int main(int argc, char *argv[])
560 {
561     int i, j = 0, ret;
562 
563     /*
564      * Set stdout to be unbuffered to avoid having to fflush when
565      * printing without a newline.
566      */
567     setvbuf(stdout, NULL, _IONBF, 0);
568 
569     if ( argc  <= 1 )
570     {
571         show_help();
572         return 0;
573     }
574     for ( i = 0; i < ARRAY_SIZE(main_options); i++ )
575         if (!strncmp(main_options[i].name, argv[1], strlen(argv[1])))
576             break;
577 
578     if ( i == ARRAY_SIZE(main_options) )
579     {
580         for ( j = 0; j < ARRAY_SIZE(action_options); j++ )
581             if (!strncmp(action_options[j].name, argv[1], strlen(argv[1])))
582                 break;
583 
584         if ( j == ARRAY_SIZE(action_options) )
585         {
586             fprintf(stderr, "Unrecognised command '%s' -- try "
587                    "'xen-livepatch help'\n", argv[1]);
588             return 1;
589         }
590     }
591 
592     xch = xc_interface_open(0,0,0);
593     if ( !xch )
594     {
595         fprintf(stderr, "failed to get the handler\n");
596         return 0;
597     }
598 
599     if ( i == ARRAY_SIZE(main_options) )
600         ret = action_func(argc -2, argv + 2, j);
601     else
602         ret = main_options[i].function(argc -2, argv + 2);
603 
604     xc_interface_close(xch);
605 
606     /*
607      * Exitcode 0 for success.
608      * Exitcode 1 for an error.
609      * Exitcode 2 if the operation should be retried for any reason (e.g. a
610      * timeout or because another operation was in progress).
611      */
612 #define EXIT_TIMEOUT (EXIT_FAILURE + 1)
613 
614     BUILD_BUG_ON(EXIT_SUCCESS != 0);
615     BUILD_BUG_ON(EXIT_FAILURE != 1);
616     BUILD_BUG_ON(EXIT_TIMEOUT != 2);
617 
618     switch ( ret )
619     {
620     case 0:
621         return EXIT_SUCCESS;
622     case EAGAIN:
623     case EBUSY:
624         return EXIT_TIMEOUT;
625     default:
626         return EXIT_FAILURE;
627     }
628 }
629 
630 /*
631  * Local variables:
632  * mode: C
633  * c-file-style: "BSD"
634  * c-basic-offset: 4
635  * tab-width: 4
636  * indent-tabs-mode: nil
637  * End:
638  */
639