uwrap: Add support for getgroups_chk()
authorAndreas Schneider <asn@samba.org>
Mon, 8 Nov 2021 15:19:12 +0000 (16:19 +0100)
committerAndreas Schneider <asn@samba.org>
Wed, 24 Nov 2021 09:50:23 +0000 (10:50 +0100)
This is required by software built with FORTIFY_SOURCE=2.

https://bugzilla.redhat.com/show_bug.cgi?id=2021214

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
ConfigureChecks.cmake
config.h.cmake
src/uid_wrapper.c

index 930904e403687e48dfd12227d6f00c6b687ee817..e299f6e49fb3144f08a7eb3774dd80c06f4e2152 100644 (file)
@@ -65,6 +65,7 @@ check_function_exists(setregid HAVE_SETREGID)
 check_function_exists(setresgid HAVE_SETRESGID)
 
 check_function_exists(getgroups HAVE_GETGROUPS)
+check_function_exists(__getgroups_chk HAVE___GETGROUPS_CHK)
 check_function_exists(setgroups HAVE_SETGROUPS)
 
 if (HAVE_SETGROUPS)
index 441966d672b960976ad619d7dd976ceec6e7d22d..5b342e3a15bb0a5c081c54844c19ae934fb2a8a4 100644 (file)
@@ -43,6 +43,7 @@
 
 /* Define to 1 if you have the `getgroups' function. */
 #cmakedefine HAVE_GETGROUPS 1
+#cmakedefine HAVE___GETGROUPS_CHK 1
 
 /* Define to 1 if you have the `setgroups' function. */
 #cmakedefine HAVE_SETGROUPS 1
index 4d31f52362bc2b60955f985f4b4cb155ada2221f..f04642af11a143a9e610b2b31225edd8012a1a81 100644 (file)
@@ -240,6 +240,9 @@ typedef int (*__libc_getresgid)(gid_t *rgid, gid_t *egid, gid_t *sgid);
 typedef gid_t (*__libc_getegid)(void);
 
 typedef int (*__libc_getgroups)(int size, gid_t list[]);
+#ifdef HAVE___GETGROUPS_CHK
+typedef int (*__libc___getgroups_chk)(int size, gid_t list[], size_t listlen);
+#endif
 
 typedef int (*__libc_setgroups)(size_t size, const gid_t *list);
 
@@ -285,6 +288,9 @@ struct uwrap_libc_symbols {
 #endif
        UWRAP_SYMBOL_ENTRY(getegid);
        UWRAP_SYMBOL_ENTRY(getgroups);
+#ifdef HAVE___GETGROUPS_CHK
+       UWRAP_SYMBOL_ENTRY(__getgroups_chk);
+#endif
        UWRAP_SYMBOL_ENTRY(setgroups);
 #ifdef HAVE_SYSCALL
        UWRAP_SYMBOL_ENTRY(syscall);
@@ -637,6 +643,17 @@ static int libc_getgroups(int size, gid_t list[])
        return uwrap.libc.symbols._libc_getgroups.f(size, list);
 }
 
+#ifdef HAVE___GETGROUPS_CHK
+static int libc___getgroups_chk(int size, gid_t list[], size_t listlen)
+{
+       uwrap_bind_symbol_libc(__getgroups_chk);
+
+       return uwrap.libc.symbols._libc___getgroups_chk.f(size,
+                                                         list,
+                                                         listlen);
+}
+#endif /* HAVE___GETGROUPS_CHK */
+
 static int libc_setgroups(size_t size, const gid_t *list)
 {
        uwrap_bind_symbol_libc(setgroups);
@@ -2137,6 +2154,30 @@ int getgroups(int size, gid_t *list)
        return uwrap_getgroups(size, list);
 }
 
+#ifdef HAVE___GETGROUPS_CHK
+static int uwrap___getgroups_chk(int size, gid_t *list, size_t listlen)
+{
+       if (size * sizeof(gid_t) > listlen) {
+               UWRAP_LOG(UWRAP_LOG_DEBUG, "Buffer overflow detected");
+               abort();
+       }
+
+       return uwrap_getgroups(size, list);
+}
+
+int __getgroups_chk(int size, gid_t *list, size_t listlen);
+
+int __getgroups_chk(int size, gid_t *list, size_t listlen)
+{
+       if (!uid_wrapper_enabled()) {
+               return libc___getgroups_chk(size, list, listlen);
+       }
+
+       uwrap_init();
+       return uwrap___getgroups_chk(size, list, listlen);
+}
+#endif /* HAVE___GETGROUPS_CHK */
+
 #if (defined(HAVE_SYS_SYSCALL_H) || defined(HAVE_SYSCALL_H)) \
     && (defined(SYS_setreuid) || defined(SYS_setreuid32))
 static long int uwrap_syscall (long int sysno, va_list vp)