Avoid some aliasing violations in libio
authorFlorian Weimer <fweimer@redhat.com>
Mon, 18 May 2015 11:58:54 +0000 (13:58 +0200)
committerFlorian Weimer <fweimer@redhat.com>
Fri, 22 May 2015 09:40:04 +0000 (11:40 +0200)
12 files changed:
ChangeLog
libio/fileops.c
libio/freopen.c
libio/freopen64.c
libio/iofopen.c
libio/iofopncook.c
libio/iofwide.c
libio/libioP.h
libio/memstream.c
libio/oldiofdopen.c
libio/oldiofopen.c
libio/oldiopopen.c

index ba7a400..27267b1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2015-05-18  Florian Weimer  <fweimer@redhat.com>
+
+       * libio/libioP.h (_IO_MEMBER_TYPE, _IO_CAST_FIELD_ACCESS)
+       (_IO_JUMPS_FILE_plus): New.
+       (_IO_WIDE_JUMPS, _IO_CHECK_WIDE, _IO_JUMPS_FUNC): Use
+       _IO_CAST_FIELD_ACCESS.
+       * libio/fileops.c (libc_hidden_def, _IO_file_setbuf_mmap,
+       mmap_remap_check, decide_maybe_mmap): Use _IO_JUMPS_FILE_plus.
+       * libio/freopen.c (freopen): Likewise.
+       * libio/freopen64.c (freopen64): Likewise.
+       * libio/iofopen.c (__fopen_maybe_mmap): Likewise.
+       * libio/iofopncook.c (_IO_old_fopencookie): Likewise.
+       * libio/iofwide.c (_IO_fwide): Likewise.
+       * libio/memstream.c (open_memstream): Likewise.
+       * libio/oldiofdopen.c (_IO_old_fdopen): Likewise.
+       * libio/oldiofopen.c (_IO_old_fopen): Likewise.
+       * libio/oldiopopen.c (_IO_old_popen): Likewise.
+
 2015-05-21  Joseph Myers  <joseph@codesourcery.com>
 
        * sysdeps/ieee754/dbl-64/e_lgamma_r.c: Include <libc-internal.h>.
index 2427320..9668024 100644 (file)
@@ -414,7 +414,7 @@ _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode,
            &result->_wide_data->_IO_state;
 
          /* From now on use the wide character callback functions.  */
-         ((struct _IO_FILE_plus *) fp)->vtable = fp->_wide_data->_wide_vtable;
+         _IO_JUMPS_FILE_plus (fp) = fp->_wide_data->_wide_vtable;
 
          /* Set the mode now.  */
          result->_mode = 1;
@@ -466,7 +466,7 @@ _IO_file_setbuf_mmap (_IO_FILE *fp, char *p, _IO_ssize_t len)
   _IO_FILE *result;
 
   /* Change the function table.  */
-  _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
+  _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
   fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
 
   /* And perform the normal operation.  */
@@ -475,7 +475,7 @@ _IO_file_setbuf_mmap (_IO_FILE *fp, char *p, _IO_ssize_t len)
   /* If the call failed, restore to using mmap.  */
   if (result == NULL)
     {
-      _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_mmap;
+      _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps_mmap;
       fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
     }
 
@@ -703,9 +703,9 @@ mmap_remap_check (_IO_FILE *fp)
       fp->_IO_buf_base = fp->_IO_buf_end = NULL;
       _IO_setg (fp, NULL, NULL, NULL);
       if (fp->_mode <= 0)
-       _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
+       _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
       else
-       _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps;
+       _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps;
       fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
 
       return 1;
@@ -773,9 +773,9 @@ decide_maybe_mmap (_IO_FILE *fp)
              fp->_offset = st.st_size;
 
              if (fp->_mode <= 0)
-               _IO_JUMPS ((struct _IO_FILE_plus *)fp) = &_IO_file_jumps_mmap;
+               _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps_mmap;
              else
-               _IO_JUMPS ((struct _IO_FILE_plus *)fp) = &_IO_wfile_jumps_mmap;
+               _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps_mmap;
              fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
 
              return;
@@ -786,9 +786,9 @@ decide_maybe_mmap (_IO_FILE *fp)
   /* We couldn't use mmap, so revert to the vanilla file operations.  */
 
   if (fp->_mode <= 0)
-    _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
+    _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
   else
-    _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps;
+    _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps;
   fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
 }
 
index 91cde19..035fa1f 100644 (file)
@@ -59,14 +59,14 @@ freopen (filename, mode, fp)
         to the old libio may be passed into shared C library and wind
         up here. */
       _IO_old_file_close_it (fp);
-      _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_old_file_jumps;
+      _IO_JUMPS_FILE_plus (fp) = &_IO_old_file_jumps;
       result = _IO_old_file_fopen (fp, gfilename, mode);
     }
   else
 #endif
     {
       _IO_file_close_it (fp);
-      _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
+      _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
       if (_IO_vtable_offset (fp) == 0 && fp->_wide_data != NULL)
        fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
       result = _IO_file_fopen (fp, gfilename, mode, 1);
index 77c83cf..fc6ccb1 100644 (file)
@@ -50,7 +50,7 @@ freopen64 (filename, mode, fp)
                           ? fd_to_filename (fd) : filename);
   fp->_flags2 |= _IO_FLAGS2_NOCLOSE;
   _IO_file_close_it (fp);
-  _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps;
+  _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
   if (_IO_vtable_offset (fp) == 0 && fp->_wide_data != NULL)
     fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
   result = _IO_file_fopen (fp, gfilename, mode, 0);
index c427ffb..be2bbb6 100644 (file)
@@ -46,9 +46,9 @@ __fopen_maybe_mmap (_IO_FILE *fp)
         vanilla file operations and reset the jump table accordingly.  */
 
       if (fp->_mode <= 0)
-       _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_maybe_mmap;
+       _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps_maybe_mmap;
       else
-       _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps_maybe_mmap;
+       _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps_maybe_mmap;
       fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_maybe_mmap;
     }
 #endif
index 54ae413..b845d29 100644 (file)
@@ -269,7 +269,7 @@ _IO_old_fopencookie (cookie, mode, io_functions)
 
   ret = _IO_fopencookie (cookie, mode, io_functions);
   if (ret != NULL)
-    _IO_JUMPS ((struct _IO_FILE_plus *) ret) = &_IO_old_cookie_jumps;
+    _IO_JUMPS_FILE_plus (ret) = &_IO_old_cookie_jumps;
 
   return ret;
 }
index a8969e5..0c175d1 100644 (file)
@@ -184,7 +184,7 @@ _IO_fwide (fp, mode)
 #endif
 
       /* From now on use the wide character callback functions.  */
-      ((struct _IO_FILE_plus *) fp)->vtable = fp->_wide_data->_wide_vtable;
+      _IO_JUMPS_FILE_plus (fp) = fp->_wide_data->_wide_vtable;
     }
 
   /* Set the mode now.  */
index d8604ca..784a47b 100644 (file)
@@ -32,6 +32,8 @@
 
    FIXME: All of the C++ cruft eventually needs to go away.  */
 
+#include <stddef.h>
+
 #include <errno.h>
 #ifndef __set_errno
 # define __set_errno(Val) errno = (Val)
@@ -104,17 +106,30 @@ extern "C" {
 # define _IO_JUMPS_OFFSET 0
 #endif
 
+/* Type of MEMBER in struct type TYPE.  */
+#define _IO_MEMBER_TYPE(TYPE, MEMBER) __typeof__ (((TYPE){}).MEMBER)
+
+/* Essentially ((TYPE *) THIS)->MEMBER, but avoiding the aliasing
+   violation in case THIS has a different pointer type.  */
+#define _IO_CAST_FIELD_ACCESS(THIS, TYPE, MEMBER) \
+  (*(_IO_MEMBER_TYPE (TYPE, MEMBER) *)(((char *) (THIS)) \
+  + offsetof(TYPE, MEMBER)))
+
 #define _IO_JUMPS(THIS) (THIS)->vtable
-#define _IO_WIDE_JUMPS(THIS) ((struct _IO_FILE *) (THIS))->_wide_data->_wide_vtable
-#define _IO_CHECK_WIDE(THIS) (((struct _IO_FILE *) (THIS))->_wide_data != NULL)
+#define _IO_JUMPS_FILE_plus(THIS) \
+  _IO_CAST_FIELD_ACCESS ((THIS), struct _IO_FILE_plus, vtable)
+#define _IO_WIDE_JUMPS(THIS) \
+  _IO_CAST_FIELD_ACCESS ((THIS), struct _IO_FILE, _wide_data)->_wide_vtable
+#define _IO_CHECK_WIDE(THIS) \
+  (_IO_CAST_FIELD_ACCESS ((THIS), struct _IO_FILE, _wide_data) != NULL)
 
 #if _IO_JUMPS_OFFSET
 # define _IO_JUMPS_FUNC(THIS) \
- (*(struct _IO_jump_t **) ((void *) &_IO_JUMPS ((struct _IO_FILE_plus *) (THIS)) \
+ (*(struct _IO_jump_t **) ((void *) &_IO_JUMPS_FILE_plus (THIS) \
                           + (THIS)->_vtable_offset))
 # define _IO_vtable_offset(THIS) (THIS)->_vtable_offset
 #else
-# define _IO_JUMPS_FUNC(THIS) _IO_JUMPS ((struct _IO_FILE_plus *) (THIS))
+# define _IO_JUMPS_FUNC(THIS) _IO_JUMPS_FILE_plus (THIS)
 # define _IO_vtable_offset(THIS) 0
 #endif
 #define _IO_WIDE_JUMPS_FUNC(THIS) _IO_WIDE_JUMPS(THIS)
index e1c5434..81bfe6d 100644 (file)
@@ -89,7 +89,7 @@ open_memstream (bufloc, sizeloc)
       return NULL;
     }
   _IO_init (&new_f->fp._sf._sbf._f, 0);
-  _IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fp._sf._sbf) = &_IO_mem_jumps;
+  _IO_JUMPS_FILE_plus (&new_f->fp._sf._sbf) = &_IO_mem_jumps;
   _IO_str_init_static_internal (&new_f->fp._sf, buf, _IO_BUFSIZ, buf);
   new_f->fp._sf._sbf._f._flags &= ~_IO_USER_BUF;
   new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc;
index e0d5354..e068ec7 100644 (file)
@@ -113,7 +113,7 @@ _IO_old_fdopen (fd, mode)
   new_f->fp.file._file._lock = &new_f->lock;
 #endif
   _IO_old_init (&new_f->fp.file._file, 0);
-  _IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fp) = &_IO_old_file_jumps;
+  _IO_JUMPS_FILE_plus (&new_f->fp) = &_IO_old_file_jumps;
   _IO_old_file_init ((struct _IO_FILE_plus *) &new_f->fp);
 #if  !_IO_UNIFIED_JUMPTABLES
   new_f->fp.vtable = NULL;
index dac424a..a90a601 100644 (file)
@@ -52,7 +52,7 @@ _IO_old_fopen (filename, mode)
   new_f->fp.file._file._lock = &new_f->lock;
 #endif
   _IO_old_init (&new_f->fp.file._file, 0);
-  _IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fp) = &_IO_old_file_jumps;
+  _IO_JUMPS_FILE_plus (&new_f->fp) = &_IO_old_file_jumps;
   _IO_old_file_init ((struct _IO_FILE_plus *) &new_f->fp);
 #if  !_IO_UNIFIED_JUMPTABLES
   new_f->fp.vtable = NULL;
index f6bcf5d..fb4c7b8 100644 (file)
@@ -215,7 +215,7 @@ _IO_old_popen (command, mode)
 #endif
   fp = &new_f->fpx.file.file._file;
   _IO_old_init (fp, 0);
-  _IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fpx.file) = &_IO_old_proc_jumps;
+  _IO_JUMPS_FILE_plus (&new_f->fpx.file) = &_IO_old_proc_jumps;
   _IO_old_file_init ((struct _IO_FILE_plus *) &new_f->fpx.file);
 #if  !_IO_UNIFIED_JUMPTABLES
   new_f->fpx.file.vtable = NULL;