[PATCH phosphor-host-ipmid v4] Whitelist IPMI commands based on Restricted mode
Patrick Williams
patrick at stwcx.xyz
Tue Jun 21 08:40:59 AEST 2016
On Thu, Jun 16, 2016 at 06:40:41AM -0500, OpenBMC Patches wrote:
> From: tomjose <tomjoseph at in.ibm.com>
>
> diff --git a/Makefile b/Makefile
> index 7a3b6af..fdae66c 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -38,6 +38,7 @@ CFLAGS += -Wall -Wno-unused-result
> INC_FLAG += $(shell pkg-config --cflags --libs libsystemd) -I. -O2
> LIB_FLAG += $(shell pkg-config --libs libsystemd) -rdynamic
> IPMID_PATH ?= -DHOST_IPMI_LIB_PATH=\"/usr/lib/host-ipmid/\"
> +WHITELIST_PATH?= -DIPMI_WHITELIST_CONF=\"/usr/share/host-ipmid/whitelist.conf\"
I am surprised to see a runtime parsing component here. I thought we
were going to pass the configuration file to the build and generate a
static set for the whitelist. Are there pros to this solution? A
build-time static set would be smaller / faster.
> @@ -157,6 +171,21 @@ ipmi_ret_t ipmi_netfn_router(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t
> // Extract the map data onto appropriate containers
> auto handler_and_context = iter->second;
>
> + // If restricted mode is true and command is not whitelisted, don't
> + // execute the command
> + if(restricted_mode)
> + {
> + auto iter = g_ipmi_whitelist.find(std::make_pair(netfn, cmd));
> + if(iter == g_ipmi_whitelist.end())
Prefer 'g_ipmi_whitelist.count(ipmi_fn_cmd_t(netfn, cmd)) == 0'.
Reasons:
1. Counts on sets are guaranteed to return 0 or 1 and has the same
performance as 'find'.
2. Calling the constructor of the underlying set-member ensures there is
not a conversion cast from pair<X> to pair<Y>.
3. The call for and comparison with the 'end' iterator is eliminated.
> + {
> + printf("Net function:[0x%X], Command:[0x%X] is not whitelisted\n", netfn, cmd);
> + rc = IPMI_CC_INSUFFICIENT_PRIVILEGE;
> + memcpy(response, &rc, IPMI_CC_LEN);
A little odd pattern for us to use memcpy for one byte, but lucky the
GCC optimizer turns this into a byte-store directly anyhow.
> +void ipmi_populate_whitelist()
> +{
> + std::ifstream file(IPMI_WHITELIST_CONF);
> + std::string str;
> + std::string str_netfn;
> + std::string str_cmd;
> + ipmi_netfn_t netfn;
> + ipmi_cmd_t cmd;
> + size_t pos = std::string::npos;
> +
> + // Read the whitelist.conf file and insert the NetFn and Command pair.
> + // Each entry in the conf file looks like this 0x01:0x02
> + // ':' character is the separator between NetFn and Command.
> + while(std::getline(file, str))
> + {
> + pos = str.find(':');
> + if(pos != std::string::npos)
> + {
> + str_netfn.assign(str.substr(pos-2,pos-1));
> + str_cmd.assign(str.substr(pos+3,pos+4));
> +
> + netfn = strtoul(str_netfn.c_str(), NULL, 16);
> + cmd = strtoul(str_cmd.c_str(), NULL, 16);
> +
> + g_ipmi_whitelist.emplace(std::make_pair(netfn, cmd));
Prefer the direct constructor on this one as well.
I know we may change this to build-time but a few comments:
1. Any reason to not support a comment character?
2. Any reason not to use istream >> operators instead of getline and
then string parsing?
3. Considering the limited utility of the iostream APIs, fscanf might
be more concise in this case.
--
Patrick Williams
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.ozlabs.org/pipermail/openbmc/attachments/20160620/a12b3c4e/attachment.sig>
More information about the openbmc
mailing list