我正在尝试清理服务崩溃后留下的一些垃圾共享内存文件。该服务作为系统用户和特定组运行。我是该组的成员,但无法删除共享内存。
$ ls -la /dev/shm
drwxrwxrwt 2 root root 600 Jun 20 11:18 .
drwxr-xr-x 22 root root 3680 Jun 19 12:43 ..
-rw-rw-rw- 1 simbot simusers 500032 Jun 20 10:35 Sim_SharedMem_SLM__data_0
$ groups | grep simusers -q && echo member || echo not member
member
$ rm -f /dev/shm/Sim_SharedMem_SLM__data_0
rm: cannot remove '/dev/shm/Sim_SharedMem_SLM__data_0': Operation not permitted
我以 root 身份删除文件没有问题。如果我是运行(并崩溃)该进程的人(我是拥有这些文件的用户),那么我删除该文件也没有问题。
繁殖
我认为展示该问题的最简单方法是以我自己的身份运行该进程,然后更改一些垃圾文件,就好像它们属于其他用户所拥有的一样。
$ /usr/local/bin/badProcess
^C
$ ls -la /dev/shm
drwxrwxrwt 2 root root 640 Jun 20 11:31 .
drwxr-xr-x 22 root root 3680 Jun 19 12:43 ..
-rw-rw-rw- 1 stew stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_0
-rw-rw-rw- 1 stew stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_1
-rw-rw-rw- 1 stew stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_2
-rw-rw-rw- 1 stew stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_3
$ sudo chown simbot Sim_SharedMem_SLM__data_1
$ sudo chown :simusers Sim_SharedMem_SLM__data_2
$ sudo chown simbot:simusers Sim_SharedMem_SLM__data_3
$ ls -la /dev/shm
drwxrwxrwt 2 root root 640 Jun 20 11:31 .
drwxr-xr-x 22 root root 3680 Jun 19 12:43 ..
-rw-rw-rw- 1 stew stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_0
-rw-rw-rw- 1 simbot stew 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_1
-rw-rw-rw- 1 stew simusers 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_2
-rw-rw-rw- 1 simbot simusers 500032 Jun 20 11:31 Sim_SharedMem_SLM__data_3
$ rm /dev/shm/*
rm: cannot remove 'Sim_SharedMem_SLM__data_1`': Operation not permitted
rm: cannot remove 'Sim_SharedMem_SLM__data_3`': Operation not permitted
lsattr
一些解决方案建议使用 lsattr 检查 +a 或 +i 属性。
$ lsattr Sim_SharedMem_SLM__data_0
lsattr: Inappropriate ioctl for device While reading flags on Sim_SharedMem_SLM__data_0
那个会发生因为 tmpfs 不支持这些属性(这就是这个目录)
$ mount | grep /dev/shm
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
ACL
我查看了 ACL,看看父目录或文件本身是否有什么奇怪的地方。我不认为我们没有从中ls
吸取教训对父目录的写权限
$ getfacl /dev/shm
getfacl: Removing leading '/' from absolute path names
# file: dev/shm
# owner: root
# group: root
# flags: --t
user::rwx
group::rwx
other::rwx
$ getfacl /dev/shm/Sim_SharedMem_SLM__data_0
getfacl: Removing leading '/' from absolute path names
# file: dev/shm/Sim_SharedMem_SLM__data_0
# owner: simbot
# group: simusers
user::rw-
group::rw-
other::rw-
答案1
删除文件时感兴趣的不是文件权限,而是文件所在目录的权限。
在您的情况下,每个人都对该目录具有写权限,但该目录还设置了“粘滞位”(位于t
权限字符串末尾)。
此类目录中的文件删除工作方式有所不同,并且您必须是所有者文件的所有者、粘性目录的所有者或 root,以便能够删除该文件。
这是来自sticky(8)
OpenBSD 系统的手册:
粘性目录
设置了“粘滞位”的目录会对文件删除施加限制:仅当用户具有该目录的写权限并且该用户是该文件的所有者、该目录的所有者或超级用户时,该用户才能删除或重命名粘性目录中的文件。此功能可有效应用于目录,例如
/tmp
必须可公开写入但应拒绝用户任意删除或重命名彼此文件的许可。
在 Ubuntu 上,chmod(1)
手册具有等效信息:
限制删除标志或粘性位
限制删除标志或粘性位是单个位,其解释取决于文件类型。 对于目录,它可以防止非特权用户删除或重命名目录中的文件,除非他们拥有该文件或目录;这称为目录的限制删除标志,通常在全局可写目录(例如
/tmp
.对于某些旧系统上的常规文件,该位将程序的文本图像保存在交换设备上,以便运行时加载速度更快;这称为粘性位。