From 6774de941d220060f8f0a365a36acd360e4397a0 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Tue, 26 May 2026 10:03:10 +0900 Subject: [PATCH] OpenBSD: honor doas user for mount ownership and FUSE access VeraCrypt derives the real (non-root) user from SUDO_UID/SUDO_GID to set default mount-point ownership and the FUSE service access filter. On OpenBSD, privileged commands are normally run through doas, which exposes the invoking login name via DOAS_USER and does not set the sudo variables. As a result, VeraCrypt launched through doas attributes both to root instead of the invoking user. When the sudo identity variables are absent, resolve DOAS_USER through the password database and use that uid/gid for default mount-point ownership and the VeraCrypt FUSE service access filter. sudo behavior is unchanged. This is a correctness fix for the doas launch path. It is not confirmed to resolve the non-root ext2fs EACCES reported in the linked issues: that failure occurs at the ext2fs layer reached through vnd, whose backing-image I/O runs as root and is therefore already permitted by the access filter. Refs #1589. Refs #1593. --- src/Core/Unix/CoreUnix.cpp | 35 +++++++++++++++++++++++++++++++++ src/Driver/Fuse/FuseService.cpp | 35 +++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/src/Core/Unix/CoreUnix.cpp b/src/Core/Unix/CoreUnix.cpp index e4167806..c23df499 100644 --- a/src/Core/Unix/CoreUnix.cpp +++ b/src/Core/Unix/CoreUnix.cpp @@ -21,6 +21,9 @@ #ifdef TC_LINUX #include #endif +#ifdef TC_OPENBSD +#include +#endif #include #include #include "Platform/FileStream.h" @@ -40,6 +43,26 @@ namespace VeraCrypt static bool SamePath (const string& path1, const string& path2); #endif +#ifdef TC_OPENBSD + static bool GetDoasUserIds (uid_t *uid, gid_t *gid) + { + const char *env = getenv ("DOAS_USER"); + if (!env || !env[0]) + return false; + + struct passwd *pw = getpwnam (env); + if (!pw) + return false; + + if (uid) + *uid = pw->pw_uid; + if (gid) + *gid = pw->pw_gid; + + return true; + } +#endif + // Struct to hold terminal emulator information struct TerminalInfo { const char* name; @@ -634,6 +657,12 @@ namespace VeraCrypt catch (...) { } } +#ifdef TC_OPENBSD + gid_t doasGid; + if (GetDoasUserIds (nullptr, &doasGid)) + return doasGid; +#endif + return getgid(); } @@ -650,6 +679,12 @@ namespace VeraCrypt catch (...) { } } +#ifdef TC_OPENBSD + uid_t doasUid; + if (GetDoasUserIds (&doasUid, nullptr)) + return doasUid; +#endif + return getuid(); } diff --git a/src/Driver/Fuse/FuseService.cpp b/src/Driver/Fuse/FuseService.cpp index c0962211..98b3d8fa 100644 --- a/src/Driver/Fuse/FuseService.cpp +++ b/src/Driver/Fuse/FuseService.cpp @@ -40,6 +40,9 @@ #include #include #include +#ifdef TC_OPENBSD +#include +#endif #include #include #include @@ -65,6 +68,26 @@ namespace VeraCrypt static const uint64 VC_FUSE_METADATA_SIZE = 64 * 1024; static const uint64 VC_FUSE_STAT_BLOCK_SIZE = 512; +#ifdef TC_OPENBSD + static bool fuse_service_get_doas_user_ids (uid_t *uid, gid_t *gid) + { + const char *env = getenv ("DOAS_USER"); + if (!env || !env[0]) + return false; + + struct passwd *pw = getpwnam (env); + if (!pw) + return false; + + if (uid) + *uid = pw->pw_uid; + if (gid) + *gid = pw->pw_gid; + + return true; + } +#endif + static uint64 fuse_service_ceil_div (uint64 value, uint64 divisor) { return (value / divisor) + ((value % divisor) ? 1 : 0); @@ -790,6 +813,18 @@ namespace VeraCrypt } catch (...) { } } +#ifdef TC_OPENBSD + else + { + uid_t doasUid; + gid_t doasGid; + if (fuse_service_get_doas_user_ids (&doasUid, &doasGid)) + { + FuseService::UserId = doasUid; + FuseService::GroupId = doasGid; + } + } +#endif static fuse_operations fuse_service_oper;