diff --git a/SOURCES/glibc-rh1912670-1.patch b/SOURCES/glibc-rh1912670-1.patch new file mode 100644 index 0000000..92bd13d --- /dev/null +++ b/SOURCES/glibc-rh1912670-1.patch @@ -0,0 +1,266 @@ +Conflicts in sysdeps/unix/sysv/linux/semctl.c were due to 64-bit time_t +and RHEL8 has a simpler implementation. + +Conflicts in sysdeps/unix/sysv/linux/Makefile were due to the usual test +case conflicts. + +commit 574500a108be1d2a6a0dc97a075c9e0a98371aba +Author: Dmitry V. Levin +Date: Tue Sep 29 14:10:20 2020 -0300 + + sysvipc: Fix SEM_STAT_ANY kernel argument pass [BZ #26637] + + Handle SEM_STAT_ANY the same way as SEM_STAT so that the buffer argument + of SEM_STAT_ANY is properly passed to the kernel and back. + + The regression testcase checks for Linux specifix SysV ipc message + control extension. For IPC_INFO/SEM_INFO it tries to match the values + against the tunable /proc values and for SEM_STAT/SEM_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). + + Co-authored-by: Adhemerval Zanella + +# Conflicts: +# sysdeps/unix/sysv/linux/Makefile +# sysdeps/unix/sysv/linux/semctl.c + +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index fb4ccd63ddec7eca..c6907796152eb09d 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -45,7 +45,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \ + tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ + tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \ + test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \ +- tst-rlimit-infinity tst-ofdlocks ++ tst-rlimit-infinity tst-ofdlocks \ ++ tst-sysvsem-linux + tests-internal += tst-ofdlocks-compat + + +diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c +index e2925447eba2ee94..bdf31ca7747fe5a4 100644 +--- a/sysdeps/unix/sysv/linux/semctl.c ++++ b/sysdeps/unix/sysv/linux/semctl.c +@@ -51,6 +51,7 @@ __new_semctl (int semid, int semnum, int cmd, ...) + case IPC_STAT: /* arg.buf */ + case IPC_SET: + case SEM_STAT: ++ case SEM_STAT_ANY: + case IPC_INFO: /* arg.__buf */ + case SEM_INFO: + va_start (ap, cmd); +@@ -90,6 +91,7 @@ __old_semctl (int semid, int semnum, int cmd, ...) + case IPC_STAT: /* arg.buf */ + case IPC_SET: + case SEM_STAT: ++ case SEM_STAT_ANY: + case IPC_INFO: /* arg.__buf */ + case SEM_INFO: + va_start (ap, cmd); +diff --git a/sysdeps/unix/sysv/linux/tst-sysvsem-linux.c b/sysdeps/unix/sysv/linux/tst-sysvsem-linux.c +new file mode 100644 +index 0000000000000000..45f19e2d37ed194a +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-sysvsem-linux.c +@@ -0,0 +1,184 @@ ++/* Basic tests for Linux SYSV semaphore extensions. ++ Copyright (C) 2020 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++/* These are for the temporary file we generate. */ ++static char *name; ++static int semid; ++ ++static void ++remove_sem (void) ++{ ++ /* Enforce message queue removal in case of early test failure. ++ Ignore error since the sem may already have being removed. */ ++ semctl (semid, 0, IPC_RMID, 0); ++} ++ ++static void ++do_prepare (int argc, char *argv[]) ++{ ++ TEST_VERIFY_EXIT (create_temp_file ("tst-sysvsem.", &name) != -1); ++} ++ ++#define PREPARE do_prepare ++ ++#define SEM_MODE 0644 ++ ++union semun ++{ ++ int val; ++ struct semid_ds *buf; ++ unsigned short *array; ++ struct seminfo *__buf; ++}; ++ ++struct test_seminfo ++{ ++ int semmsl; ++ int semmns; ++ int semopm; ++ int semmni; ++}; ++ ++/* It tries to obtain some system-wide SysV semaphore information from /proc ++ to check against IPC_INFO/SEM_INFO. The /proc only returns the tunables ++ value of SEMMSL, SEMMNS, SEMOPM, and SEMMNI. ++ ++ The kernel also returns constant value for SEMVMX, SEMMNU, SEMMAP, SEMUME, ++ and also SEMUSZ and SEMAEM (for IPC_INFO). The issue to check them is they ++ might change over kernel releases. */ ++ ++static void ++read_sem_stat (struct test_seminfo *tseminfo) ++{ ++ FILE *f = fopen ("/proc/sys/kernel/sem", "r"); ++ if (f == NULL) ++ FAIL_UNSUPPORTED ("/proc is not mounted or /proc/sys/kernel/sem is not " ++ "available"); ++ ++ int r = fscanf (f, "%d %d %d %d", ++ &tseminfo->semmsl, &tseminfo->semmns, &tseminfo->semopm, ++ &tseminfo->semmni); ++ TEST_VERIFY_EXIT (r == 4); ++ ++ fclose (f); ++} ++ ++ ++/* Check if the semaphore with IDX (index into the kernel's internal array) ++ matches the one with KEY. The CMD is either SEM_STAT or SEM_STAT_ANY. */ ++ ++static bool ++check_seminfo (int idx, key_t key, int cmd) ++{ ++ struct semid_ds seminfo; ++ int sid = semctl (idx, 0, cmd, (union semun) { .buf = &seminfo }); ++ /* Ignore unused array slot returned by the kernel or information from ++ unknown semaphores. */ ++ if ((sid == -1 && errno == EINVAL) || sid != semid) ++ return false; ++ ++ if (sid == -1) ++ FAIL_EXIT1 ("semctl with SEM_STAT failed (errno=%d)", errno); ++ ++ TEST_COMPARE (seminfo.sem_perm.__key, key); ++ TEST_COMPARE (seminfo.sem_perm.mode, SEM_MODE); ++ TEST_COMPARE (seminfo.sem_nsems, 1); ++ ++ return true; ++} ++ ++static int ++do_test (void) ++{ ++ atexit (remove_sem); ++ ++ key_t key = ftok (name, 'G'); ++ if (key == -1) ++ FAIL_EXIT1 ("ftok failed: %m"); ++ ++ semid = semget (key, 1, IPC_CREAT | IPC_EXCL | SEM_MODE); ++ if (semid == -1) ++ FAIL_EXIT1 ("semget failed: %m"); ++ ++ struct test_seminfo tipcinfo; ++ read_sem_stat (&tipcinfo); ++ ++ int semidx; ++ ++ { ++ struct seminfo ipcinfo; ++ semidx = semctl (semid, 0, IPC_INFO, (union semun) { .__buf = &ipcinfo }); ++ if (semidx == -1) ++ FAIL_EXIT1 ("semctl with IPC_INFO failed: %m"); ++ ++ TEST_COMPARE (ipcinfo.semmsl, tipcinfo.semmsl); ++ TEST_COMPARE (ipcinfo.semmns, tipcinfo.semmns); ++ TEST_COMPARE (ipcinfo.semopm, tipcinfo.semopm); ++ TEST_COMPARE (ipcinfo.semmni, tipcinfo.semmni); ++ } ++ ++ /* Same as before but with SEM_INFO. */ ++ { ++ struct seminfo ipcinfo; ++ semidx = semctl (semid, 0, SEM_INFO, (union semun) { .__buf = &ipcinfo }); ++ if (semidx == -1) ++ FAIL_EXIT1 ("semctl with IPC_INFO failed: %m"); ++ ++ TEST_COMPARE (ipcinfo.semmsl, tipcinfo.semmsl); ++ TEST_COMPARE (ipcinfo.semmns, tipcinfo.semmns); ++ TEST_COMPARE (ipcinfo.semopm, tipcinfo.semopm); ++ TEST_COMPARE (ipcinfo.semmni, tipcinfo.semmni); ++ } ++ ++ /* We check if the created semaphore shows in the system-wide status. */ ++ bool found = false; ++ for (int i = 0; i <= semidx; i++) ++ { ++ /* We can't tell apart if SEM_STAT_ANY is not supported (kernel older ++ than 4.17) or if the index used is invalid. So it just check if ++ value returned from a valid call matches the created semaphore. */ ++ check_seminfo (i, key, SEM_STAT_ANY); ++ ++ if (check_seminfo (i, key, SEM_STAT)) ++ { ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) ++ FAIL_EXIT1 ("semctl with SEM_STAT/SEM_STAT_ANY could not find the " ++ "created semaphore"); ++ ++ if (semctl (semid, 0, IPC_RMID, 0) == -1) ++ FAIL_EXIT1 ("semctl failed: %m"); ++ ++ return 0; ++} ++ ++#include +diff --git a/sysvipc/test-sysvsem.c b/sysvipc/test-sysvsem.c +index a8e9bff000949ff8..d197772917a7579d 100644 +--- a/sysvipc/test-sysvsem.c ++++ b/sysvipc/test-sysvsem.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + #include diff --git a/SOURCES/glibc-rh1912670-2.patch b/SOURCES/glibc-rh1912670-2.patch new file mode 100644 index 0000000..7f730f0 --- /dev/null +++ b/SOURCES/glibc-rh1912670-2.patch @@ -0,0 +1,151 @@ +Rewrite of the following commit but adjusted pre-64-bit time_t +conversion. We want to follow the same upstream behaviour and return +EINVAL for unknown commands rather than to attempt the command with an +argument of {0} which has likely never been tested upstream. + +commit a16d2abd496bd974a88207d5599265aae5ae4880 +Author: Adhemerval Zanella +Date: Tue Sep 29 14:29:48 2020 -0300 + + sysvipc: Return EINVAL for invalid semctl commands + + It avoids regressions on possible future commands that might require + additional libc support. The downside is new commands added by newer + kernels will need further glibc support. + + Checked on x86_64-linux-gnu and i686-linux-gnu (Linux v4.15 and v5.4). + +diff --git a/sysdeps/unix/sysv/linux/semctl.c b/sysdeps/unix/sysv/linux/semctl.c +index bdf31ca7747fe5a4..03c56c69a5412c82 100644 +--- a/sysdeps/unix/sysv/linux/semctl.c ++++ b/sysdeps/unix/sysv/linux/semctl.c +@@ -58,6 +58,15 @@ __new_semctl (int semid, int semnum, int cmd, ...) + arg = va_arg (ap, union semun); + va_end (ap); + break; ++ case IPC_RMID: /* arg ignored. */ ++ case GETNCNT: ++ case GETPID: ++ case GETVAL: ++ case GETZCNT: ++ break; ++ default: ++ __set_errno (EINVAL); ++ return -1; + } + + #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS +diff --git a/sysvipc/test-sysvipc.h b/sysvipc/test-sysvipc.h +new file mode 100644 +index 0000000000000000..d7ed496511c10afb +--- /dev/null ++++ b/sysvipc/test-sysvipc.h +@@ -0,0 +1,85 @@ ++/* Basic definition for Sysv IPC test functions. ++ Copyright (C) 2020 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#ifndef _TEST_SYSV_H ++#define _TEST_SYSV_H ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* Return the first invalid command SysV IPC command from common shared ++ between message queue, shared memory, and semaphore. */ ++static inline int ++first_common_invalid_cmd (void) ++{ ++ const int common_cmds[] = { ++ IPC_RMID, ++ IPC_SET, ++ IPC_STAT, ++ IPC_INFO, ++ }; ++ ++ int invalid = 0; ++ for (int i = 0; i < array_length (common_cmds); i++) ++ { ++ if (invalid == common_cmds[i]) ++ { ++ invalid++; ++ i = 0; ++ } ++ } ++ ++ return invalid; ++} ++ ++/* Return the first invalid command SysV IPC command for semaphore. */ ++static inline int ++first_sem_invalid_cmd (void) ++{ ++ const int sem_cmds[] = { ++ GETPID, ++ GETVAL, ++ GETALL, ++ GETNCNT, ++ GETZCNT, ++ SETVAL, ++ SETALL, ++ SEM_STAT, ++ SEM_INFO, ++#ifdef SEM_STAT_ANY ++ SEM_STAT_ANY, ++#endif ++ }; ++ ++ int invalid = first_common_invalid_cmd (); ++ for (int i = 0; i < array_length (sem_cmds); i++) ++ { ++ if (invalid == sem_cmds[i]) ++ { ++ invalid++; ++ i = 0; ++ } ++ } ++ ++ return invalid; ++} ++ ++#endif /* _TEST_SYSV_H */ +diff --git a/sysvipc/test-sysvsem.c b/sysvipc/test-sysvsem.c +index d197772917a7579d..43a1460ec2b9308f 100644 +--- a/sysvipc/test-sysvsem.c ++++ b/sysvipc/test-sysvsem.c +@@ -25,6 +25,8 @@ + #include + #include + ++#include ++ + #include + #include + #include +@@ -80,6 +82,9 @@ do_test (void) + FAIL_EXIT1 ("semget failed (errno=%d)", errno); + } + ++ TEST_COMPARE (semctl (semid, 0, first_sem_invalid_cmd (), NULL), -1); ++ TEST_COMPARE (errno, EINVAL); ++ + /* Get semaphore kernel information and do some sanity checks. */ + struct semid_ds seminfo; + if (semctl (semid, 0, IPC_STAT, (union semun) { .buf = &seminfo }) == -1) diff --git a/SOURCES/glibc-rh1912670-3.patch b/SOURCES/glibc-rh1912670-3.patch new file mode 100644 index 0000000..046f63b --- /dev/null +++ b/SOURCES/glibc-rh1912670-3.patch @@ -0,0 +1,224 @@ +Backport only the test case: + * sysdeps/unix/sysv/linux/tst-sysvmsg-linux.c + +This improves coverage for IPC_INFO and MSG_INFO. + +We don't need the actual fix in the bug because we don't have the 64-bit +time_t handling backported. + +commit 20a00dbefca5695cccaa44846a482db8ccdd85ab +Author: Adhemerval Zanella +Date: Tue Sep 29 14:39:56 2020 -0300 + + 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). + +diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile +index 7d04e3313c56c15d..688cf9fa9dea23a6 100644 +--- a/sysdeps/unix/sysv/linux/Makefile ++++ b/sysdeps/unix/sysv/linux/Makefile +@@ -46,7 +46,7 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \ + tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \ + test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \ + tst-rlimit-infinity tst-ofdlocks \ +- tst-sysvsem-linux ++ tst-sysvsem-linux tst-sysvmsg-linux + tests-internal += tst-ofdlocks-compat + + +diff --git a/sysdeps/unix/sysv/linux/tst-sysvmsg-linux.c b/sysdeps/unix/sysv/linux/tst-sysvmsg-linux.c +new file mode 100644 +index 0000000000000000..1857fab8c1fdf041 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/tst-sysvmsg-linux.c +@@ -0,0 +1,177 @@ ++/* Basic tests for Linux SYSV message queue extensions. ++ Copyright (C) 2020-2021 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#define MSGQ_MODE 0644 ++ ++/* These are for the temporary file we generate. */ ++static char *name; ++static int msqid; ++ ++static void ++remove_msq (void) ++{ ++ /* Enforce message queue removal in case of early test failure. ++ Ignore error since the msg may already have being removed. */ ++ msgctl (msqid, IPC_RMID, NULL); ++} ++ ++static void ++do_prepare (int argc, char *argv[]) ++{ ++ TEST_VERIFY_EXIT (create_temp_file ("tst-sysvmsg.", &name) != -1); ++} ++ ++#define PREPARE do_prepare ++ ++struct test_msginfo ++{ ++ int msgmax; ++ int msgmnb; ++ int msgmni; ++}; ++ ++/* It tries to obtain some system-wide SysV messsage queue information from ++ /proc to check against IPC_INFO/MSG_INFO. The /proc only returns the ++ tunables value of MSGMAX, MSGMNB, and MSGMNI. ++ ++ The kernel also returns constant value for MSGSSZ, MSGSEG and also MSGMAP, ++ MSGPOOL, and MSGTQL (for IPC_INFO). The issue to check them is they might ++ change over kernel releases. */ ++ ++static int ++read_proc_file (const char *file) ++{ ++ FILE *f = fopen (file, "r"); ++ if (f == NULL) ++ FAIL_UNSUPPORTED ("/proc is not mounted or %s is not available", file); ++ ++ int v; ++ int r = fscanf (f, "%d", & v); ++ TEST_VERIFY_EXIT (r == 1); ++ ++ fclose (f); ++ return v; ++} ++ ++ ++/* Check if the message queue with IDX (index into the kernel's internal ++ array) matches the one with KEY. The CMD is either MSG_STAT or ++ MSG_STAT_ANY. */ ++ ++static bool ++check_msginfo (int idx, key_t key, int cmd) ++{ ++ struct msqid_ds msginfo; ++ int mid = msgctl (idx, cmd, &msginfo); ++ /* Ignore unused array slot returned by the kernel or information from ++ unknown message queue. */ ++ if ((mid == -1 && errno == EINVAL) || mid != msqid) ++ return false; ++ ++ if (mid == -1) ++ FAIL_EXIT1 ("msgctl with %s failed: %m", ++ cmd == MSG_STAT ? "MSG_STAT" : "MSG_STAT_ANY"); ++ ++ TEST_COMPARE (msginfo.msg_perm.__key, key); ++ TEST_COMPARE (msginfo.msg_perm.mode, MSGQ_MODE); ++ TEST_COMPARE (msginfo.msg_qnum, 0); ++ ++ return true; ++} ++ ++static int ++do_test (void) ++{ ++ atexit (remove_msq); ++ ++ key_t key = ftok (name, 'G'); ++ if (key == -1) ++ FAIL_EXIT1 ("ftok failed: %m"); ++ ++ msqid = msgget (key, MSGQ_MODE | IPC_CREAT); ++ if (msqid == -1) ++ FAIL_EXIT1 ("msgget failed: %m"); ++ ++ struct test_msginfo tipcinfo; ++ tipcinfo.msgmax = read_proc_file ("/proc/sys/kernel/msgmax"); ++ tipcinfo.msgmnb = read_proc_file ("/proc/sys/kernel/msgmnb"); ++ tipcinfo.msgmni = read_proc_file ("/proc/sys/kernel/msgmni"); ++ ++ int msqidx; ++ ++ { ++ struct msginfo ipcinfo; ++ msqidx = msgctl (msqid, IPC_INFO, (struct msqid_ds *) &ipcinfo); ++ if (msqidx == -1) ++ FAIL_EXIT1 ("msgctl with IPC_INFO failed: %m"); ++ ++ TEST_COMPARE (ipcinfo.msgmax, tipcinfo.msgmax); ++ TEST_COMPARE (ipcinfo.msgmnb, tipcinfo.msgmnb); ++ TEST_COMPARE (ipcinfo.msgmni, tipcinfo.msgmni); ++ } ++ ++ /* Same as before but with MSG_INFO. */ ++ { ++ struct msginfo ipcinfo; ++ msqidx = msgctl (msqid, MSG_INFO, (struct msqid_ds *) &ipcinfo); ++ if (msqidx == -1) ++ FAIL_EXIT1 ("msgctl with IPC_INFO failed: %m"); ++ ++ TEST_COMPARE (ipcinfo.msgmax, tipcinfo.msgmax); ++ TEST_COMPARE (ipcinfo.msgmnb, tipcinfo.msgmnb); ++ TEST_COMPARE (ipcinfo.msgmni, tipcinfo.msgmni); ++ } ++ ++ /* We check if the created message queue shows in global list. */ ++ bool found = false; ++ for (int i = 0; i <= msqidx; i++) ++ { ++ /* We can't tell apart if MSG_STAT_ANY is not supported (kernel older ++ than 4.17) or if the index used is invalid. So it just check if the ++ value returned from a valid call matches the created message ++ queue. */ ++ check_msginfo (i, key, MSG_STAT_ANY); ++ ++ if (check_msginfo (i, key, MSG_STAT)) ++ { ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) ++ FAIL_EXIT1 ("msgctl with MSG_STAT/MSG_STAT_ANY could not find the " ++ "created message queue"); ++ ++ if (msgctl (msqid, IPC_RMID, NULL) == -1) ++ FAIL_EXIT1 ("msgctl failed"); ++ ++ return 0; ++} ++ ++#include diff --git a/SOURCES/glibc-rh1912670-4.patch b/SOURCES/glibc-rh1912670-4.patch new file mode 100644 index 0000000..2b0c33f --- /dev/null +++ b/SOURCES/glibc-rh1912670-4.patch @@ -0,0 +1,98 @@ +This is a rewrite of the commit for the pre-64-bit time_t version of +the msgctl handling. Similar to semctl we want the RHEL8 handling of +the unknown commands to be the same as upstream. + +commit be9b0b9a012780a403a266c90878efffb9a5f3ca +Author: Adhemerval Zanella +Date: Tue Sep 29 14:45:09 2020 -0300 + + sysvipc: Return EINVAL for invalid msgctl commands + + It avoids regressions on possible future commands that might require + additional libc support. The downside is new commands added by newer + kernels will need further glibc support. + + Checked on x86_64-linux-gnu and i686-linux-gnu (Linux v4.15 and v5.4). + +diff --git a/sysdeps/unix/sysv/linux/msgctl.c b/sysdeps/unix/sysv/linux/msgctl.c +index 7280cba31a8815a2..6a2c79d188b875b9 100644 +--- a/sysdeps/unix/sysv/linux/msgctl.c ++++ b/sysdeps/unix/sysv/linux/msgctl.c +@@ -29,6 +29,20 @@ + int + __new_msgctl (int msqid, int cmd, struct msqid_ds *buf) + { ++ switch (cmd) ++ { ++ case IPC_RMID: ++ case IPC_SET: ++ case IPC_STAT: ++ case MSG_STAT: ++ case MSG_STAT_ANY: ++ case IPC_INFO: ++ case MSG_INFO: ++ break; ++ default: ++ __set_errno (EINVAL); ++ return -1; ++ } + #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS + return INLINE_SYSCALL_CALL (msgctl, msqid, cmd | __IPC_64, buf); + #else +diff --git a/sysvipc/test-sysvipc.h b/sysvipc/test-sysvipc.h +index ed0057b7871e505c..133fb71c6113a2b5 100644 +--- a/sysvipc/test-sysvipc.h ++++ b/sysvipc/test-sysvipc.h +@@ -134,4 +134,29 @@ first_shm_invalid_cmd (void) + return invalid; + } + ++/* Return the first invalid command SysV IPC command for message queue. */ ++static inline int ++first_msg_invalid_cmd (void) ++{ ++ const int msg_cmds[] = { ++ MSG_STAT, ++ MSG_INFO, ++#ifdef MSG_STAT_ANY ++ MSG_STAT_ANY, ++#endif ++ }; ++ ++ int invalid = first_common_invalid_cmd (); ++ for (int i = 0; i < array_length (msg_cmds); i++) ++ { ++ if (invalid == msg_cmds[i]) ++ { ++ invalid++; ++ i = 0; ++ } ++ } ++ ++ return invalid; ++} ++ + #endif /* _TEST_SYSV_H */ +diff --git a/sysvipc/test-sysvmsg.c b/sysvipc/test-sysvmsg.c +index 1e0471807cd26da1..74a907ad39ee114e 100644 +--- a/sysvipc/test-sysvmsg.c ++++ b/sysvipc/test-sysvmsg.c +@@ -24,6 +24,8 @@ + #include + #include + ++#include ++ + #include + #include + #include +@@ -86,6 +88,9 @@ do_test (void) + FAIL_EXIT1 ("msgget failed (errno=%d)", errno); + } + ++ TEST_COMPARE (msgctl (msqid, first_msg_invalid_cmd (), NULL), -1); ++ TEST_COMPARE (errno, EINVAL); ++ + /* Get message queue kernel information and do some sanity checks. */ + struct msqid_ds msginfo; + if (msgctl (msqid, IPC_STAT, &msginfo) == -1) diff --git a/SOURCES/glibc-rh1912670-5.patch b/SOURCES/glibc-rh1912670-5.patch new file mode 100644 index 0000000..2ffdbca --- /dev/null +++ b/SOURCES/glibc-rh1912670-5.patch @@ -0,0 +1,128 @@ +Rewrite of the following commit to support returning EINVAL for unknown +commands and therefore match upstream behaviour. + +commit 9ebaabeaac1a96b0d91f52902ce1dbf4f5a562dd +Author: Adhemerval Zanella +Date: Tue Sep 29 14:55:02 2020 -0300 + + sysvipc: Return EINVAL for invalid shmctl commands + + It avoids regressions on possible future commands that might require + additional libc support. The downside is new commands added by newer + kernels will need further glibc support. + + Checked on x86_64-linux-gnu and i686-linux-gnu (Linux v4.15 and v5.4). + +diff --git a/sysdeps/unix/sysv/linux/shmctl.c b/sysdeps/unix/sysv/linux/shmctl.c +index 25c5152944a6fcf3..00768bc47614f9aa 100644 +--- a/sysdeps/unix/sysv/linux/shmctl.c ++++ b/sysdeps/unix/sysv/linux/shmctl.c +@@ -33,6 +33,22 @@ + int + __new_shmctl (int shmid, int cmd, struct shmid_ds *buf) + { ++ switch (cmd) ++ { ++ case IPC_RMID: ++ case SHM_LOCK: ++ case SHM_UNLOCK: ++ case IPC_SET: ++ case IPC_STAT: ++ case SHM_STAT: ++ case SHM_STAT_ANY: ++ case IPC_INFO: ++ case SHM_INFO: ++ break; ++ default: ++ __set_errno (EINVAL); ++ break; ++ } + #ifdef __ASSUME_DIRECT_SYSVIPC_SYSCALLS + return INLINE_SYSCALL_CALL (shmctl, shmid, cmd | __IPC_64, buf); + #else +diff --git a/sysvipc/test-sysvipc.h b/sysvipc/test-sysvipc.h +index 21ef6c656581519e..d1c8349b45b5ce49 100644 +--- a/sysvipc/test-sysvipc.h ++++ b/sysvipc/test-sysvipc.h +@@ -25,7 +25,7 @@ + #include + #include + +-/* Return the first invalid command SysV IPC command from common shared ++/* Return the first invalid SysV IPC command from common shared + between message queue, shared memory, and semaphore. */ + static inline int + first_common_invalid_cmd (void) +@@ -50,7 +50,7 @@ first_common_invalid_cmd (void) + return invalid; + } + +-/* Return the first invalid command SysV IPC command for semaphore. */ ++/* Return the first invalid SysV IPC command for semaphore. */ + static inline int + first_sem_invalid_cmd (void) + { +@@ -82,7 +82,7 @@ first_sem_invalid_cmd (void) + return invalid; + } + +-/* Return the first invalid command SysV IPC command for message queue. */ ++/* Return the first invalid SysV IPC command for message queue. */ + static inline int + first_msg_invalid_cmd (void) + { +@@ -107,4 +107,31 @@ first_msg_invalid_cmd (void) + return invalid; + } + ++/* Return the first invalid SysV IPC command for shared memory. */ ++static inline int ++first_shm_invalid_cmd (void) ++{ ++ const int shm_cmds[] = { ++ SHM_STAT, ++ SHM_INFO, ++#ifdef SHM_STAT_ANY ++ SHM_STAT_ANY, ++#endif ++ SHM_LOCK, ++ SHM_UNLOCK ++ }; ++ ++ int invalid = first_common_invalid_cmd (); ++ for (int i = 0; i < array_length (shm_cmds); i++) ++ { ++ if (invalid == shm_cmds[i]) ++ { ++ invalid++; ++ i = 0; ++ } ++ } ++ ++ return invalid; ++} ++ + #endif /* _TEST_SYSV_H */ +diff --git a/sysvipc/test-sysvshm.c b/sysvipc/test-sysvshm.c +index a7c2e0bd4065dbcd..0fdfddf8550413e4 100644 +--- a/sysvipc/test-sysvshm.c ++++ b/sysvipc/test-sysvshm.c +@@ -25,6 +25,8 @@ + #include + #include + ++#include ++ + #include + #include + #include +@@ -81,6 +83,9 @@ do_test (void) + FAIL_EXIT1 ("shmget failed (errno=%d)", errno); + } + ++ TEST_COMPARE (shmctl (shmid, first_shm_invalid_cmd (), NULL), -1); ++ TEST_COMPARE (errno, EINVAL); ++ + /* Get shared memory kernel information and do some sanity checks. */ + struct shmid_ds shminfo; + if (shmctl (shmid, IPC_STAT, &shminfo) == -1) diff --git a/SOURCES/glibc-rh1930302-1.patch b/SOURCES/glibc-rh1930302-1.patch new file mode 100644 index 0000000..0c0d614 --- /dev/null +++ b/SOURCES/glibc-rh1930302-1.patch @@ -0,0 +1,25 @@ +commit dc91a19e6f71e1523f4ac179191a29b2131d74bb +Author: Joseph Myers +Date: Mon Jun 3 11:16:02 2019 +0000 + + Add INADDR_ALLSNOOPERS_GROUP from Linux 5.1 to netinet/in.h. + + This patch adds INADDR_ALLSNOOPERS_GROUP from Linux 5.1 to + netinet/in.h. + + Tested for x86_64. + + * inet/netinet/in.h (INADDR_ALLSNOOPERS_GROUP): New macro. + +diff --git a/inet/netinet/in.h b/inet/netinet/in.h +index 03a31b634c8bfbed..c2d12a04aab6c022 100644 +--- a/inet/netinet/in.h ++++ b/inet/netinet/in.h +@@ -204,6 +204,7 @@ enum + #define INADDR_UNSPEC_GROUP ((in_addr_t) 0xe0000000) /* 224.0.0.0 */ + #define INADDR_ALLHOSTS_GROUP ((in_addr_t) 0xe0000001) /* 224.0.0.1 */ + #define INADDR_ALLRTRS_GROUP ((in_addr_t) 0xe0000002) /* 224.0.0.2 */ ++#define INADDR_ALLSNOOPERS_GROUP ((in_addr_t) 0xe000006a) /* 224.0.0.106 */ + #define INADDR_MAX_LOCAL_GROUP ((in_addr_t) 0xe00000ff) /* 224.0.0.255 */ + + #if !__USE_KERNEL_IPV6_DEFS diff --git a/SOURCES/glibc-rh1930302-2.patch b/SOURCES/glibc-rh1930302-2.patch new file mode 100644 index 0000000..a0b75ad --- /dev/null +++ b/SOURCES/glibc-rh1930302-2.patch @@ -0,0 +1,28 @@ +commit f9ac84f92f151e07586c55e14ed628d493a5929d +Author: Joseph Myers +Date: Fri Apr 3 18:08:28 2020 +0000 + + Add IPPROTO_ETHERNET and IPPROTO_MPTCP from Linux 5.6 to netinet/in.h. + + This patch adds the IPPROTO_ETHERNET and IPPROTO_MPTCP constants from + Linux 5.6 to glibc's netinet/in.h. + + Tested for x86_64. + +diff --git a/inet/netinet/in.h b/inet/netinet/in.h +index c2d12a04aab6c022..5880e909ff3e06fb 100644 +--- a/inet/netinet/in.h ++++ b/inet/netinet/in.h +@@ -87,8 +87,12 @@ enum + #define IPPROTO_UDPLITE IPPROTO_UDPLITE + IPPROTO_MPLS = 137, /* MPLS in IP. */ + #define IPPROTO_MPLS IPPROTO_MPLS ++ IPPROTO_ETHERNET = 143, /* Ethernet-within-IPv6 Encapsulation. */ ++#define IPPROTO_ETHERNET IPPROTO_ETHERNET + IPPROTO_RAW = 255, /* Raw IP packets. */ + #define IPPROTO_RAW IPPROTO_RAW ++ IPPROTO_MPTCP = 262, /* Multipath TCP connection. */ ++#define IPPROTO_MPTCP IPPROTO_MPTCP + IPPROTO_MAX + }; + diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec index d4b0ff3..9e50f8e 100644 --- a/SPECS/glibc.spec +++ b/SPECS/glibc.spec @@ -1,6 +1,6 @@ %define glibcsrcdir glibc-2.28 %define glibcversion 2.28 -%define glibcrelease 152%{?dist} +%define glibcrelease 154%{?dist} # Pre-release tarballs are pulled in from git using a command that is # effectively: # @@ -689,6 +689,13 @@ Patch552: glibc-rh1871386-4.patch Patch553: glibc-rh1871386-5.patch Patch554: glibc-rh1871386-6.patch Patch555: glibc-rh1871386-7.patch +Patch556: glibc-rh1912670-1.patch +Patch557: glibc-rh1912670-2.patch +Patch558: glibc-rh1912670-3.patch +Patch559: glibc-rh1912670-4.patch +Patch560: glibc-rh1912670-5.patch +Patch561: glibc-rh1930302-1.patch +Patch562: glibc-rh1930302-2.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2600,6 +2607,14 @@ fi %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared %changelog +* Thu Mar 18 2021 Carlos O'Donell - 2.28-154 +- Add IPPROTO_ETHERNET, IPPROTO_MPTCP, and INADDR_ALLSNOOPERS_GROUP defines + (#1930302) + +* Thu Mar 18 2021 Carlos O'Donell - 2.28-153 +- Support SEM_STAT_ANY via semctl. Return EINVAL for unknown commands to semctl, + msgctl, and shmctl. (#1912670) + * Tue Mar 16 2021 Patsy Griffin - 2.28-152 - Update syscall-names.list to 5.7, 5.8, 5.9, 5.10 and 5.11. (#1871386)