非root进程sem_open打开信号量失败案例分析

问题描述

root进程调sem_open(XXX, O_CREAT, 0666, 1)创建信号量后,非root进程使用sem_open打开同一个信号量失败,报Permission Denied

原因分析

非root进程调用sem_open, 以O_CREAT方式打开信号量,需要同时有对该信号量文件的读权限 + 写权限。

ll /dev/shm/sem.semname 查看信号量文件权限,发现权限为0644,缺少其他用户写权限。这个权限与sem_open中指定的权限值0666不一致。

为什么sem_open中mode参数指定的权限(0666)和创建文件的实际权限(0644)不一致?

首先了解Linux中umask的概念。umask为用户文件创建掩码,是一种进程属性。当进程创建文件或目录时,该属性用于指明应屏蔽的权限位。大多数Linux系统的默认掩码为022,可在shell中通过umask命令查看。umask作用如下:

  • 若没有文件掩码,则创建文件的默认权限为0666, 创建目录的默认权限为0777
  • 若使用默认掩码022, 则创建文件的权限为0666 - 0022 = 0644, 创建目录的权限为 0777 - 0022 = 0755

解决方法

可以在进程调用sem_open之前,修改umask值为0,再创建有其他用户写权限的信号量即可。

系统调用umask()可以将进程的umask值改为mask参数所指定的值

#include <sys/stat.h>
mode_t umask(mode_t mask); //调用总是成功,返回值为进程的前一个umask的值

写法参考如下:

sem_t *SemOpen() {
	mode_t mask = umask(0);							// 取消屏蔽的权限位
	sem_t *sem = sem_open(XXX, O_CREAT, 0666, 1);	// 创建权限0666的二值有名信号量
	umask(mask);									// 恢复umask的值
	return sem;
}

参考资料

《Linux/UNIX系统编程手册(上)》 —— 15.4.6 进程的文件模式创建掩码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pcj_888

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值