You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

普通用户创建的SYS V共享内存改属主为root后被非特权用户删除的原因咨询

为什么普通用户能删除属主为root的System V共享内存段?

我来帮你拆解这个反直觉的问题——你用普通用户身份创建了一段System V共享内存段,通过程序把它的UID和GID修改为0(也就是root用户),结果发现原来的普通用户居然还能删掉这个共享内存段,这背后的核心原因在于System V IPC对象的权限控制逻辑和文件系统不一样。

关键原因:创建者身份(cuid/cgid)优先于属主身份(uid/gid)

System V共享内存的权限由struct ipc_perm结构体控制,其中有几个核心字段:

  • uid/gid:共享内存段的属主、属组ID,这是你修改的字段
  • cuid/cgid:共享内存段的创建者UID、GID,这个字段是不可被普通用户修改的(哪怕你调用shmctl(IPC_SET)也只能改uid、gid、mode,无法修改cuid/cgid)

哪怕你把uid改成root,只要cuid还是原来普通用户的UID,这个创建者用户就天然拥有对该共享内存段的完全控制权——包括查看、修改、删除操作,不受uid字段和权限位的限制。

结合你的代码分析

你的代码应该是通过shmctl的IPC_SET命令来修改共享内存的属主,补全逻辑后类似这样:

#include<stdio.h>
#include<stdint.h>
#include<sys/ipc.h>
#include<sys/shm.h>

int main(int argc, char *argv[]) {
    int ret = 0;
    int shmid = 0;
    key_t key = ftok(".", 'a'); // 示例key生成方式
    struct shmid_ds shm_buf;

    // 普通用户身份创建共享内存段
    shmid = shmget(key, 4096, IPC_CREAT | 0666);
    if (shmid == -1) {
        perror("shmget failed");
        return 1;
    }

    // 获取当前共享内存属性
    ret = shmctl(shmid, IPC_STAT, &shm_buf);
    if (ret == -1) {
        perror("shmctl IPC_STAT failed");
        return 1;
    }

    // 修改属主为root
    shm_buf.shm_perm.uid = 0;
    shm_buf.shm_perm.gid = 0;

    // 应用修改
    ret = shmctl(shmid, IPC_SET, &shm_buf);
    if (ret == -1) {
        perror("shmctl IPC_SET failed");
        return 1;
    }

    printf("Shared memory owner changed to root\n");
    return 0;
}

这段代码修改了shm_perm.uid和shm_perm.gid,但没有也无法修改shm_perm.cuid和shm_perm.cgid,它们依然保留着创建该共享内存段的普通用户ID。所以这个普通用户依然能执行shmctl(shmid, IPC_RMID, NULL)来删除共享内存。

验证方式

你可以用ipcs -m -c命令查看共享内存段的创建者和属主信息,会看到类似这样的输出:

------ Shared Memory Creator/Owner Info --------
shmid      creator     creator     owner       owner      
           uid         gid         uid         gid       
123456     1000        1000        0           0

这里的creator uid就是原来的普通用户ID,这就是为什么该用户能删除属主为root的共享内存段。

如何让普通用户无法删除?

如果想让原来的普通用户无法删除这个共享内存段,你需要:

  • 用root用户直接创建共享内存段,此时cuid和uid都是0,普通用户没有权限操作
  • 注意:仅修改权限位(shm_perm.mode)无法限制创建者,因为创建者天然拥有绕过权限位的操作权限,只有第一种方法能彻底限制。

内容的提问来源于stack exchange,提问作者rdssonawane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:36:32