为什么启用SELinux的execve调用失败?

时间:2018-11-26 08:18:02

标签: linux linux-kernel selinux libselinux

我在Linux系统上,最近以许可和强制模式启用了SELinux。 在具有正确用户名和密码的shell中执行登录命令时,我在execve()系统调用上收到“权限被拒绝”错误消息。 使用strace调试所有系统调用会导致以下输出。

...
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x400a3000
set_tls(0x400a2d90)                     = 0
mprotect(0x40201000, 8192, PROT_READ)   = 0
mprotect(0x40364000, 4096, PROT_READ)   = 0
mprotect(0x402e4000, 4096, PROT_READ)   = 0
mprotect(0x402b8000, 4096, PROT_READ)   = 0
mprotect(0x4021d000, 4096, PROT_READ)   = 0
mprotect(0x400aa000, 4096, PROT_READ)   = 0
munmap(0x4009e000, 9811)                = 0
statfs("/sys/fs/selinux", {f_type=SELINUX_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_RELATIME}) = 0
statfs("/sys/fs/selinux", {f_type=SELINUX_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_RELATIME}) = 0
stat64("/sys/fs/selinux", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
brk(NULL)                               = 0x907000
brk(0x928000)                           = 0x928000
access("/etc/selinux/config", F_OK)     = 0
getuid32()                              = 0
geteuid32()                             = 0
open("/dev/null", O_RDWR)               = 3
close(3)                                = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0
rt_sigaction(SIGALRM, {sa_handler=0x400b76ed, sa_mask=[ALRM], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x4013cae1}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
setitimer(ITIMER_REAL, {it_interval={tv_sec=0, tv_usec=0}, it_value={tv_sec=60, tv_usec=0}}, {it_interval={tv_sec=0, tv_usec=0}, it_value={tv_sec=0, tv_usec=0}}) = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
fstat64(0, {st_mode=S_IFCHR|0622, st_rdev=makedev(136, 1), ...}) = 0
readlink("/proc/self/fd/0", "/dev/pts/1", 126) = 10
stat64("/dev/pts/1", {st_mode=S_IFCHR|0622, st_rdev=makedev(136, 1), ...}) = 0
ioctl(0, TCFLSH, TCIFLUSH)              = 0
uname({sysname="Linux", nodename="node", ...}) = 0
fstat64(1, {st_mode=S_IFCHR|0622, st_rdev=makedev(136, 1), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4009e000
write(1, "node login: ", node login: )            = 12
fstat64(0, {st_mode=S_IFCHR|0622, st_rdev=makedev(136, 1), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x4009f000
read(0, 
"\n", 1024)                 = 5
open("/etc/passwd", O_RDONLY)           = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=63, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x400a0000
read(3, ""..., 1024) = 63
close(3)                                = 0
munmap(0x400a0000, 4096)                = 0
open("/etc/securetty", O_RDONLY)        = -1 ENOENT (No such file or directory)
ioctl(0, TCFLSH, TCIFLUSH)              = 0
write(1, "Password: ", 10Password: )              = 10
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon -echo ...}) = 0
rt_sigaction(SIGINT, {sa_handler=0x400f43b9, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x4013cae1}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x4013cae1}, NULL, 8) = 0
ioctl(0, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = 0
write(1, "\n", 1
)                       = 1
open("/proc/sys/crypto/fips_enabled", O_RDONLY) = -1 ENOENT (No such file or directory)
setitimer(ITIMER_REAL, {it_interval={tv_sec=0, tv_usec=0}, it_value={tv_sec=0, tv_usec=0}}, {it_interval={tv_sec=0, tv_usec=0}, it_value={tv_sec=57, tv_usec=707306}}) = 0
open("/etc/selinux/config", O_RDONLY|O_CLOEXEC) = 3
fcntl64(3, F_GETFD)                     = 0x1 (flags FD_CLOEXEC)
fstat64(3, {st_mode=S_IFREG|0644, st_size=586, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x400a0000
read(3, "# This file controls the state o"..., 1024) = 586
read(3, "", 1024)                       = 0
close(3)                                = 0
munmap(0x400a0000, 4096)                = 0
open("/proc/thread-self/attr/current", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
gettid()                                = 970
open("/proc/self/task/970/attr/current", O_RDONLY|O_CLOEXEC) = 3
read(3, "system_u:system_r:init_t\0", 4095) = 25
close(3)                                = 0
access("/var/run/setrans/.setrans-unix", F_OK) = -1 ENOENT (No such file or directory)
open("/sys/fs/selinux/user", O_RDWR|O_CLOEXEC) = 3
write(3, "system_u:system_r:init_t root", 29) = 29
read(3, "5\0root:staff_r:shutdown_t\0root:s"..., 4095) = 127
close(3)                                = 0
open("/etc/selinux/refpolicy/contexts/users/root", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=630, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x400a0000
read(3, "system_r:crond_t\tunconfined_r:un"..., 1024) = 630
read(3, "", 1024)                       = 0
close(3)                                = 0
munmap(0x400a0000, 4096)                = 0
open("/etc/selinux/refpolicy/contexts/default_contexts", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=951, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x400a0000
read(3, "system_r:crond_t\tuser_r:user_t s"..., 1024) = 951
read(3, "", 1024)                       = 0
close(3)                                = 0
munmap(0x400a0000, 4096)                = 0
open("/etc/selinux/refpolicy/contexts/failsafe_context", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=18, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x400a0000
read(3, "sysadm_r:sysadm_t\n", 1024)    = 18
close(3)                                = 0
munmap(0x400a0000, 4096)                = 0
open("/sys/fs/selinux/context", O_RDWR|O_CLOEXEC) = 3
write(3, "root:sysadm_r:sysadm_t\0", 23) = 23
close(3)                                = 0
getxattr("/dev/pts/1", "security.selinux", "system_u:object_r:devpts_t", 255) = 27
open("/sys/fs/selinux/relabel", O_RDWR|O_CLOEXEC) = 3
write(3, "root:sysadm_r:sysadm_t system_u:"..., 52) = 52
read(3, "root:object_r:devpts_t\0", 4095) = 23
close(3)                                = 0
setxattr("/dev/pts/1", "security.selinux", "root:object_r:devpts_t", 23, 0) = 0
fchown32(0, 0, 0)                       = 0
fchmod(0, 0600)                         = 0
open("/etc/group", O_RDONLY)            = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=10, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x400a0000
read(3, "root:x:0:\n", 1024)            = 10
read(3, "", 1024)                       = 0
close(3)                                = 0
munmap(0x400a0000, 4096)                = 0
setgroups32(1, [0])                     = 0
setgid32(0)                             = 0
setuid32(0)                             = 0
chdir("/root")                          = 0
access(".hushlogin", F_OK)              = -1 ENOENT (No such file or directory)
open("/etc/motd", O_RDONLY)             = -1 ENOENT (No such file or directory)
gettimeofday({tv_sec=1542874616, tv_usec=399369}, NULL) = 0
open("/etc/localtime", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x400a0000
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\10\0\0\0\10\0\0\0\0"..., 1024) = 1024
_llseek(3, 1257, [2281], SEEK_CUR)      = 0
read(3, "\nCET-1CEST,M3.5.0,M10.5.0/3\n", 1024) = 28
close(3)                                = 0
munmap(0x400a0000, 4096)                = 0
getpid()                                = 970
socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0) = 3
connect(3, {sa_family=AF_UNIX, sun_path="/dev/log"}, 110) = -1 EPROTOTYPE (Protocol wrong type for socket)
close(3)                                = 0
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0) = 3
connect(3, {sa_family=AF_UNIX, sun_path="/dev/log"}, 110) = 0
send(3, "<38>Nov 22 09:16:56 login[970]: "..., 54, MSG_NOSIGNAL) = 54
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[INT], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x4013cae1}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x4013cae1}, 8) = 0
open("/proc/thread-self/attr/exec", O_RDWR|O_CLOEXEC) = -1 ENOENT (No such file or directory)
gettid()                                = 970
open("/proc/self/task/970/attr/exec", O_RDWR|O_CLOEXEC) = 4
write(4, "root:sysadm_r:sysadm_t\0", 23) = 23
close(4)                                = 0
execve("/bin/sh", ["-sh"], 0x907b30 /* 6 vars */) = -1 EACCES (Permission denied)
write(2, "login: can't execute '/bin/sh': "..., 50login: can't execute '/bin/sh': Permission denied
) = 50
exit_group(1)                           = ?
+++ exited with 1 +++

禁用SELinux后,错误消息消失,并且登录命令成功。参见下面的输出。

...
send(3, "<38>Nov 23 16:25:16 login[883]: "..., 54, MSG_NOSIGNAL) = 54
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[INT], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x400fcae1}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x400fcae1}, 8) = 0
execve("/bin/sh", ["-sh"], 0x32a3d0 /* 6 vars */) = 0
brk(NULL)                               = 0x1e14000
...

另一种尝试在特定上下文中运行ssh的测试也会导致“权限被拒绝”消息。

~ # runcon system_u:system_r:sshd_t /usr/sbin/sshd 
runcon: can't execute '/usr/sbin/sshd': Permission denied
~ # strace runcon system_u:system_r:sshd_t /usr/sbin/sshd 
execve("/usr/bin/runcon", ["runcon", "system_u:system_r:sshd_t", "/usr/sbin/sshd"], 0xbea60de8 /* 12 vars */) = 0
brk(NULL)                               = 0x120b000
uname({sysname="Linux", nodename="node", ...}) = 0
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x400cb000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=9811, ...}) = 0
mmap2(NULL, 9811, PROT_READ, MAP_PRIVATE, 3, 0) = 0x400cd000
close(3)                                = 0
...
various lib loading with no error
...
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x400d2000
set_tls(0x400d1d90)                     = 0
mprotect(0x40230000, 8192, PROT_READ)   = 0
mprotect(0x40393000, 4096, PROT_READ)   = 0
mprotect(0x40313000, 4096, PROT_READ)   = 0
mprotect(0x402e7000, 4096, PROT_READ)   = 0
mprotect(0x4024c000, 4096, PROT_READ)   = 0
mprotect(0x400d9000, 4096, PROT_READ)   = 0
munmap(0x400cd000, 9811)                = 0
statfs("/sys/fs/selinux", {f_type=SELINUX_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_RELATIME}) = 0
statfs("/sys/fs/selinux", {f_type=SELINUX_MAGIC, f_bsize=4096, f_blocks=0, f_bfree=0, f_bavail=0, f_files=0, f_ffree=0, f_fsid={val=[0, 0]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_RELATIME}) = 0
stat64("/sys/fs/selinux", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
brk(NULL)                               = 0x120b000
brk(0x122c000)                          = 0x122c000
access("/etc/selinux/config", F_OK)     = 0
access("/var/run/setrans/.setrans-unix", F_OK) = -1 ENOENT (No such file or directory)
open("/sys/fs/selinux/context", O_RDWR|O_CLOEXEC) = 3
write(3, "system_u:system_r:sshd_t\0", 25) = 25
close(3)                                = 0
open("/proc/thread-self/attr/exec", O_RDWR|O_CLOEXEC) = -1 ENOENT (No such file or directory)
gettid()                                = 976
open("/proc/self/task/976/attr/exec", O_RDWR|O_CLOEXEC) = 3
write(3, "system_u:system_r:sshd_t\0", 25) = 25
close(3)                                = 0
execve("/usr/sbin/sshd", ["/usr/sbin/sshd"], 0xbec8dde4 /* 12 vars */) = -1 EACCES (Permission denied)
write(2, "runcon: can't execute '/usr/sbin"..., 58runcon: can't execute '/usr/sbin/sshd': Permission denied
) = 58
exit_group(126)                         = ?
+++ exited with 126 +++

启用SELinux后如何解决此错误?

编辑: 在调查了sys_execve()实现之后,该错误应该在函数do_open_exec()(https://elixir.bootlin.com/linux/v3.18/source/fs/exec.c#L750)中发生。 我不确定哪个文件访问会触发该错误。

1 个答案:

答案 0 :(得分:0)

找到了解决此问题的方法。 我的根分区已使用nosuid标志挂载。如本博客文章https://danwalsh.livejournal.com/68723.html所述,该过程无法更改其域。 挂载没有nosuid的分区可以解决此问题。