【问题标题】:MemoryMappedFileSecurity missing in .NET 6.NET 6 中缺少 MemoryMappedFileSecurity
【发布时间】:2022-01-18 15:22:15
【问题描述】:

我有一个使用 MemoryMappedFiles 进行进程间通信的服务。它多年来一直运行良好,并且是在 .NET Framework 4.6.1 中开发的。现在是将代码移植到 .NET 6 的时候了。除了一个问题:内存映射文件的安全 ACL 之外,我已经让大部分代码都能正常工作。这个论点似乎在 .NET 6 中消失了。 这是 4.6.1 框架版本的 sn-p

    fs = new FileStream(FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
    FileSecurity fSec = File.GetAccessControl(FileName);
    fSec.AddAccessRule(new FileSystemAccessRule("everyone", FileSystemRights.FullControl, AccessControlType.Allow));
    File.SetAccessControl(FileName, fSec);
    if (fs.Length == 0)
        fs.SetLength(_SectionSize);
    long fLen = fs.Length;
    MemoryMappedFileSecurity security = new MemoryMappedFileSecurity();
    security.AddAccessRule(new AccessRule<MemoryMappedFileRights>("everyone", MemoryMappedFileRights.FullControl, AccessControlType.Allow));
    //Name = @"Global\DCCCache";    // "Global\" when running as a service so session 0 stuff available to everyone
    _MMFHandle = MemoryMappedFile.CreateFromFile(fs, Name, _SectionSize, MemoryMappedFileAccess.ReadWrite, security, HandleInheritability.Inheritable, false);
    _VAHandle = _MMFHandle.CreateViewAccessor();

这一切都有效,并允许非管理员用户进程访问内存映射文件。 .NET 6 从.CreateFromFile 方法中删除了 security 参数。因此,只有以管理员权限运行的进程才能访问内存映射文件。对于非管理员进程,MemoryMappedFileOpenExisting 方法会引发“拒绝访问”IO 异常。

当我创建内存映射文件以便非管理员进程可以访问时,有没有办法修改安全性?

【问题讨论】:

  • 感谢您的链接。讨论看起来像 6 中特别缺少该功能,并希望添加它。除非我没有看到它,否则最近在实施它方面没有任何动静。

标签: c# access-denied memory-mapped-files .net-6.0


【解决方案1】:

我做了一个解决方法。将创建具有正确安全性的内存映射文件所需的调用放在一起,并在拥有它的服务中调用它一次。在调用下面的例程之后,我将主线代码更改为使用 OpenExisting,以便其余代码可以按预期使用 .NET 6 库。不理想,但它解决了问题。

using System.ComponentModel;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;

namespace MMFService {
    internal class MMFNet6Shim : IDisposable {
        private bool win32Result = false;
        private int cbSid = SECURITY_MAX_SID_SIZE;
        private SECURITY_ATTRIBUTES securityAttributes = new SECURITY_ATTRIBUTES();
        private SafeMemoryMappedFileHandle hFile;

        private const int SDDL_REVISION_1 = 1;
        private const int SECURITY_MAX_SID_SIZE = 68;
        private const int PAGE_READWRITE = 0x04;
        private const int FILE_MAP_WRITE = 0X02;

        public MMFNet6Shim(FileStream fs, string DBName) {
            win32Result = ConvertStringSecurityDescriptorToSecurityDescriptor("D:(A;OICI;GA;;;WD)", SDDL_REVISION_1, out securityAttributes.lpSecurityDescriptor, IntPtr.Zero);
            if (!win32Result)
                throw new Exception("ConvertStringSecurityDescriptorToSecurityDescriptor", new Win32Exception(Marshal.GetLastWin32Error()));
            securityAttributes.nLength = Marshal.SizeOf(securityAttributes);
            securityAttributes.bInheritHandle = false;
            long fLen = fs.Length;
            hFile = CreateFileMapping(fs.SafeFileHandle, ref securityAttributes, PAGE_READWRITE, 0, Convert.ToInt32(fLen), DBName);
            if (hFile.IsInvalid) 
                throw new Exception("CreateFileMapping", new Win32Exception(Marshal.GetLastWin32Error()));
        }

        public void Dispose() {
            if(!hFile.IsInvalid)
                hFile.Close();
        }


        [StructLayout(LayoutKind.Sequential)]
        public struct SECURITY_ATTRIBUTES {
            public int nLength;
            public IntPtr lpSecurityDescriptor;
            public bool bInheritHandle;
        }

        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern bool ConvertStringSecurityDescriptorToSecurityDescriptor
        (
        [In] string StringSecurityDescriptor,
        [In] int StringSDRevision,
        [Out] out IntPtr SecurityDescriptor,
        [Out] IntPtr SecurityDescriptorSize
        );

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern IntPtr LocalFree([In] IntPtr hMem);

        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern SafeMemoryMappedFileHandle CreateFileMapping(
        [In] SafeFileHandle hFile,
        [In][Optional] ref SECURITY_ATTRIBUTES lpAttributes,
        [In] int flProtect,
        [In] int dwMaximumSizeHigh,
        [In] int dwMaximumSizeLow,
        [In][Optional] string lpName
        );

    }
}

【讨论】:

    猜你喜欢
    • 2022-07-15
    • 2015-11-27
    • 2023-02-02
    • 2011-04-06
    • 1970-01-01
    • 2015-06-20
    • 2015-04-02
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多