Reputation: 70893
I tried to set the size of a POSIX message queue and do not seem to be permitted.
The msgctl()
man page states:
IPC_SET can only be executed by a process with appropriate privileges or that has an effective user ID equal to the value of msg_perm.cuid or msg_perm.uid in the msqid_ds data structure associated with msqid. Only a process with appropriate privileges can raise the value of msg_qbytes.
The following test program returns:
uid: 1324
effective uid: 1324
msgctl(msqid=8028175, IPC_SET, ...) failed
(msg_perm.uid=1324,msg_perm.cuid=1324): Operation not permitted (errno=1)
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/msg.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
int main(int iArgC, char ** ppszArgv)
{
printf("uid: %u\n", getuid());
printf("effective uid: %u\n", geteuid());
int msqid = msgget(
IPC_PRIVATE,
IPC_CREAT |
S_IRGRP | S_IWGRP |
S_IRUSR | S_IWUSR |
S_IROTH | S_IWOTH);
if (0 > msqid)
{
fprintf(stderr,
"msgget() failed.\n");
return EXIT_FAILURE;
}
{
struct msqid_ds ds = {0};
if (msgctl(
msqid,
IPC_STAT,
&ds))
{
fprintf(stderr,
"msgctl(msqid=%d, IPC_STAT, ...) failed: "
"%s (errno=%d)\n",
msqid,
strerror(errno),
errno);
return EXIT_FAILURE;
}
ds.msg_qbytes = 1024*1024;
if (msgctl(
msqid,
IPC_SET,
&ds))
{
fprintf(stderr,
"msgctl(msqid=%d, IPC_SET, ...) failed "
"(msg_perm.uid=%u,"
"msg_perm.cuid=%u): "
"%s (errno=%d)\n",
msqid,
ds.msg_perm.uid,
ds.msg_perm.cuid,
strerror(errno),
errno);
}
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
/* EOF */
So, what's the trick?
Upvotes: 0
Views: 3850
Reputation: 47762
From man msgctl
:
Appropriate privilege (Linux: the CAP_IPC_RESOURCE capability) is required to raise the msg_qbytes value beyond the system parameter MSGMNB.
On my system, MSGNMB is 16 kB which is well below the 1 MB you try to set it to. Have you checked this limit? (Do cat /proc/sys/kernel/msgmnb
)
Upvotes: 1