Make read-only guarantee user-settable
authorSamuel Mendoza-Jonas <sam.mj@au1.ibm.com>
Wed, 6 May 2015 07:03:30 +0000 (17:03 +1000)
committerSamuel Mendoza-Jonas <sam.mj@au1.ibm.com>
Thu, 6 Aug 2015 04:08:33 +0000 (14:08 +1000)
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 <sam.mj@au1.ibm.com>
discover/device-handler.c
discover/platform-powerpc.c
discover/platform.c
lib/pb-config/pb-config.c
lib/pb-protocol/pb-protocol.c
lib/types/types.h
ui/ncurses/nc-config.c

index 31cbcc2c1da50b87b9b5bf472227ebe2ce8559ab..4f7a7b7500c4fee446747df10861095d30b2ce33 100644 (file)
@@ -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;
 
index 2b3b043489e889573d0033d8c354d5bffb39d8d4..fc96305ad70bc56d71d5e002a5b03617a84a57a6 100644 (file)
@@ -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);
index 74e2a82df3225519fdcc2ad49ebc3502214bda09..b1d0f19bafadd8a1ca1059bfe530c04de26eb801 100644 (file)
@@ -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,
index 98a6078bc552bb19f6a95d841ba2dd13024807f2..8200883a4a5d8ddd44bf593e6b60c0d24e441b00 100644 (file)
@@ -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
index 69ea35d2eed735382abe2bf22acc64444311159c..7d45f512b0dcb81db6b83ba6223e6eb921dde30f 100644 (file)
@@ -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;
 
index e5c7e3e00225daa162c7850eb1d302da63074f7a..f7e47522dcd818d6b2a226e469fd7ee48543f50e 100644 (file)
@@ -146,6 +146,8 @@ struct config {
        unsigned int            ipmi_bootdev;
        bool                    ipmi_bootdev_persistent;
 
+       bool                    allow_writes;
+
        char                    *lang;
 
        /* not user-settable */
index 76ede39905755b5cc9d747a5bc673e1a4ce02b8b..6363bb9a0f7785b5a470573a356ce0a19e9ccc0e 100644 (file)
@@ -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"),