summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0016-add-better-sdbusplus-exception-handling.patch
blob: 873eb6b16eba4cdc0c608de0e9c4ce2d8ad60ccc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
From a445f287d4aebca68dc0321e292933311caf59ba Mon Sep 17 00:00:00 2001
From: Yong Li <yong.b.li@linux.intel.com>
Date: Sun, 16 Sep 2018 20:14:55 +0800
Subject: [PATCH] add better sdbusplus exception handling

Now that sdbusplus throws, we need to catch more stuff. To compound the
problem, even though sdbusplus::exception::exception inherits from
std::exception, there is a problem that prevents the code from simply
catching std::exception.

Change-Id: I2a330e542f5d87722a4c04e6d47de2cfb2f7d7c9
Signed-off-by: Vernon Mauery <vernon.mauery@intel.com>
Signed-off-by: Yong Li <yong.b.li@linux.intel.com>

---
 apphandler.cpp | 14 +++++++--
 ipmid.cpp      | 77 +++++++++++++++++++++++++++++++++++---------------
 2 files changed, 66 insertions(+), 25 deletions(-)

diff --git a/apphandler.cpp b/apphandler.cpp
index 126de33..3cae6d5 100644
--- a/apphandler.cpp
+++ b/apphandler.cpp
@@ -312,9 +312,19 @@ ipmi_ret_t ipmi_app_get_device_id(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
             auto version = getActiveSoftwareVersionInfo();
             r = convert_version(version.c_str(), &rev);
         }
-        catch (const std::exception& e)
+        catch (sdbusplus::exception::exception& e)
         {
-            log<level::ERR>(e.what());
+            log<level::ERR>("sdbusplus::exception",
+                            entry("ERROR=%s", e.what()));
+        }
+        catch (std::exception& e)
+        {
+            log<level::ERR>("unexpected exception",
+                            entry("ERROR=%s", e.what()));
+        }
+        catch (...)
+        {
+            log<level::ERR>("unknown exception");
         }
 
         if (r >= 0)
diff --git a/ipmid.cpp b/ipmid.cpp
index 2d48bfe..8d2fb37 100644
--- a/ipmid.cpp
+++ b/ipmid.cpp
@@ -273,6 +273,10 @@ ipmi_ret_t ipmi_netfn_router(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
     }
     // IPMI command handlers can throw unhandled exceptions, catch those
     // and return sane error code.
+    catch (sdbusplus::exception::exception& e)
+    {
+        log<level::ERR>("sdbusplus exception", entry("EXCEPTION=%s", e.what()));
+    }
     catch (const std::exception& e)
     {
         log<level::ERR>(e.what(), entry("NET_FUN=0x%X", netfn),
@@ -281,6 +285,23 @@ ipmi_ret_t ipmi_netfn_router(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
         *data_len = 0;
         // fall through
     }
+    catch (...)
+    {
+        std::exception_ptr eptr = std::current_exception();
+        try
+        {
+            std::rethrow_exception(eptr);
+        }
+        catch (std::exception& e)
+        {
+            log<level::ERR>("unexpected uncaught exception",
+                            entry("EXCEPTION=%s", e.what()),
+                            entry("NET_FUN=0x%X", netfn),
+                            entry("CMD=0x%X", cmd));
+            rc = IPMI_CC_UNSPECIFIED_ERROR;
+            *data_len = 0;
+        }
+    }
     // Now copy the return code that we got from handler and pack it in first
     // byte.
     std::memcpy(response, &rc, IPMI_CC_LEN);
@@ -361,32 +382,42 @@ final:
 void cache_restricted_mode()
 {
     restricted_mode = false;
-    using namespace sdbusplus::xyz::openbmc_project::Control::Security::server;
-    using namespace internal;
-    using namespace internal::cache;
-    sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection());
-    const auto& restrictionModeSetting =
-        objects->map.at(restrictionModeIntf).front();
-    auto method = dbus.new_method_call(
-        objects->service(restrictionModeSetting, restrictionModeIntf).c_str(),
-        restrictionModeSetting.c_str(), "org.freedesktop.DBus.Properties",
-        "Get");
-    method.append(restrictionModeIntf, "RestrictionMode");
-    auto resp = dbus.call(method);
-    if (resp.is_method_error())
+    try
     {
-        log<level::ERR>("Error in RestrictionMode Get");
-        // Fail-safe to true.
-        restricted_mode = true;
-        return;
+        using namespace sdbusplus::xyz::openbmc_project::Control::Security::
+            server;
+        using namespace internal;
+        using namespace internal::cache;
+        sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection());
+        const auto& restrictionModeSetting =
+            objects->map.at(restrictionModeIntf).front();
+        auto method = dbus.new_method_call(
+            objects->service(restrictionModeSetting, restrictionModeIntf)
+                .c_str(),
+            restrictionModeSetting.c_str(), "org.freedesktop.DBus.Properties",
+            "Get");
+        method.append(restrictionModeIntf, "RestrictionMode");
+        auto resp = dbus.call(method);
+        if (resp.is_method_error())
+        {
+            log<level::ERR>("Error in RestrictionMode Get");
+            // Fail-safe to true.
+            restricted_mode = true;
+            return;
+        }
+        sdbusplus::message::variant<std::string> result;
+        resp.read(result);
+        auto restrictionMode = RestrictionMode::convertModesFromString(
+            sdbusplus::message::variant_ns::get<std::string>(result));
+        if (RestrictionMode::Modes::Whitelist == restrictionMode)
+        {
+            restricted_mode = true;
+        }
     }
-    sdbusplus::message::variant<std::string> result;
-    resp.read(result);
-    auto restrictionMode = RestrictionMode::convertModesFromString(
-        variant_ns::get<std::string>(result));
-    if (RestrictionMode::Modes::Whitelist == restrictionMode)
+    catch (sdbusplus::exception::exception& e)
     {
-        restricted_mode = true;
+        // restrictionModeIntf does not exist; default to not enforcing
+        log<level::ERR>("sdbusplus exception", entry("EXCEPTION=%s", e.what()));
     }
 }
 
-- 
2.17.1