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 <ldv@altlinux.org>
+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  <adhemerval.zanella@linaro.org>
+
+# 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
++   <https://www.gnu.org/licenses/>.  */
++
++#include <sys/ipc.h>
++#include <sys/sem.h>
++#include <errno.h>
++#include <stdlib.h>
++#include <stdbool.h>
++#include <stdio.h>
++
++#include <support/check.h>
++#include <support/temp_file.h>
++
++/* 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 <support/test-driver.c>
+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 <stdlib.h>
+ #include <errno.h>
+ #include <string.h>
++#include <stdbool.h>
+ #include <sys/types.h>
+ #include <sys/ipc.h>
+ #include <sys/sem.h>
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 <adhemerval.zanella@linaro.org>
+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
++   <https://www.gnu.org/licenses/>.  */
++
++#ifndef _TEST_SYSV_H
++#define _TEST_SYSV_H
++
++#include <sys/ipc.h>
++#include <sys/sem.h>
++#include <sys/msg.h>
++#include <sys/shm.h>
++#include <include/array_length.h>
++
++/* 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 <sys/ipc.h>
+ #include <sys/sem.h>
+ 
++#include <test-sysvipc.h>
++
+ #include <support/support.h>
+ #include <support/check.h>
+ #include <support/temp_file.h>
+@@ -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 <adhemerval.zanella@linaro.org>
+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
++   <https://www.gnu.org/licenses/>.  */
++
++#include <sys/ipc.h>
++#include <sys/msg.h>
++#include <errno.h>
++#include <stdlib.h>
++#include <stdbool.h>
++#include <stdio.h>
++
++#include <support/check.h>
++#include <support/temp_file.h>
++
++#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 <support/test-driver.c>
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 <adhemerval.zanella@linaro.org>
+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 <sys/ipc.h>
+ #include <sys/msg.h>
+ 
++#include <test-sysvipc.h>
++
+ #include <support/support.h>
+ #include <support/check.h>
+ #include <support/temp_file.h>
+@@ -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 <adhemerval.zanella@linaro.org>
+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 <sys/shm.h>
+ #include <include/array_length.h>
+ 
+-/* 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 <sys/ipc.h>
+ #include <sys/shm.h>
+ 
++#include <test-sysvipc.h>
++
+ #include <support/support.h>
+ #include <support/check.h>
+ #include <support/temp_file.h>
+@@ -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 <joseph@codesourcery.com>
+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 <joseph@codesourcery.com>
+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 <carlos@redhat.com> - 2.28-154
+- Add IPPROTO_ETHERNET, IPPROTO_MPTCP, and INADDR_ALLSNOOPERS_GROUP defines
+  (#1930302)
+
+* Thu Mar 18 2021 Carlos O'Donell <carlos@redhat.com> - 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 <patsy@redhat.com> - 2.28-152
 - Update syscall-names.list to 5.7, 5.8, 5.9, 5.10 and 5.11. (#1871386)