import Oracle_OSS opencryptoki-3.25.0-4.el9_7.2
This commit is contained in:
parent
532501cd19
commit
5fcbe4e726
517
SOURCES/opencryptoki-3.25.0-CVE-2026-23893.patch
Normal file
517
SOURCES/opencryptoki-3.25.0-CVE-2026-23893.patch
Normal file
@ -0,0 +1,517 @@
|
||||
commit 66e5bbdc0019fdf547409152df6b7668639f65e7
|
||||
Author: Pavel Kohout <pavel@aisle.com>
|
||||
Date: Tue Jan 13 00:00:00 2026 +0000
|
||||
|
||||
Fix symlink-following vulnerabilities (CWE-59)
|
||||
|
||||
Multiple symlink-following vulnerabilities exist in OpenCryptoki that run
|
||||
in privileged contexts. These allow a token-group user to redirect file
|
||||
operations to arbitrary filesystem targets by planting symlinks in
|
||||
group-writable token directories, resulting in privilege escalation or
|
||||
data exposure.
|
||||
|
||||
Affected components:
|
||||
1. pkcstok_admin: set_file_permissions() uses stat() which follows symlinks,
|
||||
then applies chmod/chown to the symlink target.
|
||||
2. pkcstok_migrate: fopen() follows symlinks, then set_perm() modifies the
|
||||
target permissions.
|
||||
3. loadsave.c: Multiple wrapper functions use fopen() followed by set_perm().
|
||||
4. hsm_mk_change.c: hsm_mk_change_op_open() uses fopen() followed by
|
||||
hsm_mk_change_op_set_perm().
|
||||
5. pbkdf.c: fopen() followed by set_perms() in two locations.
|
||||
|
||||
This fix:
|
||||
- Introduces fopen_nofollow() helper in platform.h
|
||||
- Checks for O_NOFOLLOW at compile time (not hardcoded per-platform)
|
||||
- On platforms with O_NOFOLLOW: uses open(O_NOFOLLOW) + fdopen() for atomic
|
||||
symlink rejection (race-condition free)
|
||||
- On platforms without O_NOFOLLOW: falls back to lstat() + fopen() and emits
|
||||
a compiler warning so the unsafe fallback doesn't go unnoticed
|
||||
- Updates all affected wrapper functions to use fopen_nofollow()
|
||||
- pkcstok_admin: Uses lstat() instead of stat() and skips symlinks
|
||||
|
||||
Reported-by: Pavel Kohout, Aisle Research, www.aisle.com
|
||||
Signed-off-by: Pavel Kohout <pavel@aisle.com>
|
||||
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
|
||||
|
||||
diff --git a/usr/lib/common/loadsave.c b/usr/lib/common/loadsave.c
|
||||
index 3b919709..e416c2b2 100644
|
||||
--- a/usr/lib/common/loadsave.c
|
||||
+++ b/usr/lib/common/loadsave.c
|
||||
@@ -66,9 +66,17 @@ static FILE *open_token_object_path(char *buf, size_t buflen,
|
||||
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 +93,17 @@ static FILE *open_token_data_store_path(char *buf, size_t buflen,
|
||||
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 +115,19 @@ static FILE *open_token_object_index(char *buf, size_t buflen,
|
||||
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)
|
||||
@@ -223,9 +247,12 @@ CK_RV save_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -286,8 +313,12 @@ CK_RV delete_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
|
||||
|
||||
fclose(fp1);
|
||||
fclose(fp2);
|
||||
- fp2 = fopen(objidx, "w");
|
||||
- fp1 = fopen(idxtmp, "r");
|
||||
+ fp2 = fopen_nofollow(objidx, "w");
|
||||
+ if (fp1 == NULL && errno == ELOOP)
|
||||
+ TRACE_ERROR("Refusing to follow symlink: %s\n", objidx);
|
||||
+ fp1 = fopen_nofollow(idxtmp, "r");
|
||||
+ if (fp2 == NULL && errno == ELOOP)
|
||||
+ TRACE_ERROR("Refusing to follow symlink: %s\n", idxtmp);
|
||||
if (!fp1 || !fp2) {
|
||||
if (fp1)
|
||||
fclose(fp1);
|
||||
@@ -616,11 +647,14 @@ CK_RV load_token_data_old(STDLL_TokData_t *tokdata, CK_SLOT_ID slot_id)
|
||||
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;
|
||||
}
|
||||
@@ -824,9 +858,12 @@ static CK_RV save_private_token_object_old(STDLL_TokData_t *tokdata, OBJECT *obj
|
||||
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));
|
||||
+ 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;
|
||||
}
|
||||
@@ -1590,9 +1627,12 @@ CK_RV reload_token_object_old(STDLL_TokData_t *tokdata, OBJECT *obj)
|
||||
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));
|
||||
+ 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;
|
||||
}
|
||||
@@ -1681,9 +1721,12 @@ CK_RV save_public_token_object_old(STDLL_TokData_t *tokdata, OBJECT * obj)
|
||||
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));
|
||||
+ 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;
|
||||
}
|
||||
@@ -2303,11 +2346,14 @@ CK_RV load_token_data(STDLL_TokData_t *tokdata, CK_SLOT_ID slot_id)
|
||||
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;
|
||||
}
|
||||
@@ -2481,7 +2527,7 @@ CK_RV save_private_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
|
||||
goto done;
|
||||
}
|
||||
|
||||
- fp = fopen(fname, "r");
|
||||
+ fp = fopen_nofollow(fname, "r");
|
||||
if (fp == NULL) {
|
||||
/* create new token object */
|
||||
new = 1;
|
||||
@@ -2579,9 +2625,12 @@ do_work:
|
||||
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;
|
||||
}
|
||||
@@ -2778,9 +2827,12 @@ CK_RV reload_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
|
||||
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;
|
||||
}
|
||||
@@ -2893,9 +2945,12 @@ CK_RV save_public_token_object(STDLL_TokData_t *tokdata, OBJECT *obj)
|
||||
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));
|
||||
+ 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;
|
||||
}
|
||||
@@ -2956,9 +3011,12 @@ CK_RV load_public_token_objects(STDLL_TokData_t *tokdata)
|
||||
sprintf(fname, "%s/%s/", tokdata->data_store, PK_LITE_OBJ_DIR);
|
||||
strcat(fname, tmp);
|
||||
|
||||
- fp2 = fopen(fname, "r");
|
||||
- if (!fp2)
|
||||
+ fp2 = fopen_nofollow(fname, "r");
|
||||
+ if (!fp2) {
|
||||
+ if (errno == ELOOP)
|
||||
+ TRACE_ERROR("Refusing to follow symlink: %s\n", fname);
|
||||
continue;
|
||||
+ }
|
||||
|
||||
if (fread(header, PUB_HEADER_LEN, 1, fp2) != 1) {
|
||||
fclose(fp2);
|
||||
diff --git a/usr/lib/common/platform.h b/usr/lib/common/platform.h
|
||||
index 799821b5..51cc1c73 100644
|
||||
--- a/usr/lib/common/platform.h
|
||||
+++ b/usr/lib/common/platform.h
|
||||
@@ -7,7 +7,16 @@
|
||||
* found in the file LICENSE file or at
|
||||
* https://opensource.org/licenses/cpl1.0.php
|
||||
*/
|
||||
+#ifndef PLATFORM_H
|
||||
+#define PLATFORM_H
|
||||
+
|
||||
#include <dlfcn.h>
|
||||
+#include <stdio.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <unistd.h>
|
||||
+#include <string.h>
|
||||
+#include <errno.h>
|
||||
+#include <sys/stat.h>
|
||||
|
||||
#if defined(_AIX)
|
||||
#include "aix/getopt.h"
|
||||
@@ -30,10 +39,81 @@
|
||||
/* for htobexx, htolexx, bexxtoh and lexxtoh macros */
|
||||
#include <endian.h>
|
||||
/* macros from bsdlog and friends */
|
||||
-#include <stdio.h>
|
||||
#include <err.h>
|
||||
|
||||
#define OCK_API_LIBNAME "libopencryptoki.so"
|
||||
#define DYNLIB_LDFLAGS (RTLD_NOW)
|
||||
|
||||
#endif /* _AIX */
|
||||
+
|
||||
+/*
|
||||
+ * 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 --git a/usr/lib/hsm_mk_change/hsm_mk_change.c b/usr/lib/hsm_mk_change/hsm_mk_change.c
|
||||
index 161ed880..492bbd83 100644
|
||||
--- a/usr/lib/hsm_mk_change/hsm_mk_change.c
|
||||
+++ b/usr/lib/hsm_mk_change/hsm_mk_change.c
|
||||
@@ -623,9 +623,13 @@ static FILE* hsm_mk_change_op_open(const char *id, CK_SLOT_ID slot_id,
|
||||
|
||||
TRACE_DEVEL("file to open: %s mode: %s\n", hsm_mk_change_file, mode);
|
||||
|
||||
- fp = fopen(hsm_mk_change_file, mode);
|
||||
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
|
||||
+ 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));
|
||||
}
|
||||
|
||||
diff --git a/usr/lib/icsf_stdll/pbkdf.c b/usr/lib/icsf_stdll/pbkdf.c
|
||||
index 47d1b97c..91230804 100644
|
||||
--- a/usr/lib/icsf_stdll/pbkdf.c
|
||||
+++ b/usr/lib/icsf_stdll/pbkdf.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "h_extern.h"
|
||||
#include "pbkdf.h"
|
||||
#include "trace.h"
|
||||
+#include "platform.h"
|
||||
|
||||
|
||||
CK_RV get_randombytes(unsigned char *output, int bytes)
|
||||
@@ -546,9 +547,13 @@ CK_RV secure_racf(STDLL_TokData_t *tokdata,
|
||||
totallen = outputlen + AES_INIT_VECTOR_SIZE;
|
||||
|
||||
snprintf(fname, sizeof(fname), "%s/%s/%s", CONFIG_PATH, tokname, RACFFILE);
|
||||
- fp = fopen(fname, "w");
|
||||
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
|
||||
+ 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;
|
||||
}
|
||||
|
||||
@@ -619,9 +624,13 @@ CK_RV secure_masterkey(STDLL_TokData_t *tokdata,
|
||||
/* get the total length */
|
||||
totallen = outputlen + SALTSIZE;
|
||||
|
||||
- fp = fopen(fname, "w");
|
||||
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
|
||||
+ 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 --git a/usr/sbin/pkcstok_admin/pkcstok_admin.c b/usr/sbin/pkcstok_admin/pkcstok_admin.c
|
||||
index 9912804e..d144cc04 100644
|
||||
--- a/usr/sbin/pkcstok_admin/pkcstok_admin.c
|
||||
+++ b/usr/sbin/pkcstok_admin/pkcstok_admin.c
|
||||
@@ -336,11 +336,18 @@ static int set_file_permissions(const char *fname, const struct group *group,
|
||||
pr_verbose("Setting permissions for '%s' with group '%s'", fname,
|
||||
group->gr_name);
|
||||
|
||||
- if (stat(fname, &sb) != 0) {
|
||||
+ /* CWE-59 fix: Use lstat to detect symlinks */
|
||||
+ if (lstat(fname, &sb) != 0) {
|
||||
warnx("'%s' does not exist.", fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ /* Only process regular files and directories (CWE-59 fix) */
|
||||
+ if (!S_ISREG(sb.st_mode) && !S_ISDIR(sb.st_mode)) {
|
||||
+ warnx("Skipping '%s': not a regular file or directory.", fname);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
if (sb.st_uid != 0) {
|
||||
/* owner is not root */
|
||||
pwd = getpwuid(sb.st_uid);
|
||||
diff --git a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c
|
||||
index 12b605b5..9579e236 100644
|
||||
--- a/usr/sbin/pkcstok_migrate/pkcstok_migrate.c
|
||||
+++ b/usr/sbin/pkcstok_migrate/pkcstok_migrate.c
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "local_types.h"
|
||||
#include "h_extern.h"
|
||||
#include "slotmgr.h" // for ock_snprintf
|
||||
+#include "platform.h"
|
||||
|
||||
#define OCK_TOOL
|
||||
#include "pkcs_utils.h"
|
||||
@@ -77,9 +78,14 @@ static FILE *open_datastore_file(char *buf, size_t buflen,
|
||||
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));
|
||||
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
|
||||
+ 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;
|
||||
}
|
||||
|
||||
@@ -94,9 +100,14 @@ static FILE *open_tokenobject(char *buf, size_t buflen,
|
||||
file, tokenobj);
|
||||
return NULL;
|
||||
}
|
||||
- res = fopen(buf, mode);
|
||||
- if (!res)
|
||||
- TRACE_ERROR("fopen(%s) failed, errno=%s\n", buf, strerror(errno));
|
||||
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
|
||||
+ 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;
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
Name: opencryptoki
|
||||
Summary: Implementation of the PKCS#11 (Cryptoki) specification v3.0 and partially v3.1
|
||||
Version: 3.25.0
|
||||
Release: 4%{?dist}.1
|
||||
Release: 4%{?dist}.2
|
||||
License: CPL-1.0
|
||||
URL: https://github.com/opencryptoki/opencryptoki
|
||||
Source0: https://github.com/opencryptoki/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz
|
||||
@ -36,6 +36,9 @@ Patch13: opencryptoki-3.25.0-fix-unwrapping-attribute-bound-EC-keys.patch
|
||||
# https://github.com/ifranzki/opencryptoki/commit/ab740fd
|
||||
Patch14: opencryptoki-3.25.0-fix-private-secure-key-blob-import.patch
|
||||
|
||||
# CVE-2026-23893, symlink-following vulnerabilities
|
||||
Patch15: opencryptoki-3.25.0-CVE-2026-23893.patch
|
||||
|
||||
Requires(pre): coreutils
|
||||
Requires: (selinux-policy >= 38.1.14-1 if selinux-policy-targeted)
|
||||
BuildRequires: gcc gcc-c++
|
||||
@ -421,6 +424,9 @@ fi
|
||||
|
||||
|
||||
%changelog
|
||||
* Tue Mar 03 2026 Than Ngo <than@redhat.com> - 3.25.0-4.2
|
||||
- Resolves: RHEL-144820, Privilege Escalation or Data Exposure via Symlink Following
|
||||
|
||||
* Tue Feb 03 2026 Than Ngo <than@redhat.com> - 3.25.0-4.1
|
||||
- Fix unwrapping of attribute bound EC keys
|
||||
- Fix private secure key blob import
|
||||
|
||||
Loading…
Reference in New Issue
Block a user