diff options
author | Florian Weimer <fweimer@redhat.com> | 2019-05-20 21:54:57 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2019-05-20 21:54:57 +0200 |
commit | 09e1b0e3f6facc1af2dbcfef204f0aaa8718772b (patch) | |
tree | 18056a8f7177511eff47519d176c310901f5e455 /libio/wfileops.c | |
parent | 75c51570c710aa9c6df6b7a1e131392e1408c63f (diff) | |
download | glibc-09e1b0e3f6facc1af2dbcfef204f0aaa8718772b.tar glibc-09e1b0e3f6facc1af2dbcfef204f0aaa8718772b.tar.gz glibc-09e1b0e3f6facc1af2dbcfef204f0aaa8718772b.tar.bz2 glibc-09e1b0e3f6facc1af2dbcfef204f0aaa8718772b.zip |
libio: Remove codecvt vtable [BZ #24588]
The codecvt vtable is not a real vtable because it also contains the
conversion state data. Furthermore, wide stream support was added to
GCC 3.0, after a C++ ABI bump, so there is no compatibility
requirement with libstdc++.
This change removes several unmangled function pointers which could
be used with a corrupted FILE object to redirect execution. (libio
vtable verification did not cover the codecvt vtable.)
Reviewed-by: Yann Droneaud <ydroneaud@opteya.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Diffstat (limited to 'libio/wfileops.c')
-rw-r--r-- | libio/wfileops.c | 89 |
1 files changed, 44 insertions, 45 deletions
diff --git a/libio/wfileops.c b/libio/wfileops.c index 69fbb62a02..f1863db638 100644 --- a/libio/wfileops.c +++ b/libio/wfileops.c @@ -72,11 +72,11 @@ _IO_wdo_write (FILE *fp, const wchar_t *data, size_t to_do) } /* Now convert from the internal format into the external buffer. */ - result = (*cc->__codecvt_do_out) (cc, &fp->_wide_data->_IO_state, - data, data + to_do, &new_data, - write_ptr, - buf_end, - &write_ptr); + result = __libio_codecvt_out (cc, &fp->_wide_data->_IO_state, + data, data + to_do, &new_data, + write_ptr, + buf_end, + &write_ptr); /* Write out what we produced so far. */ if (_IO_new_do_write (fp, write_base, write_ptr - write_base) == EOF) @@ -140,12 +140,12 @@ _IO_wfile_underflow (FILE *fp) fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_buf_base; - status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, - fp->_IO_read_ptr, fp->_IO_read_end, - &read_stop, - fp->_wide_data->_IO_read_ptr, - fp->_wide_data->_IO_buf_end, - &fp->_wide_data->_IO_read_end); + status = __libio_codecvt_in (cd, &fp->_wide_data->_IO_state, + fp->_IO_read_ptr, fp->_IO_read_end, + &read_stop, + fp->_wide_data->_IO_read_ptr, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); fp->_IO_read_base = fp->_IO_read_ptr; fp->_IO_read_ptr = (char *) read_stop; @@ -266,11 +266,11 @@ _IO_wfile_underflow (FILE *fp) naccbuf += to_copy; from = accbuf; } - status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, - from, to, &read_ptr_copy, - fp->_wide_data->_IO_read_end, - fp->_wide_data->_IO_buf_end, - &fp->_wide_data->_IO_read_end); + status = __libio_codecvt_in (cd, &fp->_wide_data->_IO_state, + from, to, &read_ptr_copy, + fp->_wide_data->_IO_read_end, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); if (__glibc_unlikely (naccbuf != 0)) fp->_IO_read_ptr += MAX (0, read_ptr_copy - &accbuf[naccbuf - to_copy]); @@ -372,12 +372,12 @@ _IO_wfile_underflow_mmap (FILE *fp) fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_buf_base; - (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state, - fp->_IO_read_ptr, fp->_IO_read_end, - &read_stop, - fp->_wide_data->_IO_read_ptr, - fp->_wide_data->_IO_buf_end, - &fp->_wide_data->_IO_read_end); + __libio_codecvt_in (cd, &fp->_wide_data->_IO_state, + fp->_IO_read_ptr, fp->_IO_read_end, + &read_stop, + fp->_wide_data->_IO_read_ptr, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); fp->_IO_read_ptr = (char *) read_stop; @@ -495,7 +495,7 @@ _IO_wfile_sync (FILE *fp) struct _IO_codecvt *cv = fp->_codecvt; off64_t new_pos; - int clen = (*cv->__codecvt_do_encoding) (cv); + int clen = __libio_codecvt_encoding (cv); if (clen > 0) /* It is easy, a fixed number of input bytes are used for each @@ -511,9 +511,9 @@ _IO_wfile_sync (FILE *fp) size_t wnread = (fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_base); fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; - nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state, - fp->_IO_read_base, - fp->_IO_read_end, wnread); + nread = __libio_codecvt_length (cv, &fp->_wide_data->_IO_state, + fp->_IO_read_base, + fp->_IO_read_end, wnread); fp->_IO_read_ptr = fp->_IO_read_base + nread; delta = -(fp->_IO_read_end - fp->_IO_read_base - nread); } @@ -548,7 +548,7 @@ adjust_wide_data (FILE *fp, bool do_convert) { struct _IO_codecvt *cv = fp->_codecvt; - int clen = (*cv->__codecvt_do_encoding) (cv); + int clen = __libio_codecvt_encoding (cv); /* Take the easy way out for constant length encodings if we don't need to convert. */ @@ -565,12 +565,12 @@ adjust_wide_data (FILE *fp, bool do_convert) { fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state; - status = (*cv->__codecvt_do_in) (cv, &fp->_wide_data->_IO_state, - fp->_IO_read_base, fp->_IO_read_ptr, - &read_stop, - fp->_wide_data->_IO_read_base, - fp->_wide_data->_IO_buf_end, - &fp->_wide_data->_IO_read_end); + status = __libio_codecvt_in (cv, &fp->_wide_data->_IO_state, + fp->_IO_read_base, fp->_IO_read_ptr, + &read_stop, + fp->_wide_data->_IO_read_base, + fp->_wide_data->_IO_buf_end, + &fp->_wide_data->_IO_read_end); /* Should we return EILSEQ? */ if (__glibc_unlikely (status == __codecvt_error)) @@ -648,7 +648,7 @@ do_ftell_wide (FILE *fp) } struct _IO_codecvt *cv = fp->_codecvt; - int clen = (*cv->__codecvt_do_encoding) (cv); + int clen = __libio_codecvt_encoding (cv); if (!unflushed_writes) { @@ -663,9 +663,9 @@ do_ftell_wide (FILE *fp) size_t delta = wide_read_ptr - wide_read_base; __mbstate_t state = fp->_wide_data->_IO_last_state; - nread = (*cv->__codecvt_do_length) (cv, &state, - fp->_IO_read_base, - fp->_IO_read_end, delta); + nread = __libio_codecvt_length (cv, &state, + fp->_IO_read_base, + fp->_IO_read_end, delta); offset -= fp->_IO_read_end - fp->_IO_read_base - nread; } } @@ -688,9 +688,8 @@ do_ftell_wide (FILE *fp) enum __codecvt_result status; __mbstate_t state = fp->_wide_data->_IO_last_state; - status = (*cv->__codecvt_do_out) (cv, &state, - in, in + delta, &in, - out, out + outsize, &outstop); + status = __libio_codecvt_out (cv, &state, in, in + delta, &in, + out, out + outsize, &outstop); /* We don't check for __codecvt_partial because it can be returned on one of two conditions: either the output @@ -801,7 +800,7 @@ _IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode) find out which position in the external buffer corresponds to the current position in the internal buffer. */ cv = fp->_codecvt; - clen = (*cv->__codecvt_do_encoding) (cv); + clen = __libio_codecvt_encoding (cv); if (mode != 0 || !was_writing) { @@ -819,10 +818,10 @@ _IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode) delta = (fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_base); fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state; - nread = (*cv->__codecvt_do_length) (cv, - &fp->_wide_data->_IO_state, - fp->_IO_read_base, - fp->_IO_read_end, delta); + nread = __libio_codecvt_length (cv, + &fp->_wide_data->_IO_state, + fp->_IO_read_base, + fp->_IO_read_end, delta); fp->_IO_read_ptr = fp->_IO_read_base + nread; fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr; offset -= fp->_IO_read_end - fp->_IO_read_base - nread; |