Boost C++ Libraries: Ticket #11632: UB in boost.format basic_oaltstringstream https://svn.boost.org/trac10/ticket/11632 <p> The constructors for basic_oaltstringstream in boost/format/alt_sstream.hpp pass the result of a member call to the constructor of a base class. </p> <p> For example the default constructor is </p> <p> <code>basic_oaltstringstream()</code> <code> : pbase_type(new stringbuf_t), stream_t(rdbuf())</code> <code> {}</code> </p> <p> Where <code>stream_t</code> is a <code>typedef</code> for the second base class. </p> <p> I discovered this when using ubsan and I initially raised GCC <a class="ext-link" href="https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67515"><span class="icon">​</span>pr67515</a> using a much simplified test-case; but as Jon Wakely pointed out: "12.6.2 [class.base.init] p16 says this is undefined (and has a very similar example)." </p> <p> One solution to avoid UB in this case is to manually inline the call to <code>rdbuf()</code> and so initialise the member of the second base class directly rather than via the <code>rdbuf()</code> function; so for example change </p> <p> <code>pbase_type(new stringbuf_t), stream_t(rdbuf())</code> </p> <p> to </p> <p> <code>pbase_type(new stringbuf_t), stream_t(pbase_type::member.get())</code> </p> <p> in the default ctor (and similarly for the other constructors.) </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11632 Trac 1.4.3 anonymous Thu, 10 Sep 2015 19:48:16 GMT <link>https://svn.boost.org/trac10/ticket/11632#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11632#comment:1</guid> <description> <p> Note that the suggested resolution assumes the anticipated direction of <a class="ext-link" href="http://www.wg21.link/cwg2056"><span class="icon">​</span>CWG 2056</a>. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Wed, 23 Sep 2015 23:11:34 GMT</pubDate> <title>component changed; owner set https://svn.boost.org/trac10/ticket/11632#comment:2 https://svn.boost.org/trac10/ticket/11632#comment:2 <ul> <li><strong>owner</strong> set to <span class="trac-author">Samuel Krempp</span> </li> <li><strong>component</strong> <span class="trac-field-old">None</span> → <span class="trac-field-new">format</span> </li> </ul> Ticket anonymous Mon, 18 Jan 2016 10:53:57 GMT <link>https://svn.boost.org/trac10/ticket/11632#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11632#comment:3</guid> <description> <p> Proposed change (rdbuf() -&gt; pbase_type::member.get() in constructors) fixes the undefined behavior for me on GCC 5.3.1, thanks! </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Mon, 18 Jan 2016 13:47:22 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11632#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11632#comment:4</guid> <description> <p> Hmmm... I've applied the following patch: </p> <pre class="wiki">diff -Naur alt_sstream.hpp.orig alt_sstream.hpp --- alt_sstream.hpp.orig 2015-12-11 11:21:50.000000000 +0100 +++ alt_sstream.hpp 2016-01-18 10:46:39.000000000 +0100 @@ -137,13 +137,13 @@ public: typedef Alloc allocator_type; basic_oaltstringstream() - : pbase_type(new stringbuf_t), stream_t(rdbuf()) + : pbase_type(new stringbuf_t), stream_t(pbase_type::member.get()) { } basic_oaltstringstream(::boost::shared_ptr&lt;stringbuf_t&gt; buf) - : pbase_type(buf), stream_t(rdbuf()) + : pbase_type(buf), stream_t(pbase_type::member.get()) { } basic_oaltstringstream(stringbuf_t * buf) - : pbase_type(buf, No_Op() ), stream_t(rdbuf()) + : pbase_type(buf, No_Op() ), stream_t(pbase_type::member.get()) { } stringbuf_t * rdbuf() const { return pbase_type::member.get(); } </pre><p> The first instance of undefined behavior was indeed no longer there, but now I get a different, slightly modified backtrace: </p> <pre class="wiki">ASAN:SIGSEGV ================================================================= ==20533==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f28b5b56110 bp 0x7ffda52eb000 sp 0x7ffda52eab50 T0) #0 0x7f28b5b5610f in __dynamic_cast (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0x6610f) #1 0x7f28b4deabcf (/usr/lib/x86_64-linux-gnu/libubsan.so.0+0x9bcf) #2 0x7f28b4dea132 (/usr/lib/x86_64-linux-gnu/libubsan.so.0+0x9132) #3 0x7f28b4dea892 in __ubsan_handle_dynamic_type_cache_miss (/usr/lib/x86_64-linux-gnu/libubsan.so.0+0x9892) #4 0x7f28b9b1759b in boost_1_57_0::io::basic_oaltstringstream&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;::basic_oaltstringstream(boost_1_57_0::io::basic_altstringbuf&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;*) (/build/debug/cpp/libotdscpp.so+0x3d1a59b) #5 0x7f28b9b0cc0a in void boost_1_57_0::io::detail::put&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt;, boost_1_57_0::io::detail::put_holder&lt;char, std::char_traits&lt;char&gt; &gt; const&amp;&gt;(boost_1_57_0::io::detail::put_holder&lt;char, std::char_traits&lt;char&gt; &gt; const&amp;, boost_1_57_0::io::detail::format_item&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, boost_1_57_0::basic_format&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;::string_type&amp;, boost_1_57_0::basic_format&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;::internal_streambuf_t&amp;, std::locale*) (/build/debug/cpp/libotdscpp.so+0x3d0fc0a) #6 0x7f28b9aff54f in void boost_1_57_0::io::detail::distribute&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt;, boost_1_57_0::io::detail::put_holder&lt;char, std::char_traits&lt;char&gt; &gt; const&amp;&gt;(boost_1_57_0::basic_format&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;&amp;, boost_1_57_0::io::detail::put_holder&lt;char, std::char_traits&lt;char&gt; &gt; const&amp;) lib/boost/install/include/boost/format/feed_args.hpp:285 #7 0x7f28b9af37c0 in boost_1_57_0::basic_format&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;&amp; boost_1_57_0::io::detail::feed_impl&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt;, boost_1_57_0::io::detail::put_holder&lt;char, std::char_traits&lt;char&gt; &gt; const&amp;&gt;(boost_1_57_0::basic_format&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;&amp;, boost_1_57_0::io::detail::put_holder&lt;char, std::char_traits&lt;char&gt; &gt; const&amp;) lib/boost/install/include/boost/format/feed_args.hpp:295 #8 0x7f28ba15ed60 in boost_1_57_0::basic_format&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;&amp; boost_1_57_0::io::detail::feed&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt;, char const (&amp;) [27]&gt;(boost_1_57_0::basic_format&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;&amp;, char const (&amp;) [27]) lib/boost/install/include/boost/format/feed_args.hpp:307 #9 0x7f28ba159694 in boost_1_57_0::basic_format&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;&amp; boost_1_57_0::basic_format&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;::operator%&lt;char [27]&gt;(char const (&amp;) [27]) lib/boost/install/include/boost/format/format_class.hpp:64 </pre><pre class="wiki">$ g++-5 -v Using built-in specs. COLLECT_GCC=/usr/bin/g++-5 COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.3.0-3ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=gcc4-compatible --disable-libstdcxx-dual-abi --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 5.3.0 20151204 (Ubuntu 5.3.0-3ubuntu1~14.04) </pre><p> Any ideas? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Tue, 19 Jan 2016 08:20:54 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11632#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11632#comment:5</guid> <description> <p> Sadly no; the fix I submitted worked for our (limited) use of boost::format with ubsan. Roger. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Wed, 27 Jan 2016 14:52:29 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11632#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11632#comment:6</guid> <description> <p> Okay, an update on this. I have done a clean rebuild, and the attached patch actually does seem to work for me as well as I have initially indicated. I'm sorry for the misleading comment. Apparently our build system didn't actually pick up my changes and I've got confused by the old error message. Once again, sorry about this... </p> <p> In the light of this additional information, it would be great if this patch could be applied to have the problem fixed out of the box. </p> </description> <category>Ticket</category> </item> <item> <author>rogero@…</author> <pubDate>Wed, 27 Jan 2016 23:11:32 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11632#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11632#comment:7</guid> <description> <p> That's good news, and I agree it would be good if this patch were to be applied. </p> </description> <category>Ticket</category> </item> <item> <author>Georg Sauthoff <mail@…></author> <pubDate>Thu, 04 Feb 2016 13:13:49 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11632#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11632#comment:8</guid> <description> <p> I can confirm this issue on Fedora 23 (Boost 1.58, gcc 5.1). It is exposed when using the ubsanitizer and boost::format(). </p> <p> With Fedora 21 (gcc 4.9 and upstream Boost 1.58) the usage of boost::format() didn't trigger this issue. </p> </description> <category>Ticket</category> </item> <item> <author>Eli Fidler <efidler@…></author> <pubDate>Fri, 19 Aug 2016 19:11:33 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11632#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11632#comment:9</guid> <description> <p> I can further confirm that this fixes the UBSan issues on GCC 5.4 and <a class="missing wiki">AppleClang</a> 8. It's been 7 months; is there any progress toward getting this landed? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Wed, 16 Nov 2016 21:31:25 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11632#comment:10 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11632#comment:10</guid> <description> <p> Can also confirm that this fixes UBSAN issues with GCC 5.3 and Boost 1.57.0. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Thu, 29 Jun 2017 05:22:33 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11632#comment:11 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11632#comment:11</guid> <description> <p> any idea when this fix will be applied? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>James E. King, III</dc:creator> <pubDate>Sat, 07 Oct 2017 04:37:18 GMT</pubDate> <title>owner, version, milestone changed; keywords set https://svn.boost.org/trac10/ticket/11632#comment:12 https://svn.boost.org/trac10/ticket/11632#comment:12 <ul> <li><strong>keywords</strong> ubsan added </li> <li><strong>owner</strong> changed from <span class="trac-author">Samuel Krempp</span> to <span class="trac-author">James E. King, III</span> </li> <li><strong>version</strong> <span class="trac-field-old">Boost Development Trunk</span> → <span class="trac-field-new">Boost 1.57.0</span> </li> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Boost 1.66.0</span> </li> </ul> Ticket James E. King, III Sat, 07 Oct 2017 04:37:51 GMT <link>https://svn.boost.org/trac10/ticket/11632#comment:13 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11632#comment:13</guid> <description> <p> Submitted a pull request in github for this, as I ran into it on one of my projects: <a class="ext-link" href="https://github.com/boostorg/format/pull/13"><span class="icon">​</span>https://github.com/boostorg/format/pull/13</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>James E. King, III</dc:creator> <pubDate>Sat, 07 Oct 2017 13:46:07 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/11632#comment:14 https://svn.boost.org/trac10/ticket/11632#comment:14 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> Ticket James E. King, III Sat, 07 Oct 2017 15:29:17 GMT status changed; resolution deleted https://svn.boost.org/trac10/ticket/11632#comment:15 https://svn.boost.org/trac10/ticket/11632#comment:15 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">fixed</span> </li> </ul> <p> Reopening this to track that it has been fixed in develop but not yet merged into master. </p> Ticket James E. King, III Fri, 20 Oct 2017 16:03:33 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/11632#comment:16 https://svn.boost.org/trac10/ticket/11632#comment:16 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> Ticket