[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