aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2015-05-18 13:58:54 +0200
committerFlorian Weimer <fweimer@redhat.com>2015-05-22 11:40:04 +0200
commite69dcccbcb53b2c0f3fbe3f6c3e04aadae7e9265 (patch)
tree9f68baa8c17a343946e69357767909297843c5c1
parent9124ccf76abc5a2ffe4603e6424b1dc2b5a5db44 (diff)
downloadglibc-e69dcccbcb53b2c0f3fbe3f6c3e04aadae7e9265.zip
glibc-e69dcccbcb53b2c0f3fbe3f6c3e04aadae7e9265.tar.gz
glibc-e69dcccbcb53b2c0f3fbe3f6c3e04aadae7e9265.tar.bz2
Avoid some aliasing violations in libio
-rw-r--r--ChangeLog18
-rw-r--r--libio/fileops.c18
-rw-r--r--libio/freopen.c4
-rw-r--r--libio/freopen64.c2
-rw-r--r--libio/iofopen.c4
-rw-r--r--libio/iofopncook.c2
-rw-r--r--libio/iofwide.c2
-rw-r--r--libio/libioP.h23
-rw-r--r--libio/memstream.c2
-rw-r--r--libio/oldiofdopen.c2
-rw-r--r--libio/oldiofopen.c2
-rw-r--r--libio/oldiopopen.c2
12 files changed, 57 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index ba7a400..27267b1 100644
--- 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>.
diff --git a/libio/fileops.c b/libio/fileops.c
index 2427320..9668024 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 91cde19..035fa1f 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 77c83cf..fc6ccb1 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 c427ffb..be2bbb6 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 54ae413..b845d29 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 a8969e5..0c175d1 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 d8604ca..784a47b 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 <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)
diff --git a/libio/memstream.c b/libio/memstream.c
index e1c5434..81bfe6d 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 e0d5354..e068ec7 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 dac424a..a90a601 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 f6bcf5d..fb4c7b8 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;