设置信号量的访问权限?
我假设一旦进程创建了信号量,任何进程/用户都可以访问它。
是否可以对特定信号量设置访问限制,以便仅某些进程/用户可以访问它,或者只有某些进程可以释放信号量。
如果我们让所有进程都可以访问信号量,我会发现一些问题。例如:虚拟进程可以读取信号量并随意释放锁,向真正等待信号量锁的实际进程发出错误信号。
所有这些问题都是因为我通过以下代码片段得到非常奇怪的输出而出现的:
use Win32::Semaphore;
$sem = Win32::Semaphore->new(0, 1,"reliance2692")
or print "Can't create semaphore\n";
$sem = Win32::Semaphore->open("reliance2692")
or print "Can't open semaphore\n";
print "Semaphore:" . $sem . "\n";
通过运行上面的程序,我得到以下输出
Can't create semaphore Can't open semaphore
输出显示它无法创建信号量,甚至无法打开信号量。 如果具有给定名称的信号量已存在,则创建信号量可能会失败。 我不明白为什么打开信号量失败。
有人可以澄清一下创建信号量和创建信号量的场景吗?打开信号量失败。
I am assuming that once a semaphore is created by a process, it will be accessible by any process/user.
Is it possible to put access restrictions on a particular semaphore so that it can be accessible by only certain processes/users or only certain processes can release the semaphore.
I see some problems if we make a semaphore accessible by all processes.Eg: a dummy process can read the semaphore and release the lock at wish making a false signal to the actual process that is really waiting for the semaphore lock.
All these questions are arising as I am getting very weird output with the following code snippet:
use Win32::Semaphore;
$sem = Win32::Semaphore->new(0, 1,"reliance2692")
or print "Can't create semaphore\n";
$sem = Win32::Semaphore->open("reliance2692")
or print "Can't open semaphore\n";
print "Semaphore:" . $sem . "\n";
By running the above program, I am getting the following output
Can't create semaphore Can't open semaphore
The output shows that its failed to create a semaphore and even failed to open semaphore.
creating a semaphore might have failed if a semaphore already exists with the given name.
I don't understand why opening a semaphore failed.
Can some clarify the scenario where both creating semaphore & opening semaphore fails.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Win32::Semaphore->new
调用 Windows API 函数CreateSemaphore
并获取进程的默认安全描述符,这通常意味着以与脚本相同的用户身份运行的进程可以拥有完全访问权限,而以其他帐户无权访问。所以,对于初学者来说,你的假设是错误的。您在 Perl 代码中选择的名称将直接传递给 API 函数,因此它遵循相同的 命名空间规则与所有其他 Win32 内核对象一样。
Win32::Semaphore 没有提供用于指定访问限制的接口。即使提供了,Windows 也不提供每进程权限。权限附加到用户,而不是进程。
如果您从
new
收到“访问被拒绝”,则表明正在运行另一个程序,该程序选择对其他内容使用相同的名称 - 可能是另一个信号量,也可能是其他内容,例如事件或互斥锁 - 该进程正在以不同的用户身份运行。如果您从
open
得到“访问被拒绝”,那么,除了new
的可能性之外,可能是另一个进程已经打开了具有相同信号量的信号量。名称,但尚未向其他用户授予完全权限。Win32::Semaphore->open
请求SEMAPHORE_ALL_ACCESS
权限。如果信号量已被以同一用户身份运行的进程打开,那么您不应收到“访问被拒绝”的消息。在这种情况下,
new
和open
都不应该失败,尽管$^E
无论如何都可能保存 183 (ERROR_ALREADY_EXISTS
)。Win32::Semaphore->new
calls the Windows API functionCreateSemaphore
and gets the process's default security descriptor, which usually means that processes running as the same user as your script can have full access whereas processes running as other accounts get no access. So, for starters, your assumption is false.The name you choose in your Perl code is passed directly to the API function, so it's subject to the same namespace rules as all other Win32 kernel objects.
Win32::Semaphore provides no interface for specifying access restrictions. Even if it did, Windows does not provide per-process permissions. Permissions are attached to the user, not the process.
If you're getting "access denied" from
new
, then that suggests there's another program running that chose to use that same name for something else — maybe another semaphore, or maybe something else, like an event or a mutex — and that process is running as a different user.If you're getting "access denied" from
open
, then, in addition to the possibilities fornew
, it could be that another process has already opened a semaphore with the same name but has not granted full permissions to other users.Win32::Semaphore->open
requestsSEMAPHORE_ALL_ACCESS
permission.If the semaphore has already been opened by a process running as the same user, then you should not get "access denied." Neither
new
noropen
should fail in that case, although$^E
might hold 183 (ERROR_ALREADY_EXISTS
) anyway.根据记录,我是 Win32::Semaphore 的作者。正如 mobrule 和 Rob 所解释的,Windows 安全性是基于用户/组的。不可能有一个只有某些进程才能访问的信号量。如果属于用户的任何进程都可以访问信号量,则该用户的任何进程都可以访问该信号量。
通常,默认访问仅允许当前用户访问信号量。没有人要求能够让 Win32::Semaphore 指定非默认安全描述符,并且相关的 API 也很重要。如果有人创建了一个模块来管理 SECURITY_ATTRIBUTES 结构,我很乐意向 Win32::Semaphore 和相关 IPC 模块添加对此的支持。 Win32-Security 似乎不是该模块,尽管它可能是一个开始。
如果您需要一个信号量来跨多个用户工作,那么您现在唯一的解决方案是在 Win32::Semaphore 外部创建信号量,并传递适当的 SECURITY_ATTRIBUTES 指针。您可以使用用 C 编写的小型帮助程序或使用 Inline::C。 (请记住,信号量一旦创建,只要任何进程拥有打开的句柄,信号量就会存在,因此您的帮助程序需要保持信号量句柄打开,直到您调用
Win32::Semaphore->open
代码>就可以了。)For the record, I'm the author of Win32::Semaphore. As mobrule and Rob have explained, Windows security is user/group based. It's not possible to have a semaphore that only certain processes can access. If any process belonging to a user can access a semaphore, then any process of that user can access that semaphore.
Normally, the default access allows only the current user to access the semaphore. Nobody's ever requested the ability to have Win32::Semaphore specify a non-default security descriptor, and the associated API is non-trivial. If somebody created a module to manage a SECURITY_ATTRIBUTES structure, I'd be happy to add support for that to Win32::Semaphore and the related IPC modules. Win32-Security does not appear to be that module, although it might be a start.
If you need a semaphore to work across multiple users, your only solution right now is to create the semaphore outside of Win32::Semaphore, passing an appropriate SECURITY_ATTRIBUTES pointer. You could do that with a small helper program written in C, or using Inline::C. (Remember that once created, a semaphore exists as long as any process has an open handle to it, so your helper program needs to keep the semaphore handle open until you've called
Win32::Semaphore->open
on it.)来自 Win32::Semaphore pod
$semaphore = Win32::Semaphore- >new($initial, $maximum, [$name])
如果我没看错的话,如果您对
Win32::Semaphore->new
的调用引用了现有信号量,那么new
调用也将打开该信号量,并且随后的open
调用将是多余的(我从 pod 中不清楚如果打开一个已经打开的信号量会发生什么)。也许您可以单步执行代码,在每一步检查
$sem
以及$!
和$^E
的值。其他回复: Windows API< /a> 确实有设置信号量访问控制的方法,但
Win32::Semaphore
模块中公开,我不知道您是否对这个问题有任何好的选择。你能修改创建信号量的过程来放宽访问限制吗?请
Win32::Semaphore
作者更新他的模块?尝试自己修复Win32::Semaphore
吗?From Win32::Semaphore pod
$semaphore = Win32::Semaphore->new($initial, $maximum, [$name])
If I'm reading this correctly, if your call to
Win32::Semaphore->new
refers to an existing semaphore, then thenew
call will open the semaphore as well, and the subsequentopen
call will be redundant (it's not clear to me from the pod what should happen if you open a sempahore that is already open).Perhaps you could step through the code, checking the value of
$sem
as well as$!
and$^E
at each step.Additional reply: the Windows API does have methods for setting access control of semaphores, but
Win32::Semaphore
moduleI don't know if you have any good options for this problem. Can you modify the process that creates the semaphore to relax access restrictions? Ask the
Win32::Semaphore
author to update his module? Try to fixWin32::Semaphore
yourself?