diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2020-09-29 14:39:56 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2020-10-02 16:11:55 -0300 |
commit | 20a00dbefca5695cccaa44846a482db8ccdd85ab (patch) | |
tree | 82b4c847c697828bd2ab783e63c91a2fa2b34bf0 /sysdeps/unix/sysv/linux/msgctl.c | |
parent | a16d2abd496bd974a88207d5599265aae5ae4880 (diff) | |
download | glibc-20a00dbefca5695cccaa44846a482db8ccdd85ab.tar.gz glibc-20a00dbefca5695cccaa44846a482db8ccdd85ab.tar.xz glibc-20a00dbefca5695cccaa44846a482db8ccdd85ab.zip |
sysvipc: Fix IPC_INFO and MSG_INFO handling [BZ #26639]
Both commands are Linux extensions where the third argument is a 'struct msginfo' instead of 'struct msqid_ds' and its information does not contain any time related fields (so there is no need to extra conversion for __IPC_TIME64. The regression testcase checks for Linux specifix SysV ipc message control extension. For IPC_INFO/MSG_INFO it tries to match the values against the tunable /proc values and for MSG_STAT/MSG_STAT_ANY it check if the create message queue is within the global list returned by the kernel. Checked on x86_64-linux-gnu and on i686-linux-gnu (Linux v5.4 and on Linux v4.15).
Diffstat (limited to 'sysdeps/unix/sysv/linux/msgctl.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/msgctl.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/sysdeps/unix/sysv/linux/msgctl.c b/sysdeps/unix/sysv/linux/msgctl.c index 0776472d5e..a1f24ab242 100644 --- a/sysdeps/unix/sysv/linux/msgctl.c +++ b/sysdeps/unix/sysv/linux/msgctl.c @@ -90,8 +90,15 @@ __msgctl64 (int msqid, int cmd, struct __msqid64_ds *buf) struct kernel_msqid64_ds ksemid, *arg = NULL; if (buf != NULL) { - msqid64_to_kmsqid64 (buf, &ksemid); - arg = &ksemid; + /* This is a Linux extension where kernel returns a 'struct msginfo' + instead. */ + if (cmd == IPC_INFO || cmd == MSG_INFO) + arg = (struct kernel_msqid64_ds *) buf; + else + { + msqid64_to_kmsqid64 (buf, &ksemid); + arg = &ksemid; + } } # ifdef __ASSUME_SYSVIPC_BROKEN_MODE_T if (cmd == IPC_SET) @@ -169,8 +176,15 @@ __msgctl (int msqid, int cmd, struct msqid_ds *buf) struct __msqid64_ds msqid64, *buf64 = NULL; if (buf != NULL) { - msqid_to_msqid64 (&msqid64, buf); - buf64 = &msqid64; + /* This is a Linux extension where kernel returns a 'struct msginfo' + instead. */ + if (cmd == IPC_INFO || cmd == MSG_INFO) + buf64 = (struct __msqid64_ds *) buf; + else + { + msqid_to_msqid64 (&msqid64, buf); + buf64 = &msqid64; + } } int ret = __msgctl64 (msqid, cmd, buf64); |