Received: by 2002:ac0:aed5:0:0:0:0:0 with SMTP id t21csp4448637imb; Wed, 6 Mar 2019 13:45:05 -0800 (PST) X-Google-Smtp-Source: APXvYqwTdZpeR8Qc5LfFwEPaSjSBKk2PP4rIlANdycJUWr6LvQQh3PljeUokjA0UOhN5AFbQM/Gk X-Received: by 2002:a63:5506:: with SMTP id j6mr8216500pgb.202.1551908705066; Wed, 06 Mar 2019 13:45:05 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1551908705; cv=none; d=google.com; s=arc-20160816; b=j/eZn3EOvlWyXb4k2GQ8K+QBAiO1OyhOLaRlgztMqITPOYMunxtkDcReqW+TsUTTov tid5hRBq/GKVexJbZk6RPS8MYcAAYKIlPINc63Au1CzHFZHSSePN5yuBGHwbxwGRgMd3 zcx4YwydNnbh6U1t93b4v0ntFLPTrQg/RpewGM/BEcHlksL078jIVAIyYJ6bT2jUrHRT H9renYea0Hd0xidWm2A83sPaa8J3GrPKhjsK/SA1/wltRqYWN6HlmYf39nep05fTyk0q 5bDTfe6OuMhIKG/i84gLZ/hcJwKNyD4snZz2MmjUvEz4vFKHEySCUDZAbQqCWJQoDUqA YCqA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=/nV4R65tDruN/v686WfRixCHJzIvFZo2KvdAUUUu1dk=; b=cOdlckqcx8ZysG2G0ZM6K2n5RYy3ZLaq9a3DeNcP+Cp0xtw1/od7PU4QoqHlhMK/e/ H8liCNhJl5SsOX3mgCa01rWG31LX/EpAq+4Q0Yr0+iY/+aThuBFynFv54tBYnkkubaj9 NuuyIgYbvi25hZPWAeAGQ1Gl7vepjQysGVMXv0uhM9t/PTZ8zj46zV/+CychOTPDzUhu XGu6tkvKBbaVhhSU+EZBZUO+L3rEBgB6wuCpP5tAXtARLwhwGlCMqfw8dJMmY1k75DzI ITGwt5mwJzzYWMnbpxfdkrhIqX+LzcQt56P6gVtR7Q2F5EoouoRPRmd9pqUoVuZr9N4u k1nA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@messagingengine.com header.s=fm2 header.b=5OtGZGAB; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m10si2212408pgk.386.2019.03.06.13.44.49; Wed, 06 Mar 2019 13:45:05 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@messagingengine.com header.s=fm2 header.b=5OtGZGAB; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726477AbfCFVnw (ORCPT + 99 others); Wed, 6 Mar 2019 16:43:52 -0500 Received: from out2-smtp.messagingengine.com ([66.111.4.26]:46159 "EHLO out2-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726432AbfCFVnu (ORCPT ); Wed, 6 Mar 2019 16:43:50 -0500 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.nyi.internal (Postfix) with ESMTP id EADC121ADE; Wed, 6 Mar 2019 16:43:48 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute3.internal (MEProxy); Wed, 06 Mar 2019 16:43:48 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; bh=/nV4R65tDruN/v686WfRixCHJzIvFZo2KvdAUUUu1dk=; b=5OtGZGAB WsqVoXcmrnh6BKuzGnwKlhU4S2XSTVJph8MsUMc+o3c8o06lAUl5mkNgqO5Ou9pv 8apDP9RZOlDaDuIq/320o1mk7ZsLN00v3VJPsIcs8uYdNOO1qiT2VHmSYicXX17G 94ck4kvxMsX/RI7eK/cqselA2O/6pMwvejAkMXO5lMLfMweXuxRjWiZifrZK9jxs 0kDZEuq58ZxhgLlkU9KkP/+Ixm8OquQ/2V8fsgCoPNpyR/M6bnxdqEDHEG0otXLG hzoApEA6OG/2bsZ1Tv3XnwA0ihOZg8q/s6h1skhcaCw1L5dTz7M3/kzd/Ow1RGfY ECuZzFZrbvX5kg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedutddrfeeigdekjecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepfdfvohgsihhn ucevrdcujfgrrhguihhnghdfuceothhosghinheskhgvrhhnvghlrdhorhhgqeenucfkph epuddvgedrudeiledrhedrudehkeenucfrrghrrghmpehmrghilhhfrhhomhepthhosghi nheskhgvrhhnvghlrdhorhhgnecuvehluhhsthgvrhfuihiivgephe X-ME-Proxy: Received: from eros.localdomain (124-169-5-158.dyn.iinet.net.au [124.169.5.158]) by mail.messagingengine.com (Postfix) with ESMTPA id 5BA3CE4362; Wed, 6 Mar 2019 16:43:43 -0500 (EST) From: "Tobin C. Harding" To: Kees Cook , Shuah Khan Cc: "Tobin C. Harding" , Jann Horn , Andy Shevchenko , Randy Dunlap , Rasmus Villemoes , Stephen Rothwell , Andy Lutomirski , Daniel Micay , Arnd Bergmann , Miguel Ojeda , "Gustavo A. R. Silva" , Greg Kroah-Hartman , Alexander Shishkin , kernel-hardening@lists.openwall.com, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 6/7] lib/string: Add strscpy_pad() function Date: Thu, 7 Mar 2019 08:42:25 +1100 Message-Id: <20190306214226.14598-7-tobin@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190306214226.14598-1-tobin@kernel.org> References: <20190306214226.14598-1-tobin@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org We have a function to copy strings safely and we have a function to copy strings and zero the tail of the destination (if source string is shorter than destination buffer) but we do not have a function to do both at once. This means developers must write this themselves if they desire this functionality. This is a chore, and also leaves us open to off by one errors unnecessarily. Add a function that calls strscpy() then memset()s the tail to zero if the source string is shorter than the destination buffer. Signed-off-by: Tobin C. Harding --- include/linux/string.h | 4 ++++ lib/string.c | 47 +++++++++++++++++++++++++++++++++++------- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/include/linux/string.h b/include/linux/string.h index 7927b875f80c..bfe95bf5d07e 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -31,6 +31,10 @@ size_t strlcpy(char *, const char *, size_t); #ifndef __HAVE_ARCH_STRSCPY ssize_t strscpy(char *, const char *, size_t); #endif + +/* Wraps calls to strscpy()/memset(), no arch specific code required */ +ssize_t strscpy_pad(char *dest, const char *src, size_t count); + #ifndef __HAVE_ARCH_STRCAT extern char * strcat(char *, const char *); #endif diff --git a/lib/string.c b/lib/string.c index 38e4ca08e757..3a3353512184 100644 --- a/lib/string.c +++ b/lib/string.c @@ -159,11 +159,9 @@ EXPORT_SYMBOL(strlcpy); * @src: Where to copy the string from * @count: Size of destination buffer * - * Copy the string, or as much of it as fits, into the dest buffer. - * The routine returns the number of characters copied (not including - * the trailing NUL) or -E2BIG if the destination buffer wasn't big enough. - * The behavior is undefined if the string buffers overlap. - * The destination buffer is always NUL terminated, unless it's zero-sized. + * Copy the string, or as much of it as fits, into the dest buffer. The + * behavior is undefined if the string buffers overlap. The destination + * buffer is always NUL terminated, unless it's zero-sized. * * Preferred to strlcpy() since the API doesn't require reading memory * from the src string beyond the specified "count" bytes, and since @@ -173,8 +171,10 @@ EXPORT_SYMBOL(strlcpy); * * Preferred to strncpy() since it always returns a valid string, and * doesn't unnecessarily force the tail of the destination buffer to be - * zeroed. If the zeroing is desired, it's likely cleaner to use strscpy() - * with an overflow test, then just memset() the tail of the dest buffer. + * zeroed. If zeroing is desired please use strscpy_pad(). + * + * Return: The number of characters copied (not including the trailing + * %NUL) or -E2BIG if the destination buffer wasn't big enough. */ ssize_t strscpy(char *dest, const char *src, size_t count) { @@ -237,6 +237,39 @@ ssize_t strscpy(char *dest, const char *src, size_t count) EXPORT_SYMBOL(strscpy); #endif +/** + * strscpy_pad() - Copy a C-string into a sized buffer + * @dest: Where to copy the string to + * @src: Where to copy the string from + * @count: Size of destination buffer + * + * Copy the string, or as much of it as fits, into the dest buffer. The + * behavior is undefined if the string buffers overlap. The destination + * buffer is always %NUL terminated, unless it's zero-sized. + * + * If the source string is shorter than the destination buffer, zeros + * the tail of the destination buffer. + * + * For full explanation of why you may want to consider using the + * 'strscpy' functions please see the function docstring for strscpy(). + * + * Return: The number of characters copied (not including the trailing + * %NUL) or -E2BIG if the destination buffer wasn't big enough. + */ +ssize_t strscpy_pad(char *dest, const char *src, size_t count) +{ + ssize_t written; + + written = strscpy(dest, src, count); + if (written < 0 || written == count - 1) + return written; + + memset(dest + written + 1, 0, count - written - 1); + + return written; +} +EXPORT_SYMBOL(strscpy_pad); + #ifndef __HAVE_ARCH_STRCAT /** * strcat - Append one %NUL-terminated string to another -- 2.20.1