File openCryptoki-SLE15-SP6-CVE-2026-23893.patch of Package openCryptoki.42499

diff -Naur a/usr/lib/common/loadsave.c b/usr/lib/common/loadsave.c
--- a/usr/lib/common/loadsave.c	2024-02-06 11:02:00.000000000 +0100
+++ b/usr/lib/common/loadsave.c	2026-01-29 10:28:50.167441078 +0100
@@ -43,6 +43,11 @@
 #include "ock_syslog.h"
 #include "slotmgr.h" // for ock_snprintf
 
+/*
+ * 
+ */
+#include "platform.h"
+
 extern void set_perm(int);
 
 CK_RV restore_private_token_object_old(STDLL_TokData_t *tokdata, CK_BYTE *data,
@@ -67,9 +72,15 @@
                                     STDLL_TokData_t *tokdata, char *path,
                                     char *mode)
 {
+    FILE *fp;
+
     if (get_token_object_path(buf, buflen, tokdata, path) < 0)
         return NULL;
-    return fopen(buf, mode);
+    fp = fopen_nofollow(buf, mode);
+    if (fp == NULL && errno == ELOOP)
+        TRACE_ERROR("Refusing to follow symlink: %s\n", buf);
+
+    return fp;
 }
 
 static int get_token_data_store_path(char *buf, size_t buflen,
@@ -86,9 +97,16 @@
                                         STDLL_TokData_t *tokdata, char *path,
                                         char *mode)
 {
+    FILE *fp;
+	
     if (get_token_data_store_path(buf, buflen, tokdata, path) < 0)
         return NULL;
-    return fopen(buf, mode);
+    fp = fopen_nofollow(buf, mode);
+    if (fp == NULL && errno == ELOOP)
+        TRACE_ERROR("Refusing to follow symlink: %s\n", buf);
+
+    return fp;
+    
 }
 
 static FILE *open_token_object_index(char *buf, size_t buflen,
@@ -100,11 +118,18 @@
 static FILE *open_token_nvdat(char *buf, size_t buflen,
                               STDLL_TokData_t *tokdata, char *mode)
 {
+    FILE *fp;
+	
     if (ock_snprintf(buf, buflen, "%s/" PK_LITE_NV, tokdata->data_store)) {
         TRACE_ERROR("NVDAT.TOK file name buffer overflow\n");
         return NULL;
     }
-    return fopen(buf, mode);
+    fp = fopen_nofollow(buf, mode);
+    if (fp == NULL && errno == ELOOP)
+        TRACE_ERROR("Refusing to follow symlink: %s\n", buf);
+
+    return fp;
+    
 }
 
 char *get_pk_dir(STDLL_TokData_t *tokdata, char *fname, size_t len)
@@ -185,9 +210,13 @@
     // we didn't find it...either the index file doesn't exist or this
     // is a new object...
     //
-    fp = fopen(fname, "a");
+    fp = fopen_nofollow(fname, "a");
+
     if (!fp) {
-        TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+        if (errno == ELOOP)
+            TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+        else
+            TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
         return CKR_FUNCTION_FAILED;
     }
 
@@ -237,8 +266,8 @@
 
     fclose(fp1);
     fclose(fp2);
-    fp2 = fopen(objidx, "w");
-    fp1 = fopen(idxtmp, "r");
+    fp2 = fopen_nofollow(objidx, "w");
+    fp1 = fopen_nofollow(idxtmp, "r");
     if (!fp1 || !fp2) {
         if (fp1)
             fclose(fp1);
@@ -526,11 +555,14 @@
         if (errno == ENOENT) {
             init_token_data(tokdata, slot_id);
 
-            fp = fopen(fname, "r");
+            fp = fopen_nofollow(fname, "r");
             if (!fp) {
                 // were really hosed here since the created
                 // did not occur
-                TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+                if (errno == ELOOP)
+                    TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+                else
+                    TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
                 rc = CKR_FUNCTION_FAILED;
                 goto out_unlock;
             }
@@ -730,10 +762,14 @@
         rc = CKR_FUNCTION_FAILED;
         goto error;
     }
-    fp = fopen(fname, "w");
+     fp = fopen_nofollow(fname, "w");
     if (!fp) {
-        TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
-        rc = CKR_FUNCTION_FAILED;
+        if (errno == ELOOP)
+            TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+        else
+            TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+
+ 	rc = CKR_FUNCTION_FAILED;
         goto error;
     }
 
@@ -1483,10 +1519,13 @@
         rc = CKR_FUNCTION_FAILED;
         goto done;
     }
-    fp = fopen(fname, "r");
     if (!fp) {
-        TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
-        rc = CKR_FUNCTION_FAILED;
+        if (errno == ELOOP)
+            TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+        else
+            TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+
+	rc = CKR_FUNCTION_FAILED;
         goto done;
     }
 
@@ -1572,10 +1611,14 @@
         rc = CKR_FUNCTION_FAILED;
         goto error;
     }
-    fp = fopen(fname, "w");
+    fp = fopen_nofollow(fname, "w");
     if (!fp) {
-        TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
-        rc = CKR_FUNCTION_FAILED;
+        if (errno == ELOOP)
+           TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+        else
+           TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+
+	rc = CKR_FUNCTION_FAILED;
         goto error;
     }
 
@@ -2179,12 +2222,16 @@
         if (errno == ENOENT) {
             init_token_data(tokdata, slot_id);
 
-            fp = fopen(fname, "r");
+            fp = fopen_nofollow(fname, "r");
             if (!fp) {
                 // were really hosed here since the created
                 // did not occur
-                TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
-                rc = CKR_FUNCTION_FAILED;
+                if (errno == ELOOP)
+                    TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+                else
+                    TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+
+		rc = CKR_FUNCTION_FAILED;
                 goto out_unlock;
             }
         } else {
@@ -2355,14 +2402,17 @@
         goto done;
     }
 
-    fp = fopen(fname, "r");
+    fp = fopen_nofollow(fname, "r");
     if (fp == NULL) {
         /* create new token object */
         new = 1;
     } else {
         if (fstat(fileno(fp), &sb) != 0) {
-            TRACE_ERROR("fstat(%s): %s\n", fname, strerror(errno));
-            rc = CKR_FUNCTION_FAILED;
+            if (errno == ELOOP)
+               TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+            else
+               TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+	    rc = CKR_FUNCTION_FAILED;
             goto done;
         }
 
@@ -2453,9 +2503,13 @@
     if (rc != CKR_OK)
         goto done;
 
-    fp = fopen(fname, "w");
+    fp = fopen_nofollow(fname, "w");
     if (!fp) {
-        TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+       if (errno == ELOOP)
+          TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+       else
+          TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+
         rc = CKR_FUNCTION_FAILED;
         goto done;
     }
@@ -2650,9 +2704,13 @@
     sprintf(fname, "%s/%s/", tokdata->data_store, PK_LITE_OBJ_DIR);
     strncat(fname, (char *) obj->name, 8);
 
-    fp = fopen(fname, "r");
+    fp = fopen_nofollow(fname, "r");
     if (!fp) {
-        TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+       if (errno == ELOOP)
+          TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+       else
+          TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+
         rc = CKR_FUNCTION_FAILED;
         goto done;
     }
@@ -2763,10 +2821,14 @@
     sprintf(fname, "%s/%s/", tokdata->data_store, PK_LITE_OBJ_DIR);
     strncat(fname, (char *) obj->name, 8);
 
-    fp = fopen(fname, "w");
+    fp = fopen_nofollow(fname, "w");
     if (!fp) {
-        TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
-        rc = CKR_FUNCTION_FAILED;
+        if (errno == ELOOP)
+           TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+        else
+           TRACE_ERROR("fopen(%s): %s\n", fname, strerror(errno));
+        
+	rc = CKR_FUNCTION_FAILED;
         goto done;
     }
 
@@ -2823,7 +2885,7 @@
         sprintf(fname, "%s/%s/", tokdata->data_store, PK_LITE_OBJ_DIR);
         strcat(fname, tmp);
 
-        fp2 = fopen(fname, "r");
+        fp2 = fopen_nofollow(fname, "r");
         if (!fp2)
             continue;
 
diff -Naur a/usr/lib/common/platform.h b/usr/lib/common/platform.h
--- a/usr/lib/common/platform.h	2026-01-28 14:25:53.710577830 +0100
+++ b/usr/lib/common/platform.h	2026-01-28 09:57:21.399916646 +0100
@@ -0,0 +1,82 @@
+#ifndef PLATFORM_H
+#define PLATFORM_H
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+/*
+ * Check for O_NOFOLLOW support at compile time.
+ * If not available, fall back to lstat() + fopen() (has TOCTOU race).
+ */
+#ifndef O_NOFOLLOW
+#define OCK_NO_O_NOFOLLOW 1
+#warning "O_NOFOLLOW not supported, symlink protection uses racy lstat() fallback!"
+#endif
+
+/*
+ * CWE-59 fix: Open file without following symlinks.
+ *
+ * On platforms with O_NOFOLLOW support:
+ *   Uses open(O_NOFOLLOW) + fdopen() for atomic symlink rejection.
+ *
+ * On platforms without O_NOFOLLOW (e.g., older AIX):
+ *   Falls back to lstat() + fopen(). This has a TOCTOU race condition,
+ *   but still catches pre-planted symlinks which is the common attack
+ *   scenario. Better than no protection at all.
+ *
+ * Returns NULL with errno=ELOOP if path is a symlink.
+ */
+static inline FILE *fopen_nofollow(const char *path, const char *mode)
+{
+#ifdef OCK_NO_O_NOFOLLOW
+    /*
+     * Fallback for platforms without O_NOFOLLOW: use lstat() check.
+     * This has a TOCTOU race but catches pre-planted symlinks.
+     */
+    struct stat sb;
+
+    if (lstat(path, &sb) == 0) {
+        if (S_ISLNK(sb.st_mode)) {
+            errno = ELOOP;
+            return NULL;
+        }
+    }
+    /* Note: if lstat fails (e.g., file doesn't exist for "w" mode),
+     * we proceed with fopen() which will handle the error appropriately */
+    return fopen(path, mode);
+#else
+    /* Preferred: atomic symlink rejection via O_NOFOLLOW */
+    int flags = O_NOFOLLOW;
+    int fd;
+    FILE *fp;
+
+    /* Determine flags based on mode */
+    if (mode[0] == 'r') {
+        flags |= (mode[1] == '+') ? O_RDWR : O_RDONLY;
+    } else if (mode[0] == 'w') {
+        flags |= O_CREAT | O_TRUNC | ((mode[1] == '+') ? O_RDWR : O_WRONLY);
+    } else if (mode[0] == 'a') {
+        flags |= O_CREAT | O_APPEND | ((mode[1] == '+') ? O_RDWR : O_WRONLY);
+    } else {
+        return NULL;
+    }
+
+    fd = open(path, flags, 0600);
+    if (fd < 0)
+        return NULL;
+
+    fp = fdopen(fd, mode);
+    if (fp == NULL) {
+        close(fd);
+        return NULL;
+    }
+    return fp;
+#endif
+}
+
+#endif /* PLATFORM_H */
+
diff -Naur a/usr/lib/hsm_mk_change/hsm_mk_change.c b/usr/lib/hsm_mk_change/hsm_mk_change.c
--- a/usr/lib/hsm_mk_change/hsm_mk_change.c	2024-02-06 11:02:00.000000000 +0100
+++ b/usr/lib/hsm_mk_change/hsm_mk_change.c	2026-01-29 10:22:06.076511781 +0100
@@ -30,6 +30,11 @@
 #include "hsm_mk_change.h"
 #include "pkcs32.h"
 
+/*
+ * 
+ */
+#include "platform.h"
+
 struct hsm_mk_change_op_hdr {
     char id[6];
     uint32_t state; /* stored in big endian */
@@ -611,10 +616,15 @@
 
     TRACE_DEVEL("file to open: %s mode: %s\n", hsm_mk_change_file, mode);
 
-    fp = fopen(hsm_mk_change_file, mode);
+    fp = fopen_nofollow(hsm_mk_change_file, mode);
     if (fp == NULL) {
-        TRACE_ERROR("%s fopen(%s, %s): %s\n", __func__,
+        if (errno == ELOOP) {
+           TRACE_ERROR("Refusing to follow symlink: %s\n", hsm_mk_change_file);		
+	}
+	else {
+           TRACE_ERROR("%s fopen(%s, %s): %s\n", __func__,
                         hsm_mk_change_file, mode, strerror(errno));
+	}
     }
 
     return fp;
diff -Naur a/usr/lib/icsf_stdll/pbkdf.c b/usr/lib/icsf_stdll/pbkdf.c
--- a/usr/lib/icsf_stdll/pbkdf.c	2024-02-06 11:02:00.000000000 +0100
+++ b/usr/lib/icsf_stdll/pbkdf.c	2026-01-29 10:58:24.764278320 +0100
@@ -27,7 +27,11 @@
 #include "h_extern.h"
 #include "pbkdf.h"
 #include "trace.h"
-
+    
+/*
+ * 
+ */
+#include "platform.h"
 
 CK_RV get_randombytes(unsigned char *output, int bytes)
 {
@@ -189,9 +193,12 @@
     }
 
     /* open the file */
-    fp = fopen(fname, "r");
+    fp = fopen_nofollow(fname, "r");
     if (fp == NULL) {
-        TRACE_ERROR("fopen failed\n");
+	if (errno == ELOOP)
+            TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+        else
+            TRACE_ERROR("fopen failed\n");
         return CKR_FUNCTION_FAILED;
     }
 
@@ -288,9 +295,12 @@
     }
 
     /* if file exists, open it */
-    fp = fopen(RACFFILE, "r");
+    fp = fopen_nofollow(RACFFILE, "r");
     if (fp == NULL) {
-        TRACE_ERROR("fopen failed\n");
+        if (errno == ELOOP)
+            TRACE_ERROR("Refusing to follow symlink: %s\n", RACFFILE);
+        else
+            TRACE_ERROR("fopen failed\n");
         return CKR_FUNCTION_FAILED;
     }
 
@@ -527,9 +537,12 @@
     /* get the total length */
     totallen = outputlen + AES_INIT_VECTOR_SIZE;
 
-    fp = fopen(RACFFILE, "w");
+    fp = fopen_nofollow(RACFFILE, "w");
     if (!fp) {
-        TRACE_ERROR("fopen failed: %s\n", strerror(errno));
+        if (errno == ELOOP)
+            TRACE_ERROR("Refusing to follow symlink: %s\n", RACFFILE);
+        else	    
+            TRACE_ERROR("fopen failed: %s\n", strerror(errno));
         return CKR_FUNCTION_FAILED;
     }
 
@@ -600,9 +613,12 @@
     /* get the total length */
     totallen = outputlen + SALTSIZE;
 
-    fp = fopen(fname, "w");
+    fp = fopen_nofollow(fname, "w");
     if (!fp) {
-        TRACE_ERROR("fopen failed: %s\n", strerror(errno));
+        if (errno == ELOOP)
+            TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+        else 	    
+            TRACE_ERROR("fopen failed: %s\n", strerror(errno));
         return CKR_FUNCTION_FAILED;
     }
 
diff -Naur a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c
--- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c	2024-02-06 11:02:00.000000000 +0100
+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c	2026-01-29 10:22:54.340861654 +0100
@@ -45,7 +45,11 @@
 #define OCK_TOOL
 #include "pkcs_utils.h"
 #include "pin_prompt.h"
-
+    
+/*
+ * 
+ */
+#include "platform.h"
 
 #define TOKVERSION_00         0x00000000
 #define TOKVERSION_312        0x0003000C
@@ -70,9 +74,13 @@
         TRACE_ERROR("Path overflow for datastore file %s\n", file);
         return NULL;
     }
-    res = fopen(buf, mode);
-    if (!res)
-        TRACE_ERROR("fopen(%s) failed, errno=%s\n", buf, strerror(errno));
+    res = fopen_nofollow(buf, mode);
+    if (!res) {
+        if (errno == ELOOP)
+            TRACE_ERROR("Refusing to follow symlink: %s\n", buf);
+        else
+            TRACE_ERROR("fopen(%s) failed, errno=%s\n", buf, strerror(errno));
+    }
     return res;
 }
 
@@ -87,9 +95,13 @@
                     file, tokenobj);
         return NULL;
     }
-    res = fopen(buf, mode);
-    if (!res)
-        TRACE_ERROR("fopen(%s) failed, errno=%s\n", buf, strerror(errno));
+    res = fopen_nofollow(buf, mode);
+    if (!res) {
+        if (errno == ELOOP)
+            TRACE_ERROR("Refusing to follow symlink: %s\n", buf);
+        else	    
+            TRACE_ERROR("fopen(%s) failed, errno=%s\n", buf, strerror(errno));
+    }
     return res;
 }
 
@@ -725,9 +737,12 @@
     /* Open file */
     memset(fname, 0, PATH_MAX);
     snprintf(fname, PATH_MAX, "%s/%s", data_store, mkfile);
-    fp = fopen(fname, "r");
+    fp = fopen_nofollow(fname, "r");
     if (!fp) {
-        TRACE_ERROR("fopen(%s) failed, errno=%s\n", fname, strerror(errno));
+        if (errno == ELOOP)
+            TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+        else	    
+            TRACE_ERROR("fopen(%s) failed, errno=%s\n", fname, strerror(errno));
         ret = CKR_FUNCTION_FAILED;
         goto done;
     }
@@ -802,9 +817,12 @@
     int rc;
     FILE *fp = NULL;
 
-    fp = fopen(mkfile, "r");
+    fp = fopen_nofollow(mkfile, "r");
     if (!fp) {
-        TRACE_ERROR("fopen(%s) failed, errno=%s\n", mkfile, strerror(errno));
+        if (errno == ELOOP)
+            TRACE_ERROR("Refusing to follow symlink: %s\n", mkfile);
+        else
+            TRACE_ERROR("fopen(%s) failed, errno=%s\n", mkfile, strerror(errno));
         return CKR_FUNCTION_FAILED;
     }
 
@@ -1175,7 +1193,7 @@
     struct ConfigBaseNode *config = NULL;
     int ret;
 
-    file = fopen(config_file, "r");
+    file = fopen_nofollow(config_file, "r");
     if (file == NULL)
         return NULL;
 
@@ -1840,7 +1858,7 @@
 
     /* Open index file OBJ.IDX */
     snprintf(iname, sizeof(iname), "%s/TOK_OBJ/OBJ.IDX", data_store);
-    fp = fopen((char *) iname, "r");
+    fp = fopen_nofollow((char *) iname, "r");
     if (!fp) {
         TRACE_INFO("Cannot open %s, datastore probably empty.\n", iname);
         ret = CKR_OK;
@@ -1890,9 +1908,12 @@
 
     /* Read the NVTOK.DAT */
     snprintf(fname, PATH_MAX, "%s/NVTOK.DAT", data_store);
-    fp = fopen((char *)fname, "r");
+    fp = fopen_nofollow((char *)fname, "r");
     if (!fp) {
-        TRACE_ERROR("Cannot open %s, errno=%s\n", fname, strerror(errno));
+        if (errno == ELOOP)
+            TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
+        else	    
+            TRACE_ERROR("Cannot open %s, errno=%s\n", fname, strerror(errno));
         return CKR_FUNCTION_FAILED;
     }
 
@@ -2112,9 +2133,12 @@
 
     /* Open new conf file for write */
     snprintf(dst_file, PATH_MAX, "%s/%s", location, "opencryptoki.conf_new");
-    fp_w = fopen(dst_file, "w");
+    fp_w = fopen_nofollow(dst_file, "w");
     if (!fp_w) {
-        TRACE_ERROR("fopen(%s) failed, errno=%s\n", dst_file, strerror(errno));
+        if (errno == ELOOP)
+            TRACE_ERROR("Refusing to follow symlink: %s\n", dst_file);
+        else	    
+            TRACE_ERROR("fopen(%s) failed, errno=%s\n", dst_file, strerror(errno));
         ret = CKR_FUNCTION_FAILED;
         goto done;
     }
@@ -2194,14 +2218,14 @@
     snprintf(dst_file, PATH_MAX, "%s/%s", dst, name);
     snprintf(src_file, PATH_MAX, "%s/%s", src, name);
 
-    fp_r = fopen(src_file, "r");
+    fp_r = fopen_nofollow(src_file, "r");
     if (!fp_r) {
         warnx("fopen(%s) failed, errno=%s", src_file, strerror(errno));
         ret = CKR_FUNCTION_FAILED;
         goto done;
     }
 
-    fp_w = fopen(dst_file, "w");
+    fp_w = fopen_nofollow(dst_file, "w");
     if (!fp_w) {
         warnx("fopen(%s) failed, errno=%s", dst_file, strerror(errno));
         ret = CKR_FUNCTION_FAILED;
@@ -2446,7 +2470,7 @@
 
     TRACE_INFO("Checking if pkcsslotd is running ...\n");
 
-    fp = fopen(PID_FILE_PATH, "r");
+    fp = fopen_nofollow(PID_FILE_PATH, "r");
     if (fp == NULL) {
         TRACE_INFO("Pid file '%s' not existent, pkcsslotd is not running\n",
                    PID_FILE_PATH);
@@ -2469,7 +2493,7 @@
     }
 
     snprintf(fname, sizeof(fname), "/proc/%ld/cmdline", lpid);
-    fp = fopen(fname, "r");
+    fp = fopen_nofollow(fname, "r");
     if (fp == NULL) {
         TRACE_INFO("Stale pid file, pkcsslotd is not running\n");
         return CK_FALSE;
openSUSE Build Service is sponsored by