From acc5ace6e58db2f3dceb1f7a27d0fc1fb29c4a27 Mon Sep 17 00:00:00 2001 From: Samuel Mendoza-Jonas Date: Wed, 6 May 2015 17:03:30 +1000 Subject: [PATCH] Make read-only guarantee user-settable Create a new Petitboot option 'petitboot,write?' that specifies whether the system is allowed to mount devices read-write. The option can be toggled by the user in the nc-config screen. Signed-off-by: Samuel Mendoza-Jonas --- discover/device-handler.c | 5 +++++ discover/platform-powerpc.c | 11 +++++++++++ discover/platform.c | 1 + lib/pb-config/pb-config.c | 2 ++ lib/pb-protocol/pb-protocol.c | 9 +++++++++ lib/types/types.h | 2 ++ ui/ncurses/nc-config.c | 28 +++++++++++++++++++++++++++- 7 files changed, 57 insertions(+), 1 deletion(-) diff --git a/discover/device-handler.c b/discover/device-handler.c index 31cbcc2..4f7a7b7 100644 --- a/discover/device-handler.c +++ b/discover/device-handler.c @@ -1391,10 +1391,15 @@ static int umount_device(struct discover_device *dev) int device_request_write(struct discover_device *dev, bool *release) { const char *fstype, *device_path; + const struct config *config; int rc; *release = false; + config = config_get(); + if (!config->allow_writes) + return -1; + if (!dev->mounted) return -1; diff --git a/discover/platform-powerpc.c b/discover/platform-powerpc.c index 2b3b043..fc96305 100644 --- a/discover/platform-powerpc.c +++ b/discover/platform-powerpc.c @@ -53,6 +53,7 @@ static const char *known_params[] = { "petitboot,bootdevs", "petitboot,language", "petitboot,debug?", + "petitboot,write?", NULL, }; @@ -548,6 +549,10 @@ static void populate_config(struct platform_powerpc *platform, val = get_param(platform, "petitboot,debug?"); config->debug = val && !strcmp(val, "true"); } + + val = get_param(platform, "petitboot,write?"); + if (val) + config->allow_writes = !strcmp(val, "true"); } static char *iface_config_str(void *ctx, struct interface_config *config) @@ -707,6 +712,12 @@ static int update_config(struct platform_powerpc *platform, val = config->lang ?: ""; update_string_config(platform, "petitboot,language", val); + if (config->allow_writes == defaults->allow_writes) + val = ""; + else + val = config->allow_writes ? "true" : "false"; + update_string_config(platform, "petitboot,write?", val); + update_network_config(platform, config); update_bootdev_config(platform, config); diff --git a/discover/platform.c b/discover/platform.c index 74e2a82..b1d0f19 100644 --- a/discover/platform.c +++ b/discover/platform.c @@ -108,6 +108,7 @@ void config_set_defaults(struct config *config) config->network.n_dns_servers = 0; config->safe_mode = false; config->lang = NULL; + config->allow_writes = true; config->n_autoboot_opts = 2; config->autoboot_opts = talloc_array(config, struct autoboot_option, diff --git a/lib/pb-config/pb-config.c b/lib/pb-config/pb-config.c index 98a6078..8200883 100644 --- a/lib/pb-config/pb-config.c +++ b/lib/pb-config/pb-config.c @@ -77,6 +77,8 @@ struct config *config_copy(void *ctx, const struct config *src) dest->ipmi_bootdev = src->ipmi_bootdev; dest->ipmi_bootdev_persistent = src->ipmi_bootdev_persistent; + dest->allow_writes = src->allow_writes; + if (src->lang && strlen(src->lang)) dest->lang = talloc_strdup(dest, src->lang); else diff --git a/lib/pb-protocol/pb-protocol.c b/lib/pb-protocol/pb-protocol.c index 69ea35d..7d45f51 100644 --- a/lib/pb-protocol/pb-protocol.c +++ b/lib/pb-protocol/pb-protocol.c @@ -290,6 +290,8 @@ int pb_protocol_config_len(const struct config *config) len += 4 + 4; /* ipmi_bootdev, ipmi_bootdev_persistent */ + len += 4; /* allow_writes */ + len += 4 + optional_strlen(config->lang); return len; @@ -502,6 +504,9 @@ int pb_protocol_serialise_config(const struct config *config, *(uint32_t *)pos = config->ipmi_bootdev_persistent; pos += 4; + *(uint32_t *)pos = config->allow_writes; + pos += 4; + pos += pb_protocol_serialise_string(pos, config->lang); assert(pos <= buf + buf_len); @@ -958,6 +963,10 @@ int pb_protocol_deserialise_config(struct config *config, goto out; config->ipmi_bootdev_persistent = !!tmp; + if (read_u32(&pos, &len, &tmp)) + goto out; + config->allow_writes = !!tmp; + if (read_string(config, &pos, &len, &str)) goto out; diff --git a/lib/types/types.h b/lib/types/types.h index e5c7e3e..f7e4752 100644 --- a/lib/types/types.h +++ b/lib/types/types.h @@ -146,6 +146,8 @@ struct config { unsigned int ipmi_bootdev; bool ipmi_bootdev_persistent; + bool allow_writes; + char *lang; /* not user-settable */ diff --git a/ui/ncurses/nc-config.c b/ui/ncurses/nc-config.c index 76ede39..6363bb9 100644 --- a/ui/ncurses/nc-config.c +++ b/ui/ncurses/nc-config.c @@ -33,7 +33,7 @@ #include "nc-config.h" #include "nc-widgets.h" -#define N_FIELDS 32 +#define N_FIELDS 34 extern struct help_text config_help_text; @@ -100,6 +100,9 @@ struct config_screen { struct nc_widget_label *dns_dhcp_help_l; struct nc_widget_label *dns_help_l; + struct nc_widget_label *allow_write_l; + struct nc_widget_select *allow_write_f; + struct nc_widget_label *safe_mode; struct nc_widget_button *ok_b; struct nc_widget_button *help_b; @@ -203,6 +206,7 @@ static int screen_process_form(struct config_screen *screen) struct config *config; int i, n_boot_opts, rc, idx; unsigned int *order; + bool allow_write; char mac[20]; config = config_copy(screen, screen->cui->config); @@ -331,6 +335,10 @@ static int screen_process_form(struct config_screen *screen) } } + allow_write = widget_select_get_value(screen->widgets.allow_write_f); + if (allow_write != config->allow_writes) + config->allow_writes = allow_write; + config->safe_mode = false; rc = cui_send_config(screen->cui, config); talloc_free(config); @@ -540,6 +548,12 @@ static void config_screen_layout_widgets(struct config_screen *screen) y += 1; } + layout_pair(screen, y, screen->widgets.allow_write_l, + widget_select_base(screen->widgets.allow_write_f)); + y += widget_height(widget_select_base(screen->widgets.allow_write_f)); + + y += 1; + widget_move(widget_button_base(screen->widgets.ok_b), y, screen->field_x); widget_move(widget_button_base(screen->widgets.help_b), @@ -900,6 +914,18 @@ static void config_screen_setup_widgets(struct config_screen *screen, screen->widgets.safe_mode = widget_new_label(set, 0, 0, _("Selecting 'OK' will exit safe mode")); + screen->widgets.allow_write_l = widget_new_label(set, 0, 0, + _("Disk R/W:")); + screen->widgets.allow_write_f = widget_new_select(set, 0, 0, + COLS - screen->field_x); + + widget_select_add_option(screen->widgets.allow_write_f, 0, + _("Prevent all writes to disk"), + !config->allow_writes); + widget_select_add_option(screen->widgets.allow_write_f, 1, + _("Allow bootloader scripts to modify disks"), + config->allow_writes); + screen->widgets.ok_b = widget_new_button(set, 0, 0, 6, _("OK"), ok_click, screen); screen->widgets.help_b = widget_new_button(set, 0, 0, 10, _("Help"), -- 2.39.2