]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
ipcs: fix ipc_msg_get_info fallback case
authorRuediger Meier <ruediger.meier@ga-group.nl>
Wed, 12 Mar 2014 13:53:20 +0000 (14:53 +0100)
committerRuediger Meier <ruediger.meier@ga-group.nl>
Thu, 13 Mar 2014 22:23:25 +0000 (23:23 +0100)
"ipcs -q" (case id < 0) was broken since v2.22-256-g35118df if /sys
is not usable. The main issue was that the use of msqid argument did not
cleanly distinguished between "queue identifier" and "index of kernel's
internal array".

Also now the fallback case and the regular case behave more equally
regarding it's return value (introducing another counter j).

Note that the case id >= 0 now performs a slower lookup. This could be
avoided but then we would better handle both case differently like it
was before the above mentioned cleanup commit.

Signed-off-by: Ruediger Meier <ruediger.meier@ga-group.nl>
sys-utils/ipcutils.c

index c98c5d8b5d82b5e53bcb3de38f245b659a26e282..2491f7c91ee7a06284091b3a09248d083a1f6a81 100644 (file)
@@ -423,26 +423,20 @@ int ipc_msg_get_info(int id, struct msg_data **msgds)
 
        /* Fallback; /proc or /sys file(s) missing. */
 msg_fallback:
-       i = id < 0 ? 0 : id;
-
-       maxid = msgctl(id, MSG_STAT, &dummy);
+       maxid = msgctl(0, MSG_INFO, &dummy);
        if (maxid < 0)
                return 0;
 
-       while (i <= maxid) {
+       for (int j = 0; j <= maxid; j++) {
                int msgid;
                struct ipc_perm *ipcp = &msgseg.msg_perm;
 
-               msgid = msgctl(i, MSG_STAT, &msgseg);
-               if (msgid < 0) {
-                       if (-1 < id) {
-                               free(*msgds);
-                               return 0;
-                       }
-                       i++;
+               msgid = msgctl(j, MSG_STAT, &msgseg);
+               if (msgid < 0 || (id > -1 && msgid != id)) {
                        continue;
                }
 
+               i++;
                p->msg_perm.key = ipcp->KEY;
                p->msg_perm.id = msgid;
                p->msg_perm.mode = ipcp->mode;
@@ -463,11 +457,12 @@ msg_fallback:
                        p->next = xcalloc(1, sizeof(struct msg_data));
                        p = p->next;
                        p->next = NULL;
-                       i++;
                } else
-                       return 1;
+                       break;
        }
 
+       if (i == 0)
+               free(*msgds);
        return i;
 }