在 Linux 上终止以提升的权限运行的进程时,套接字锁定
Posted
技术标签:
【中文标题】在 Linux 上终止以提升的权限运行的进程时,套接字锁定【英文标题】:Socket locks up when killing a process ran with elevated permissions on Linux 【发布时间】:2018-12-03 04:57:00 【问题描述】:我遇到了一个我想了解更多的问题。
我在 Linux 机器上有一个 C++ 应用程序。我们称之为program1
。 program1
使用 ZeroMQ 进行 IPC 通信。我想 ZeroMQ 层与行为有点关系,但想介绍所有事实。如果我在没有提升权限的情况下通过终端运行program1
,我可以多次杀死它。我也可以毫无问题地使用 Eclipse 运行 program1
。
但是,如果我以提升的权限运行 program1
:
$ sudo ./program1
并杀死它 (Ctrl+C),IPC 套接字将锁定并且在尝试在没有提升权限的情况下运行应用程序时无法使用。但是,如果我以提升的权限重新运行程序,它就可以正常工作。
我的理论是,一旦您以提升的权限运行应用程序,文件描述符就会将所有权更改为父进程(具有提升的权限)。然后,当您终止该进程时,文件描述符永远不会被正确清理,因此它们的权限会被提升,如果没有提升的权限就无法使用。
这是在标记吗?如果是这样,有没有办法在代码中防止此类问题,或者在问题发生后解决问题而无需重新启动整个计算机?
更新了******
更新以添加更多信息:
1) 当我按下 Ctr+C 时,软件确实退出了。即使以 sudo 运行,也无法在系统监视器中找到它。 (sudo gnome-system-monitor)
2) 套接字在创建时返回“地址已在使用中”。
3) 理想情况下,我希望它们无论以何种方式运行都能够相互连接。这不是我在开发过程中考虑的问题,并且承认我是 Linux 和 IPC 通信的新手。
【问题讨论】:
僵尸文件描述符理论对我来说听起来不正确。您使用的是什么 ZeroMQ 传输?当你 Ctrl+C 程序时,它真的退出了吗(检查进程是否真的消失了)?程序fork()
关闭任何儿童吗?还有……你能创建一个minimal reproducible example吗?
您所描述的确切行为是什么“...锁定[ed]并且无法使用”?
我们需要看看您是如何使用 ZeroMQ 的。您还必须仔细考虑您想要发生的事情。您是否希望所有程序即使在完全不同的用户/安全上下文中也能相互连接?还是您想为不同的上下文设置单独的“区域”?
这听起来与SO_LINGER
有关:man7.org/linux/man-pages/man7/socket.7.html 另见ZMQ_LINGER
:api.zeromq.org/4-2:zmq-setsockopt
【参考方案1】:
您说的是:“IPC 套接字”。
我猜这不是 TCP 套接字。如果 zeromq 以 root 身份创建 System V IPC 对象,则用户无法重用它,这就是权限错误的原因:IPC 对象不会因进程死亡而被破坏,并且具有用户所有权和权限。
您可以使用命令ipcs
列出现有的IPC 对象,使用ipcrm
删除它们。
哦,是的——注意不要删除与你的工作无关的 IPC 对象......
如果我猜错了,你可以使用命令strace
来检查哪个系统调用实际上没有找到真正的罪魁祸首。
【讨论】:
嘿伙计,这似乎是它的主要内容。很好的答案。我还意识到,如果一个软件以 sudo 运行,而另一个不是,则由于级别不同,它们无法通过 IPC 进行通信。很棒的东西。以上是关于在 Linux 上终止以提升的权限运行的进程时,套接字锁定的主要内容,如果未能解决你的问题,请参考以下文章