Pergunta

I have two code samples:
First, runs correctly:

#include <sys/capability.h>
#include <unistd.h>
#include <cstdio>

int main()
{
    __user_cap_header_struct *hdr = new __user_cap_header_struct;
    __user_cap_data_struct *data = new __user_cap_data_struct;
    hdr->pid = getpid();
    hdr->version = _LINUX_CAPABILITY_VERSION;
    data->effective &= ~CAP_TO_MASK(CAP_IPC_LOCK);
    data->permitted &= ~CAP_TO_MASK(CAP_IPC_LOCK);
    data->inheritable = 0;
    if (capset(hdr, data) < 0)
        printf("capset failed: %m");

    return 0
}

Second, fail: Operation not permitted:

#include <sys/capability.h>
#include <unistd.h>
#include <cstdio>

int main()
{
    struct __user_cap_header_struct hdr;
    hdr.pid = getpid();
    hdr.version = _LINUX_CAPABILITY_VERSION;
    struct __user_cap_data_struct data;   
    data.effective &= ~CAP_TO_MASK(CAP_IPC_LOCK);    
    data.permitted &= ~CAP_TO_MASK(CAP_IPC_LOCK);   
    if(capset(&hdr, &data))   
        printf("capset failed: %m");   

    return 0;
}

I think both code samples are the same.
When I run the first one it executes correctly (uses pointer to struct).
But the second fails (uses instance of struct).
I don't know why. Can you help me?

Foi útil?

Solução

Most likely because how the structures are initialized. When declaring a local variable, its value is indeterminate, using that value then leads to undefined behavior.

The same goes for local structure variables. The member field values are simply undefined, so when you do e.g. data.effective &= ~CAP_TO_MASK(CAP_IPC_LOCK); you use an indeterminate (and seemingly random) value for the operation.

You need to initialize the structure to a well know value before using it. Like

struct __user_cap_header_struct hdr = { 0 };

The above will set all fields in the structure to zero.

When you allocate with new (which is C++ and not C!) then for structures (or classes) without default constructors all member fields are default constructed, and for integer fields this means they are zeroed. If you allocated the structures in the first example using malloc (as that's the C way of allocating memory) then you would have the same result as the second example, as then the allocated memory would not be initialized at all.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top