mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-06-09 22:36:59 -05:00
macOS: stabilize FUSE-T SMB auxiliary mounts
Add statfs metadata for the auxiliary FUSE mount, keep /control read-only by sending hdiutil device data through /aux-device-info and tolerate delayed SMB rediscovery during mount completion. Log final control-file retry failures for diagnostics.
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
@@ -59,6 +60,20 @@ namespace VeraCrypt
|
||||
static const ino_t VC_FUSE_INODE_ROOT = 1;
|
||||
static const ino_t VC_FUSE_INODE_VOLUME = 2;
|
||||
static const ino_t VC_FUSE_INODE_CONTROL = 3;
|
||||
static const ino_t VC_FUSE_INODE_AUX_DEVICE_INFO = 4;
|
||||
static const uint64 VC_FUSE_BLOCK_SIZE = 4096;
|
||||
static const uint64 VC_FUSE_STAT_BLOCK_SIZE = 512;
|
||||
|
||||
static uint64 fuse_service_ceil_div (uint64 value, uint64 divisor)
|
||||
{
|
||||
return (value / divisor) + ((value % divisor) ? 1 : 0);
|
||||
}
|
||||
|
||||
static void fuse_service_set_stat_blocks (struct stat *statData)
|
||||
{
|
||||
statData->st_blksize = VC_FUSE_BLOCK_SIZE;
|
||||
statData->st_blocks = fuse_service_ceil_div ((uint64) statData->st_size, VC_FUSE_STAT_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
static int fuse_service_fill_dir_entry (void *buf, fuse_fill_dir_t filler, const char *name, mode_t mode, ino_t ino, off_t nextOff)
|
||||
{
|
||||
@@ -69,6 +84,7 @@ namespace VeraCrypt
|
||||
st.st_uid = FuseService::GetUserId();
|
||||
st.st_gid = FuseService::GetGroupId();
|
||||
st.st_ino = ino;
|
||||
fuse_service_set_stat_blocks (&st);
|
||||
|
||||
return VC_FUSE_FILL_DIR (filler, buf, name, &st, nextOff);
|
||||
}
|
||||
@@ -169,6 +185,7 @@ namespace VeraCrypt
|
||||
statData->st_atime = time (NULL);
|
||||
statData->st_ctime = time (NULL);
|
||||
statData->st_mtime = time (NULL);
|
||||
statData->st_blksize = VC_FUSE_BLOCK_SIZE;
|
||||
|
||||
if (strcmp (path, "/") == 0)
|
||||
{
|
||||
@@ -181,12 +198,21 @@ namespace VeraCrypt
|
||||
if (!FuseService::CheckAccessRights())
|
||||
return -EACCES;
|
||||
|
||||
if (strcmp (path, FuseService::GetVolumeImagePath()) == 0)
|
||||
if (strcmp (path, FuseService::GetAuxDeviceInfoPath()) == 0)
|
||||
{
|
||||
statData->st_mode = S_IFREG | 0200;
|
||||
statData->st_nlink = 1;
|
||||
statData->st_size = VC_FUSE_BLOCK_SIZE;
|
||||
statData->st_ino = VC_FUSE_INODE_AUX_DEVICE_INFO;
|
||||
fuse_service_set_stat_blocks (statData);
|
||||
}
|
||||
else if (strcmp (path, FuseService::GetVolumeImagePath()) == 0)
|
||||
{
|
||||
statData->st_mode = S_IFREG | 0600;
|
||||
statData->st_nlink = 1;
|
||||
statData->st_size = FuseService::GetVolumeSize();
|
||||
statData->st_ino = VC_FUSE_INODE_VOLUME;
|
||||
fuse_service_set_stat_blocks (statData);
|
||||
}
|
||||
else if (strcmp (path, FuseService::GetControlPath()) == 0)
|
||||
{
|
||||
@@ -194,6 +220,7 @@ namespace VeraCrypt
|
||||
statData->st_nlink = 1;
|
||||
statData->st_size = FuseService::GetVolumeInfo()->Size();
|
||||
statData->st_ino = VC_FUSE_INODE_CONTROL;
|
||||
fuse_service_set_stat_blocks (statData);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -222,6 +249,35 @@ namespace VeraCrypt
|
||||
}
|
||||
#endif
|
||||
|
||||
static int fuse_service_statfs (const char *path, struct statvfs *statData)
|
||||
{
|
||||
try
|
||||
{
|
||||
(void) path;
|
||||
|
||||
uint64 blockCount = fuse_service_ceil_div (FuseService::GetVolumeSize(), VC_FUSE_BLOCK_SIZE);
|
||||
if (blockCount == 0)
|
||||
blockCount = 1;
|
||||
|
||||
Memory::Zero (statData, sizeof (*statData));
|
||||
statData->f_bsize = VC_FUSE_BLOCK_SIZE;
|
||||
statData->f_frsize = VC_FUSE_BLOCK_SIZE;
|
||||
statData->f_blocks = blockCount;
|
||||
statData->f_bfree = blockCount;
|
||||
statData->f_bavail = blockCount;
|
||||
statData->f_files = 4;
|
||||
statData->f_ffree = 0;
|
||||
statData->f_favail = 0;
|
||||
statData->f_namemax = 255;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return FuseService::ExceptionToErrorCode();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fuse_service_opendir (const char *path, struct fuse_file_info *fi)
|
||||
{
|
||||
try
|
||||
@@ -250,6 +306,12 @@ namespace VeraCrypt
|
||||
if (strcmp (path, FuseService::GetVolumeImagePath()) == 0)
|
||||
return 0;
|
||||
|
||||
if (strcmp (path, FuseService::GetAuxDeviceInfoPath()) == 0)
|
||||
{
|
||||
fi->direct_io = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp (path, FuseService::GetControlPath()) == 0)
|
||||
{
|
||||
fi->direct_io = 1;
|
||||
@@ -351,6 +413,8 @@ namespace VeraCrypt
|
||||
return 0;
|
||||
if (fuse_service_fill_dir_entry (buf, filler, FuseService::GetControlPath() + 1, S_IFREG | 0600, VC_FUSE_INODE_CONTROL, 0) != 0)
|
||||
return 0;
|
||||
if (fuse_service_fill_dir_entry (buf, filler, FuseService::GetAuxDeviceInfoPath() + 1, S_IFREG | 0200, VC_FUSE_INODE_AUX_DEVICE_INFO, 0) != 0)
|
||||
return 0;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@@ -388,12 +452,12 @@ namespace VeraCrypt
|
||||
return size;
|
||||
}
|
||||
|
||||
if (strcmp (path, FuseService::GetControlPath()) == 0)
|
||||
if (strcmp (path, FuseService::GetAuxDeviceInfoPath()) == 0)
|
||||
{
|
||||
if (FuseService::AuxDeviceInfoReceived())
|
||||
return -EACCES;
|
||||
|
||||
FuseService::ReceiveAuxDeviceInfo (ConstBufferPtr ((const uint8 *)buf, size));
|
||||
FuseService::ReceiveAuxDeviceInfo (ConstBufferPtr ((const uint8 *) buf, size));
|
||||
return size;
|
||||
}
|
||||
}
|
||||
@@ -594,7 +658,7 @@ namespace VeraCrypt
|
||||
void FuseService::SendAuxDeviceInfo (const DirectoryPath &fuseMountPoint, const DevicePath &virtualDevice, const DevicePath &loopDevice)
|
||||
{
|
||||
File fuseServiceControl;
|
||||
fuseServiceControl.Open (string (fuseMountPoint) + GetControlPath(), File::OpenWrite);
|
||||
fuseServiceControl.Open (string (fuseMountPoint) + GetAuxDeviceInfoPath(), File::OpenWrite);
|
||||
|
||||
shared_ptr <Stream> stream (new MemoryStream);
|
||||
Serializer sr (stream);
|
||||
@@ -664,6 +728,7 @@ namespace VeraCrypt
|
||||
fuse_service_oper.opendir = fuse_service_opendir;
|
||||
fuse_service_oper.read = fuse_service_read;
|
||||
fuse_service_oper.readdir = fuse_service_readdir;
|
||||
fuse_service_oper.statfs = fuse_service_statfs;
|
||||
fuse_service_oper.write = fuse_service_write;
|
||||
|
||||
// Create a new session
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace VeraCrypt
|
||||
static bool CheckAccessRights ();
|
||||
static void Dismount ();
|
||||
static int ExceptionToErrorCode ();
|
||||
static const char *GetAuxDeviceInfoPath () { return "/aux-device-info"; }
|
||||
static const char *GetControlPath () { return "/control"; }
|
||||
static const char *GetVolumeImagePath ();
|
||||
static string GetDeviceType () { return "veracrypt"; }
|
||||
|
||||
Reference in New Issue
Block a user