about summary refs log tree commit diff
path: root/libio/libioP.h
diff options
context:
space:
mode:
authorAdhemerval Zanella Netto <adhemerval.zanella@linaro.org>2022-12-27 18:11:43 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2023-03-27 13:57:55 -0300
commit3020f72618e4f1d7338cd42b8bc7b2813e961b5a (patch)
treed61cc39cb5aa140de5331cd1a2ba6ab796db0c81 /libio/libioP.h
parentf65ca70deaf38db4ca12458e74cefd8ad9063956 (diff)
downloadglibc-3020f72618e4f1d7338cd42b8bc7b2813e961b5a.tar.gz
glibc-3020f72618e4f1d7338cd42b8bc7b2813e961b5a.tar.xz
glibc-3020f72618e4f1d7338cd42b8bc7b2813e961b5a.zip
libio: Remove the usage of __libc_IO_vtables
Instead of using a special ELF section along with a linker script
directive to put the IO vtables within the RELRO section, the libio
vtables are all moved to an array marked as data.relro (so linker
will place in the RELRO segment without the need of extra directives).

To avoid static linking namespace issues and including all vtable
referenced objects, all required function pointers are set to weak alias.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Diffstat (limited to 'libio/libioP.h')
-rw-r--r--libio/libioP.h136
1 files changed, 109 insertions, 27 deletions
diff --git a/libio/libioP.h b/libio/libioP.h
index 80941b763f..d777553cb0 100644
--- a/libio/libioP.h
+++ b/libio/libioP.h
@@ -469,19 +469,68 @@ extern int _IO_default_sync (FILE *) __THROW;
 extern int _IO_default_showmanyc (FILE *) __THROW;
 extern void _IO_default_imbue (FILE *, void *) __THROW;
 
-extern const struct _IO_jump_t _IO_file_jumps;
-libc_hidden_proto (_IO_file_jumps)
-extern const struct _IO_jump_t _IO_file_jumps_mmap attribute_hidden;
-extern const struct _IO_jump_t _IO_file_jumps_maybe_mmap attribute_hidden;
-extern const struct _IO_jump_t _IO_wfile_jumps;
-libc_hidden_proto (_IO_wfile_jumps)
-extern const struct _IO_jump_t _IO_wfile_jumps_mmap attribute_hidden;
-extern const struct _IO_jump_t _IO_wfile_jumps_maybe_mmap attribute_hidden;
-extern const struct _IO_jump_t _IO_old_file_jumps attribute_hidden;
-extern const struct _IO_jump_t _IO_streambuf_jumps;
-extern const struct _IO_jump_t _IO_old_proc_jumps attribute_hidden;
-extern const struct _IO_jump_t _IO_str_jumps attribute_hidden;
-extern const struct _IO_jump_t _IO_wstr_jumps attribute_hidden;
+extern int __printf_buffer_as_file_overflow (FILE *fp, int ch);
+extern size_t __printf_buffer_as_file_xsputn (FILE *fp, const void *buf,
+					      size_t len);
+extern wint_t __wprintf_buffer_as_file_overflow (FILE *fp, int ch);
+extern size_t __wprintf_buffer_as_file_xsputn (FILE *fp, const void *buf,
+					       size_t len);
+
+enum
+{
+  IO_STR_JUMPS                    = 0,
+  IO_WSTR_JUMPS                   = 1,
+  IO_FILE_JUMPS                   = 2,
+  IO_FILE_JUMPS_MMAP              = 3,
+  IO_FILE_JUMPS_MAYBE_MMAP        = 4,
+  IO_WFILE_JUMPS                  = 5,
+  IO_WFILE_JUMPS_MMAP             = 6,
+  IO_WFILE_JUMPS_MAYBE_MMAP       = 7,
+  IO_COOKIE_JUMPS                 = 8,
+  IO_PROC_JUMPS                   = 9,
+  IO_MEM_JUMPS                    = 10,
+  IO_WMEM_JUMPS                   = 11,
+  IO_PRINTF_BUFFER_AS_FILE_JUMPS  = 12,
+  IO_WPRINTF_BUFFER_AS_FILE_JUMPS = 13,
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+  IO_OLD_FILE_JUMPS               = 14,
+  IO_OLD_PROC_JUMPS               = 15,
+  IO_OLD_COOKIED_JUMPS            = 16,
+  IO_VTABLES_NUM		  = IO_OLD_COOKIED_JUMPS + 1,
+#elif SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+  IO_OLD_COOKIED_JUMPS            = 14,
+  IO_VTABLES_NUM		  = IO_OLD_COOKIED_JUMPS + 1,
+#else
+  IO_VTABLES_NUM		  = IO_WPRINTF_BUFFER_AS_FILE_JUMPS + 1
+#endif
+};
+#define IO_VTABLES_LEN (IO_VTABLES_NUM * sizeof (struct _IO_jump_t))
+
+extern const struct _IO_jump_t __io_vtables[] attribute_hidden;
+#define _IO_str_jumps                    (__io_vtables[IO_STR_JUMPS])
+#define _IO_wstr_jumps                   (__io_vtables[IO_WSTR_JUMPS])
+#define _IO_file_jumps                   (__io_vtables[IO_FILE_JUMPS])
+#define _IO_file_jumps_mmap              (__io_vtables[IO_FILE_JUMPS_MMAP])
+#define _IO_file_jumps_maybe_mmap        (__io_vtables[IO_FILE_JUMPS_MAYBE_MMAP])
+#define _IO_wfile_jumps                  (__io_vtables[IO_WFILE_JUMPS])
+#define _IO_wfile_jumps_mmap             (__io_vtables[IO_WFILE_JUMPS_MMAP])
+#define _IO_wfile_jumps_maybe_mmap       (__io_vtables[IO_WFILE_JUMPS_MAYBE_MMAP])
+#define _IO_cookie_jumps                 (__io_vtables[IO_COOKIE_JUMPS])
+#define _IO_proc_jumps                   (__io_vtables[IO_PROC_JUMPS])
+#define _IO_mem_jumps                    (__io_vtables[IO_MEM_JUMPS])
+#define _IO_wmem_jumps                   (__io_vtables[IO_WMEM_JUMPS])
+#define _IO_printf_buffer_as_file_jumps  (__io_vtables[IO_PRINTF_BUFFER_AS_FILE_JUMPS])
+#define _IO_wprintf_buffer_as_file_jumps (__io_vtables[IO_WPRINTF_BUFFER_AS_FILE_JUMPS])
+#define _IO_old_file_jumps               (__io_vtables[IO_OLD_FILE_JUMPS])
+#define _IO_old_proc_jumps               (__io_vtables[IO_OLD_PROC_JUMPS])
+#define _IO_old_cookie_jumps             (__io_vtables[IO_OLD_COOKIED_JUMPS])
+
+#ifdef SHARED
+# define libio_static_fn_required(name)
+#else
+# define libio_static_fn_required(name) __asm (".globl " #name);
+#endif
+
 extern int _IO_do_write (FILE *, const char *, size_t);
 libc_hidden_proto (_IO_do_write)
 extern int _IO_new_do_write (FILE *, const char *, size_t);
@@ -593,6 +642,14 @@ extern void _IO_new_file_init_internal (struct _IO_FILE_plus *)
 extern FILE* _IO_new_file_setbuf (FILE *, char *, ssize_t);
 extern FILE* _IO_file_setbuf_mmap (FILE *, char *, ssize_t);
 extern int _IO_new_file_sync (FILE *);
+extern int _IO_file_sync_mmap (FILE *) attribute_hidden;
+extern size_t  _IO_file_xsgetn_maybe_mmap (FILE *fp, void *data, size_t n)
+  attribute_hidden;
+extern size_t _IO_file_xsgetn_mmap (FILE *fp, void *data, size_t n)
+  attribute_hidden;
+extern off64_t _IO_file_seekoff_maybe_mmap (FILE *fp, off64_t offset, int dir,
+					    int mode)
+     attribute_hidden;
 extern int _IO_new_file_underflow (FILE *);
 extern int _IO_new_file_overflow (FILE *, int);
 extern off64_t _IO_new_file_seekoff (FILE *, off64_t, int, int);
@@ -625,6 +682,10 @@ extern wint_t _IO_wfile_overflow (FILE *, wint_t);
 libc_hidden_proto (_IO_wfile_overflow)
 extern off64_t _IO_wfile_seekoff (FILE *, off64_t, int, int);
 libc_hidden_proto (_IO_wfile_seekoff)
+extern wint_t _IO_wfile_underflow_maybe_mmap (FILE *fp)
+     attribute_hidden;
+extern wint_t _IO_wfile_underflow_mmap (FILE *fp)
+     attribute_hidden;
 
 /* Jumptable functions for proc_files. */
 extern FILE* _IO_proc_open (FILE *, const char *, const char *)
@@ -643,13 +704,41 @@ extern int _IO_str_overflow (FILE *, int) __THROW;
 libc_hidden_proto (_IO_str_overflow)
 extern int _IO_str_pbackfail (FILE *, int) __THROW;
 libc_hidden_proto (_IO_str_pbackfail)
-extern off64_t _IO_str_seekoff (FILE *, off64_t, int, int) __THROW;
+extern off64_t _IO_str_seekoff (FILE *, off64_t, int, int) __THROW
+ ;
 libc_hidden_proto (_IO_str_seekoff)
 extern void _IO_str_finish (FILE *, int) __THROW;
+extern int _IO_str_chk_overflow (FILE *fp, int c) __THROW
+  attribute_hidden;
+
+/* Jumptable functions for fopencookie.  */
+extern ssize_t _IO_cookie_read (FILE *fp, void *buf, ssize_t size)
+  attribute_hidden;
+extern ssize_t _IO_cookie_write (FILE *fp, const void *buf, ssize_t size)
+  attribute_hidden;
+extern off64_t _IO_cookie_seek (FILE *fp, off64_t offset, int dir)
+  attribute_hidden;
+extern int _IO_cookie_close (FILE *fp) attribute_hidden;
+extern off64_t _IO_cookie_seekoff (FILE *fp, off64_t offset, int dir, int mode)
+  attribute_hidden;
+extern off64_t _IO_old_cookie_seek (FILE *fp, off64_t offset, int dir)
+  attribute_hidden;
+
+/* Jumptable functions for obstack.  */
+extern int __IO_obstack_overflow (FILE *fp, int c) attribute_hidden;
+extern size_t __IO_obstack_xsputn (FILE *fp, const void *data, size_t n)
+  attribute_hidden;
+
+/* Jumptable functions for open_{w}memstream.  */
+extern int _IO_mem_sync (FILE* fp) __THROW attribute_hidden;
+extern void _IO_mem_finish (FILE* fp, int) __THROW attribute_hidden;
+extern int _IO_wmem_sync (FILE* fp) __THROW attribute_hidden;
+extern void _IO_wmem_finish (FILE* fp, int) __THROW attribute_hidden;
 
 /* Other strfile functions */
 struct _IO_strfile_;
 extern ssize_t _IO_str_count (FILE *) __THROW;
+extern int _IO_strn_overflow (FILE *fp, int c) __THROW attribute_hidden;
 
 /* And the wide character versions.  */
 extern void _IO_wstr_init_static (FILE *, wchar_t *, size_t, wchar_t *)
@@ -662,6 +751,10 @@ extern off64_t _IO_wstr_seekoff (FILE *, off64_t, int, int)
 extern wint_t _IO_wstr_pbackfail (FILE *, wint_t) __THROW;
 extern void _IO_wstr_finish (FILE *, int) __THROW;
 
+/* Helper functions.  */
+int _IO_helper_overflow (FILE *s, int c);
+int _IO_whelper_overflow (FILE *s, int c);
+
 /* Internal versions of v*printf that take an additional flags
    parameter.  */
 extern int __vfprintf_internal (FILE *fp, const char *format, va_list ap,
@@ -895,14 +988,6 @@ _IO_acquire_lock_fct (FILE **p)
   } while (0)
 #endif
 
-/* Collect all vtables in a special section for vtable verification.
-   These symbols cover the extent of this section.  */
-symbol_set_declare (__libc_IO_vtables)
-
-/* libio vtables need to carry this attribute so that they pass
-   validation.  */
-#define libio_vtable __attribute__ ((section ("__libc_IO_vtables")))
-
 #ifdef SHARED
 /* If equal to &_IO_vtable_check (with pointer guard protection),
    unknown vtable pointers are valid.  This function pointer is solely
@@ -937,12 +1022,9 @@ void _IO_vtable_check (void) attribute_hidden;
 static inline const struct _IO_jump_t *
 IO_validate_vtable (const struct _IO_jump_t *vtable)
 {
-  /* Fast path: The vtable pointer is within the __libc_IO_vtables
-     section.  */
-  uintptr_t section_length = __stop___libc_IO_vtables - __start___libc_IO_vtables;
   uintptr_t ptr = (uintptr_t) vtable;
-  uintptr_t offset = ptr - (uintptr_t) __start___libc_IO_vtables;
-  if (__glibc_unlikely (offset >= section_length))
+  uintptr_t offset = ptr - (uintptr_t) &__io_vtables;
+  if (__glibc_unlikely (offset >= IO_VTABLES_LEN))
     /* The vtable pointer is not in the expected section.  Use the
        slow path, which will terminate the process if necessary.  */
     _IO_vtable_check ();