diff options
Diffstat (limited to 'vpnor/mboxd_msg.cpp')
-rw-r--r-- | vpnor/mboxd_msg.cpp | 36 |
1 files changed, 35 insertions, 1 deletions
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); +} |