From e69dcccbcb53b2c0f3fbe3f6c3e04aadae7e9265 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Mon, 18 May 2015 13:58:54 +0200 Subject: Avoid some aliasing violations in libio --- ChangeLog | 18 ++++++++++++++++++ libio/fileops.c | 18 +++++++++--------- libio/freopen.c | 4 ++-- libio/freopen64.c | 2 +- libio/iofopen.c | 4 ++-- libio/iofopncook.c | 2 +- libio/iofwide.c | 2 +- libio/libioP.h | 23 +++++++++++++++++++---- libio/memstream.c | 2 +- libio/oldiofdopen.c | 2 +- libio/oldiofopen.c | 2 +- libio/oldiopopen.c | 2 +- 12 files changed, 57 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index ba7a400e53..27267b1f22 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2015-05-18 Florian Weimer + + * 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 * sysdeps/ieee754/dbl-64/e_lgamma_r.c: Include . diff --git a/libio/fileops.c b/libio/fileops.c index 2427320325..966802443c 100644 --- a/libio/fileops.c +++ b/libio/fileops.c @@ -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; } diff --git a/libio/freopen.c b/libio/freopen.c index 91cde193ee..035fa1fa79 100644 --- a/libio/freopen.c +++ b/libio/freopen.c @@ -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); diff --git a/libio/freopen64.c b/libio/freopen64.c index 77c83cf128..fc6ccb12f0 100644 --- a/libio/freopen64.c +++ b/libio/freopen64.c @@ -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); diff --git a/libio/iofopen.c b/libio/iofopen.c index c427ffb2d1..be2bbb663b 100644 --- a/libio/iofopen.c +++ b/libio/iofopen.c @@ -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 diff --git a/libio/iofopncook.c b/libio/iofopncook.c index 54ae4138c9..b845d29657 100644 --- a/libio/iofopncook.c +++ b/libio/iofopncook.c @@ -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; } diff --git a/libio/iofwide.c b/libio/iofwide.c index a8969e58c7..0c175d19d1 100644 --- a/libio/iofwide.c +++ b/libio/iofwide.c @@ -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. */ diff --git a/libio/libioP.h b/libio/libioP.h index d8604ca21d..784a47b743 100644 --- a/libio/libioP.h +++ b/libio/libioP.h @@ -32,6 +32,8 @@ FIXME: All of the C++ cruft eventually needs to go away. */ +#include + #include #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) diff --git a/libio/memstream.c b/libio/memstream.c index e1c543404b..81bfe6dd67 100644 --- a/libio/memstream.c +++ b/libio/memstream.c @@ -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; diff --git a/libio/oldiofdopen.c b/libio/oldiofdopen.c index e0d5354bd1..e068ec70fc 100644 --- a/libio/oldiofdopen.c +++ b/libio/oldiofdopen.c @@ -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; diff --git a/libio/oldiofopen.c b/libio/oldiofopen.c index dac424ac53..a90a60168b 100644 --- a/libio/oldiofopen.c +++ b/libio/oldiofopen.c @@ -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; diff --git a/libio/oldiopopen.c b/libio/oldiopopen.c index f6bcf5df4b..fb4c7b8597 100644 --- a/libio/oldiopopen.c +++ b/libio/oldiopopen.c @@ -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; -- cgit v1.2.3