From patchwork Tue Sep 11 15:00:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Ga=C3=ABtan_Rivet?= X-Patchwork-Id: 44584 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 37D274C95; Tue, 11 Sep 2018 17:01:16 +0200 (CEST) Received: from mail-wr1-f67.google.com (mail-wr1-f67.google.com [209.85.221.67]) by dpdk.org (Postfix) with ESMTP id 011E94C94 for ; Tue, 11 Sep 2018 17:01:14 +0200 (CEST) Received: by mail-wr1-f67.google.com with SMTP id 20-v6so26382888wrb.12 for ; Tue, 11 Sep 2018 08:01:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ubQBRI6PeYg4rrDzLerhpP0ZbOiqiOGnXs4lnpsAFR0=; b=aV2suh+mdmGQZuipX0Au3aHCIFA3GCVcyM8pJf1dHwNyqFlVwYk/JR1WNQZENvRB08 g/7vWGsSM3YAL1aiS9KNAKyhECWOacDGuVBRJzomi1CQYXXyAqgv8zGBnYGk1Rg3RxHu Lw121mvwS6rBNcW8O79SICaYSCgbZF28qt/SIv7G6Js3Sw4P4E9sAAGOBnd6nJO1HYMr NK9+HW1qCwL6lCzgzgyFPJNnh6fZrmoP2Vq7Qb88vUShaPxTuTkuvN/dm6UTpM+w/6D+ S/4BrZwdjdsJ1FhiqDVTa9JD/AcmrCComICK691Az4wFJplp4fzkADKEeA0OTuH47D28 UbfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ubQBRI6PeYg4rrDzLerhpP0ZbOiqiOGnXs4lnpsAFR0=; b=dYOx7jWoVXY7jspKjbpksrHld7KaaDlpoJCyrv5nu4lCnvKsLYMQxYrIXVros9FHcJ xTR3jRd7+ViwfeaL5IBn6RnsKm+zzwTM1qYUOmk1T1x3GSi8W2SUd2+xzQ5PviMP4AjD Pt+kaq4KSVpUZONCNyqA3LiP7L/f7JDUM8pjkkQ8w8/TIjAG3G+e1MFdLe9Sp6fTY7cZ 9iXGv96tweeBiRMOhkzWD5P1nJlIX0sWX7EpcKXYWySqF/vkc1g7NQ4IyFYhIMXnnmNk hRNr19x6oo0JaRgH6/dMLWbDfYhPr+XffJ4StOzI9mBHW1ncm+OWg8SEP7hZkp1tbAUM kQrA== X-Gm-Message-State: APzg51CqzY0/iZnjut0aEo52630K/FfYuZVCT6Nv0IJfvjpAIDczTbU5 wr9SbWgi9WVrOPinqNs3hd8wWngM1co= X-Google-Smtp-Source: ANB0VdZNJOiFcinPwEKlGhh5fRlxw/COSfwrVph10qwFe2pRKLTyUVRznbhR89OCaND455IinDiiZg== X-Received: by 2002:adf:f984:: with SMTP id f4-v6mr19611997wrr.105.1536678073915; Tue, 11 Sep 2018 08:01:13 -0700 (PDT) Received: from bidouze.dev.6wind.com. (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id w3-v6sm23547924wrn.16.2018.09.11.08.01.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 11 Sep 2018 08:01:12 -0700 (PDT) From: Gaetan Rivet To: dev@dpdk.org Cc: Gaetan Rivet Date: Tue, 11 Sep 2018 17:00:49 +0200 Message-Id: <20180911150049.14755-1-gaetan.rivet@6wind.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: References: Subject: [dpdk-dev] [PATCH v2] eal: add strscpy function X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The strncpy function has long been deemed unsafe for use, in favor of strlcpy or snprintf. While snprintf is standard and strlcpy is still largely available, they both have issues regarding error checking and performance. Both will force reading the source buffer past the requested size if the input is not a proper c-string, and will return the expected number of bytes copied, meaning that error checking needs to verify that the number of bytes copied is not superior to the destination size. This contributes to awkward code flow, unclear error checking and potential issues with malformed input. The function strscpy has been discussed for some time already and has been made available in the linux kernel[1]. Propose this new function as a safe alternative. [1]: http://git.kernel.org/linus/30c44659f4a3 Signed-off-by: Gaetan Rivet Acked-by: Juhamatti Kuusisaari Acked-by: Ferruh Yigit --- v2: use rte_prefix, avoid assignment in if() I agree with the original email, here is a proposed implementation. I have added the function as part of 18.11 API proper, because this API is definitely not meant to change. This is not meant to be enforced on existing code, or even on new code. But I think it is better to have it available. lib/librte_eal/common/eal_common_string_fns.c | 26 +++++++++++++++++++ .../common/include/rte_string_fns.h | 23 ++++++++++++++++ lib/librte_eal/rte_eal_version.map | 7 +++++ 3 files changed, 56 insertions(+) diff --git a/lib/librte_eal/common/eal_common_string_fns.c b/lib/librte_eal/common/eal_common_string_fns.c index 6ac5f8289..60c5dd66f 100644 --- a/lib/librte_eal/common/eal_common_string_fns.c +++ b/lib/librte_eal/common/eal_common_string_fns.c @@ -38,3 +38,29 @@ rte_strsplit(char *string, int stringlen, errno = EINVAL; return -1; } + +/* Copy src string into dst. + * + * Return negative value and NUL-terminate if dst is too short, + * Otherwise return number of bytes copied. + */ +ssize_t +rte_strscpy(char *dst, const char *src, size_t dsize) +{ + size_t nleft = dsize; + size_t res = 0; + + /* Copy as many bytes as will fit. */ + while (nleft != 0) { + dst[res] = src[res]; + if (src[res] == '\0') + return res; + res++; + nleft--; + } + + /* Not enough room in dst, set NUL and return error. */ + if (res != 0) + dst[res - 1] = '\0'; + return -E2BIG; +} diff --git a/lib/librte_eal/common/include/rte_string_fns.h b/lib/librte_eal/common/include/rte_string_fns.h index 97597a148..ecd141b85 100644 --- a/lib/librte_eal/common/include/rte_string_fns.h +++ b/lib/librte_eal/common/include/rte_string_fns.h @@ -76,6 +76,29 @@ rte_strlcpy(char *dst, const char *src, size_t size) #endif /* RTE_USE_LIBBSD */ #endif /* BSDAPP */ +/** + * Copy string src to buffer dst of size dsize. + * At most dsize-1 chars will be copied. + * Always NUL-terminates, unless (dsize == 0). + * Returns number of bytes copied (terminating NUL-byte excluded) on success ; + * negative errno on error. + * + * @param dst + * The destination string. + * + * @param src + * The input string to be copied. + * + * @param dsize + * Length in bytes of the destination buffer. + * + * @return + * The number of bytes copied on success + * -E2BIG if the destination buffer is too small. + */ +ssize_t +rte_strscpy(char *dst, const char *src, size_t dsize); + #ifdef __cplusplus } #endif diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index 344a43d32..2031d7b15 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -262,6 +262,13 @@ DPDK_18.08 { } DPDK_18.05; +DPDK_18.11 { + global: + + rte_strscpy; + +} DPDK_18.08; + EXPERIMENTAL { global: