From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 99095 invoked by alias); 29 Sep 2015 18:54:46 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 99073 invoked by uid 89); 29 Sep 2015 18:54:45 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mail-qg0-f50.google.com Received: from mail-qg0-f50.google.com (HELO mail-qg0-f50.google.com) (209.85.192.50) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 29 Sep 2015 18:54:44 +0000 Received: by qgev79 with SMTP id v79so14790568qge.0; Tue, 29 Sep 2015 11:54:42 -0700 (PDT) X-Received: by 10.140.233.130 with SMTP id e124mr32827085qhc.79.1443552882057; Tue, 29 Sep 2015 11:54:42 -0700 (PDT) Received: from [192.168.0.26] (97-124-165-221.hlrn.qwest.net. [97.124.165.221]) by smtp.gmail.com with ESMTPSA id g49sm9851911qgg.10.2015.09.29.11.54.40 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 29 Sep 2015 11:54:40 -0700 (PDT) Message-ID: <560ADE6F.30104@gmail.com> Date: Tue, 29 Sep 2015 19:49:00 -0000 From: Martin Sebor User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 MIME-Version: 1.0 To: Jonathan Wakely , libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: Re: [patch] libstdc++/67747 Allocate space for dirent::d_name References: <20150929113726.GU12094@redhat.com> In-Reply-To: <20150929113726.GU12094@redhat.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2015-09/txt/msg02251.txt.bz2 On 09/29/2015 05:37 AM, Jonathan Wakely wrote: > POSIX says that dirent::d_name has an unspecified length, so calls to > readdir_r must pass a buffer with enough trailing space for > {NAME_MAX}+1 characters. I wasn't doing that, which works OK on > GNU/Linux and BSD where d_name is a large array, but fails on Solaris > 32-bit. > > This uses pathconf to get NAME_MAX and allocates a buffer. > > Tested powerpc64le-linux and x86_64-dragonfly4.1, I'm going to commit > this to trunk today (and backport all the filesystem fixes to > gcc-5-branch). Calling pathconf is only necessary when _POSIX_NO_TRUNC is zero which I think exists mainly for legacy file systems. Otherwise, it's safe to use NAME_MAX instead. Avoiding the call to pathconf also avoids the TOCTOU between it and the call to opendir, and hardcoding the value makes it possible to avoid dynamically allocating the dirent buffer. I didn't remember the MAX_PATH value on Windows anymore but from what I've just read online it sounds like it's defined to 260. Defaulting to 255 on POSIX is appropriate. On XSI systems, the minimum required value is _XOPEN_NAME_MAX which is 255 (I would suggest using the macro instead when it's defined). Otherwise, the strictly conforming minimum value would be 14 -- the value of _POSIX_NAME_MAX, but since 255 is greater it's fine. Other than that, I tend to be leery of using plain char arrays as buffers for objects of bigger types. I don't know to what extent this is a problem for libstdc++ anymore as more and more hardware is tolerant of misaligned accesses and as the default new expression typically returns memory suitably aligned for the largest fundamental type. But since there is no requirement in the language that it do so and I would tend to err on the side of caution and use operator new (as opposed to new char[len]). Martin PS I'm interpreting _POSIX_NO_TRUNC being zero as more restrictive than if it was non-zero and so calling pathconf(p, _PC_NO_TRUNC) should be required to also return non-zero for such an implementation, regardless of p. But let me check that I'm reading it right.