1

2 つのコード サンプルがあります。
まず、正しく実行されます。

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

第二に、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;
}

どちらのコード サンプルも同じだと思います。
最初のものを実行すると、正しく実行されます(構造体へのポインターを使用します)。
しかし、2 番目は失敗します (構造体のインスタンスを使用します)。
どうしてか分かりません。手伝って頂けますか?

4

1 に答える 1

5

おそらく、構造体の初期化方法が原因です。ローカル変数を宣言するとき、その値は不確定であり、その値を使用すると未定義の動作につながります。

同じことがローカル構造変数にも当てはまります。メンバー フィールドの値は単純に定義されていないdata.effective &= ~CAP_TO_MASK(CAP_IPC_LOCK);ため、操作に不確定な (一見ランダムな) 値を使用する場合などです。

構造体を使用する前に、既知の値に構造体を初期化する必要があります。お気に入り

struct __user_cap_header_struct hdr = { 0 };

上記は、構造内のすべてのフィールドをゼロに設定します。

new(これは C++ であり、C ではありません!) で割り当てると、デフォルト コンストラクターのない構造体 (またはクラス) の場合、すべてのメンバー フィールドはデフォルトで構築され、整数フィールドの場合、これはそれらがゼロであることを意味します。最初の例で構造体を割り当てた場合malloc(メモリを割り当てる C の方法であるため)、割り当てられたメモリはまったく初期化されないため、2 番目の例と同じ結果になります。

于 2013-08-13T06:59:31.243 に答える