diff options
Diffstat (limited to 'discover')
-rw-r--r-- | discover/Makefile.am | 7 | ||||
-rw-r--r-- | discover/boot.c | 147 | ||||
-rw-r--r-- | discover/device-handler.c | 2 | ||||
-rw-r--r-- | discover/discover-server.c | 15 | ||||
-rw-r--r-- | discover/elf.c | 86 | ||||
-rw-r--r-- | discover/elf.h | 29 | ||||
-rw-r--r-- | discover/event.c | 1 | ||||
-rw-r--r-- | discover/grub2/blscfg.c | 19 | ||||
-rw-r--r-- | discover/grub2/builtins.c | 208 | ||||
-rw-r--r-- | discover/grub2/env.c | 2 | ||||
-rw-r--r-- | discover/grub2/grub2-parser.y | 17 | ||||
-rw-r--r-- | discover/grub2/grub2.c | 110 | ||||
-rw-r--r-- | discover/grub2/grub2.h | 32 | ||||
-rw-r--r-- | discover/grub2/script.c | 29 | ||||
-rw-r--r-- | discover/ipmi.c | 1 | ||||
-rw-r--r-- | discover/ipmi.h | 23 | ||||
-rw-r--r-- | discover/paths.c | 3 | ||||
-rw-r--r-- | discover/platform-powerpc.c | 187 | ||||
-rw-r--r-- | discover/platform.c | 15 | ||||
-rw-r--r-- | discover/platform.h | 5 | ||||
-rw-r--r-- | discover/pxe-parser.c | 7 | ||||
-rw-r--r-- | discover/user-event.c | 19 | ||||
-rw-r--r-- | discover/yaboot-parser.c | 4 |
23 files changed, 775 insertions, 193 deletions
diff --git a/discover/Makefile.am b/discover/Makefile.am index bfe33fa..2339203 100644 --- a/discover/Makefile.am +++ b/discover/Makefile.am @@ -58,7 +58,8 @@ discover_pb_discover_LDADD = \ discover/native/native-parser.ro \ discover/platform.ro \ $(core_lib) \ - $(UDEV_LIBS) + $(UDEV_LIBS) \ + $(ELF_LIBS) discover_pb_discover_LDFLAGS = \ $(AM_LDFLAGS) \ @@ -79,7 +80,9 @@ discover_platform_ro_SOURCES = \ discover/ipmi.h \ discover/dt.c \ discover/dt.h \ - discover/hostboot.h + discover/hostboot.h \ + discover/elf.c \ + discover/elf.h if PLATFORM_ARM64 discover_platform_ro_SOURCES += discover/platform-arm64.c diff --git a/discover/boot.c b/discover/boot.c index 91fc46d..00507b7 100644 --- a/discover/boot.c +++ b/discover/boot.c @@ -25,6 +25,7 @@ #include "paths.h" #include "resource.h" #include "platform.h" +#include "sysinfo.h" #include <security/security.h> @@ -60,30 +61,50 @@ static void __attribute__((format(__printf__, 4, 5))) update_status( */ static int kexec_load(struct boot_task *boot_task) { + const char *load_args[] = {"-l", "-s"}; + const struct system_info *sysinfo; struct process *process; char *s_initrd = NULL; char *s_args = NULL; const char *argv[8]; char *s_dtb = NULL; const char **p; + char *err_buf; int result; + size_t i; + sysinfo = system_info_get(); boot_task->local_initrd_override = NULL; boot_task->local_dtb_override = NULL; boot_task->local_image_override = NULL; - if ((result = validate_boot_files(boot_task))) { - if (result == KEXEC_LOAD_DECRYPTION_FALURE) { - pb_log("%s: Aborting kexec due to" - " decryption failure\n", __func__); - } - if (result == KEXEC_LOAD_SIGNATURE_FAILURE) { - pb_log("%s: Aborting kexec due to signature" - " verification failure\n", __func__); + result = validate_boot_files(boot_task); + if (result) { + const char *msg; + + switch (result) { + case KEXEC_LOAD_DECRYPTION_FALURE: + msg = _("decryption failed"); + break; + case KEXEC_LOAD_SIGNATURE_FAILURE: + msg = _("signature verification failed"); + break; + case KEXEC_LOAD_SIG_SETUP_INVALID: + msg = _("invalid signature configuration"); + break; + default: + msg = _("unknown verification failure"); } - goto abort_kexec; + update_status(boot_task->status_fn, boot_task->status_arg, + STATUS_ERROR, + _("Boot verification failure: %s"), msg); + pb_log_fn("Aborting kexec due to verification failure: %s", + msg); + + validate_boot_files_cleanup(boot_task); + return result; } const char* local_initrd = (boot_task->local_initrd_override) ? @@ -93,20 +114,10 @@ static int kexec_load(struct boot_task *boot_task) const char* local_image = (boot_task->local_image_override) ? boot_task->local_image_override : boot_task->local_image; - process = process_create(boot_task); - if (!process) { - pb_log_fn("failed to create process\n"); - return -1; - } - - process->path = pb_system_apps.kexec; - process->argv = argv; - process->keep_stdout = true; - process->add_stderr = true; - + /* set up process arguments */ p = argv; *p++ = pb_system_apps.kexec; /* 1 */ - *p++ = "-l"; /* 2 */ + *p++ = NULL; /* 2; modified below */ if (pb_log_get_debug()) { *p++ = "--debug"; /* 3 */ @@ -134,21 +145,57 @@ static int kexec_load(struct boot_task *boot_task) *p++ = local_image; /* 7 */ *p++ = NULL; /* 8 */ - result = process_run_sync(process); - if (result) { - pb_log_fn("failed to run process\n"); - goto abort_kexec; - } + err_buf = NULL; - result = process->exit_status; + for (i = 0; i < ARRAY_SIZE(load_args); i++) { + /* our first argument is the action: -s or -l */ + argv[1] = load_args[i]; - if (result) { - pb_log_fn("failed: (%d)\n", result); - update_status(boot_task->status_fn, boot_task->status_arg, - STATUS_ERROR, "%s", process->stdout_buf); + /* if we're enforcing, we know a -l load will fail; skip */ + if (sysinfo->stb_os_enforcing && argv[1][1] == 'l') + continue; + + process = process_create(boot_task); + if (!process) { + result = -1; + pb_log_fn("failed to create process\n"); + continue; + } + + process->path = pb_system_apps.kexec; + process->argv = argv; + process->keep_stdout = true; + process->add_stderr = true; + + result = process_run_sync(process); + if (result) { + pb_log_fn("failed to run process\n"); + continue; + } + + result = 0; + + if (process_exit_ok(process)) + break; + + result = -1; + + if (process->stdout_len) + err_buf = talloc_strndup(boot_task, process->stdout_buf, + process->stdout_len); + + pb_log_fn("kexec load (%s) failed (rc %d): %s\n", argv[1], + WEXITSTATUS(process->exit_status), + err_buf ?: ""); + + process_release(process); } -abort_kexec: + if (result) + update_status(boot_task->status_fn, boot_task->status_arg, + STATUS_ERROR, _("kexec load failed: %s"), + err_buf ?: "(no output)"); + validate_boot_files_cleanup(boot_task); return result; @@ -401,6 +448,24 @@ static void cleanup_cancellations(struct boot_task *task, talloc_free(task); } +static bool preboot_check(struct boot_task *task) +{ + const char *local_image = (task->local_image_override) ? + task->local_image_override : task->local_image; + + char *preboot_check_err_msg = NULL; + bool preboot_check_ret = platform_preboot_check(local_image, + &preboot_check_err_msg); + + if (preboot_check_err_msg) { + update_status(task->status_fn, task->status_arg, + STATUS_ERROR, "%s", preboot_check_err_msg); + talloc_free(preboot_check_err_msg); + } + + return preboot_check_ret; +} + static void boot_process(struct load_url_result *result, void *data) { struct boot_task *task = data; @@ -424,25 +489,13 @@ static void boot_process(struct load_url_result *result, void *data) run_boot_hooks(task); + if (!preboot_check(task)) + return; + update_status(task->status_fn, task->status_arg, STATUS_INFO, _("Performing kexec load")); rc = kexec_load(task); - pb_log_fn("kexec_load returned %d\n", rc); - if (rc == KEXEC_LOAD_DECRYPTION_FALURE) { - update_status(task->status_fn, task->status_arg, - STATUS_ERROR, _("Decryption failed")); - } - else if (rc == KEXEC_LOAD_SIGNATURE_FAILURE) { - update_status(task->status_fn, task->status_arg, - STATUS_ERROR, - _("Signature verification failed")); - } - else if (rc == KEXEC_LOAD_SIG_SETUP_INVALID) { - update_status(task->status_fn, task->status_arg, - STATUS_ERROR, - _("Invalid signature configuration")); - } no_load: list_for_each_entry(&task->resources, resource, list) diff --git a/discover/device-handler.c b/discover/device-handler.c index d41bb4b..d85f1af 100644 --- a/discover/device-handler.c +++ b/discover/device-handler.c @@ -1209,7 +1209,7 @@ void device_handler_add_ramdisk(struct device_handler *handler, } handler->ramdisks[i] = dev; - i = handler->n_ramdisks++; + handler->n_ramdisks++; } struct ramdisk_device *device_handler_get_ramdisk( diff --git a/discover/discover-server.c b/discover/discover-server.c index 1a332cb..e29ce27 100644 --- a/discover/discover-server.c +++ b/discover/discover-server.c @@ -298,7 +298,7 @@ static int discover_server_handle_auth_message(struct client *client, { struct status *status; char *hash; - int rc; + int rc = 0; status = talloc_zero(client, struct status); @@ -403,7 +403,7 @@ static int discover_server_process_message(void *arg) struct client *client = arg; struct config *config; char *url; - int rc; + int rc = 0; message = pb_protocol_read_message(client, client->fd); @@ -460,7 +460,7 @@ static int discover_server_process_message(void *arg) talloc_free(status); } } - return 0; + return rc; } switch (message->action) { @@ -537,7 +537,7 @@ static int discover_server_process_message(void *arg) break; } - rc = discover_server_handle_auth_message(client, auth_msg); + discover_server_handle_auth_message(client, auth_msg); talloc_free(auth_msg); break; default: @@ -791,8 +791,11 @@ struct discover_server *discover_server_init(struct waitset *waitset) /* Allow all clients to communicate on this socket */ group = getgrnam("petitgroup"); if (group) { - chown(PB_SOCKET_PATH, 0, group->gr_gid); - chmod(PB_SOCKET_PATH, 0660); + if (chown(PB_SOCKET_PATH, 0, group->gr_gid)) + pb_log_fn("Error setting socket ownership: %m\n"); + errno = 0; + if (chmod(PB_SOCKET_PATH, 0660)) + pb_log_fn("Error setting socket permissions: %m\n"); } if (listen(server->socket, 8)) { diff --git a/discover/elf.c b/discover/elf.c new file mode 100644 index 0000000..8c2711e --- /dev/null +++ b/discover/elf.c @@ -0,0 +1,86 @@ +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> + +#include <log/log.h> +#include "elf.h" + +Elf *elf_open_image(const char *image) +{ + int fd; + Elf *elf = NULL; + int err; + + if (!image) { + pb_log_fn("kernel image path is null\n"); + return NULL; + } + + if ((elf_version(EV_CURRENT) == EV_NONE) || + ((fd = open(image, O_RDONLY, 0)) == -1) || + (!(elf = elf_begin(fd, ELF_C_READ, NULL)))) { + err = elf_errno(); + if (err) + pb_log_fn("failed to read %s elf: %s\n", + image, elf_errmsg(err)); + } + + return elf; +} + +static bool elf_getnote_offset(Elf_Data * const edata, + const char *namespace, + const uint32_t type, GElf_Nhdr *nhdr, + size_t *n_off, size_t *d_off) +{ + size_t off = 0; + size_t next; + + /* Iterate through notes */ + while ((next = gelf_getnote(edata, off, nhdr, n_off, d_off)) > 0) { + char *note_ns = (char *) edata->d_buf + (*n_off); + if ((strcmp(note_ns, namespace) == 0) && (nhdr->n_type == type)) + return true; + + off = next; + } + return false; +} + +void *elf_getnote_desc(Elf *elf, + const char *namespace, + uint32_t type) +{ + Elf_Scn *scn = NULL; + Elf_Data *edata = NULL; + GElf_Shdr shdr; + GElf_Nhdr nhdr; + + size_t n_off; + size_t d_off; + void *desc = NULL; + + if (!elf || !namespace) + return NULL; + + /* Iterate through sections */ + while ((scn = elf_nextscn(elf, scn))) { + gelf_getshdr(scn, &shdr); + + /* ELF might have more than one SHT_NOTE section but + only one has the 'namespace' note */ + if (shdr.sh_type == SHT_NOTE) { + edata = elf_getdata(scn, NULL); + if (elf_getnote_offset(edata, namespace, type, + &nhdr, &n_off, &d_off)) { + desc = calloc(nhdr.n_descsz, sizeof(char)); + memcpy(desc, edata->d_buf + d_off, + nhdr.n_descsz); + break; + } + } + } + + return desc; +} + diff --git a/discover/elf.h b/discover/elf.h new file mode 100644 index 0000000..742b791 --- /dev/null +++ b/discover/elf.h @@ -0,0 +1,29 @@ +#ifndef _PB_ELF_H +#define _PB_ELF_H + +#include <elfutils/libdw.h> +#include <libelf.h> + +/* + * The PowerPC namespace in an ELF Note of the kernel binary is used to store + * capabilities and information which can be used by a bootloader or userland + * + * docs: Documentation/powerpc/elfnote.rst + */ +#define POWERPC_ELFNOTE_NAMESPACE "PowerPC" + +/* + * The capabilities supported/required by the kernel + * This type uses a bitmap as "desc" field. + */ +#define PPC_ELFNOTE_CAPABILITIES 0x1 + +/* bitmap fields: */ +#define PPCCAP_ULTRAVISOR_BIT 0x1 + +Elf *elf_open_image(const char *image); +void *elf_getnote_desc(Elf *elf, + const char *namespace, + uint32_t type); + +#endif /* _PB_ELF_H */ diff --git a/discover/event.c b/discover/event.c index ec5537a..4c46d41 100644 --- a/discover/event.c +++ b/discover/event.c @@ -101,7 +101,6 @@ static void event_parse_params(struct event *event, const char *buf, int len) sep = memchr(buf, '=', param_len); if (!sep) { name_len = param_len; - value_len = 0; param->value = ""; } else { name_len = sep - buf; diff --git a/discover/grub2/blscfg.c b/discover/grub2/blscfg.c index d4754aa..d08f8f0 100644 --- a/discover/grub2/blscfg.c +++ b/discover/grub2/blscfg.c @@ -166,7 +166,6 @@ static void bls_finish(struct conf_context *conf) struct discover_context *dc = conf->dc; struct discover_boot_option *opt = state->opt; struct boot_option *option = opt->option; - const char *root; char *filename; if (!state->image) { @@ -192,23 +191,21 @@ static void bls_finish(struct conf_context *conf) else option->name = talloc_strdup(option, state->image); - root = script_env_get(state->script, "root"); - - opt->boot_image = create_grub2_resource(opt, conf->dc->device, - root, state->image); + opt->boot_image = create_grub2_resource(state->script, opt, + state->image); if (state->initrd) - opt->initrd = create_grub2_resource(opt, conf->dc->device, - root, state->initrd); + opt->initrd = create_grub2_resource(state->script, opt, + state->initrd); if (state->dtb) - opt->dtb = create_grub2_resource(opt, conf->dc->device, - root, state->dtb); + opt->dtb = create_grub2_resource(state->script, opt, + state->dtb); char* args_sigfile_default = talloc_asprintf(opt, "%s.cmdline.sig", state->image); - opt->args_sig_file = create_grub2_resource(opt, conf->dc->device, - root, args_sigfile_default); + opt->args_sig_file = create_grub2_resource(state->script, opt, + args_sigfile_default); talloc_free(args_sigfile_default); option->is_default = option_is_default(state, option); diff --git a/discover/grub2/builtins.c b/discover/grub2/builtins.c index 7e92299..ab1407a 100644 --- a/discover/grub2/builtins.c +++ b/discover/grub2/builtins.c @@ -1,4 +1,7 @@ +#define _GNU_SOURCE + +#include <getopt.h> #include <stdio.h> #include <string.h> @@ -43,7 +46,6 @@ static int builtin_linux(struct grub2_script *script, int argc, char *argv[]) { struct discover_boot_option *opt = script->opt; - const char *root; int i; if (!opt) { @@ -58,10 +60,7 @@ static int builtin_linux(struct grub2_script *script, return -1; } - root = script_env_get(script, "root"); - - opt->boot_image = create_grub2_resource(opt, script->ctx->device, - root, argv[1]); + opt->boot_image = create_grub2_resource(script, opt, argv[1]); opt->option->boot_args = NULL; if (argc > 2) @@ -74,8 +73,8 @@ static int builtin_linux(struct grub2_script *script, char* args_sigfile_default = talloc_asprintf(opt, "%s.cmdline.sig", argv[1]); - opt->args_sig_file = create_grub2_resource(opt, script->ctx->device, - root, args_sigfile_default); + opt->args_sig_file = create_grub2_resource(script, opt, + args_sigfile_default); talloc_free(args_sigfile_default); return 0; } @@ -85,7 +84,6 @@ static int builtin_initrd(struct grub2_script *script, int argc, char *argv[]) { struct discover_boot_option *opt = script->opt; - const char *root; if (!opt) { pb_log("grub2 syntax error: 'initrd' statement outside " @@ -99,35 +97,128 @@ static int builtin_initrd(struct grub2_script *script, return -1; } - root = script_env_get(script, "root"); - opt->initrd = create_grub2_resource(opt, script->ctx->device, - root, argv[1]); + opt->initrd = create_grub2_resource(script, opt, argv[1]); return 0; } +static const struct option search_options[] = { + { + .name = "set", + .has_arg = required_argument, + .val = 's', + }, + { + .name = "file", + .has_arg = no_argument, + .val = 'f', + }, + { + .name = "label", + .has_arg = no_argument, + .val = 'l', + }, + { + .name = "fs-uuid", + .has_arg = no_argument, + .val = 'u', + }, + { 0 }, +}; + static int builtin_search(struct grub2_script *script, void *data __attribute__((unused)), int argc, char *argv[]) { - const char *env_var, *spec; - int i; - - env_var = NULL; + const char *env_var, *spec, *res; + struct discover_device *dev; + enum { + LOOKUP_UUID = 'u', + LOOKUP_LABEL = 'l', + LOOKUP_FILE = 'f', + } lookup_type; + + env_var = "root"; + optind = 0; + + /* Default to UUID, for backwards compat with earlier petitboot + * versions. This argument is non-optional in GRUB. */ + lookup_type = LOOKUP_UUID; + + for (;;) { + int c = getopt_long(argc, argv, ":flu", search_options, NULL); + if (c == -1) + break; - for (i = 1; i < argc - 1; i++) { - if (!strncmp(argv[i], "--set=", strlen("--set="))) { - env_var = argv[i] + strlen("--set="); + switch (c) { + case 's': + env_var = optarg; + break; + case LOOKUP_UUID: + case LOOKUP_LABEL: + case LOOKUP_FILE: + lookup_type = c; + break; + case '?': + case ':': break; } } - if (!env_var) + if (!strlen(env_var)) return 0; - spec = argv[argc - 1]; + if (optind >= argc) + return -1; + + spec = argv[optind]; + res = NULL; + + switch (lookup_type) { + case LOOKUP_UUID: + dev = device_lookup_by_uuid(script->ctx->handler, + spec); + res = dev ? dev->device->id : spec; + break; + case LOOKUP_LABEL: + dev = device_lookup_by_label(script->ctx->handler, + spec); + if (dev) + res = dev->device->id; + break; + case LOOKUP_FILE: + /* not yet implemented */ + break; + } + + if (res) + script_env_set(script, env_var, res); + + return 0; +} + +static int parse_to_device_path(struct grub2_script *script, + const char *desc, struct discover_device **devp, + char **pathp) +{ + struct discover_device *dev; + struct grub2_file *file; + + file = grub2_parse_file(script, desc); + if (!file) + return -1; + + dev = script->ctx->device; + if (file->dev) + dev = grub2_lookup_device(script->ctx->handler, file->dev); + + if (!dev) + return -1; + + *devp = dev; + *pathp = talloc_strdup(script, file->path); - script_env_set(script, env_var, spec); + talloc_free(file); return 0; } @@ -139,12 +230,17 @@ static int builtin_search(struct grub2_script *script, static bool builtin_test_op_file(struct grub2_script *script, char op, const char *file) { + struct discover_device *dev; + struct stat statbuf; bool result; + char *path; int rc; - struct stat statbuf; - rc = parser_stat_path(script->ctx, script->ctx->device, - file, &statbuf); + rc = parse_to_device_path(script, file, &dev, &path); + if (rc) + return false; + + rc = parser_stat_path(script->ctx, dev, path, &statbuf); if (rc) return false; @@ -172,16 +268,21 @@ static bool builtin_test_op_file(struct grub2_script *script, char op, static bool builtin_test_op_dir(struct grub2_script *script, char op, const char *dir) { - int rc; + struct discover_device *dev; struct stat statbuf; + char *path; + int rc; if (op != 'd') return false; - rc = parser_stat_path(script->ctx, script->ctx->device, dir, &statbuf); - if (rc) { + rc = parse_to_device_path(script, dir, &dev, &path); + if (rc) + return false; + + rc = parser_stat_path(script->ctx, dev, path, &statbuf); + if (rc) return false; - } return S_ISDIR(statbuf.st_mode); } @@ -300,6 +401,51 @@ static int builtin_test(struct grub2_script *script, return rc ? 0 : 1; } +static int builtin_source(struct grub2_script *script, + void *data __attribute__((unused)), + int argc, char *argv[]) +{ + struct grub2_statements *statements; + struct discover_device *dev; + const char *filename; + char *path, *buf; + int rc, len; + + if (argc != 2) + return false; + + /* limit script recursion */ + if (script->include_depth >= 10) + return false; + + rc = parse_to_device_path(script, argv[1], &dev, &path); + if (rc) + return false; + + rc = parser_request_file(script->ctx, dev, path, &buf, &len); + if (rc) + return false; + + /* save current script state */ + statements = script->statements; + filename = script->filename; + script->include_depth++; + + rc = grub2_parser_parse(script->parser, argv[1], buf, len); + + if (!rc) + statements_execute(script, script->statements); + + talloc_free(script->statements); + + /* restore state */ + script->statements = statements; + script->filename = filename; + script->include_depth--; + + return !rc; +} + static int builtin_true(struct grub2_script *script __attribute__((unused)), void *data __attribute__((unused)), int argc __attribute__((unused)), @@ -390,7 +536,11 @@ static struct { { .name = "blscfg", .fn = builtin_blscfg, - } + }, + { + .name = "source", + .fn = builtin_source, + }, }; static const char *nops[] = { diff --git a/discover/grub2/env.c b/discover/grub2/env.c index 7eda095..74d5729 100644 --- a/discover/grub2/env.c +++ b/discover/grub2/env.c @@ -86,6 +86,8 @@ int builtin_load_env(struct grub2_script *script, if (!rc) { rc = parse_buf_to_env(script, buf, len); + if (rc) + pb_debug_fn("Failed to set env\n"); talloc_free(buf); } diff --git a/discover/grub2/grub2-parser.y b/discover/grub2/grub2-parser.y index 527a61c..f99bbfd 100644 --- a/discover/grub2/grub2-parser.y +++ b/discover/grub2/grub2-parser.y @@ -331,14 +331,15 @@ struct grub2_parser *grub2_parser_create(struct discover_context *ctx) return parser; } -void grub2_parser_parse(struct grub2_parser *parser, const char *filename, +/* performs a parse on buf, setting parser->script->statements */ +int grub2_parser_parse(struct grub2_parser *parser, const char *filename, char *buf, int len) { YY_BUFFER_STATE bufstate; int rc; if (!len) - return; + return -1; parser->script->filename = filename; @@ -349,6 +350,18 @@ void grub2_parser_parse(struct grub2_parser *parser, const char *filename, yy_delete_buffer(bufstate, parser->scanner); + parser->inter_word = false; + + return rc; +} + +void grub2_parser_parse_and_execute(struct grub2_parser *parser, + const char *filename, char *buf, int len) +{ + int rc; + + rc = grub2_parser_parse(parser, filename, buf, len); + if (!rc) script_execute(parser->script); } diff --git a/discover/grub2/grub2.c b/discover/grub2/grub2.c index f62ccdd..b176ce2 100644 --- a/discover/grub2/grub2.c +++ b/discover/grub2/grub2.c @@ -33,18 +33,35 @@ static const char *const grub2_conf_files[] = { NULL }; -struct grub2_resource_info { - char *root; - char *path; -}; +struct discover_device *grub2_lookup_device(struct device_handler *handler, + const char *desc) +{ + struct discover_device *dev; + + if (!desc || !*desc) + return NULL; + + dev = device_lookup_by_id(handler, desc); + if (dev) + return dev; + + /* for now, only lookup by UUID */ + dev = device_lookup_by_uuid(handler, desc); + if (dev) + return dev; + + return NULL; +} /* we use slightly different resources for grub2 */ -struct resource *create_grub2_resource(struct discover_boot_option *opt, - struct discover_device *orig_device, - const char *root, const char *path) +struct resource *create_grub2_resource(struct grub2_script *script, + struct discover_boot_option *opt, + const char *path) { - struct grub2_resource_info *info; + struct discover_device *dev; + struct grub2_file *file; struct resource *res; + const char *root; if (strstr(path, "://")) { struct pb_url *url = pb_url_parse(opt, path); @@ -52,19 +69,29 @@ struct resource *create_grub2_resource(struct discover_boot_option *opt, return create_url_resource(opt, url); } + file = grub2_parse_file(script, path); + if (!file) + return NULL; + res = talloc(opt, struct resource); + root = script_env_get(script, "root"); - if (root) { - info = talloc(res, struct grub2_resource_info); - talloc_reference(info, root); - info->root = talloc_strdup(info, root); - info->path = talloc_strdup(info, path); + if (!file->dev && root && strlen(root)) + file->dev = talloc_strdup(file, root); - res->resolved = false; - res->info = info; + /* if we don't have a device specified, or the lookup succeeds now, + * then we can resolve the resource right away */ + if (file->dev) + dev = grub2_lookup_device(script->ctx->handler, file->dev); + else + dev = script->ctx->device; - } else - resolve_resource_against_device(res, orig_device, path); + if (dev) { + resolve_resource_against_device(res, dev, file->path); + } else { + res->resolved = false; + res->info = talloc_steal(opt, file); + } return res; } @@ -72,22 +99,59 @@ struct resource *create_grub2_resource(struct discover_boot_option *opt, bool resolve_grub2_resource(struct device_handler *handler, struct resource *res) { - struct grub2_resource_info *info = res->info; + struct grub2_file *file = res->info; struct discover_device *dev; assert(!res->resolved); - dev = device_lookup_by_uuid(handler, info->root); - + dev = grub2_lookup_device(handler, file->dev); if (!dev) return false; - resolve_resource_against_device(res, dev, info->path); - talloc_free(info); + resolve_resource_against_device(res, dev, file->path); + talloc_free(file); return true; } +struct grub2_file *grub2_parse_file(struct grub2_script *script, + const char *str) +{ + struct grub2_file *file; + size_t dev_len; + char *pos; + + if (!str) + return NULL; + + file = talloc_zero(script, struct grub2_file); + + if (*str != '(') { + /* just a path - no device, return path as-is */ + file->path = talloc_strdup(file, str); + + } else { + /* device plus path - split into components */ + + pos = strchr(str, ')'); + + /* no closing bracket, or zero-length path? */ + if (!pos || *(pos+1) == '\0') { + talloc_free(file); + return NULL; + } + + file->path = talloc_strdup(file, pos + 1); + + dev_len = pos - str - 1; + if (dev_len) + file->dev = talloc_strndup(file, str + 1, dev_len); + } + + return file; +} + + static int grub2_parse(struct discover_context *dc) { const char * const *filename; @@ -105,7 +169,7 @@ static int grub2_parse(struct discover_context *dc) continue; parser = grub2_parser_create(dc); - grub2_parser_parse(parser, *filename, buf, len); + grub2_parser_parse_and_execute(parser, *filename, buf, len); device_handler_status_dev_info(dc->handler, dc->device, _("Parsed GRUB configuration from %s"), *filename); diff --git a/discover/grub2/grub2.h b/discover/grub2/grub2.h index 68176fb..75f6aa0 100644 --- a/discover/grub2/grub2.h +++ b/discover/grub2/grub2.h @@ -91,6 +91,7 @@ struct grub2_statement_for { }; struct grub2_script { + struct grub2_parser *parser; struct grub2_statements *statements; struct list environment; struct list symtab; @@ -99,6 +100,7 @@ struct grub2_script { const char *filename; unsigned int n_options; struct list options; + int include_depth; }; struct grub2_parser { @@ -107,6 +109,14 @@ struct grub2_parser { bool inter_word; }; +/* References to files in grub2 consist of an optional device and a path + * (specified here by UUID). If the dev is unspecified, we fall back to a + * default - usually the 'root' environment variable. */ +struct grub2_file { + char *dev; + char *path; +}; + /* type for builtin functions */ typedef int (*grub2_function)(struct grub2_script *script, void *data, int argc, char *argv[]); @@ -156,6 +166,9 @@ void word_append(struct grub2_word *w1, struct grub2_word *w2); /* script interface */ void script_execute(struct grub2_script *script); +int statements_execute(struct grub2_script *script, + struct grub2_statements *stmts); + int statement_simple_execute(struct grub2_script *script, struct grub2_statement *statement); int statement_block_execute(struct grub2_script *script, @@ -183,16 +196,25 @@ void script_register_function(struct grub2_script *script, void register_builtins(struct grub2_script *script); /* resources */ -struct resource *create_grub2_resource(struct discover_boot_option *opt, - struct discover_device *orig_device, - const char *root, const char *path); +struct resource *create_grub2_resource(struct grub2_script *script, + struct discover_boot_option *opt, const char *path); bool resolve_grub2_resource(struct device_handler *handler, struct resource *res); +/* grub-style device+path parsing */ +struct grub2_file *grub2_parse_file(struct grub2_script *script, + const char *str); +struct discover_device *grub2_lookup_device(struct device_handler *handler, + const char *desc); + +/* internal parse api */ +int grub2_parser_parse(struct grub2_parser *parser, const char *filename, + char *buf, int len); + /* external parser api */ struct grub2_parser *grub2_parser_create(struct discover_context *ctx); -void grub2_parser_parse(struct grub2_parser *parser, const char *filename, - char *buf, int len); +void grub2_parser_parse_and_execute(struct grub2_parser *parser, + const char *filename, char *buf, int len); #endif /* GRUB2_H */ diff --git a/discover/grub2/script.c b/discover/grub2/script.c index 1a802b9..14931f9 100644 --- a/discover/grub2/script.c +++ b/discover/grub2/script.c @@ -117,12 +117,10 @@ static bool option_is_default(struct grub2_script *script, if (end != var && *end == '\0') return default_idx == script->n_options; - /* if we don't have an explicit id for this option, fall back to - * the name */ - if (!id) - id = opt->option->name; + if (id && !strcmp(id, var)) + return true; - return !strcmp(id, var); + return !strcmp(opt->option->name, var); } static void append_text_to_current_arg(struct grub2_argv *argv, @@ -227,11 +225,11 @@ static void process_expansions(struct grub2_script *script, } /* we may have allocated an extra argv element but not populated it */ - if (!argv->argv[argv->argc - 1]) + if (argv->argv && !argv->argv[argv->argc - 1]) argv->argc--; } -static int statements_execute(struct grub2_script *script, +int statements_execute(struct grub2_script *script, struct grub2_statements *stmts) { struct grub2_statement *stmt; @@ -341,9 +339,16 @@ int statement_menuentry_execute(struct grub2_script *script, * implementation to get --id= working. */ for (i = 1; i < st->argv->argc; ++i) { - if (strncmp("--id=", st->argv->argv[i], 5) == 0) { - id = st->argv->argv[i] + 5; - break; + if (strncmp("--id", st->argv->argv[i], strlen("--id")) == 0) { + if (strlen(st->argv->argv[i]) > strlen("--id=")) { + id = st->argv->argv[i] + strlen("--id="); + break; + } + + if (i + 1 < st->argv->argc) { + id = st->argv->argv[i + 1]; + break; + } } } if (st->argv->argc > 0) @@ -489,6 +494,9 @@ void script_execute(struct grub2_script *script) { struct discover_boot_option *opt, *tmp; + if (!script) + return; + init_env(script); statements_execute(script, script->statements); @@ -510,6 +518,7 @@ struct grub2_script *create_script(struct grub2_parser *parser, script = talloc_zero(parser, struct grub2_script); script->ctx = ctx; + script->parser = parser; list_init(&script->symtab); list_init(&script->options); diff --git a/discover/ipmi.c b/discover/ipmi.c index ae02bb0..66b465e 100644 --- a/discover/ipmi.c +++ b/discover/ipmi.c @@ -306,7 +306,6 @@ int parse_ipmi_interface_override(struct config *config, uint8_t *buf, return -1; } ifconf->static_config.gateway = gatewaystr; - i += ipsize; } ifconf->override = true; diff --git a/discover/ipmi.h b/discover/ipmi.h index c8ccb46..f8672b0 100644 --- a/discover/ipmi.h +++ b/discover/ipmi.h @@ -29,6 +29,29 @@ enum ipmi_sensor_ids { struct ipmi; +#define CHASSIS_BOOT_MBOX_IANA_SZ 3 +#define CHASSIS_BOOT_MBOX_DATA_SZ 16 +#define CHASSIS_BOOT_MBOX_BLOCK0_DATA_SZ \ + (CHASSIS_BOOT_MBOX_DATA_SZ - CHASSIS_BOOT_MBOX_IANA_SZ) + +typedef struct __attribute__((packed)) { + uint8_t iana[CHASSIS_BOOT_MBOX_IANA_SZ]; + uint8_t data[CHASSIS_BOOT_MBOX_BLOCK0_DATA_SZ]; +} mbox_block0_t; + +typedef union { + uint8_t data[CHASSIS_BOOT_MBOX_DATA_SZ]; + mbox_block0_t b0; +} mbox_t; + +typedef struct __attribute__((packed)) { + uint8_t cc; + uint8_t param_version; + uint8_t param_valid; + uint8_t block_selector; + mbox_t mbox; +} ipmi_mbox_response_t; + static const int ipmi_timeout = 10000; /* milliseconds. */ bool ipmi_present(void); diff --git a/discover/paths.c b/discover/paths.c index 54b843e..16fdd59 100644 --- a/discover/paths.c +++ b/discover/paths.c @@ -450,7 +450,8 @@ static void load_local(struct load_task *task) result->status = LOAD_OK; } - task->async_cb(task->result, task->async_data); + if (task->async_cb) + task->async_cb(task->result, task->async_data); } static void load_url_async_start_pending(struct load_task *task, int flags) diff --git a/discover/platform-powerpc.c b/discover/platform-powerpc.c index 5d7cc59..c6ab416 100644 --- a/discover/platform-powerpc.c +++ b/discover/platform-powerpc.c @@ -21,6 +21,7 @@ #include "platform.h" #include "ipmi.h" #include "dt.h" +#include "elf.h" static const char *partition = "common"; static const char *sysparams_dir = "/sys/firmware/opal/sysparams/"; @@ -222,6 +223,13 @@ static void params_update_all(struct param_list *pl, params_update_network_values(pl, "petitboot,network", config); params_update_bootdev_values(pl, "petitboot,bootdevs", config); + + if (config->preboot_check_enabled == defaults->preboot_check_enabled) + val = ""; + else + val = config->preboot_check_enabled ? "true" : "false"; + + param_list_set_non_empty(pl, "petitboot,preboot-check", val, true); } static void config_set_ipmi_bootdev(struct config *config, enum ipmi_bootdev bootdev, @@ -437,10 +445,10 @@ static int get_ipmi_bootdev_ipmi(struct platform_powerpc *platform, } static int get_ipmi_boot_mailbox_block(struct platform_powerpc *platform, - char *buf, uint8_t block) + mbox_t *mailbox, uint8_t block) { size_t blocksize = 16; - uint8_t resp[3 + 16]; + ipmi_mbox_response_t ipmi_mbox_resp = { .cc = 0xFF }; uint16_t resp_len; char *debug_buf; int rc; @@ -449,60 +457,71 @@ static int get_ipmi_boot_mailbox_block(struct platform_powerpc *platform, block, /* set selector */ 0x00, /* no block selector */ }; + size_t ipmi_header_len = sizeof(ipmi_mbox_response_t) - sizeof(mbox_t); - resp_len = sizeof(resp); + resp_len = sizeof(ipmi_mbox_response_t); rc = ipmi_transaction(platform->ipmi, IPMI_NETFN_CHASSIS, IPMI_CMD_CHASSIS_GET_SYSTEM_BOOT_OPTIONS, req, sizeof(req), - resp, &resp_len, + (uint8_t*)&ipmi_mbox_resp, &resp_len, ipmi_timeout); if (rc) { pb_log("platform: error reading IPMI boot options\n"); return -1; } - if (resp_len < sizeof(resp)) { - if (resp_len < 3) { - pb_log("platform: unexpected length (%d) in " - "boot options mailbox response\n", - resp_len); - return -1; - } - - if (resp_len == 4) { - pb_debug_fn("block %hu empty\n", block); - return 0; - } + if (resp_len > sizeof(ipmi_mbox_response_t)) { + pb_debug("platform: invalid mailbox response size!\n"); + return -1; + } - blocksize = sizeof(resp) - 3; - pb_debug_fn("Mailbox block %hu returns only %zu bytes in block\n", - block, blocksize); + if (resp_len < ipmi_header_len) { + pb_log("platform: unexpected length (%d) in " + "boot options mailbox response\n", + resp_len); + return -1; } - debug_buf = format_buffer(platform, resp, resp_len); + blocksize = resp_len - ipmi_header_len; + pb_debug_fn("Mailbox block %hu returns only %zu bytes in block\n", + block, blocksize); + + debug_buf = format_buffer(platform, (uint8_t*)&ipmi_mbox_resp, resp_len); pb_debug_fn("IPMI bootdev mailbox block %hu:\n%s\n", block, debug_buf); talloc_free(debug_buf); - if (resp[0] != 0) { + if (ipmi_mbox_resp.cc != 0) { pb_log("platform: non-zero completion code %d from IPMI req\n", - resp[0]); + ipmi_mbox_resp.cc); return -1; } /* check for correct parameter version */ - if ((resp[1] & 0xf) != 0x1) { + if ((ipmi_mbox_resp.param_version & 0xf) != 0x1) { pb_log("platform: unexpected version (0x%x) in " - "boot mailbox response\n", resp[0]); + "boot mailbox response\n", ipmi_mbox_resp.param_version); return -1; } /* check for valid paramters */ - if (resp[2] & 0x80) { + if (ipmi_mbox_resp.param_valid & 0x80) { pb_debug("platform: boot mailbox parameters are invalid/locked\n"); return -1; } - memcpy(buf, &resp[3], blocksize); + /* check for block number */ + if (ipmi_mbox_resp.block_selector != block) { + pb_debug("platform: returned boot mailbox block doesn't match " + "requested\n"); + return -1; + } + + if (!blocksize) { + pb_debug_fn("block %hu empty\n", block); + return 0; + } + + memcpy(mailbox, &ipmi_mbox_resp.mbox, blocksize); return blocksize; } @@ -511,12 +530,10 @@ static int get_ipmi_boot_mailbox(struct platform_powerpc *platform, char **buf) { char *mailbox_buffer, *prefix; - const size_t blocksize = 16; - char block_buffer[blocksize]; + mbox_t mailbox; size_t mailbox_size; int content_size; uint8_t i; - int rc; mailbox_buffer = NULL; mailbox_size = 0; @@ -527,15 +544,16 @@ static int get_ipmi_boot_mailbox(struct platform_powerpc *platform, * on higher numbers. */ for (i = 0; i < UCHAR_MAX; i++) { - rc = get_ipmi_boot_mailbox_block(platform, block_buffer, i); - if (rc < 3 && i == 0) { + uint8_t *boot_opt_data; + int block_size = get_ipmi_boot_mailbox_block(platform, &mailbox, i); + if (block_size < CHASSIS_BOOT_MBOX_IANA_SZ && i == 0) { /* * Immediate failure, no blocks read or missing IANA * number. */ return -1; } - if (rc < 1) { + if (block_size < 1) { /* Error or no bytes read */ break; } @@ -543,28 +561,33 @@ static int get_ipmi_boot_mailbox(struct platform_powerpc *platform, if (i == 0) { /* * The first three bytes of block zero are an IANA - * Enterprise ID number. Check it matches the IBM - * number, '2'. + * Enterprise ID number */ - if (block_buffer[0] != 0x02 || - block_buffer[1] != 0x00 || - block_buffer[2] != 0x00) { + block_size -= CHASSIS_BOOT_MBOX_IANA_SZ; + boot_opt_data = &mailbox.b0.data; + + /* Check IANA matches the IBM number, '2' */ + if (mailbox.b0.iana[0] != 0x02 || + mailbox.b0.iana[1] != 0x00 || + mailbox.b0.iana[2] != 0x00) { pb_log_fn("IANA number unrecognised: 0x%x:0x%x:0x%x\n", - block_buffer[0], - block_buffer[1], - block_buffer[2]); + mailbox.b0.iana[0], + mailbox.b0.iana[1], + mailbox.b0.iana[2]); return -1; } + } else { + boot_opt_data = &mailbox.data; } mailbox_buffer = talloc_realloc(platform, mailbox_buffer, - char, mailbox_size + rc); + char, mailbox_size + block_size); if (!mailbox_buffer) { pb_log_fn("Failed to allocate mailbox buffer\n"); return -1; } - memcpy(mailbox_buffer + mailbox_size, block_buffer, rc); - mailbox_size += rc; + memcpy(mailbox_buffer + mailbox_size, boot_opt_data, block_size); + mailbox_size += block_size; } if (i < 5) @@ -574,10 +597,10 @@ static int get_ipmi_boot_mailbox(struct platform_powerpc *platform, else pb_debug_fn("%hu blocks read (%zu bytes)\n", i, mailbox_size); - if (mailbox_size < 3 + strlen("petitboot,bootdevs=")) + if (mailbox_size < strlen("petitboot,bootdevs=")) return -1; - prefix = talloc_strndup(mailbox_buffer, mailbox_buffer + 3, + prefix = talloc_strndup(mailbox_buffer, mailbox_buffer, strlen("petitboot,bootdevs=")); if (!prefix) { pb_log_fn("Couldn't check prefix\n"); @@ -595,9 +618,9 @@ static int get_ipmi_boot_mailbox(struct platform_powerpc *platform, } /* Don't include IANA number in buffer */ - content_size = mailbox_size - 3 - strlen("petitboot,bootdevs="); + content_size = mailbox_size - strlen("petitboot,bootdevs="); *buf = talloc_memdup(platform, - mailbox_buffer + 3 + strlen("petitboot,bootdevs="), + mailbox_buffer + strlen("petitboot,bootdevs="), content_size + 1); (*buf)[content_size] = '\0'; @@ -923,6 +946,72 @@ static void pre_boot(struct platform *p, const struct config *config) platform->set_os_boot_sensor(platform); } +static bool preboot_check(struct platform *p, + const struct config *config, + const char *image, + char **err_msg) +{ + struct platform_powerpc *platform = p->platform_data; + unsigned int *ppc_cap_bitmap = NULL; + bool ultravisor_enabled; + struct stat statbuf; + bool ret = true; + + /* check if ultravisor-system is enabled */ + ultravisor_enabled = stat("/proc/device-tree/ibm,ultravisor", + &statbuf) == 0; + + /* if ultravisor-system is disabled, continue the boot process */ + if (!ultravisor_enabled) + return true; + + ppc_cap_bitmap = elf_getnote_desc(elf_open_image(image), + POWERPC_ELFNOTE_NAMESPACE, + PPC_ELFNOTE_CAPABILITIES); + + if ((ppc_cap_bitmap) && (*ppc_cap_bitmap & PPCCAP_ULTRAVISOR_BIT)) { + pb_debug("kernel capabilities: ultravisor mode found.\n"); + } else { + ret = false; + pb_log_fn("kernel capabilities failed:" + " IBM Ultravisor mode is required.\n"); + *err_msg = talloc_strdup(platform, "IBM Ultravisor capability" + " not found"); + } + free(ppc_cap_bitmap); + + /* if preboot_check is disabled, continue the boot process */ + if (!config->preboot_check_enabled) + return true; + + return ret; +} + +static void get_sysinfo_stb(struct platform_powerpc *platform, + struct system_info *sysinfo) +{ + char *filename; + unsigned int i; + int rc; + struct { + const char *name; + bool *flag; + } props[] = { + { "secure-enabled", &sysinfo->stb_fw_enforcing }, + { "trusted-enabled", &sysinfo->stb_fw_measurement }, + { "os-secureboot-enforcing", &sysinfo->stb_os_enforcing }, + }; + + for (i = 0; i < ARRAY_SIZE(props); i++) { + struct stat statbuf; + filename = talloc_asprintf(platform, "%sibm,secureboot/%s", + devtree_dir, props[i].name); + rc = stat(filename, &statbuf); + *props[i].flag = (rc == 0); + talloc_free(filename); + } +} + static int get_sysinfo(struct platform *p, struct system_info *sysinfo) { struct platform_powerpc *platform = p->platform_data; @@ -951,6 +1040,9 @@ static int get_sysinfo(struct platform *p, struct system_info *sysinfo) if (platform->get_platform_versions) platform->get_platform_versions(sysinfo); + get_sysinfo_stb(platform, sysinfo); + + return 0; } @@ -1028,6 +1120,7 @@ static struct platform platform_powerpc = { .get_sysinfo = get_sysinfo, .restrict_clients = restrict_clients, .set_password = set_password, + .preboot_check = preboot_check, }; register_platform(platform_powerpc); diff --git a/discover/platform.c b/discover/platform.c index 8ce52fc..38bd241 100644 --- a/discover/platform.c +++ b/discover/platform.c @@ -159,6 +159,7 @@ void config_set_defaults(struct config *config) else config->lang = NULL; + config->preboot_check_enabled = true; } int platform_init(void *ctx) @@ -206,6 +207,17 @@ void platform_pre_boot(void) platform->pre_boot(platform, config); } +bool platform_preboot_check(const char *image, char **err_msg) +{ + const struct config *config = config_get(); + + if (platform && config && platform->preboot_check) + return platform->preboot_check(platform, config, + image, err_msg); + + return true; +} + int platform_get_sysinfo(struct system_info *info) { if (platform && platform->get_sysinfo) @@ -572,6 +584,9 @@ void config_populate_all(struct config *config, const struct param_list *pl) val = param_list_get_value(pl, "petitboot,https_proxy"); if (val) config->https_proxy = talloc_strdup(config, val); + + val = param_list_get_value(pl, "petitboot,preboot-check"); + config->preboot_check_enabled = !val || strcmp(val, "false"); } static char *interface_config_str(void *ctx, struct interface_config *config) diff --git a/discover/platform.h b/discover/platform.h index 5a5c990..fe3d390 100644 --- a/discover/platform.h +++ b/discover/platform.h @@ -14,6 +14,10 @@ struct platform { int (*get_sysinfo)(struct platform *, struct system_info *); bool (*restrict_clients)(struct platform *); int (*set_password)(struct platform *, const char *hash); + bool (*preboot_check)(struct platform *, + const struct config *, + const char *image, + char **err_msg); uint16_t dhcp_arch_id; void *platform_data; }; @@ -25,6 +29,7 @@ int platform_get_sysinfo(struct system_info *info); bool platform_restrict_clients(void); int platform_set_password(const char *hash); void platform_pre_boot(void); +bool platform_preboot_check(const char *image, char **err_msg); /* configuration interface */ const struct config *config_get(void); diff --git a/discover/pxe-parser.c b/discover/pxe-parser.c index ba0f81c..035794c 100644 --- a/discover/pxe-parser.c +++ b/discover/pxe-parser.c @@ -292,9 +292,14 @@ static bool ipxe_simple_parser(struct conf_context *ctx, char *buf, int len) continue; } + if (!name) { + pb_debug_fn("missing name from conf_get_pair\n"); + continue; + } + /* All other parameters require a value */ if (!value) { - pb_debug("%s: '%s' missing value\n", __func__, name); + pb_debug_fn("'%s' missing value\n", name); continue; } diff --git a/discover/user-event.c b/discover/user-event.c index d3d4a5e..cc03ffd 100644 --- a/discover/user-event.c +++ b/discover/user-event.c @@ -657,10 +657,10 @@ static void user_event_handle_message(struct user_event *uev, char *buf, break; case EVENT_ACTION_URL: result = user_event_url(uev, event); - goto out; + break; case EVENT_ACTION_DHCP: result = user_event_dhcp(uev, event); - goto out; + break; case EVENT_ACTION_BOOT: result = user_event_boot(uev, event); break; @@ -671,13 +671,17 @@ static void user_event_handle_message(struct user_event *uev, char *buf, result = user_event_plugin(uev, event); break; default: + result = -1; break; } + if (result) + pb_log_fn("failed to handle action %d\n", event->action); + /* user_event_url() and user_event_dhcp() will steal the event context, * but all others still need to free */ - talloc_free(event); -out: + if (talloc_parent(event) == uev) + talloc_free(event); return; } @@ -751,8 +755,11 @@ struct user_event *user_event_init(struct device_handler *handler, } /* Don't allow events from non-priviledged users */ - chown(PBOOT_USER_EVENT_SOCKET, 0, 0); - chmod(PBOOT_USER_EVENT_SOCKET, 0660); + if (chown(PBOOT_USER_EVENT_SOCKET, 0, 0)) + pb_log_fn("Error setting socket ownership: %m\n"); + errno = 0; + if (chmod(PBOOT_USER_EVENT_SOCKET, 0660)) + pb_log_fn("Error setting socket permissions: %m\n"); waiter_register_io(waitset, uev->socket, WAIT_IN, user_event_process, uev); diff --git a/discover/yaboot-parser.c b/discover/yaboot-parser.c index b06248f..d0a40b1 100644 --- a/discover/yaboot-parser.c +++ b/discover/yaboot-parser.c @@ -213,6 +213,8 @@ static void yaboot_process_pair(struct conf_context *conf, const char *name, /* Then start the new image. */ opt = state_start_new_option(conf, state); + if (!opt) + pb_debug_fn("new opt is NULL\n"); state->boot_image = talloc_strdup(state, value); @@ -235,6 +237,8 @@ static void yaboot_process_pair(struct conf_context *conf, const char *name, /* Then start the new image. */ opt = state_start_new_option(conf, state); + if (!opt) + pb_debug_fn("new opt is NULL\n"); if (*value == '/') { state->boot_image = talloc_strdup(state, value); |