• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  ** Licensed under the Apache License, Version 2.0 (the "License");
3  ** you may not use this file except in compliance with the License.
4  ** You may obtain a copy of the License at
5  **
6  ** http://www.apache.org/licenses/LICENSE-2.0
7  **
8  ** Unless required by applicable law or agreed to in writing, software
9  ** distributed under the License is distributed on an "AS IS" BASIS,
10  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  ** See the License for the specific language governing permissions and
12  ** limitations under the License.
13  **
14  ** Copyright 2021 NXP
15  **
16  */
17 
18 #define LOG_TAG "OmapiTransport_SignalHandler"
19 
20 #include <android-base/logging.h>
21 #include <log/log.h>
22 #include <signal.h>
23 #include <iomanip>
24 #include <vector>
25 
26 #include <AppletConnection.h>
27 #include <SignalHandler.h>
28 
29 keymint::javacard::AppletConnection* g_AppClient = nullptr;
30 
31 #define NUM_OF_SIGNALS 6
32 int handledSignals[] = {SIGTRAP, SIGFPE, SIGILL, SIGSEGV, SIGBUS, SIGTERM};
33 struct sigaction old_action[NUM_OF_SIGNALS] = {};
34 
35 namespace keymint::javacard {
36 
37 /* Handle Fatal signals to close opened Logical channel before
38  * the process dies
39  */
customSignalHandler(int sig,siginfo_t * info,void * ucontext)40 void customSignalHandler(int sig, siginfo_t* info, void* ucontext) {
41     LOG(WARNING) << "received signal " << sig;
42     if (g_AppClient != nullptr) g_AppClient->close();
43     // default handling of the received signal
44     for (int i = 0; i < NUM_OF_SIGNALS; i++) {
45         if (handledSignals[i] == sig) {
46             if (old_action[i].sa_sigaction != nullptr) {
47                 LOG(INFO) << "execute originally installed handler" << sig;
48                 (*(old_action[i].sa_sigaction))(sig, info, ucontext);
49             } else if (old_action[i].sa_handler == SIG_DFL || old_action[i].sa_handler == SIG_IGN) {
50                 signal(sig, old_action[i].sa_handler);  // reset to old handler
51                 raise(sig);
52             }
53             break;
54         }
55     }
56 }
57 
58 /**
59  * Register signal Handler.
60  * Use mPtrC to pass handle/data which might be required in signal Handler context
61  * marks registration OK if at least one of signal is registered successfully
62  */
63 
installHandler(void * mPtr)64 void SignalHandler::installHandler(void* mPtr) {
65     mContext = mPtr;
66     g_AppClient = (keymint::javacard::AppletConnection*)mContext;
67     int reg_signals = 0;
68     for (int i = 0; i < NUM_OF_SIGNALS; i++) {
69         struct sigaction enable_act = {};
70         enable_act.sa_sigaction = customSignalHandler;
71         enable_act.sa_flags = SA_RESTART | SA_SIGINFO;
72         if (sigaction(handledSignals[i], &enable_act, &(old_action[i])) != 0) {
73             LOG(ERROR) << "Unable to set up signal handler for signal " << handledSignals[i]
74                        << "errno " << errno;
75         } else {
76             reg_signals++;
77         }
78     }
79     if (reg_signals > 0) isRegistered = true;
80 }
81 
SignalHandler()82 SignalHandler::SignalHandler() {
83     sigemptyset(&blockedSignals);
84     sigemptyset(&oldMask);
85     mContext = nullptr;
86     isRegistered = false;
87 }
88 
89 SignalHandler* SignalHandler::instance = nullptr;
90 
getInstance()91 SignalHandler* SignalHandler::getInstance() {
92     if (!instance) {
93         instance = new SignalHandler();
94     }
95     return instance;
96 }
97 
isHandlerRegistered()98 bool SignalHandler::isHandlerRegistered() {
99     return isRegistered;
100 }
101 
102 /**
103  * block Signals to prevent interrupts during critical parts of code
104  */
105 
blockSignals()106 void SignalHandler::blockSignals() {
107     if (!isRegistered) return;
108     sigemptyset(&blockedSignals);
109     sigemptyset(&oldMask);
110 
111     for (int i = 0; i < NUM_OF_SIGNALS; i++) {
112         sigaddset(&blockedSignals, handledSignals[i]);
113     }
114     if (sigprocmask(SIG_BLOCK, &blockedSignals, &oldMask) < 0) {
115         LOG(ERROR) << "failed to block signal " << errno;
116     }
117 }
118 
119 /**
120  * Unblock signal previously blocked using blockSignals()
121  * Pending signals are delivered after they are unblocked.
122  */
123 
unblockSignals()124 void SignalHandler::unblockSignals() {
125     if (!isRegistered) return;
126     if (sigprocmask(SIG_SETMASK, &oldMask, NULL) < 0) {
127         LOG(ERROR) << "failed to set sigmask " << errno;
128     }
129 }
130 
131 }  // namespace keymint::javacard
132