Home > front end >  How to solve “access denied” error trying to create a message queue?
How to solve “access denied” error trying to create a message queue?

Time:09-17

Only happens when the code is called from .NET. When the same code is compiled as a C console app, or called from a C console app, it runs without errors.

The following code compiles a C DLL called from .NET, and it prints “mq_open failed, code 1, message Operation not permitted”:

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;
    }
}

However, when the same DLL is called from C console application, it runs fine and prints ”mq_open completed OK”:

// 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();
}

I’m running both programs under the same user account, yet the C one has all the required permissions, while the C# program doesn’t. Any ideas how to find out what's going on?

The OS is Ubuntu 20.04.3 LTS, the architecture is AMD64, the .NET is 5.0.9.

CodePudding user response:

It was snap. Microsoft made an interesting choice to ship their .NET framework, designed to be used by software developers, inside a sandbox which is hiding the actual operating system behind an abstraction.

Under the hood, that thing is using AppArmor kernel module. That’s what produced that access denied status. Again, interesting choice, IMO SELinux is generally better for such things.

As soon as I uninstalled the snap package of the .NET runtine, and installed the native version with apt-get, my code started to work fine.

  • Related