Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1030885AbbD1Quk (ORCPT ); Tue, 28 Apr 2015 12:50:40 -0400 Received: from mail-ig0-f169.google.com ([209.85.213.169]:38100 "EHLO mail-ig0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1030545AbbD1Que (ORCPT ); Tue, 28 Apr 2015 12:50:34 -0400 MIME-Version: 1.0 In-Reply-To: <20150428160523.GJ889@ZenIV.linux.org.uk> References: <20150428034859.GI889@ZenIV.linux.org.uk> <1363736428.511175.1430199310500.open-xchange@webmail.nmp.proximus.be> <20150428160523.GJ889@ZenIV.linux.org.uk> Date: Tue, 28 Apr 2015 09:42:38 -0700 X-Google-Sender-Auth: xqlFPIoQSwWXch4zII73QbHSeRI Message-ID: Subject: Re: revert "fs/befs/linuxvfs.c: replace strncpy by strlcpy" From: Linus Torvalds To: Al Viro Cc: Fabian Frederick , Linux Kernel Mailing List Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2297 Lines: 64 On Tue, Apr 28, 2015 at 9:05 AM, Al Viro wrote: > > Unfortunately, we _can't_ make strlcpy() never look past src + size - 1 - > not without changing its semantics. Yeah, strlcpy is actually nasty. I don't understand why people like it so much. It's a crap interface, and completely unsuitable for untrusted sources because of the overrun issue. Now, strncpy is nasty too, because of the two main flaws: - no guaranteed NUL at the end - crazy "fill with NUL" at the end the first of which causes security issues, and the second of which causes performance issues when you have small strings and size your buffers generously. Generally, what we want is "strncpy()" that forces a _single_ NUL at the end. Basically, what we want is that good_strncpy(dst, src, n); assert(strlen(dst) < n); always just works, but it doesn't try to pad the 'dst' to zero. Alternatively, the return value should be really obvious and unambiguous. That's what our "strncpy_from_user()" does: it is a but more complex because it needs to show three cases (ok, too long, and EFAULT), so the semantics for 'strncpy_from_user() is that you have to just always check the return value, but at least it's simple: - negative means error - >= n means "too long" - 0..n-1 means "ok" and is the size of the string. for a normal in-kernel strncpy(), we'd likely be better off just returing "we truncated" as an error. Then you could just do mystrncpy(dst, src, sizeof(dst)); and the result would be a valid string (possibly truncated), and if you care about truncation you just do if (good_strncpy(dst, src, sizeof(dst)) < 0) return -ETOOLONG; both of which are just very *obvious* things, and neither of which leans a possibly unsafe string in "dst", nor look past the end of 'src'. Oh well. I can certainly imagine other more complex forms too (max length of destination _and_ separately max length of source). But strncpy and strlcpy are both horrible nasty error-prone crap. Linus -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/