Blob Blame History Raw
commit 7b7d83c571ceb3050969359817d4145600f14ae8
Author: Ingo Franzki <ifranzki@linux.ibm.com>
Date:   Fri Apr 9 17:07:31 2021 +0200

    Check CKF_LIBRARY_CANT_CREATE_OS_THREADS at C_Initialize
    
    Fail if flag CKF_LIBRARY_CANT_CREATE_OS_THREADS is set at C_Initialize,
    and event support is enabled (this is the default). We need to use pthreads
    for the event thread, so we can't work if CKF_LIBRARY_CANT_CREATE_OS_THREADS
    is set. Fail with CKR_NEED_TO_CREATE_THREADS if so.
    
    The event support can be globally disabled using keyword 'disable-event-support'
    in opencryptoki.conf. This disables pkcsslots to accept admin connections,
    and it does not monitor for AP UDEV events (on s390 platform). No event
    thread is started in the opencryptoki processes, thus we can accept if flag
    CKF_LIBRARY_CANT_CREATE_OS_THREADS is set in that case.
    
    Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>

diff --git a/man/man5/opencryptoki.conf.5.in b/man/man5/opencryptoki.conf.5.in
index 71218f79..7dc676ab 100644
--- a/man/man5/opencryptoki.conf.5.in
+++ b/man/man5/opencryptoki.conf.5.in
@@ -10,8 +10,16 @@ pkcs#11 slots. At startup, the pkcsslotd daemon parses this file to
 determine which slots will be made available.
 
 .SH SYNTAX
-This file is made up of slot descriptions. Each slot description
-is composed of a slot number, brackets and key-value pairs.
+This file is made up of optional global definitions, and slot descriptions.
+
+The following global definitions are valid:
+
+.TP
+.BR disable-event-support
+If this keyword is specified the openCryptoki event support is disabled.
+
+.P
+Each slot description is composed of a slot number, brackets and key-value pairs.
 
  slot number
  {
diff --git a/usr/include/slotmgr.h b/usr/include/slotmgr.h
index e37368a5..451a8cf1 100644
--- a/usr/include/slotmgr.h
+++ b/usr/include/slotmgr.h
@@ -99,6 +99,7 @@ typedef struct {
     LW_SHM_TYPE *shm_addr;      // token specific shm address
 } Slot_Info_t;
 
+#define FLAG_EVENT_SUPPORT_DISABLED   0x01
 
 #ifdef PKCS64
 
@@ -200,6 +201,7 @@ typedef struct {
 
 typedef struct {
     uint8 num_slots;
+    uint8 flags;
     CK_INFO_64 ck_info;
     Slot_Info_t_64 slot_info[NUMBER_SLOTS_MANAGED];
 } Slot_Mgr_Socket_t;
@@ -214,6 +216,7 @@ typedef struct {
 
 typedef struct {
     uint8 num_slots;
+    uint8 flags;
     CK_INFO ck_info;
     Slot_Info_t slot_info[NUMBER_SLOTS_MANAGED];
 } Slot_Mgr_Socket_t;
diff --git a/usr/lib/api/api_interface.c b/usr/lib/api/api_interface.c
index 2873a20a..6517ca6c 100644
--- a/usr/lib/api/api_interface.c
+++ b/usr/lib/api/api_interface.c
@@ -308,7 +308,8 @@ void parent_fork_after()
         return;
 
     /* Restart the event thread in the parent when fork is complete */
-    if (Anchor->event_thread == 0)
+    if ((Anchor->SocketDataP.flags & FLAG_EVENT_SUPPORT_DISABLED) == 0 &&
+        Anchor->event_thread == 0)
         start_event_thread();
 }
 
@@ -2752,13 +2753,7 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid)
                 goto error;
             }
         }
-        // If we EVER need to create threads from this library we must
-        // check the Flags for the Can_Create_OS_Threads flag
-        // Right now the library DOES NOT create threads and therefore this
-        // check is irrelavant.
-        if (pArg->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) {
-            TRACE_DEVEL("Can't create OS threads...This is OK\n");
-        }
+
         // Since this is an initialization path, we will be verbose in the
         // code rather than efficient.
         //
@@ -2848,7 +2843,21 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid)
         rc = CKR_FUNCTION_FAILED;
         goto error_shm;
     }
-    // Initialize structure values
+
+    if (pVoid != NULL) {
+        pArg = (CK_C_INITIALIZE_ARGS *) pVoid;
+
+        if ((Anchor->SocketDataP.flags & FLAG_EVENT_SUPPORT_DISABLED) == 0 &&
+            (pArg->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) != 0) {
+            TRACE_ERROR("Flag CKF_LIBRARY_CANT_CREATE_OS_THREADS is set and "
+                        "event support is enabled\n");
+            OCK_SYSLOG(LOG_ERR, "C_Initialize: Application specified that "
+                       "library can't create OS threads. PKCS11 Module requires "
+                       "to create threads when event support is enabled.\n");
+            rc = CKR_NEED_TO_CREATE_THREADS;
+            goto error;
+        }
+    }
 
     //Register with pkcsslotd
     if (!API_Register()) {
@@ -2867,7 +2876,8 @@ CK_RV C_Initialize(CK_VOID_PTR pVoid)
     }
 
     /* Start event receiver thread */
-    if (start_event_thread() != 0) {
+    if ((Anchor->SocketDataP.flags & FLAG_EVENT_SUPPORT_DISABLED) == 0 &&
+        start_event_thread() != 0) {
         TRACE_ERROR("Failed to start event thread\n");
 
         // unload all the STDLL's from the application
diff --git a/usr/lib/common/configparser.h b/usr/lib/common/configparser.h
index 13ca648d..b3c32496 100644
--- a/usr/lib/common/configparser.h
+++ b/usr/lib/common/configparser.h
@@ -35,6 +35,7 @@ typedef int  (*end_slot_f)(void *private);
 typedef int  (*key_str_f)(void *private, int tok, const char *val);
 typedef int  (*key_vers_f)(void *private, int tok, unsigned int vers);
 typedef void (*eolcomment_f)(void *private, const char *comment);
+typedef void (*disab_event_supp_f)(void *private);
 /*
  * Report an error.  If the error is not reported by the parser itself
  * but via one of the parse functions, \c parsermsg will be \c NULL.
@@ -52,6 +53,7 @@ typedef void (*error_f)(void *private, int line, const char *parsermsg);
  */
 struct parsefuncs {
     ockversion_f  version;
+    disab_event_supp_f disab_event_supp;
     eol_f         eol;
     begin_slot_f  begin_slot;
     end_slot_f    end_slot;
diff --git a/usr/lib/common/lexer.l b/usr/lib/common/lexer.l
index b35a0b72..38cbcb70 100644
--- a/usr/lib/common/lexer.l
+++ b/usr/lib/common/lexer.l
@@ -69,6 +69,7 @@ extern char *configparse_strdup(const char *s);
 
 version                 return OCKVERSION;
 slot                    return SLOT;
+disable-event-support   return DISABLE_EVENT_SUPPORT;
 
 [^\"= \t\n]+		{
 			  yylval.str = configparse_strdup(yytext);
diff --git a/usr/lib/common/parser.y b/usr/lib/common/parser.y
index 86806fcb..40c3994d 100644
--- a/usr/lib/common/parser.y
+++ b/usr/lib/common/parser.y
@@ -65,7 +65,7 @@ int lookup_keyword(const char *key);
     int err;
 }
 
-%token EQUAL DOT SLOT EOL OCKVERSION BEGIN_DEF END_DEF
+%token EQUAL DOT SLOT EOL OCKVERSION BEGIN_DEF END_DEF DISABLE_EVENT_SUPPORT
 %token <str> STRING
 %token <str> KEYWORD
 %token <num> INTEGER
@@ -81,6 +81,7 @@ config_file:
 
 sections:
 	version_def eolcomment
+	| disable_event_support_def eolcomment
 	| SLOT INTEGER BEGIN_DEF
 	{
         if (parsefuncs->begin_slot && parsefuncs->begin_slot(parsedata, $2, 0)) {
@@ -125,6 +126,13 @@ version_def:
         }
         configparse_freestringsfrom($2);
     }
+    
+disable_event_support_def:
+    DISABLE_EVENT_SUPPORT
+    {
+        if (parsefuncs->disab_event_supp)
+            parsefuncs->disab_event_supp(parsedata);
+    }
 
 line_def:
     STRING EQUAL TOKVERSION
diff --git a/usr/sbin/pkcsslotd/pkcsslotd.h b/usr/sbin/pkcsslotd/pkcsslotd.h
index d7edcb3c..1dd0bac9 100644
--- a/usr/sbin/pkcsslotd/pkcsslotd.h
+++ b/usr/sbin/pkcsslotd/pkcsslotd.h
@@ -88,7 +88,7 @@ int XProcLock(void);
 int XProcUnLock(void);
 int CreateXProcLock(void);
 
-int init_socket_server();
+int init_socket_server(int event_support_disabled);
 int term_socket_server();
 int init_socket_data(Slot_Mgr_Socket_t *sp);
 int socket_connection_handler(int timeout_secs);
diff --git a/usr/sbin/pkcsslotd/slotmgr.c b/usr/sbin/pkcsslotd/slotmgr.c
index efbfe8fd..3b328a6c 100644
--- a/usr/sbin/pkcsslotd/slotmgr.c
+++ b/usr/sbin/pkcsslotd/slotmgr.c
@@ -34,6 +34,7 @@ int shmid;
 key_t tok;
 Slot_Info_t_64 sinfo[NUMBER_SLOTS_MANAGED];
 unsigned int NumberSlotsInDB = 0;
+int event_support_disabled = 0;
 
 Slot_Info_t_64 *psinfo;
 
@@ -467,6 +468,13 @@ static int slotmgr_key_vers(void *private, int tok, unsigned int vers)
     return 1;
 }
 
+static void slotmgr_disab_event_supp(void *private)
+{
+    UNUSED(private);
+
+    event_support_disabled = 1;
+}
+
 static void slotmgr_parseerror(void *private, int line, const char *parsermsg)
 {
     struct parse_data *d = (struct parse_data *)private;
@@ -480,6 +488,7 @@ static struct parsefuncs slotmgr_parsefuncs = {
     .end_slot   = slotmgr_end_slot,
     .key_str    = slotmgr_key_str,
     .key_vers   = slotmgr_key_vers,
+    .disab_event_supp = slotmgr_disab_event_supp,
     .parseerror = slotmgr_parseerror
 };
 
@@ -568,7 +577,7 @@ int main(int argc, char *argv[], char *envp[])
     if (!XProcUnLock())
         return 4;
 
-    if (!init_socket_server()) {
+    if (!init_socket_server(event_support_disabled)) {
         DestroyMutexes();
         DetachFromSharedMemory();
         DestroySharedMemory();
@@ -582,6 +591,8 @@ int main(int argc, char *argv[], char *envp[])
         DestroySharedMemory();
         return 6;
     }
+    if (event_support_disabled)
+        socketData.flags |= FLAG_EVENT_SUPPORT_DISABLED;
 
     /* Create customized token directories */
     psinfo = &socketData.slot_info[0];
diff --git a/usr/sbin/pkcsslotd/socket_server.c b/usr/sbin/pkcsslotd/socket_server.c
index 41408670..3aa40267 100644
--- a/usr/sbin/pkcsslotd/socket_server.c
+++ b/usr/sbin/pkcsslotd/socket_server.c
@@ -139,12 +139,12 @@ struct event_info {
 };
 
 static int epoll_fd = -1;
-static struct listener_info proc_listener;
+static struct listener_info proc_listener = { .socket = -1 };
 static DL_NODE *proc_connections = NULL;
-static struct listener_info admin_listener;
+static struct listener_info admin_listener = { .socket = -1 };
 static DL_NODE *admin_connections = NULL;
 #ifdef WITH_LIBUDEV
-static struct udev_mon udev_mon;
+static struct udev_mon udev_mon = { .socket = -1 };
 #endif
 static DL_NODE *pending_events = NULL;
 static unsigned long pending_events_count = 0;
@@ -1620,6 +1620,9 @@ static void udev_mon_term(struct udev_mon *udev_mon)
     if (udev_mon == NULL)
         return;
 
+    if (udev_mon->socket < 0)
+        return;
+
     epoll_ctl(epoll_fd, EPOLL_CTL_DEL, udev_mon->socket, NULL);
     if (udev_mon->udev != NULL)
         udev_unref(udev_mon->udev);
@@ -1636,6 +1639,7 @@ int init_socket_data(Slot_Mgr_Socket_t *socketData)
 {
     unsigned int processed = 0;
 
+    socketData->flags = 0;
     PopulateCKInfo(&(socketData->ck_info));
     socketData->num_slots = NumberSlotsInDB;
     PopulateSlotInfo(socketData->slot_info, &processed);
@@ -1692,7 +1696,7 @@ int socket_connection_handler(int timeout_secs)
     return TRUE;
 }
 
-int init_socket_server()
+int init_socket_server(int event_support_disabled)
 {
     int err;
 
@@ -1710,18 +1714,20 @@ int init_socket_server()
         return FALSE;
     }
 
-    if (!listener_create(ADMIN_SOCKET_FILE_PATH, &admin_listener,
-                         admin_new_conn, NUMBER_ADMINS_ALLOWED)) {
-        term_socket_server();
-        return FALSE;
-    }
+    if (!event_support_disabled) {
+        if (!listener_create(ADMIN_SOCKET_FILE_PATH, &admin_listener,
+                             admin_new_conn, NUMBER_ADMINS_ALLOWED)) {
+            term_socket_server();
+            return FALSE;
+        }
 
 #ifdef WITH_LIBUDEV
-    if (!udev_mon_init(UDEV_SUBSYSTEM_AP, &udev_mon)) {
-        term_socket_server();
-        return FALSE;
-    }
+        if (!udev_mon_init(UDEV_SUBSYSTEM_AP, &udev_mon)) {
+            term_socket_server();
+            return FALSE;
+        }
 #endif
+    }
 
     DbgLog(DL0, "%s: Socket server started", __func__);
 
diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c
index 7c225730..94fd1196 100644
--- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c
+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c
@@ -2066,6 +2066,13 @@ static int parseupdate_ockversion(void *private, const char *version)
     return 0;
 }
 
+static void parseupdate_disab_event_supp(void *private)
+{
+    struct parseupdate *u = (struct parseupdate *)private;
+
+    fprintf(u->f, "disable-event-support");
+}
+
 static void parseupdate_eol(void *private)
 {
 	struct parseupdate *u = (struct parseupdate *)private;
@@ -2124,6 +2131,7 @@ static void parseupdate_eolcomment(void *private, const char *comment)
 
 static struct parsefuncs parseupdatefuncs = {
     .version    = parseupdate_ockversion,
+    .disab_event_supp = parseupdate_disab_event_supp,
     .eol        = parseupdate_eol,
     .begin_slot = parseupdate_begin_slot,
     .end_slot   = parseupdate_end_slot,