Compare commits
4 Commits
| Author | SHA256 | Date | |
|---|---|---|---|
| 50f918c479 | |||
| 385978d731 | |||
| a4136eb6b0 | |||
| c3bf64bbeb |
@@ -1,460 +0,0 @@
|
|||||||
From 5e6e4b42f2b1fcc1e4ef1b920e463bfa55da8b45 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Pavel Kohout <pavel@aisle.com>
|
|
||||||
Date: Tue, 13 Jan 2026 00:00:00 +0000
|
|
||||||
Subject: [PATCH] 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>
|
|
||||||
---
|
|
||||||
usr/lib/common/loadsave.c | 81 +++++++++++++++++----
|
|
||||||
usr/lib/common/platform.h | 82 +++++++++++++++++++++-
|
|
||||||
usr/lib/hsm_mk_change/hsm_mk_change.c | 8 ++-
|
|
||||||
usr/lib/icsf_stdll/pbkdf.c | 17 +++--
|
|
||||||
usr/sbin/pkcstok_admin/pkcstok_admin.c | 9 ++-
|
|
||||||
usr/sbin/pkcstok_migrate/pkcstok_migrate.c | 23 ++++--
|
|
||||||
6 files changed, 194 insertions(+), 26 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/usr/lib/common/loadsave.c b/usr/lib/common/loadsave.c
|
|
||||||
index 18b8aa044..f9c0cc7f0 100644
|
|
||||||
--- a/usr/lib/common/loadsave.c
|
|
||||||
+++ b/usr/lib/common/loadsave.c
|
|
||||||
@@ -68,9 +68,17 @@ static FILE *open_token_object_path(char *buf, size_t buflen,
|
|
||||||
STDLL_TokData_t *tokdata, const char *path,
|
|
||||||
const char *mode)
|
|
||||||
{
|
|
||||||
+ FILE *fp;
|
|
||||||
+
|
|
||||||
if (get_token_object_path(buf, buflen, tokdata, path, NULL) < 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_path_new(char *newbuf, size_t newbuflen,
|
|
||||||
@@ -78,11 +86,19 @@ static FILE *open_token_object_path_new(char *newbuf, size_t newbuflen,
|
|
||||||
STDLL_TokData_t *tokdata,
|
|
||||||
const char *path, const char *mode)
|
|
||||||
{
|
|
||||||
+ FILE *fp;
|
|
||||||
+
|
|
||||||
if (get_token_object_path(newbuf, newbuflen, tokdata, path, ".TMP") < 0)
|
|
||||||
return NULL;
|
|
||||||
if (get_token_object_path(basebuf, basebuflen, tokdata, path, NULL) < 0)
|
|
||||||
return NULL;
|
|
||||||
- return fopen(newbuf, mode);
|
|
||||||
+
|
|
||||||
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
|
|
||||||
+ fp = fopen_nofollow(newbuf, mode);
|
|
||||||
+ if (fp == NULL && errno == ELOOP)
|
|
||||||
+ TRACE_ERROR("Refusing to follow symlink: %s\n", newbuf);
|
|
||||||
+
|
|
||||||
+ return fp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_token_data_store_path(char *buf, size_t buflen,
|
|
||||||
@@ -101,9 +117,17 @@ static FILE *open_token_data_store_path(char *buf, size_t buflen,
|
|
||||||
STDLL_TokData_t *tokdata,
|
|
||||||
const char *path, const char *mode)
|
|
||||||
{
|
|
||||||
+ FILE *fp;
|
|
||||||
+
|
|
||||||
if (get_token_data_store_path(buf, buflen, tokdata, path, NULL) < 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_data_store_path_new(char *newbuf, size_t newbuflen,
|
|
||||||
@@ -111,11 +135,19 @@ static FILE *open_token_data_store_path_new(char *newbuf, size_t newbuflen,
|
|
||||||
STDLL_TokData_t *tokdata,
|
|
||||||
const char *path, const char *mode)
|
|
||||||
{
|
|
||||||
+ FILE *fp;
|
|
||||||
+
|
|
||||||
if (get_token_data_store_path(newbuf, newbuflen, tokdata, path, ".TMP") < 0)
|
|
||||||
return NULL;
|
|
||||||
if (get_token_data_store_path(basebuf, basebuflen, tokdata, path, NULL) < 0)
|
|
||||||
return NULL;
|
|
||||||
- return fopen(newbuf, mode);
|
|
||||||
+
|
|
||||||
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
|
|
||||||
+ fp = fopen_nofollow(newbuf, mode);
|
|
||||||
+ if (fp == NULL && errno == ELOOP)
|
|
||||||
+ TRACE_ERROR("Refusing to follow symlink: %s\n", newbuf);
|
|
||||||
+
|
|
||||||
+ return fp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FILE *open_token_object_index(char *buf, size_t buflen,
|
|
||||||
@@ -127,17 +159,27 @@ 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, const 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FILE *open_token_nvdat_new(char *newbuf, size_t newbuflen,
|
|
||||||
char *basebuf, size_t basebuflen,
|
|
||||||
STDLL_TokData_t *tokdata, const char *mode)
|
|
||||||
{
|
|
||||||
+ FILE *fp;
|
|
||||||
+
|
|
||||||
if (ock_snprintf(newbuf, newbuflen, "%s/" PK_LITE_NV ".TMP",
|
|
||||||
tokdata->data_store)) {
|
|
||||||
TRACE_ERROR("NVDAT.TOK file name buffer overflow\n");
|
|
||||||
@@ -148,7 +190,13 @@ static FILE *open_token_nvdat_new(char *newbuf, size_t newbuflen,
|
|
||||||
TRACE_ERROR("NVDAT.TOK file name buffer overflow\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
- return fopen(newbuf, mode);
|
|
||||||
+
|
|
||||||
+ /* CWE-59 fix: Use fopen_nofollow to prevent symlink attacks */
|
|
||||||
+ fp = fopen_nofollow(newbuf, mode);
|
|
||||||
+ if (fp == NULL && errno == ELOOP)
|
|
||||||
+ TRACE_ERROR("Refusing to follow symlink: %s\n", newbuf);
|
|
||||||
+
|
|
||||||
+ return fp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CK_RV close_token_file_new(FILE * fp, CK_RV rc,
|
|
||||||
@@ -289,9 +337,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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -663,11 +714,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;
|
|
||||||
}
|
|
||||||
@@ -2345,11 +2399,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;
|
|
||||||
}
|
|
||||||
diff --git a/usr/lib/common/platform.h b/usr/lib/common/platform.h
|
|
||||||
index 799821b57..51cc1c737 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 f40dfb43e..8c66546f6 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 47d1b97c3..91230804f 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 9912804ee..d144cc04c 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 12b605b5b..9579e2364 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,24 +1,14 @@
|
|||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Thu Jan 22 16:34:43 UTC 2026 - Nikolay Gueorguiev <nikolay.gueorguiev@suse.com>
|
Fri Jan 16 08:33:23 UTC 2026 - Nikolay Gueorguiev <nikolay.gueorguiev@suse.com>
|
||||||
|
|
||||||
- Applied a patch (bsc#1257116, CVE-2026-23893)
|
|
||||||
* openCryptoki-CVE-2026-23893-commit-5e6e4b4.patch
|
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
Wed Jan 14 13:06:33 UTC 2026 - Nikolay Gueorguiev <nikolay.gueorguiev@suse.com>
|
|
||||||
|
|
||||||
- Applied a patch (bsc#1256673, CVE-2026-22791)
|
- Applied a patch (bsc#1256673, CVE-2026-22791)
|
||||||
* openCryptoki-CVE-2026-22791-commit-e37e912.patch
|
* openCryptoki-CVE-2026-22791-commit-e37e912.patch
|
||||||
|
- Modified the .spec file for Immutable Mode (jsc#PED-14798)
|
||||||
-------------------------------------------------------------------
|
|
||||||
Thu Jan 8 10:14:17 UTC 2026 - Nikolay Gueorguiev <nikolay.gueorguiev@suse.com>
|
|
||||||
|
|
||||||
- Modified the .spec file for Immutable Mode (jsc#PED-14798)
|
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Wed Nov 12 09:04:02 UTC 2025 - Nikolay Gueorguiev <nikolay.gueorguiev@suse.com>
|
Wed Nov 12 09:04:02 UTC 2025 - Nikolay Gueorguiev <nikolay.gueorguiev@suse.com>
|
||||||
|
|
||||||
- Upgrade openCryptoki to 3.26
|
- Upgrade openCryptoki to 3.26 (jsc#PED-14609)
|
||||||
* Soft: Add support for RSA keys up to 16K bits.
|
* Soft: Add support for RSA keys up to 16K bits.
|
||||||
* CCA: Add support for RSA keys up to 8K bits (requires CCA v8.4 or v7.6 or later).
|
* CCA: Add support for RSA keys up to 8K bits (requires CCA v8.4 or v7.6 or later).
|
||||||
* p11sak: Add support for generating RSA keys up to 16K bits.
|
* p11sak: Add support for generating RSA keys up to 16K bits.
|
||||||
|
|||||||
@@ -26,16 +26,6 @@
|
|||||||
%define pkcs_group pkcs11
|
%define pkcs_group pkcs11
|
||||||
%define oc_cvs_tag opencryptoki
|
%define oc_cvs_tag opencryptoki
|
||||||
|
|
||||||
%ifarch s390 s390x
|
|
||||||
%define ocki_conf_flags --enable-icatok --enable-ccatok --enable-ep11tok --enable-pkcsep11_migrate
|
|
||||||
%else
|
|
||||||
%ifnarch i586
|
|
||||||
%define ocki_conf_flags --disable-icatok --enable-ccatok --disable-ep11tok --disable-pkcsep11_migrate --enable-pkcscca_migrate
|
|
||||||
%else
|
|
||||||
%define ocki_conf_flags --disable-icatok --disable-ccatok --disable-ep11tok --disable-pkcsep11_migrate --disable-pkcscca_migrate
|
|
||||||
%endif
|
|
||||||
%endif
|
|
||||||
|
|
||||||
Name: openCryptoki
|
Name: openCryptoki
|
||||||
Version: 3.26.0
|
Version: 3.26.0
|
||||||
Release: 0
|
Release: 0
|
||||||
@@ -52,7 +42,6 @@ Source3: openCryptoki-rpmlintrc
|
|||||||
Patch000: ocki-3.26-remove-make-install-chgrp.patch
|
Patch000: ocki-3.26-remove-make-install-chgrp.patch
|
||||||
#
|
#
|
||||||
Patch010: openCryptoki-CVE-2026-22791-commit-e37e912.patch
|
Patch010: openCryptoki-CVE-2026-22791-commit-e37e912.patch
|
||||||
Patch011: openCryptoki-CVE-2026-23893-commit-5e6e4b4.patch
|
|
||||||
#
|
#
|
||||||
BuildRequires: bison
|
BuildRequires: bison
|
||||||
BuildRequires: dos2unix
|
BuildRequires: dos2unix
|
||||||
@@ -166,7 +155,15 @@ cp %{SOURCE2} .
|
|||||||
%ifarch aarch64 # Apparently, gcc for aarch64 doesn't support transactional memory
|
%ifarch aarch64 # Apparently, gcc for aarch64 doesn't support transactional memory
|
||||||
--enable-locks \
|
--enable-locks \
|
||||||
%endif
|
%endif
|
||||||
%{ocki_conf_flags}
|
%ifarch s390 s390x
|
||||||
|
--enable-icatok --enable-ccatok --enable-ep11tok --enable-pkcsep11_migrate
|
||||||
|
%else
|
||||||
|
%ifnarch i586
|
||||||
|
--disable-icatok --enable-ccatok --disable-ep11tok --disable-pkcsep11_migrate --enable-pkcscca_migrate
|
||||||
|
%else
|
||||||
|
--disable-icatok --disable-ccatok --disable-ep11tok --disable-pkcsep11_migrate --disable-pkcscca_migrate
|
||||||
|
%endif
|
||||||
|
%endif
|
||||||
|
|
||||||
make %{?_smp_mflags}
|
make %{?_smp_mflags}
|
||||||
dos2unix doc/README.ep11_stdll
|
dos2unix doc/README.ep11_stdll
|
||||||
|
|||||||
Reference in New Issue
Block a user