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.
This commit is contained in:
Mounir IDRASSI
2026-05-26 10:03:10 +09:00
parent 5d7a2a78b8
commit 6774de941d
2 changed files with 70 additions and 0 deletions

View File

@@ -21,6 +21,9 @@
#ifdef TC_LINUX
#include <sys/utsname.h>
#endif
#ifdef TC_OPENBSD
#include <pwd.h>
#endif
#include <stdio.h>
#include <unistd.h>
#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();
}

View File

@@ -40,6 +40,9 @@
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#ifdef TC_OPENBSD
#include <pwd.h>
#endif
#include <sys/mman.h>
#include <sys/statvfs.h>
#include <sys/time.h>
@@ -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;