代码之家  ›  专栏  ›  技术社区  ›  Soonts

如何解决尝试创建消息队列时出现的拒绝访问错误?

  •  0
  • Soonts  · 技术社区  · 4 年前

    仅在从.NET调用代码时发生。当将相同的代码编译为C++控制台应用程序,或者从C++控制台应用程序调用时,它运行时无错误。

    下面的代码编译了一个C++从.NET调用的DLL,并打印了MQUOPEN OPEN失败,代码1,消息操作不允许:

    extern "C" __attribute__((visibility("default")))
    int mq_test()
    {
        const char* name = "/985a8e18-08ee-46e5-acf5-fc4f2ffb4d4f";
        constexpr int oflag = O_RDWR | O_CLOEXEC | O_CREAT | O_EXCL;
        constexpr mode_t mode = 0660;
    
        mq_attr qa;
        memset( &qa, 0, sizeof( qa ) );
        qa.mq_maxmsg = 10;
        qa.mq_msgsize = sizeof( void* );
    
        int fd = mq_open( name, oflag, mode, &qa );
        if( fd >= 0 )
        {
            mq_unlink( name );
            printf( "mq_open completed OK\n" );
            return 0;
        }
        else
        {
            const int code = errno;
            printf( "mq_open failed, code %i, message %s\n", code, strerror( code ) );
            return -1;
        }
    }
    

    // gcc load.cpp -ldl && ./a.out
    #include <dlfcn.h>
    #include <stdio.h>
    
    using pfnTest = int( * )( );
    int main()
    {
        void * const handle = dlopen( "./libNativeHelpers.so", RTLD_NOW );
        if( nullptr == handle )
        {
            printf( "dlopen failed: %s\n", dlerror() );
            return 1;
        }
    
        const pfnTest pfn = (pfnTest)dlsym( handle, "mq_test" );
        if( nullptr == pfn )
        {
            printf( "dlsym failed: %s\n", dlerror() );
            return 2;
        }
        return pfn();
    }
    

    我在同一个用户帐户下运行这两个程序,而C++一个拥有所有必需的权限,而C语言程序则不需要。你知道怎么弄清楚发生了什么吗?

    操作系统是Ubuntu 20.04.3 LTS,体系结构是AMD64,.NET是5.0.9。

    0 回复  |  直到 4 年前
        1
  •  1
  •   Soonts    4 年前

    是的 snap . 微软做出了一个有趣的选择,将他们的.NET框架(专为软件开发人员使用而设计)放在一个沙箱中,沙箱将实际操作系统隐藏在一个抽象背后。

    在引擎盖下,那东西正在使用 AppArmor 内核模块。这就是导致访问被拒绝状态的原因。再一次,有趣的选择,IMO SELinux

    当我卸载了.NET runtine的snap包并安装了带有apt get的本机版本后,我的代码就开始正常工作了。