File openCryptoki-SLE15-SP4-CVE-2026-23893.patch of Package openCryptoki.42501
diff -Naur a/usr/lib/common/loadsave.c b/usr/lib/common/loadsave.c
--- a/usr/lib/common/loadsave.c 2021-10-13 14:09:21.000000000 +0200
+++ b/usr/lib/common/loadsave.c 2026-01-28 10:29:26.025985201 +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,
@@ -66,9 +71,17 @@
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);
+
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
+ 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,
@@ -85,9 +98,17 @@
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);
+
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
+ 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,
@@ -99,11 +120,19 @@
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);
+
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
+ 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)
@@ -184,9 +213,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;
}
@@ -236,8 +269,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);
@@ -499,11 +532,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;
}
@@ -701,10 +737,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;
}
@@ -1421,10 +1461,14 @@
rc = CKR_FUNCTION_FAILED;
goto done;
}
- fp = fopen(fname, "r");
+ fp = fopen_nofollow(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;
}
@@ -1502,10 +1546,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;
}
@@ -2054,12 +2102,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 {
@@ -2214,15 +2266,19 @@
goto done;
}
- fp = fopen(fname, "r");
+ fp = fopen_nofollow(fname, "r");
if (fp == NULL) {
/* create new token object */
new = 1;
} else {
/* update existing token object */
if (fread(data, HEADER_LEN, 1, fp) != 1) {
- TRACE_ERROR("fread(%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;
}
@@ -2294,9 +2350,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;
}
@@ -2488,10 +2548,14 @@
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));
- 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;
}
@@ -2595,10 +2659,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;
}
@@ -2655,7 +2723,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 09:31:44.428046985 +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/icsf_stdll/pbkdf.c b/usr/lib/icsf_stdll/pbkdf.c
--- a/usr/lib/icsf_stdll/pbkdf.c 2021-10-13 14:09:21.000000000 +0200
+++ b/usr/lib/icsf_stdll/pbkdf.c 2026-01-28 11:06:18.030346523 +0100
@@ -28,6 +28,10 @@
#include "pbkdf.h"
#include "trace.h"
+/*
+ *
+ */
+#include "platform.h"
CK_RV get_randombytes(unsigned char *output, int bytes)
{
@@ -156,10 +160,14 @@
}
/* open the file */
- fp = fopen(fname, "r");
+ fp = fopen_nofollow(fname, "r");
if (fp == NULL) {
TRACE_ERROR("fopen failed\n");
- return CKR_FUNCTION_FAILED;
+ 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;
}
ret = fread(&totallen, sizeof(CK_ULONG_32), 1, fp);
@@ -231,10 +239,14 @@
}
/* if file exists, open it */
- fp = fopen(RACFFILE, "r");
+ fp = fopen_nofollow(RACFFILE, "r");
if (fp == NULL) {
- TRACE_ERROR("fopen failed\n");
- return CKR_FUNCTION_FAILED;
+ 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;
}
readsize = fread(&len, sizeof(CK_ULONG_32), 1, fp);
@@ -408,10 +420,15 @@
/* 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));
- return CKR_FUNCTION_FAILED;
+ 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;
}
/* set permisions on the file */
@@ -478,10 +495,14 @@
/* 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));
- return CKR_FUNCTION_FAILED;
+ 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;
}
/* set permisions on the file */
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 2021-10-13 14:09:21.000000000 +0200
+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c 2026-01-28 12:33:07.672343791 +0100
@@ -45,6 +45,10 @@
#define OCK_TOOL
#include "pkcs_utils.h"
+/*
+ *
+ */
+#include "platform.h"
#define TOKVERSION_00 0x00000000
#define TOKVERSION_312 0x0003000C
@@ -68,9 +72,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;
}
@@ -85,9 +93,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;
}
@@ -722,7 +734,7 @@
TRACE_ERROR("fopen(%s) failed, errno=%s\n", fname, strerror(errno));
ret = CKR_FUNCTION_FAILED;
goto done;
- }
+}
/* Read wrapped key from file */
rc = fread(inbuf, sizeof(inbuf), 1, fp);