0

I want to send messages between two processes. But I get a EACCES error when im trying to send a message with msgsnd()

Creating the message queue

const char* MSG_QUEUE = "/tmp/msg_queue";

int file = open(MSG_QUEUE, O_CREAT | O_RDWR | O_APPEND, 0755);
close(file);
key_t key = ftok(MSG_QUEUE, 1);
errno = 0;
msg_queue = msgget(key, IPC_CREAT);
if(msg_queue == -1) {
    M_DEBUG("Error %s\r\n", strerror(errno));
}

message struct

struct feld_msg_s {
    long id;
    char mtext[5];
};

sending a message

struct feld_msg_s a_msg = {1, "Test"};
errno = 0;
int ret = msgsnd(msg_queue, &a_msg, sizeof(a_msg.mtext), 0);
if(ret == -1) {
    if(errno == EACCES) {
        printf("\r\n NO PERMISSION\r\n");
    } else {
        printf("msgsnd ERROR!: %s\r\n", strerror(errno));
    }
}

in the manpage of msgsnd is written

EACCES The calling process does not have read permission on the message queue, and does not have the CAP_IPC_OWNER capability.

so I've added the following capabilities with the setcap command

sudo setcap CAP_SETFCAP,CAP_IPC_OWNER+epi /home/mvollmer/build-APP-Desktop_Qt_5_6_1_GCC_64bit-Debug/APP 

I've checked with getcap if the application got the capabilities. It's fine. But I still receive the No Permission Error.

When execute the application with root rights, its working!

One thing is very strange, altough msgget was succesfull ipcs dont show any message queues.

So where is my fault?

I'm using Linux Mint

Additional Question: Is is possible to use another datatype then char in the msg struct or is a message restricted to strings?

mvollmer
  • 187
  • 2
  • 11
  • 2
    try this `msg_queue = msgget(key, IPC_CREAT | 0666)` – Arash Mar 03 '17 at 08:10
  • with this i get an EACCES when `msgget` is called. When i delete the file `/tmp/msg_queue` `msgget` and `msgsnd` is succesful...Thanks! But why?! – mvollmer Mar 03 '17 at 08:18
  • This is strange.. it works now every time.. After deleting the file and add | 0666 to the msgget flag. and the message queue is shown with ipcs now! Thanks you very much – mvollmer Mar 03 '17 at 08:25
  • You're welcome. This was a matter of setting the right permissions on the message queue. 0666 means read/write is allowed to all. – Arash Mar 03 '17 at 08:36
  • You did not allow *group* and *other* to write to this file. – szpanczyk Mar 03 '17 at 08:48
  • @mvollmer After you deleted the file, `ftok()` returned a different key. So you were creating and accessing an IPCS message queue using a different key and therefore getting a different message queue ID. Unless you've rebooted, `ipcs -a` will probably show your previous message queue, with its `000` permissions, still there. – Andrew Henle Mar 03 '17 at 10:27

1 Answers1

0

You need to read the man page. Per the POSIX msgget() standard:

SYNOPSIS

#include <sys/msg.h>

int msgget(key_t key, int msgflg); [Option End]

DESCRIPTION

...

  • The low-order 9 bits of msg_perm.mode shall be set to the low-order 9 bits of msgflg.

Thus, this code

msg_queue = msgget(key, IPC_CREAT);

has the "low-order 9 bits of msgflg" all set to zero. Thus the message queue mode is also all 0 - no permissions for anyone.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56