* [PATCH] libio: do not cleanup wide buffers of legacy standard files [BZ #24228]
@ 2019-02-18 12:44 Dmitry V. Levin
2019-02-18 12:56 ` Florian Weimer
0 siblings, 1 reply; 20+ messages in thread
From: Dmitry V. Levin @ 2019-02-18 12:44 UTC (permalink / raw)
To: libc-alpha
Commit glibc-2.23~693 (a601b74d31ca086de38441d316a3dee24c866305)
introduced a regression: _IO_unbuffer_all() now invokes _IO_wsetb() to
free wide buffers of all files, including legacy standard files that
are small statically allocated objects that do not have wide buffers.
Fix this by skipping _IO_wsetb() invocation for legacy standard files.
[BZ #24228]
* libio/genops.c (_IO_unbuffer_all)
[SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)]: Skip _IO_wsetb() invocation
for legacy standard files.
---
ChangeLog | 7 +++++++
libio/genops.c | 7 +++++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/libio/genops.c b/libio/genops.c
index 2a0d9b81df..c53696f2e0 100644
--- a/libio/genops.c
+++ b/libio/genops.c
@@ -816,8 +816,11 @@ _IO_unbuffer_all (void)
_IO_SETBUF (fp, NULL, 0);
- if (fp->_mode > 0)
- _IO_wsetb (fp, NULL, NULL, 0);
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+ if (!_IO_legacy_file (fp))
+#endif
+ if (fp->_mode > 0)
+ _IO_wsetb (fp, NULL, NULL, 0);
#ifdef _IO_MTSAFE_IO
if (cnt < MAXTRIES && fp->_lock != NULL)
--
ldv
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH] libio: do not cleanup wide buffers of legacy standard files [BZ #24228]
2019-02-18 12:44 [PATCH] libio: do not cleanup wide buffers of legacy standard files [BZ #24228] Dmitry V. Levin
@ 2019-02-18 12:56 ` Florian Weimer
2019-02-18 19:10 ` Dmitry V. Levin
0 siblings, 1 reply; 20+ messages in thread
From: Florian Weimer @ 2019-02-18 12:56 UTC (permalink / raw)
To: Dmitry V. Levin; +Cc: libc-alpha
* Dmitry V. Levin:
> Commit glibc-2.23~693 (a601b74d31ca086de38441d316a3dee24c866305)
> introduced a regression: _IO_unbuffer_all() now invokes _IO_wsetb() to
> free wide buffers of all files, including legacy standard files that
> are small statically allocated objects that do not have wide buffers.
Maybe at “and the _mode member”?
Does the crash reproduce under mtrace? Then perhaps we can create a
test case by hiding the _IO_stdin_used symbol.
> diff --git a/libio/genops.c b/libio/genops.c
> index 2a0d9b81df..c53696f2e0 100644
> --- a/libio/genops.c
> +++ b/libio/genops.c
> @@ -816,8 +816,11 @@ _IO_unbuffer_all (void)
>
> _IO_SETBUF (fp, NULL, 0);
>
> - if (fp->_mode > 0)
> - _IO_wsetb (fp, NULL, NULL, 0);
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> + if (!_IO_legacy_file (fp))
> +#endif
> + if (fp->_mode > 0)
> + _IO_wsetb (fp, NULL, NULL, 0);
I can change my patch to always define _IO_legacy_file, for newer ABI
baselines as constantly return false.
Thanks,
Florian
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH] libio: do not cleanup wide buffers of legacy standard files [BZ #24228]
2019-02-18 12:56 ` Florian Weimer
@ 2019-02-18 19:10 ` Dmitry V. Levin
2019-02-18 21:38 ` [PATCH v2] " Dmitry V. Levin
2019-02-19 0:57 ` [PATCH] " Dmitry V. Levin
0 siblings, 2 replies; 20+ messages in thread
From: Dmitry V. Levin @ 2019-02-18 19:10 UTC (permalink / raw)
To: Florian Weimer; +Cc: libc-alpha
[-- Attachment #1: Type: text/plain, Size: 1806 bytes --]
On Mon, Feb 18, 2019 at 01:56:47PM +0100, Florian Weimer wrote:
> * Dmitry V. Levin:
>
> > Commit glibc-2.23~693 (a601b74d31ca086de38441d316a3dee24c866305)
> > introduced a regression: _IO_unbuffer_all() now invokes _IO_wsetb() to
> > free wide buffers of all files, including legacy standard files that
> > are small statically allocated objects that do not have wide buffers.
>
> Maybe at “and the _mode member”?
Yes, the _mode member is also not available.
> Does the crash reproduce under mtrace? Then perhaps we can create a
> test case by hiding the _IO_stdin_used symbol.
Yes and no. Apparently, this simple test crashes under mtrace:
$ cat tst-bz24228.c
#include <mcheck.h>
int main() { mtrace(); return 0; }
$ cat tst-bz24228.map
{ local: _IO_stdin_used; };
$ gcc -Wall -O2 -Wl,--version-script,tst-bz24228.map tst-bz24228.c
$ MALLOC_TRACE=/dev/null ./a.out
Segmentation fault
But the crash is caused by a different issue that arises when
_IO_stdin_used == NULL.
> > diff --git a/libio/genops.c b/libio/genops.c
> > index 2a0d9b81df..c53696f2e0 100644
> > --- a/libio/genops.c
> > +++ b/libio/genops.c
> > @@ -816,8 +816,11 @@ _IO_unbuffer_all (void)
> >
> > _IO_SETBUF (fp, NULL, 0);
> >
> > - if (fp->_mode > 0)
> > - _IO_wsetb (fp, NULL, NULL, 0);
> > +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> > + if (!_IO_legacy_file (fp))
> > +#endif
> > + if (fp->_mode > 0)
> > + _IO_wsetb (fp, NULL, NULL, 0);
Oops, this change makes misc/tst-error1-mem fail again for exactly
the same reason that led to commit glibc-2.23~693.
> I can change my patch to always define _IO_legacy_file, for newer ABI
> baselines as constantly return false.
Yes, that would be handy, but not necessary.
--
ldv
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v2] libio: do not cleanup wide buffers of legacy standard files [BZ #24228]
2019-02-18 19:10 ` Dmitry V. Levin
@ 2019-02-18 21:38 ` Dmitry V. Levin
2019-02-19 0:57 ` [PATCH] " Dmitry V. Levin
1 sibling, 0 replies; 20+ messages in thread
From: Dmitry V. Levin @ 2019-02-18 21:38 UTC (permalink / raw)
To: libc-alpha
Commit glibc-2.23~693 (a601b74d31ca086de38441d316a3dee24c866305)
introduced a regression: _IO_unbuffer_all() now invokes _IO_wsetb() to
free wide buffers of all files, including legacy standard files that
are small statically allocated objects that do not have wide buffers
and the _mode member.
Fix this by skipping _IO_wsetb() invocation for legacy standard files.
[BZ #24228]
* libio/genops.c (_IO_unbuffer_all)
[SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)]: Skip _IO_wsetb() invocation
for legacy standard files in compatibility mode.
---
ChangeLog | 7 +++++++
libio/genops.c | 7 +++++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/libio/genops.c b/libio/genops.c
index 2a0d9b81df..95d53595a2 100644
--- a/libio/genops.c
+++ b/libio/genops.c
@@ -816,8 +816,11 @@ _IO_unbuffer_all (void)
_IO_SETBUF (fp, NULL, 0);
- if (fp->_mode > 0)
- _IO_wsetb (fp, NULL, NULL, 0);
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+ if (__glibc_likely (&_IO_stdin_used != NULL) || !_IO_legacy_file (fp))
+#endif
+ if (fp->_mode > 0)
+ _IO_wsetb (fp, NULL, NULL, 0);
#ifdef _IO_MTSAFE_IO
if (cnt < MAXTRIES && fp->_lock != NULL)
--
ldv
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH] libio: do not cleanup wide buffers of legacy standard files [BZ #24228]
2019-02-18 19:10 ` Dmitry V. Levin
2019-02-18 21:38 ` [PATCH v2] " Dmitry V. Levin
@ 2019-02-19 0:57 ` Dmitry V. Levin
2019-02-19 1:29 ` [PATCH v3] libio: do not unbuffer legacy standard files in compatibility mode " Dmitry V. Levin
1 sibling, 1 reply; 20+ messages in thread
From: Dmitry V. Levin @ 2019-02-19 0:57 UTC (permalink / raw)
To: Florian Weimer; +Cc: libc-alpha
[-- Attachment #1: Type: text/plain, Size: 1256 bytes --]
On Mon, Feb 18, 2019 at 10:10:21PM +0300, Dmitry V. Levin wrote:
> On Mon, Feb 18, 2019 at 01:56:47PM +0100, Florian Weimer wrote:
> > * Dmitry V. Levin:
> >
> > > Commit glibc-2.23~693 (a601b74d31ca086de38441d316a3dee24c866305)
> > > introduced a regression: _IO_unbuffer_all() now invokes _IO_wsetb() to
> > > free wide buffers of all files, including legacy standard files that
> > > are small statically allocated objects that do not have wide buffers.
> >
> > Maybe at “and the _mode member”?
>
> Yes, the _mode member is also not available.
>
> > Does the crash reproduce under mtrace? Then perhaps we can create a
> > test case by hiding the _IO_stdin_used symbol.
>
> Yes and no. Apparently, this simple test crashes under mtrace:
>
> $ cat tst-bz24228.c
> #include <mcheck.h>
> int main() { mtrace(); return 0; }
> $ cat tst-bz24228.map
> { local: _IO_stdin_used; };
> $ gcc -Wall -O2 -Wl,--version-script,tst-bz24228.map tst-bz24228.c
> $ MALLOC_TRACE=/dev/null ./a.out
> Segmentation fault
This memory corruption is caused by "fp->_mode = -1;" statement in
_IO_unbuffer_all(). I think we should avoid touching legacy standard
files in compatibility mode. A fix with a test follows.
--
ldv
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v3] libio: do not unbuffer legacy standard files in compatibility mode [BZ #24228]
2019-02-19 0:57 ` [PATCH] " Dmitry V. Levin
@ 2019-02-19 1:29 ` Dmitry V. Levin
2019-03-13 15:08 ` Florian Weimer
2019-06-19 13:10 ` Florian Weimer
0 siblings, 2 replies; 20+ messages in thread
From: Dmitry V. Levin @ 2019-02-19 1:29 UTC (permalink / raw)
To: Florian Weimer; +Cc: libc-alpha
Commit glibc-2.23~693 (a601b74d31ca086de38441d316a3dee24c866305)
introduced a regression: _IO_unbuffer_all() now invokes _IO_wsetb() to
free wide buffers of all files, including legacy standard files which
are small statically allocated objects that do not have wide buffers
and the _mode member, causing memory corruption.
Another memory corruption in _IO_unbuffer_all() happens when -1
is assigned to the _mode member of legacy standard files that do not
have it.
Fix both issues by changing _IO_unbuffer_all() to skip legacy standard
files in compatibility mode.
[BZ #24228]
* libio/genops.c (_IO_unbuffer_all)
[SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)]: Skip legacy standard files
in compatibility mode.
* libio/tst-bz24228.c: New file.
* libio/tst-bz24228.map: Likewise.
* libio/Makefile (tests): Add tst-bz24228.
(generated): Add tst-bz24228.mtrace and tst-bz24228.check.
(tests-special): Add $(objpfx)tst-bz24228-mem.out.
(LDFLAGS-tst-bz24228, tst-bz24228-ENV): New variables.
($(objpfx)tst-bz24228-mem.out): New rule.
---
ChangeLog | 14 ++++++++++++++
libio/Makefile | 12 ++++++++++--
libio/genops.c | 4 ++++
libio/tst-bz24228.c | 30 ++++++++++++++++++++++++++++++
libio/tst-bz24228.map | 3 +++
5 files changed, 61 insertions(+), 2 deletions(-)
create mode 100644 libio/tst-bz24228.c
create mode 100644 libio/tst-bz24228.map
diff --git a/libio/Makefile b/libio/Makefile
index 95b91084dd..d6cabe5ef3 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -65,7 +65,7 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \
tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \
tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof \
- tst-sprintf-ub tst-sprintf-chk-ub tst-bz24051 tst-bz24153
+ tst-sprintf-ub tst-sprintf-chk-ub tst-bz24051 tst-bz24153 tst-bz24228
tests-internal = tst-vtables tst-vtables-interposed tst-readline
@@ -157,15 +157,19 @@ CFLAGS-tst_putwc.c += -DOBJPFX=\"$(objpfx)\"
CFLAGS-tst-sprintf-ub.c += -Wno-restrict
CFLAGS-tst-sprintf-chk-ub.c += -Wno-restrict
+LDFLAGS-tst-bz24228 = -Wl,--version-script=tst-bz24228.map
+
tst_wprintf2-ARGS = "Some Text"
test-fmemopen-ENV = MALLOC_TRACE=$(objpfx)test-fmemopen.mtrace
tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace
tst-bz22415-ENV = MALLOC_TRACE=$(objpfx)tst-bz22415.mtrace
+tst-bz24228-ENV = MALLOC_TRACE=$(objpfx)tst-bz24228.mtrace
generated += test-fmemopen.mtrace test-fmemopen.check
generated += tst-fopenloc.mtrace tst-fopenloc.check
generated += tst-bz22415.mtrace tst-bz22415.check
+generated += tst-bz24228.mtrace tst-bz24228.check
aux := fileops genops stdfiles stdio strops
@@ -180,7 +184,7 @@ shared-only-routines = oldiofopen oldiofdopen oldiofclose oldfileops \
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)test-freopen.out $(objpfx)test-fmemopen-mem.out \
- $(objpfx)tst-bz22415-mem.out
+ $(objpfx)tst-bz22415-mem.out $(objpfx)tst-bz24228-mem.out
ifeq (yes,$(build-shared))
# Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared
# library is enabled since they depend on tst-fopenloc.out.
@@ -235,3 +239,7 @@ $(objpfx)tst-fopenloc-mem.out: $(objpfx)tst-fopenloc.out
$(objpfx)tst-bz22415-mem.out: $(objpfx)tst-bz22415.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-bz22415.mtrace > $@; \
$(evaluate-test)
+
+$(objpfx)tst-bz24228-mem.out: $(objpfx)tst-bz24228.out
+ $(common-objpfx)malloc/mtrace $(objpfx)tst-bz24228.mtrace > $@; \
+ $(evaluate-test)
diff --git a/libio/genops.c b/libio/genops.c
index 2a0d9b81df..aa92d61b6b 100644
--- a/libio/genops.c
+++ b/libio/genops.c
@@ -789,6 +789,10 @@ _IO_unbuffer_all (void)
for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
{
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+ if (__glibc_unlikely (&_IO_stdin_used == NULL) && _IO_legacy_file (fp))
+ continue;
+#endif
if (! (fp->_flags & _IO_UNBUFFERED)
/* Iff stream is un-orientated, it wasn't used. */
&& fp->_mode != 0)
diff --git a/libio/tst-bz24228.c b/libio/tst-bz24228.c
new file mode 100644
index 0000000000..3692f14b71
--- /dev/null
+++ b/libio/tst-bz24228.c
@@ -0,0 +1,30 @@
+/* BZ #24228 check for memory corruption in legacy libio
+
+ Copyright (C) 2019 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <mcheck.h>
+#include <support/test-driver.h>
+
+static int
+do_test (void)
+{
+ mtrace ();
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/libio/tst-bz24228.map b/libio/tst-bz24228.map
new file mode 100644
index 0000000000..ecb8c058f5
--- /dev/null
+++ b/libio/tst-bz24228.map
@@ -0,0 +1,3 @@
+{
+ local: _IO_stdin_used;
+};
--
ldv
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v3] libio: do not unbuffer legacy standard files in compatibility mode [BZ #24228]
2019-02-19 1:29 ` [PATCH v3] libio: do not unbuffer legacy standard files in compatibility mode " Dmitry V. Levin
@ 2019-03-13 15:08 ` Florian Weimer
2019-03-13 15:46 ` Dmitry V. Levin
2019-06-19 13:10 ` Florian Weimer
1 sibling, 1 reply; 20+ messages in thread
From: Florian Weimer @ 2019-03-13 15:08 UTC (permalink / raw)
To: Dmitry V. Levin; +Cc: libc-alpha
* Dmitry V. Levin:
> Commit glibc-2.23~693 (a601b74d31ca086de38441d316a3dee24c866305)
Please quote the commit hash and commit subject, kernel-style. (How did
you determine this reference, anyway?)
> diff --git a/libio/genops.c b/libio/genops.c
> index 2a0d9b81df..aa92d61b6b 100644
> --- a/libio/genops.c
> +++ b/libio/genops.c
> @@ -789,6 +789,10 @@ _IO_unbuffer_all (void)
>
> for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
> {
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> + if (__glibc_unlikely (&_IO_stdin_used == NULL) && _IO_legacy_file (fp))
> + continue;
> +#endif
I wonder if we should check _IO_legacy_file only here. This is related
to the previous discussion.
> diff --git a/libio/tst-bz24228.c b/libio/tst-bz24228.c
> new file mode 100644
> index 0000000000..3692f14b71
> --- /dev/null
> +++ b/libio/tst-bz24228.c
> @@ -0,0 +1,30 @@
> +/* BZ #24228 check for memory corruption in legacy libio
> +
> + Copyright (C) 2019 Free Software Foundation, Inc.
> + This file is part of the GNU C Library.
We do not generally have a blank line for the “Copyright” line, I think.
> +#include <mcheck.h>
> +#include <support/test-driver.h>
> +
> +static int
> +do_test (void)
> +{
> + mtrace ();
> + return 0;
> +}
> +
> +#include <support/test-driver.c>
> diff --git a/libio/tst-bz24228.map b/libio/tst-bz24228.map
> new file mode 100644
> index 0000000000..ecb8c058f5
> --- /dev/null
> +++ b/libio/tst-bz24228.map
> @@ -0,0 +1,3 @@
> +{
> + local: _IO_stdin_used;
> +};
Please add a comment to the file why you are doing this, something like
“hide the symbol from libc.so.6 to switch to the libio/oldfileops.c
implementation (if it is available for the architecture)”.
Thanks,
Florian
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3] libio: do not unbuffer legacy standard files in compatibility mode [BZ #24228]
2019-03-13 15:08 ` Florian Weimer
@ 2019-03-13 15:46 ` Dmitry V. Levin
2019-03-13 15:49 ` Florian Weimer
0 siblings, 1 reply; 20+ messages in thread
From: Dmitry V. Levin @ 2019-03-13 15:46 UTC (permalink / raw)
To: Florian Weimer; +Cc: libc-alpha
[-- Attachment #1: Type: text/plain, Size: 2584 bytes --]
On Wed, Mar 13, 2019 at 04:08:16PM +0100, Florian Weimer wrote:
> * Dmitry V. Levin:
>
> > Commit glibc-2.23~693 (a601b74d31ca086de38441d316a3dee24c866305)
>
> Please quote the commit hash and commit subject, kernel-style.
The kernel-style reference would look this way:
Commit a601b74d31ca ("In preparation for fixing BZ#16734, fix failure in
misc/tst-error1-mem when _G_HAVE_MMAP is turned off.")
I'd like to add a reference to glibc-2.23~693 somewhere because
I find it useful, but I don't see any suitable place for it
in this long kernel-style form.
> (How did you determine this reference, anyway?)
Sorry?
> > diff --git a/libio/genops.c b/libio/genops.c
> > index 2a0d9b81df..aa92d61b6b 100644
> > --- a/libio/genops.c
> > +++ b/libio/genops.c
> > @@ -789,6 +789,10 @@ _IO_unbuffer_all (void)
> >
> > for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
> > {
> > +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> > + if (__glibc_unlikely (&_IO_stdin_used == NULL) && _IO_legacy_file (fp))
> > + continue;
> > +#endif
>
> I wonder if we should check _IO_legacy_file only here. This is related
> to the previous discussion.
If we omitted the check for _IO_stdin_used, then standard files
would be skipped and misc/tst-error1-mem would complain.
> > diff --git a/libio/tst-bz24228.c b/libio/tst-bz24228.c
> > new file mode 100644
> > index 0000000000..3692f14b71
> > --- /dev/null
> > +++ b/libio/tst-bz24228.c
> > @@ -0,0 +1,30 @@
> > +/* BZ #24228 check for memory corruption in legacy libio
> > +
> > + Copyright (C) 2019 Free Software Foundation, Inc.
> > + This file is part of the GNU C Library.
>
> We do not generally have a blank line for the “Copyright” line, I think.
No problem, I can remove it.
I don't think we are quite consistent about it, though.
> > +#include <mcheck.h>
> > +#include <support/test-driver.h>
> > +
> > +static int
> > +do_test (void)
> > +{
> > + mtrace ();
> > + return 0;
> > +}
> > +
> > +#include <support/test-driver.c>
> > diff --git a/libio/tst-bz24228.map b/libio/tst-bz24228.map
> > new file mode 100644
> > index 0000000000..ecb8c058f5
> > --- /dev/null
> > +++ b/libio/tst-bz24228.map
> > @@ -0,0 +1,3 @@
> > +{
> > + local: _IO_stdin_used;
> > +};
>
> Please add a comment to the file why you are doing this, something like
> “hide the symbol from libc.so.6 to switch to the libio/oldfileops.c
> implementation (if it is available for the architecture)”.
Indeed, thanks for the suggestion.
--
ldv
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3] libio: do not unbuffer legacy standard files in compatibility mode [BZ #24228]
2019-03-13 15:46 ` Dmitry V. Levin
@ 2019-03-13 15:49 ` Florian Weimer
2019-03-13 15:59 ` Dmitry V. Levin
0 siblings, 1 reply; 20+ messages in thread
From: Florian Weimer @ 2019-03-13 15:49 UTC (permalink / raw)
To: Dmitry V. Levin; +Cc: libc-alpha
* Dmitry V. Levin:
> On Wed, Mar 13, 2019 at 04:08:16PM +0100, Florian Weimer wrote:
>> * Dmitry V. Levin:
>>
>> > Commit glibc-2.23~693 (a601b74d31ca086de38441d316a3dee24c866305)
>>
>> Please quote the commit hash and commit subject, kernel-style.
>
> The kernel-style reference would look this way:
>
> Commit a601b74d31ca ("In preparation for fixing BZ#16734, fix failure in
> misc/tst-error1-mem when _G_HAVE_MMAP is turned off.")
>
> I'd like to add a reference to glibc-2.23~693 somewhere because
> I find it useful, but I don't see any suitable place for it
> in this long kernel-style form.
Hmm. It's not strictly speaking unique because we do not reject
branches, unfortunately.
>> (How did you determine this reference, anyway?)
>
> Sorry?
glibc-2.23~693 looks nice, but I can't get “git describe” to produce.
>> > diff --git a/libio/genops.c b/libio/genops.c
>> > index 2a0d9b81df..aa92d61b6b 100644
>> > --- a/libio/genops.c
>> > +++ b/libio/genops.c
>> > @@ -789,6 +789,10 @@ _IO_unbuffer_all (void)
>> >
>> > for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
>> > {
>> > +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
>> > + if (__glibc_unlikely (&_IO_stdin_used == NULL) && _IO_legacy_file (fp))
>> > + continue;
>> > +#endif
>>
>> I wonder if we should check _IO_legacy_file only here. This is related
>> to the previous discussion.
>
> If we omitted the check for _IO_stdin_used, then standard files
> would be skipped and misc/tst-error1-mem would complain.
Really? Why would _IO_legacy_file be true for those? That's definitely
not what I intended.
Thanks,
Florian
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3] libio: do not unbuffer legacy standard files in compatibility mode [BZ #24228]
2019-03-13 15:49 ` Florian Weimer
@ 2019-03-13 15:59 ` Dmitry V. Levin
0 siblings, 0 replies; 20+ messages in thread
From: Dmitry V. Levin @ 2019-03-13 15:59 UTC (permalink / raw)
To: Florian Weimer; +Cc: libc-alpha
[-- Attachment #1: Type: text/plain, Size: 2047 bytes --]
On Wed, Mar 13, 2019 at 04:49:59PM +0100, Florian Weimer wrote:
> * Dmitry V. Levin:
>
> > On Wed, Mar 13, 2019 at 04:08:16PM +0100, Florian Weimer wrote:
> >> * Dmitry V. Levin:
> >>
> >> > Commit glibc-2.23~693 (a601b74d31ca086de38441d316a3dee24c866305)
> >>
> >> Please quote the commit hash and commit subject, kernel-style.
> >
> > The kernel-style reference would look this way:
> >
> > Commit a601b74d31ca ("In preparation for fixing BZ#16734, fix failure in
> > misc/tst-error1-mem when _G_HAVE_MMAP is turned off.")
> >
> > I'd like to add a reference to glibc-2.23~693 somewhere because
> > I find it useful, but I don't see any suitable place for it
> > in this long kernel-style form.
>
> Hmm. It's not strictly speaking unique because we do not reject
> branches, unfortunately.
No, it's not unique so I also add the commit hash, but it's handy.
> >> (How did you determine this reference, anyway?)
> >
> > Sorry?
>
> glibc-2.23~693 looks nice, but I can't get “git describe” to produce.
git describe --contains a601b74d31ca
> >> > diff --git a/libio/genops.c b/libio/genops.c
> >> > index 2a0d9b81df..aa92d61b6b 100644
> >> > --- a/libio/genops.c
> >> > +++ b/libio/genops.c
> >> > @@ -789,6 +789,10 @@ _IO_unbuffer_all (void)
> >> >
> >> > for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
> >> > {
> >> > +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> >> > + if (__glibc_unlikely (&_IO_stdin_used == NULL) && _IO_legacy_file (fp))
> >> > + continue;
> >> > +#endif
> >>
> >> I wonder if we should check _IO_legacy_file only here. This is related
> >> to the previous discussion.
> >
> > If we omitted the check for _IO_stdin_used, then standard files
> > would be skipped and misc/tst-error1-mem would complain.
>
> Really? Why would _IO_legacy_file be true for those? That's definitely
> not what I intended.
I don't see why it shouldn't be the case, but it was a month ago
when I looked at the code, so I'll re-check.
--
ldv
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3] libio: do not unbuffer legacy standard files in compatibility mode [BZ #24228]
2019-02-19 1:29 ` [PATCH v3] libio: do not unbuffer legacy standard files in compatibility mode " Dmitry V. Levin
2019-03-13 15:08 ` Florian Weimer
@ 2019-06-19 13:10 ` Florian Weimer
2019-06-19 16:03 ` Dmitry V. Levin
1 sibling, 1 reply; 20+ messages in thread
From: Florian Weimer @ 2019-06-19 13:10 UTC (permalink / raw)
To: Dmitry V. Levin; +Cc: libc-alpha
* Dmitry V. Levin:
> diff --git a/libio/genops.c b/libio/genops.c
> index 2a0d9b81df..aa92d61b6b 100644
> --- a/libio/genops.c
> +++ b/libio/genops.c
> @@ -789,6 +789,10 @@ _IO_unbuffer_all (void)
>
> for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
> {
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> + if (__glibc_unlikely (&_IO_stdin_used == NULL) && _IO_legacy_file (fp))
> + continue;
> +#endif
> if (! (fp->_flags & _IO_UNBUFFERED)
> /* Iff stream is un-orientated, it wasn't used. */
> && fp->_mode != 0)
I believe a better fix would be this, in case an old-style file showed
up for a different reason:
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
bool potentially_wide_stream = _IO_vtable_offset (fp) != 0;
#else
bool potentially_wide_stream = true;
#endif
if (potentially_wide_stream && fp->_mode > 0)
_IO_wsetb (fp, NULL, NULL, 0);
This is _IO_new_fclose handles this situation.
I fear the test is unreliable because it depends on what fp->_mode
evaluates to (which is not actually present in the struct with old
files). But the test is definitely better than nothing.
Thanks,
Florian
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3] libio: do not unbuffer legacy standard files in compatibility mode [BZ #24228]
2019-06-19 13:10 ` Florian Weimer
@ 2019-06-19 16:03 ` Dmitry V. Levin
2019-06-19 16:15 ` Florian Weimer
0 siblings, 1 reply; 20+ messages in thread
From: Dmitry V. Levin @ 2019-06-19 16:03 UTC (permalink / raw)
To: Florian Weimer; +Cc: libc-alpha
[-- Attachment #1: Type: text/plain, Size: 1933 bytes --]
On Wed, Jun 19, 2019 at 03:10:14PM +0200, Florian Weimer wrote:
> * Dmitry V. Levin:
>
> > diff --git a/libio/genops.c b/libio/genops.c
> > index 2a0d9b81df..aa92d61b6b 100644
> > --- a/libio/genops.c
> > +++ b/libio/genops.c
> > @@ -789,6 +789,10 @@ _IO_unbuffer_all (void)
> >
> > for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
> > {
> > +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> > + if (__glibc_unlikely (&_IO_stdin_used == NULL) && _IO_legacy_file (fp))
> > + continue;
> > +#endif
> > if (! (fp->_flags & _IO_UNBUFFERED)
> > /* Iff stream is un-orientated, it wasn't used. */
> > && fp->_mode != 0)
>
> I believe a better fix would be this, in case an old-style file showed
> up for a different reason:
>
> #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> bool potentially_wide_stream = _IO_vtable_offset (fp) != 0;
> #else
> bool potentially_wide_stream = true;
> #endif
> if (potentially_wide_stream && fp->_mode > 0)
> _IO_wsetb (fp, NULL, NULL, 0);
>
> This is _IO_new_fclose handles this situation.
Yes, this approach seems to work, too:
diff --git a/libio/genops.c b/libio/genops.c
index 2a0d9b81df..575f0e6584 100644
--- a/libio/genops.c
+++ b/libio/genops.c
@@ -789,6 +789,10 @@ _IO_unbuffer_all (void)
for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
{
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+ if (__glibc_unlikely (_IO_vtable_offset (fp) != 0))
+ continue;
+#endif
if (! (fp->_flags & _IO_UNBUFFERED)
/* Iff stream is un-orientated, it wasn't used. */
&& fp->_mode != 0)
> I fear the test is unreliable because it depends on what fp->_mode
> evaluates to (which is not actually present in the struct with old
> files). But the test is definitely better than nothing.
Sorry, I couldn't think of a more reliable test than that.
--
ldv
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v3] libio: do not unbuffer legacy standard files in compatibility mode [BZ #24228]
2019-06-19 16:03 ` Dmitry V. Levin
@ 2019-06-19 16:15 ` Florian Weimer
2019-06-19 17:46 ` Dmitry V. Levin
0 siblings, 1 reply; 20+ messages in thread
From: Florian Weimer @ 2019-06-19 16:15 UTC (permalink / raw)
To: Dmitry V. Levin; +Cc: libc-alpha
* Dmitry V. Levin:
> On Wed, Jun 19, 2019 at 03:10:14PM +0200, Florian Weimer wrote:
>> * Dmitry V. Levin:
>>
>> > diff --git a/libio/genops.c b/libio/genops.c
>> > index 2a0d9b81df..aa92d61b6b 100644
>> > --- a/libio/genops.c
>> > +++ b/libio/genops.c
>> > @@ -789,6 +789,10 @@ _IO_unbuffer_all (void)
>> >
>> > for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
>> > {
>> > +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
>> > + if (__glibc_unlikely (&_IO_stdin_used == NULL) && _IO_legacy_file (fp))
>> > + continue;
>> > +#endif
>> > if (! (fp->_flags & _IO_UNBUFFERED)
>> > /* Iff stream is un-orientated, it wasn't used. */
>> > && fp->_mode != 0)
>>
>> I believe a better fix would be this, in case an old-style file showed
>> up for a different reason:
>>
>> #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
>> bool potentially_wide_stream = _IO_vtable_offset (fp) != 0;
>> #else
>> bool potentially_wide_stream = true;
>> #endif
>> if (potentially_wide_stream && fp->_mode > 0)
>> _IO_wsetb (fp, NULL, NULL, 0);
>>
>> This is _IO_new_fclose handles this situation.
>
> Yes, this approach seems to work, too:
>
> diff --git a/libio/genops.c b/libio/genops.c
> index 2a0d9b81df..575f0e6584 100644
> --- a/libio/genops.c
> +++ b/libio/genops.c
> @@ -789,6 +789,10 @@ _IO_unbuffer_all (void)
>
> for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
> {
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> + if (__glibc_unlikely (_IO_vtable_offset (fp) != 0))
> + continue;
> +#endif
> if (! (fp->_flags & _IO_UNBUFFERED)
> /* Iff stream is un-orientated, it wasn't used. */
> && fp->_mode != 0)
Hmm, right there's an early access to fp->_mode that I had missed.
Should we still flush buffers in old binaries?
I think we could do this instead:
int mode;
#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
if (__glibc_unlikely (_IO_vtable_offset (fp) != 0))
mode = 1; /* Old streams are never wide. */
else
mode = fp->_mode;
#else
mode = fp->_mode;
#endif
And then use mode instead of fp->_mode below. Does this make sense?
>> I fear the test is unreliable because it depends on what fp->_mode
>> evaluates to (which is not actually present in the struct with old
>> files). But the test is definitely better than nothing.
>
> Sorry, I couldn't think of a more reliable test than that.
I came up with this (also with the linker script). But curiously
enough, the padding is not actually needed. The test is only valid with
GLIBC_2.0 targets, it crashes for newer targets which do not define
_IO_stdout_.
#include <stdio.h>
#include <stdlib.h>
int pad1[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
int _IO_stdout_[20] __attribute__ ((nocommon));
int pad2[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
int
main (void)
{
/* Simulate old-style printf. */
fprintf ((FILE *) &_IO_stdout_, "info: testing old printing\n");
return 0;
}
This could be improved by using internal headers when the test is built
within the glibc tree, so that hard-coding the size of _IO_stdout_ is
not required.
I guess we could add both tests, just in case.
Thanks,
Florian
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v3] libio: do not unbuffer legacy standard files in compatibility mode [BZ #24228]
2019-06-19 16:15 ` Florian Weimer
@ 2019-06-19 17:46 ` Dmitry V. Levin
2019-06-19 19:04 ` Florian Weimer
0 siblings, 1 reply; 20+ messages in thread
From: Dmitry V. Levin @ 2019-06-19 17:46 UTC (permalink / raw)
To: Florian Weimer; +Cc: libc-alpha
[-- Attachment #1: Type: text/plain, Size: 3894 bytes --]
On Wed, Jun 19, 2019 at 06:15:06PM +0200, Florian Weimer wrote:
> * Dmitry V. Levin:
> > On Wed, Jun 19, 2019 at 03:10:14PM +0200, Florian Weimer wrote:
> >> * Dmitry V. Levin:
> >>
> >> > diff --git a/libio/genops.c b/libio/genops.c
> >> > index 2a0d9b81df..aa92d61b6b 100644
> >> > --- a/libio/genops.c
> >> > +++ b/libio/genops.c
> >> > @@ -789,6 +789,10 @@ _IO_unbuffer_all (void)
> >> >
> >> > for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
> >> > {
> >> > +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> >> > + if (__glibc_unlikely (&_IO_stdin_used == NULL) && _IO_legacy_file (fp))
> >> > + continue;
> >> > +#endif
> >> > if (! (fp->_flags & _IO_UNBUFFERED)
> >> > /* Iff stream is un-orientated, it wasn't used. */
> >> > && fp->_mode != 0)
> >>
> >> I believe a better fix would be this, in case an old-style file showed
> >> up for a different reason:
> >>
> >> #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> >> bool potentially_wide_stream = _IO_vtable_offset (fp) != 0;
> >> #else
> >> bool potentially_wide_stream = true;
> >> #endif
> >> if (potentially_wide_stream && fp->_mode > 0)
> >> _IO_wsetb (fp, NULL, NULL, 0);
> >>
> >> This is _IO_new_fclose handles this situation.
> >
> > Yes, this approach seems to work, too:
> >
> > diff --git a/libio/genops.c b/libio/genops.c
> > index 2a0d9b81df..575f0e6584 100644
> > --- a/libio/genops.c
> > +++ b/libio/genops.c
> > @@ -789,6 +789,10 @@ _IO_unbuffer_all (void)
> >
> > for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
> > {
> > +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> > + if (__glibc_unlikely (_IO_vtable_offset (fp) != 0))
> > + continue;
> > +#endif
> > if (! (fp->_flags & _IO_UNBUFFERED)
> > /* Iff stream is un-orientated, it wasn't used. */
> > && fp->_mode != 0)
>
> Hmm, right there's an early access to fp->_mode that I had missed.
> Should we still flush buffers in old binaries?
>
> I think we could do this instead:
>
> int mode;
> #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> if (__glibc_unlikely (_IO_vtable_offset (fp) != 0))
> mode = 1; /* Old streams are never wide. */
> else
> mode = fp->_mode;
> #else
> mode = fp->_mode;
> #endif
>
> And then use mode instead of fp->_mode below. Does this make sense?
_mode is not the only member that is not available in legacy libio,
_freeres_list and _freeres_buf also should be avoided.
Would you prefer the following approach?
diff --git a/libio/genops.c b/libio/genops.c
index 2a0d9b81df..11a15549e8 100644
--- a/libio/genops.c
+++ b/libio/genops.c
@@ -789,9 +789,16 @@ _IO_unbuffer_all (void)
for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
{
+ int legacy = 0;
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+ if (__glibc_unlikely (_IO_vtable_offset (fp) != 0))
+ legacy = 1;
+#endif
+
if (! (fp->_flags & _IO_UNBUFFERED)
/* Iff stream is un-orientated, it wasn't used. */
- && fp->_mode != 0)
+ && (legacy || fp->_mode != 0))
{
#ifdef _IO_MTSAFE_IO
int cnt;
@@ -805,7 +812,7 @@ _IO_unbuffer_all (void)
__sched_yield ();
#endif
- if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
+ if (! legacy && ! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
{
fp->_flags |= _IO_USER_BUF;
@@ -816,7 +823,7 @@ _IO_unbuffer_all (void)
_IO_SETBUF (fp, NULL, 0);
- if (fp->_mode > 0)
+ if (! legacy && fp->_mode > 0)
_IO_wsetb (fp, NULL, NULL, 0);
#ifdef _IO_MTSAFE_IO
@@ -827,7 +834,8 @@ _IO_unbuffer_all (void)
/* Make sure that never again the wide char functions can be
used. */
- fp->_mode = -1;
+ if (! legacy)
+ fp->_mode = -1;
}
#ifdef _IO_MTSAFE_IO
--
ldv
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v3] libio: do not unbuffer legacy standard files in compatibility mode [BZ #24228]
2019-06-19 17:46 ` Dmitry V. Levin
@ 2019-06-19 19:04 ` Florian Weimer
2019-06-19 19:51 ` [PATCH v4] libio: do not attempt to free wide buffers of legacy streams " Dmitry V. Levin
0 siblings, 1 reply; 20+ messages in thread
From: Florian Weimer @ 2019-06-19 19:04 UTC (permalink / raw)
To: Dmitry V. Levin; +Cc: Florian Weimer, libc-alpha
* Dmitry V. Levin:
> _mode is not the only member that is not available in legacy libio,
> _freeres_list and _freeres_buf also should be avoided.
> Would you prefer the following approach?
>
> diff --git a/libio/genops.c b/libio/genops.c
> index 2a0d9b81df..11a15549e8 100644
> --- a/libio/genops.c
> +++ b/libio/genops.c
> @@ -789,9 +789,16 @@ _IO_unbuffer_all (void)
>
> for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
> {
> + int legacy = 0;
> +
> +#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
> + if (__glibc_unlikely (_IO_vtable_offset (fp) != 0))
> + legacy = 1;
> +#endif
This approach looks reasonable to me. It's certainly much better than
what we have today. If you post a full patch, I'll test it against
one of the problematic OpenJDK 8 builds.
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v4] libio: do not attempt to free wide buffers of legacy streams [BZ #24228]
2019-06-19 19:04 ` Florian Weimer
@ 2019-06-19 19:51 ` Dmitry V. Levin
2019-06-19 21:15 ` Florian Weimer
0 siblings, 1 reply; 20+ messages in thread
From: Dmitry V. Levin @ 2019-06-19 19:51 UTC (permalink / raw)
To: Florian Weimer; +Cc: Florian Weimer, libc-alpha
Commit a601b74d31ca086de38441d316a3dee24c866305 aka glibc-2.23~693
("In preparation for fixing BZ#16734, fix failure in misc/tst-error1-mem
when _G_HAVE_MMAP is turned off.") introduced a regression:
_IO_unbuffer_all() now invokes _IO_wsetb() to free wide buffers of all
files, including legacy standard files which are small statically
allocated objects that do not have wide buffers and the _mode member,
causing memory corruption.
Another memory corruption in _IO_unbuffer_all() happens when -1
is assigned to the _mode member of legacy standard files that do not
have it.
[BZ #24228]
* libio/genops.c (_IO_unbuffer_all)
[SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)]: Do not attempt to free wide
buffers and access _IO_FILE_complete members of legacy libio streams.
* libio/tst-bz24228.c: New file.
* libio/tst-bz24228.map: Likewise.
* libio/Makefile (tests): Add tst-bz24228.
(generated): Add tst-bz24228.mtrace and tst-bz24228.check.
(tests-special): Add $(objpfx)tst-bz24228-mem.out.
(LDFLAGS-tst-bz24228, tst-bz24228-ENV): New variables.
($(objpfx)tst-bz24228-mem.out): New rule.
---
ChangeLog | 14 ++++++++++++++
libio/Makefile | 11 ++++++++++-
libio/genops.c | 16 ++++++++++++----
libio/tst-bz24228.c | 29 +++++++++++++++++++++++++++++
libio/tst-bz24228.map | 5 +++++
5 files changed, 70 insertions(+), 5 deletions(-)
create mode 100644 libio/tst-bz24228.c
create mode 100644 libio/tst-bz24228.map
diff --git a/libio/Makefile b/libio/Makefile
index 7d53cb06b0..b81e8bf5e2 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -65,7 +65,7 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \
tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \
tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof \
- tst-sprintf-ub tst-sprintf-chk-ub tst-bz24051 tst-bz24153 \
+ tst-sprintf-ub tst-sprintf-chk-ub tst-bz24051 tst-bz24153 tst-bz24228 \
tst-wfile-sync tst-wfile-gconv
# This test tests interaction with the gconv cache. Setting
@@ -162,16 +162,20 @@ CFLAGS-tst_putwc.c += -DOBJPFX=\"$(objpfx)\"
CFLAGS-tst-sprintf-ub.c += -Wno-restrict
CFLAGS-tst-sprintf-chk-ub.c += -Wno-restrict
+LDFLAGS-tst-bz24228 = -Wl,--version-script=tst-bz24228.map
+
tst_wprintf2-ARGS = "Some Text"
test-fmemopen-ENV = MALLOC_TRACE=$(objpfx)test-fmemopen.mtrace
tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace
tst-bz22415-ENV = MALLOC_TRACE=$(objpfx)tst-bz22415.mtrace
+tst-bz24228-ENV = MALLOC_TRACE=$(objpfx)tst-bz24228.mtrace
tst-wfile-gconv-ENV = MALLOC_TRACE=$(objpfx)tst-wfile-gconv.mtrace
generated += test-fmemopen.mtrace test-fmemopen.check
generated += tst-fopenloc.mtrace tst-fopenloc.check
generated += tst-bz22415.mtrace tst-bz22415.check
+generated += tst-bz24228.mtrace tst-bz24228.check
generated += tst-wfile-gconv.mtrace tst-wfile-gconv.check
aux := fileops genops stdfiles stdio strops
@@ -188,6 +192,7 @@ shared-only-routines = oldiofopen oldiofdopen oldiofclose oldfileops \
ifeq ($(run-built-tests),yes)
tests-special += $(objpfx)test-freopen.out $(objpfx)test-fmemopen-mem.out \
$(objpfx)tst-bz22415-mem.out \
+ $(objpfx)tst-bz24228-mem.out \
$(objpfx)tst-wfile-gconv-mem.out
ifeq (yes,$(build-shared))
# Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared
@@ -246,6 +251,10 @@ $(objpfx)tst-bz22415-mem.out: $(objpfx)tst-bz22415.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-bz22415.mtrace > $@; \
$(evaluate-test)
+$(objpfx)tst-bz24228-mem.out: $(objpfx)tst-bz24228.out
+ $(common-objpfx)malloc/mtrace $(objpfx)tst-bz24228.mtrace > $@; \
+ $(evaluate-test)
+
$(objpfx)tst-wfile-gconv-mem.out: $(objpfx)tst-wfile-gconv.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-wfile-gconv.mtrace > $@; \
$(evaluate-test)
diff --git a/libio/genops.c b/libio/genops.c
index 2a0d9b81df..11a15549e8 100644
--- a/libio/genops.c
+++ b/libio/genops.c
@@ -789,9 +789,16 @@ _IO_unbuffer_all (void)
for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
{
+ int legacy = 0;
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+ if (__glibc_unlikely (_IO_vtable_offset (fp) != 0))
+ legacy = 1;
+#endif
+
if (! (fp->_flags & _IO_UNBUFFERED)
/* Iff stream is un-orientated, it wasn't used. */
- && fp->_mode != 0)
+ && (legacy || fp->_mode != 0))
{
#ifdef _IO_MTSAFE_IO
int cnt;
@@ -805,7 +812,7 @@ _IO_unbuffer_all (void)
__sched_yield ();
#endif
- if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
+ if (! legacy && ! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
{
fp->_flags |= _IO_USER_BUF;
@@ -816,7 +823,7 @@ _IO_unbuffer_all (void)
_IO_SETBUF (fp, NULL, 0);
- if (fp->_mode > 0)
+ if (! legacy && fp->_mode > 0)
_IO_wsetb (fp, NULL, NULL, 0);
#ifdef _IO_MTSAFE_IO
@@ -827,7 +834,8 @@ _IO_unbuffer_all (void)
/* Make sure that never again the wide char functions can be
used. */
- fp->_mode = -1;
+ if (! legacy)
+ fp->_mode = -1;
}
#ifdef _IO_MTSAFE_IO
diff --git a/libio/tst-bz24228.c b/libio/tst-bz24228.c
new file mode 100644
index 0000000000..6a74500d47
--- /dev/null
+++ b/libio/tst-bz24228.c
@@ -0,0 +1,29 @@
+/* BZ #24228 check for memory corruption in legacy libio
+ Copyright (C) 2019 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <mcheck.h>
+#include <support/test-driver.h>
+
+static int
+do_test (void)
+{
+ mtrace ();
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/libio/tst-bz24228.map b/libio/tst-bz24228.map
new file mode 100644
index 0000000000..4383e0817d
--- /dev/null
+++ b/libio/tst-bz24228.map
@@ -0,0 +1,5 @@
+# Hide the symbol from libc.so.6 to switch to the libio/oldfileops.c
+# implementation when it is available for the architecture.
+{
+ local: _IO_stdin_used;
+};
--
ldv
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v4] libio: do not attempt to free wide buffers of legacy streams [BZ #24228]
2019-06-19 19:51 ` [PATCH v4] libio: do not attempt to free wide buffers of legacy streams " Dmitry V. Levin
@ 2019-06-19 21:15 ` Florian Weimer
2019-06-19 22:08 ` [PATCH v5] " Dmitry V. Levin
0 siblings, 1 reply; 20+ messages in thread
From: Florian Weimer @ 2019-06-19 21:15 UTC (permalink / raw)
To: Dmitry V. Levin; +Cc: libc-alpha
* Dmitry V. Levin:
> Commit a601b74d31ca086de38441d316a3dee24c866305 aka glibc-2.23~693
> ("In preparation for fixing BZ#16734, fix failure in misc/tst-error1-mem
> when _G_HAVE_MMAP is turned off.") introduced a regression:
> _IO_unbuffer_all() now invokes _IO_wsetb() to free wide buffers of all
> files, including legacy standard files which are small statically
> allocated objects that do not have wide buffers and the _mode member,
> causing memory corruption.
>
> Another memory corruption in _IO_unbuffer_all() happens when -1
> is assigned to the _mode member of legacy standard files that do not
> have it.
GNU style calls for not putting () after function names. (Sorry, I must
sound like a broken record).
> diff --git a/libio/Makefile b/libio/Makefile
> index 7d53cb06b0..b81e8bf5e2 100644
> --- a/libio/Makefile
> +++ b/libio/Makefile
> @@ -65,7 +65,7 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \
> tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \
> tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \
> tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof \
> - tst-sprintf-ub tst-sprintf-chk-ub tst-bz24051 tst-bz24153 \
> + tst-sprintf-ub tst-sprintf-chk-ub tst-bz24051 tst-bz24153 tst-bz24228 \
> tst-wfile-sync tst-wfile-gconv
I suggest to qualify the new test with “ifeq ($(build-shared),yes)”. It
can never meet its test objective with static linking because the
relevant code just is not there.
Rest looks good to me, thanks.
I can confirm that it fixes the OpenJDK failure we saw.
Thanks,
Florian
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH v5] libio: do not attempt to free wide buffers of legacy streams [BZ #24228]
2019-06-19 21:15 ` Florian Weimer
@ 2019-06-19 22:08 ` Dmitry V. Levin
2019-06-20 8:59 ` Florian Weimer
0 siblings, 1 reply; 20+ messages in thread
From: Dmitry V. Levin @ 2019-06-19 22:08 UTC (permalink / raw)
To: Florian Weimer; +Cc: libc-alpha
Commit a601b74d31ca086de38441d316a3dee24c866305 aka glibc-2.23~693
("In preparation for fixing BZ#16734, fix failure in misc/tst-error1-mem
when _G_HAVE_MMAP is turned off.") introduced a regression:
_IO_unbuffer_all now invokes _IO_wsetb to free wide buffers of all
files, including legacy standard files which are small statically
allocated objects that do not have wide buffers and the _mode member,
causing memory corruption.
Another memory corruption in _IO_unbuffer_all happens when -1
is assigned to the _mode member of legacy standard files that
do not have it.
[BZ #24228]
* libio/genops.c (_IO_unbuffer_all)
[SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)]: Do not attempt to free wide
buffers and access _IO_FILE_complete members of legacy libio streams.
* libio/tst-bz24228.c: New file.
* libio/tst-bz24228.map: Likewise.
* libio/Makefile [build-shared] (tests): Add tst-bz24228.
[build-shared] (generated): Add tst-bz24228.mtrace and
tst-bz24228.check.
[run-built-tests && build-shared] (tests-special): Add
$(objpfx)tst-bz24228-mem.out.
(LDFLAGS-tst-bz24228, tst-bz24228-ENV): New variables.
($(objpfx)tst-bz24228-mem.out): New rule.
---
ChangeLog | 17 +++++++++++++++++
libio/Makefile | 14 +++++++++++++-
libio/genops.c | 16 ++++++++++++----
libio/tst-bz24228.c | 29 +++++++++++++++++++++++++++++
libio/tst-bz24228.map | 5 +++++
5 files changed, 76 insertions(+), 5 deletions(-)
create mode 100644 libio/tst-bz24228.c
create mode 100644 libio/tst-bz24228.map
diff --git a/ChangeLog b/ChangeLog
index 729301f75e..a795d6ac77 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2019-06-19 Dmitry V. Levin <ldv@altlinux.org>
+ Florian Weimer <fweimer@redhat.com>
+
+ [BZ #24228]
+ * libio/genops.c (_IO_unbuffer_all)
+ [SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)]: Do not attempt to free wide
+ buffers and access _IO_FILE_complete members of legacy libio streams.
+ * libio/tst-bz24228.c: New file.
+ * libio/tst-bz24228.map: Likewise.
+ * libio/Makefile [build-shared] (tests): Add tst-bz24228.
+ [build-shared] (generated): Add tst-bz24228.mtrace and
+ tst-bz24228.check.
+ [run-built-tests && build-shared] (tests-special): Add
+ $(objpfx)tst-bz24228-mem.out.
+ (LDFLAGS-tst-bz24228, tst-bz24228-ENV): New variables.
+ ($(objpfx)tst-bz24228-mem.out): New rule.
+
2019-06-19 Rafal Luzynski <digitalfreak@lingonborough.com>
[BZ #24614]
diff --git a/libio/Makefile b/libio/Makefile
index 7d53cb06b0..6e594b8ec5 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -78,6 +78,9 @@ ifeq (yes,$(build-shared))
# Add test-fopenloc only if shared library is enabled since it depends on
# shared localedata objects.
tests += tst-fopenloc
+# Add tst-bz24228 only if shared library is enabled since it can never meet its
+# objective with static linking because the relevant code just is not there.
+tests += tst-bz24228
endif
test-srcs = test-freopen
@@ -162,11 +165,14 @@ CFLAGS-tst_putwc.c += -DOBJPFX=\"$(objpfx)\"
CFLAGS-tst-sprintf-ub.c += -Wno-restrict
CFLAGS-tst-sprintf-chk-ub.c += -Wno-restrict
+LDFLAGS-tst-bz24228 = -Wl,--version-script=tst-bz24228.map
+
tst_wprintf2-ARGS = "Some Text"
test-fmemopen-ENV = MALLOC_TRACE=$(objpfx)test-fmemopen.mtrace
tst-fopenloc-ENV = MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace
tst-bz22415-ENV = MALLOC_TRACE=$(objpfx)tst-bz22415.mtrace
+tst-bz24228-ENV = MALLOC_TRACE=$(objpfx)tst-bz24228.mtrace
tst-wfile-gconv-ENV = MALLOC_TRACE=$(objpfx)tst-wfile-gconv.mtrace
generated += test-fmemopen.mtrace test-fmemopen.check
@@ -177,6 +183,7 @@ generated += tst-wfile-gconv.mtrace tst-wfile-gconv.check
aux := fileops genops stdfiles stdio strops
ifeq ($(build-shared),yes)
+generated += tst-bz24228.mtrace tst-bz24228.check
aux += oldfileops oldstdfiles
endif
@@ -192,7 +199,8 @@ tests-special += $(objpfx)test-freopen.out $(objpfx)test-fmemopen-mem.out \
ifeq (yes,$(build-shared))
# Run tst-fopenloc-cmp.out and tst-openloc-mem.out only if shared
# library is enabled since they depend on tst-fopenloc.out.
-tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out
+tests-special += $(objpfx)tst-fopenloc-cmp.out $(objpfx)tst-fopenloc-mem.out \
+ $(objpfx)tst-bz24228-mem.out
endif
endif
@@ -246,6 +254,10 @@ $(objpfx)tst-bz22415-mem.out: $(objpfx)tst-bz22415.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-bz22415.mtrace > $@; \
$(evaluate-test)
+$(objpfx)tst-bz24228-mem.out: $(objpfx)tst-bz24228.out
+ $(common-objpfx)malloc/mtrace $(objpfx)tst-bz24228.mtrace > $@; \
+ $(evaluate-test)
+
$(objpfx)tst-wfile-gconv-mem.out: $(objpfx)tst-wfile-gconv.out
$(common-objpfx)malloc/mtrace $(objpfx)tst-wfile-gconv.mtrace > $@; \
$(evaluate-test)
diff --git a/libio/genops.c b/libio/genops.c
index 2a0d9b81df..11a15549e8 100644
--- a/libio/genops.c
+++ b/libio/genops.c
@@ -789,9 +789,16 @@ _IO_unbuffer_all (void)
for (fp = (FILE *) _IO_list_all; fp; fp = fp->_chain)
{
+ int legacy = 0;
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+ if (__glibc_unlikely (_IO_vtable_offset (fp) != 0))
+ legacy = 1;
+#endif
+
if (! (fp->_flags & _IO_UNBUFFERED)
/* Iff stream is un-orientated, it wasn't used. */
- && fp->_mode != 0)
+ && (legacy || fp->_mode != 0))
{
#ifdef _IO_MTSAFE_IO
int cnt;
@@ -805,7 +812,7 @@ _IO_unbuffer_all (void)
__sched_yield ();
#endif
- if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
+ if (! legacy && ! dealloc_buffers && !(fp->_flags & _IO_USER_BUF))
{
fp->_flags |= _IO_USER_BUF;
@@ -816,7 +823,7 @@ _IO_unbuffer_all (void)
_IO_SETBUF (fp, NULL, 0);
- if (fp->_mode > 0)
+ if (! legacy && fp->_mode > 0)
_IO_wsetb (fp, NULL, NULL, 0);
#ifdef _IO_MTSAFE_IO
@@ -827,7 +834,8 @@ _IO_unbuffer_all (void)
/* Make sure that never again the wide char functions can be
used. */
- fp->_mode = -1;
+ if (! legacy)
+ fp->_mode = -1;
}
#ifdef _IO_MTSAFE_IO
diff --git a/libio/tst-bz24228.c b/libio/tst-bz24228.c
new file mode 100644
index 0000000000..6a74500d47
--- /dev/null
+++ b/libio/tst-bz24228.c
@@ -0,0 +1,29 @@
+/* BZ #24228 check for memory corruption in legacy libio
+ Copyright (C) 2019 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <mcheck.h>
+#include <support/test-driver.h>
+
+static int
+do_test (void)
+{
+ mtrace ();
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/libio/tst-bz24228.map b/libio/tst-bz24228.map
new file mode 100644
index 0000000000..4383e0817d
--- /dev/null
+++ b/libio/tst-bz24228.map
@@ -0,0 +1,5 @@
+# Hide the symbol from libc.so.6 to switch to the libio/oldfileops.c
+# implementation when it is available for the architecture.
+{
+ local: _IO_stdin_used;
+};
--
ldv
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v5] libio: do not attempt to free wide buffers of legacy streams [BZ #24228]
2019-06-19 22:08 ` [PATCH v5] " Dmitry V. Levin
@ 2019-06-20 8:59 ` Florian Weimer
2019-06-20 17:42 ` Dmitry V. Levin
0 siblings, 1 reply; 20+ messages in thread
From: Florian Weimer @ 2019-06-20 8:59 UTC (permalink / raw)
To: Dmitry V. Levin; +Cc: libc-alpha
* Dmitry V. Levin:
> Commit a601b74d31ca086de38441d316a3dee24c866305 aka glibc-2.23~693
> ("In preparation for fixing BZ#16734, fix failure in misc/tst-error1-mem
> when _G_HAVE_MMAP is turned off.") introduced a regression:
> _IO_unbuffer_all now invokes _IO_wsetb to free wide buffers of all
> files, including legacy standard files which are small statically
> allocated objects that do not have wide buffers and the _mode member,
> causing memory corruption.
>
> Another memory corruption in _IO_unbuffer_all happens when -1
> is assigned to the _mode member of legacy standard files that
> do not have it.
>
> [BZ #24228]
> * libio/genops.c (_IO_unbuffer_all)
> [SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)]: Do not attempt to free wide
> buffers and access _IO_FILE_complete members of legacy libio streams.
> * libio/tst-bz24228.c: New file.
> * libio/tst-bz24228.map: Likewise.
> * libio/Makefile [build-shared] (tests): Add tst-bz24228.
> [build-shared] (generated): Add tst-bz24228.mtrace and
> tst-bz24228.check.
> [run-built-tests && build-shared] (tests-special): Add
> $(objpfx)tst-bz24228-mem.out.
> (LDFLAGS-tst-bz24228, tst-bz24228-ENV): New variables.
> ($(objpfx)tst-bz24228-mem.out): New rule.
This version looks fine to me. Thanks.
Sorry, it took me a while to really understand this issue.
Florian
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v5] libio: do not attempt to free wide buffers of legacy streams [BZ #24228]
2019-06-20 8:59 ` Florian Weimer
@ 2019-06-20 17:42 ` Dmitry V. Levin
0 siblings, 0 replies; 20+ messages in thread
From: Dmitry V. Levin @ 2019-06-20 17:42 UTC (permalink / raw)
To: libc-alpha
[-- Attachment #1: Type: text/plain, Size: 1440 bytes --]
On Thu, Jun 20, 2019 at 10:59:28AM +0200, Florian Weimer wrote:
> * Dmitry V. Levin:
>
> > Commit a601b74d31ca086de38441d316a3dee24c866305 aka glibc-2.23~693
> > ("In preparation for fixing BZ#16734, fix failure in misc/tst-error1-mem
> > when _G_HAVE_MMAP is turned off.") introduced a regression:
> > _IO_unbuffer_all now invokes _IO_wsetb to free wide buffers of all
> > files, including legacy standard files which are small statically
> > allocated objects that do not have wide buffers and the _mode member,
> > causing memory corruption.
> >
> > Another memory corruption in _IO_unbuffer_all happens when -1
> > is assigned to the _mode member of legacy standard files that
> > do not have it.
> >
> > [BZ #24228]
> > * libio/genops.c (_IO_unbuffer_all)
> > [SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)]: Do not attempt to free wide
> > buffers and access _IO_FILE_complete members of legacy libio streams.
> > * libio/tst-bz24228.c: New file.
> > * libio/tst-bz24228.map: Likewise.
> > * libio/Makefile [build-shared] (tests): Add tst-bz24228.
> > [build-shared] (generated): Add tst-bz24228.mtrace and
> > tst-bz24228.check.
> > [run-built-tests && build-shared] (tests-special): Add
> > $(objpfx)tst-bz24228-mem.out.
> > (LDFLAGS-tst-bz24228, tst-bz24228-ENV): New variables.
> > ($(objpfx)tst-bz24228-mem.out): New rule.
>
> This version looks fine to me. Thanks.
Pushed. Thanks.
--
ldv
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2019-06-20 17:42 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-18 12:44 [PATCH] libio: do not cleanup wide buffers of legacy standard files [BZ #24228] Dmitry V. Levin
2019-02-18 12:56 ` Florian Weimer
2019-02-18 19:10 ` Dmitry V. Levin
2019-02-18 21:38 ` [PATCH v2] " Dmitry V. Levin
2019-02-19 0:57 ` [PATCH] " Dmitry V. Levin
2019-02-19 1:29 ` [PATCH v3] libio: do not unbuffer legacy standard files in compatibility mode " Dmitry V. Levin
2019-03-13 15:08 ` Florian Weimer
2019-03-13 15:46 ` Dmitry V. Levin
2019-03-13 15:49 ` Florian Weimer
2019-03-13 15:59 ` Dmitry V. Levin
2019-06-19 13:10 ` Florian Weimer
2019-06-19 16:03 ` Dmitry V. Levin
2019-06-19 16:15 ` Florian Weimer
2019-06-19 17:46 ` Dmitry V. Levin
2019-06-19 19:04 ` Florian Weimer
2019-06-19 19:51 ` [PATCH v4] libio: do not attempt to free wide buffers of legacy streams " Dmitry V. Levin
2019-06-19 21:15 ` Florian Weimer
2019-06-19 22:08 ` [PATCH v5] " Dmitry V. Levin
2019-06-20 8:59 ` Florian Weimer
2019-06-20 17:42 ` Dmitry V. Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).