diff options
Diffstat (limited to 'vpnor')
-rw-r--r-- | vpnor/mboxd_flash.cpp | 13 | ||||
-rw-r--r-- | vpnor/mboxd_msg.cpp | 36 | ||||
-rw-r--r-- | vpnor/mboxd_msg.hpp | 3 | ||||
-rw-r--r-- | vpnor/test/Makefile.am.include | 3 |
4 files changed, 45 insertions, 10 deletions
diff --git a/vpnor/mboxd_flash.cpp b/vpnor/mboxd_flash.cpp index ffe75c6..a774ec1 100644 --- a/vpnor/mboxd_flash.cpp +++ b/vpnor/mboxd_flash.cpp @@ -203,7 +203,9 @@ int write_flash(struct mbox_context* context, uint32_t offset, void* buf, const struct pnor_partition& part = table->partition(offset); if (part.data.user.data[1] & PARTITION_READONLY) { - /* FIXME: This should be done on CREATE_WRITE_WINDOW, not here */ + MSG_ERR("Unreachable: Host attempted to write to read-only " + "partition %s\n", + part.data.name); return -MBOX_R_WRITE_ERROR; } @@ -214,11 +216,10 @@ int write_flash(struct mbox_context* context, uint32_t offset, void* buf, } catch (vpnor::UnmappedOffset& e) { - /* Paper over the fact that the write isn't persistent */ - MSG_INFO("Dropping %d bytes host wrote to unmapped offset 0x%" PRIx32 - "\n", - count, offset); - return 0; + MSG_ERR("Unreachable: Host attempted to write %" PRIu32 + " bytes to unmapped offset 0x%" PRIx32 "\n", + count, offset); + return -MBOX_R_WRITE_ERROR; } catch (const vpnor::OutOfBoundsOffset& e) { diff --git a/vpnor/mboxd_msg.cpp b/vpnor/mboxd_msg.cpp index 130c098..dd9e64a 100644 --- a/vpnor/mboxd_msg.cpp +++ b/vpnor/mboxd_msg.cpp @@ -6,6 +6,7 @@ extern "C" { }; #include "vpnor/mboxd_msg.hpp" +#include "vpnor/pnor_partition_table.hpp" // clang-format off const mboxd_mbox_handler vpnor_mbox_handlers[NUM_MBOX_CMDS] = @@ -15,10 +16,43 @@ const mboxd_mbox_handler vpnor_mbox_handlers[NUM_MBOX_CMDS] = mbox_handle_flash_info, mbox_handle_read_window, mbox_handle_close_window, - mbox_handle_write_window, + vpnor_handle_write_window, mbox_handle_dirty_window, mbox_handle_flush_window, mbox_handle_ack, mbox_handle_erase_window }; // clang-format on + +/* XXX: Maybe this should be a method on a class? */ +static bool vpnor_partition_is_readonly(const pnor_partition& part) +{ + return part.data.user.data[1] & PARTITION_READONLY; +} + +int vpnor_handle_write_window(struct mbox_context* context, + union mbox_regs* req, struct mbox_msg* resp) +{ + size_t offset = get_u16(&req->msg.args[0]); + offset <<= context->block_size_shift; + try + { + const pnor_partition& part = context->vpnor->table->partition(offset); + if (vpnor_partition_is_readonly(part)) + { + return -MBOX_R_WINDOW_ERROR; + } + } + catch (const openpower::virtual_pnor::UnmappedOffset& e) + { + /* + * Writes to unmapped areas are not meaningful, so deny the request. + * This removes the ability for a compromised host to abuse unused + * space if any data was to be persisted (which it isn't). + */ + return -MBOX_R_WINDOW_ERROR; + } + + /* Defer to the default handler */ + return mbox_handle_write_window(context, req, resp); +} diff --git a/vpnor/mboxd_msg.hpp b/vpnor/mboxd_msg.hpp index 7485c38..d9a05bb 100644 --- a/vpnor/mboxd_msg.hpp +++ b/vpnor/mboxd_msg.hpp @@ -2,4 +2,7 @@ extern "C" { #include "mbox.h" extern const mboxd_mbox_handler vpnor_mbox_handlers[NUM_MBOX_CMDS]; + +int vpnor_handle_write_window(struct mbox_context *context, + union mbox_regs *req, struct mbox_msg *resp); }; diff --git a/vpnor/test/Makefile.am.include b/vpnor/test/Makefile.am.include index 85b2cbc..819343b 100644 --- a/vpnor/test/Makefile.am.include +++ b/vpnor/test/Makefile.am.include @@ -247,7 +247,4 @@ check_PROGRAMS += \ %reldir%/create_write_window_ro_partition \ %reldir%/create_write_window_rw_partition \ %reldir%/create_write_window_unmapped - -XFAIL_TESTS += %reldir%/create_write_window_ro_partition -XFAIL_TESTS += %reldir%/create_write_window_unmapped endif |