[PATCH] Make read-only guarantee user-settable
Samuel Mendoza-Jonas
sam.mj at au1.ibm.com
Thu May 14 16:06:53 AEST 2015
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 at au1.ibm.com>
---
This depends on the prevous dm-snapshots patches to actually make a
guarantee about read-only access
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 55363f4..69e53e2 100644
--- a/discover/device-handler.c
+++ b/discover/device-handler.c
@@ -1387,10 +1387,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 b4f2a77..fe53e6e 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 6164873..44e6fcd 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);
@@ -539,6 +547,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),
@@ -899,6 +913,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.1.0
More information about the Petitboot
mailing list