共享内存的访问控制不起作用?

Posted

技术标签:

【中文标题】共享内存的访问控制不起作用?【英文标题】:Access control of share memory takes no effect? 【发布时间】:2013-08-11 03:57:48 【问题描述】:

我正在使用共享内存在 linux 上的不相关进程之间进行通信。我只希望我在 struct ipc_perm 中指定的进程能够访问共享内存。但似乎代码不起作用:

进程 A:创建共享内存

      int main (int argc, char* argv[])
          int segment_id;
          key_t key;
          key = 56789;

          char* shared_memory;
          int shm_size = 512;

          segment_id = shmget(key, shm_size, IPC_CREAT | 0666);
          if (segment_id < 0)
             perror("shmget");
             exit(1);
          else 
             struct shmid_ds shmbuf;
             struct ipc_perm perms;

             //here i specified the process whose
             //uid is 1234 has the read/write access
             //to this shared memory
             perms.uid = 1234;
             perms.gid = 2000;
             perms.mode = 0660;

             shmctl(segment_id, IPC_STAT, &shmbuf);
             shmbuf.shm_perm = perms;
             int ret = shmctl(segment_id, IPC_SET, &shmbuf);
             if (ret < 0)
                 perror("shmctl IPC_SET");
                 exit(1);
              
           

           shared_memory = (char*)shmat(segment_id, NULL, 0);
           if (shared_memory == (char*) -1)
              perror("shmat");
              exit(1);
           

           sprintf(shared_memory, "Server Updated The Memory -PID- %lu", getpid());
           while(*shared_memory != '*')
               sleep(1);

           printf("The memory has been updated: \n   %s\n", shared_memory);
           sleep(5);
           shmdt(shared_memory);
           shmctl(segment_id, IPC_RMID, 0);
           return 0;
      

进程B:访问进程A创建的共享内存

          int main()
              int segment_id;
              key_t key;
              key = 56789;

              char* shared_memory, *s;
              int shm_size = 512;

              segment_id = shmget(key, shm_size, 0666);
              if (segment_id < 0)
                   perror("shmget");
                   exit(1);
              

              shared_memory = (char*)shmat(segment_id, NULL, 0);
              if (shared_memory == (char*) -1)
                   perror("shmat");
                   exit(1);
               

              for (s = shared_memory; *s != NULL; s++)
                     putchar(*s);
              putchar('\n');

              sprintf(shared_memory, "*Client Updated The Memory - pid-%lu", getpid());
              return 0;
          

在我的测试过程中,进程 B 始终具有对进程 A 创建的共享内存的读/写访问权限。为什么会发生这种情况? (我在ubuntu上运行,打开两个控制台分别启动上述进程。)

【问题讨论】:

是否是同一个用户和/或组同时运行这两个进程?因为您正在设置权限以允许 ID 为 1234 的用户和/或 ID 为 2000 的组中的任何人读/写。 @Casey 我在两个不同的控制台上运行这两个进程。这里有什么问题吗? 如果两个进程都有 UID 1234 或 GID 2000,那么它们应该都可以访问共享内存段。从源代码中的注释“the uid 为 1234 的进程”的方式来看,您似乎将术语 UID(用户标识符)与 PID(进程标识符)混淆了。 @Casey 是的,你是对的。我坚持不同的进程有不同的uid!我将了解更多关于 uid 和 pid 的信息,并在今天下午晚些时候更新这篇文章。 @Casey 我把 UID 误认为是 PID。现在我想知道创建者是否有办法指定它想要验证哪个进程来访问内存?感谢您的建议,如果您发布您的 cmets 作为答案,我会接受。 【参考方案1】:

如果两个进程都有 UID 1234 或 GID 2000,那么它们应该都可以访问共享内存段。您在源代码中的评论:“uid 为 1234 的进程”似乎表明您将术语 UID(用户标识符)与 PID(进程标识符)混淆了。

据我所知,没有办法通过 PID 将共享内存段的访问限制为一组特定的进程。限制由特定用户运行的进程——通过在调用shm_ctl(...IPC_SET...) 时在shm_perm.uid 中指定该用户的ID——通常就足够了。如果要限制可以访问该段的进程,请限制您运行的访问该段的进程。

【讨论】:

以上是关于共享内存的访问控制不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

睡觉的理发师 - 共享内存队列不起作用?

为啥标头访问控制允许来源不起作用?

pthread读写锁不起作用吗? [关闭]

访问控制允许来源 htaccess 文件不起作用

更改 NSURLCache 内存和磁盘容量不起作用

修改矩阵后,通过内存指针(memptr)直接访问犰狳矩阵的条目不起作用