设置信号量的访问权限?

发布于 2024-08-05 13:24:33 字数 680 浏览 6 评论 0原文

我假设一旦进程创建了信号量,任何进程/用户都可以访问它。

是否可以对特定信号量设置访问限制,以便仅某些进程/用户可以访问它,或者只有某些进程可以释放信号量。
如果我们让所有进程都可以访问信号量,我会发现一些问题。例如:虚拟进程可以读取信号量并随意释放锁,向真正等待信号量锁的实际进程发出错误信号。

所有这些问题都是因为我通过以下代码片段得到非常奇怪的输出而出现的:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

暖树树初阳… 2024-08-12 13:24:33

Win32::Semaphore->new 调用 Windows API 函数 CreateSemaphore 并获取进程的默认安全描述符,这通常意味着以与脚本相同的用户身份运行的进程可以拥有完全访问权限,而以其他帐户无权访问。所以,对于初学者来说,你的假设是错误的。

您在 Perl 代码中选择的名称将直接传递给 API 函数,因此它遵循相同的 命名空间规则与所有其他 Win32 内核对象一样。

Win32::Semaphore 没有提供用于指定访问限制的接口。即使提供了,Windows 也不提供每进程权限。权限附加到用户,而不是进程

如果您从 new 收到“访问被拒绝”,则表明正在运行另一个程序,该程序选择对其他内容使用相同的名称 - 可能是另一个信号量,也可能是其他内容,例如事件或互斥锁 - 该进程正在以不同的用户身份运行。

如果您从 open 得到“访问被拒绝”,那么,除了 new 的可能性之外,可能是另一个进程已经打开了具有相同信号量的信号量。名称,但尚未向其他用户授予完全权限。 Win32::Semaphore->open 请求 SEMAPHORE_ALL_ACCESS 权限

如果信号量已被以同一用户身份运行的进程打开,那么您不应收到“访问被拒绝”的消息。在这种情况下,newopen 都不应该失败,尽管 $^E 无论如何都可能保存 183 (ERROR_ALREADY_EXISTS)。

Win32::Semaphore->new calls the Windows API function CreateSemaphore 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 for new, 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 requests SEMAPHORE_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 nor open should fail in that case, although $^E might hold 183 (ERROR_ALREADY_EXISTS) anyway.

灼痛 2024-08-12 13:24:33

根据记录,我是 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.)

指尖凝香 2024-08-12 13:24:33

来自 Win32::Semaphore pod

$semaphore = Win32::Semaphore- >new($initial, $maximum, [$name])

新信号量对象的构造函数。 $initial 是初始计数,$maximum 是
信号量的最大计数。如果省略 $name 或 undef,则创建一个未命名的
信号量对象。

如果 $name 表示现有信号量对象,则 $initial 和 $maximum 被忽略
并且该对象被打开。
如果发生这种情况,$^E 将被设置为 183
(ERROR_ALREADY_EXISTS)。

如果我没看错的话,如果您对 Win32::Semaphore->new 的调用引用了现有信号量,那么 new 调用也将打开该信号量,并且随后的 open 调用将是多余的(我从 pod 中不清楚如果打开一个已经打开的信号量会发生什么)。

也许您可以单步执行代码,在每一步检查 $sem 以及 $!$^E 的值。

其他回复: Windows API< /a> 确实有设置信号量访问控制的方法,但

  1. 它们似乎没有在 Perl Win32::Semaphore 模块中公开,
  2. 除非已经允许,否则无法设置访问控制创建信号量的另一个进程

我不知道您是否对这个问题有任何好的选择。你能修改创建信号量的过程来放宽访问限制吗?请Win32::Semaphore 作者更新他的模块?尝试自己修复 Win32::Semaphore 吗?

From Win32::Semaphore pod

$semaphore = Win32::Semaphore->new($initial, $maximum, [$name])

Constructor for a new semaphore object. $initial is the initial count, and $maximum is
the maximum count for the semaphore. If $name is omitted or undef, creates an unnamed
semaphore object.

If $name signifies an existing semaphore object, then $initial and $maximum are ignored
and the object is opened.
If this happens, $^E will be set to 183
(ERROR_ALREADY_EXISTS).

If I'm reading this correctly, if your call to Win32::Semaphore->new refers to an existing semaphore, then the new call will open the semaphore as well, and the subsequent open 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

  1. they don't appear to be exposed in the Perl Win32::Semaphore module
  2. access control can't be set unless it was already allowed by the other process that created the semaphore

I 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 fix Win32::Semaphore yourself?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文