hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/lib/string.c
....@@ -27,6 +27,7 @@
2727 #include <linux/export.h>
2828 #include <linux/bug.h>
2929 #include <linux/errno.h>
30
+#include <linux/slab.h>
3031
3132 #include <asm/byteorder.h>
3233 #include <asm/word-at-a-time.h>
....@@ -172,8 +173,9 @@
172173 * doesn't unnecessarily force the tail of the destination buffer to be
173174 * zeroed. If zeroing is desired please use strscpy_pad().
174175 *
175
- * Return: The number of characters copied (not including the trailing
176
- * %NUL) or -E2BIG if the destination buffer wasn't big enough.
176
+ * Returns:
177
+ * * The number of characters copied (not including the trailing %NUL)
178
+ * * -E2BIG if count is 0 or @src was truncated.
177179 */
178180 ssize_t strscpy(char *dest, const char *src, size_t count)
179181 {
....@@ -181,7 +183,7 @@
181183 size_t max = count;
182184 long res = 0;
183185
184
- if (count == 0)
186
+ if (count == 0 || WARN_ON_ONCE(count > INT_MAX))
185187 return -E2BIG;
186188
187189 #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
....@@ -237,6 +239,40 @@
237239 #endif
238240
239241 /**
242
+ * strscpy_pad() - Copy a C-string into a sized buffer
243
+ * @dest: Where to copy the string to
244
+ * @src: Where to copy the string from
245
+ * @count: Size of destination buffer
246
+ *
247
+ * Copy the string, or as much of it as fits, into the dest buffer. The
248
+ * behavior is undefined if the string buffers overlap. The destination
249
+ * buffer is always %NUL terminated, unless it's zero-sized.
250
+ *
251
+ * If the source string is shorter than the destination buffer, zeros
252
+ * the tail of the destination buffer.
253
+ *
254
+ * For full explanation of why you may want to consider using the
255
+ * 'strscpy' functions please see the function docstring for strscpy().
256
+ *
257
+ * Returns:
258
+ * * The number of characters copied (not including the trailing %NUL)
259
+ * * -E2BIG if count is 0 or @src was truncated.
260
+ */
261
+ssize_t strscpy_pad(char *dest, const char *src, size_t count)
262
+{
263
+ ssize_t written;
264
+
265
+ written = strscpy(dest, src, count);
266
+ if (written < 0 || written == count - 1)
267
+ return written;
268
+
269
+ memset(dest + written + 1, 0, count - written - 1);
270
+
271
+ return written;
272
+}
273
+EXPORT_SYMBOL(strscpy_pad);
274
+
275
+/**
240276 * stpcpy - copy a string from src to dest returning a pointer to the new end
241277 * of dest, including src's %NUL-terminator. May overrun dest.
242278 * @dest: pointer to end of string being copied into. Must be large enough
....@@ -259,39 +295,6 @@
259295 return --dest;
260296 }
261297 EXPORT_SYMBOL(stpcpy);
262
-
263
-/**
264
- * strscpy_pad() - Copy a C-string into a sized buffer
265
- * @dest: Where to copy the string to
266
- * @src: Where to copy the string from
267
- * @count: Size of destination buffer
268
- *
269
- * Copy the string, or as much of it as fits, into the dest buffer. The
270
- * behavior is undefined if the string buffers overlap. The destination
271
- * buffer is always %NUL terminated, unless it's zero-sized.
272
- *
273
- * If the source string is shorter than the destination buffer, zeros
274
- * the tail of the destination buffer.
275
- *
276
- * For full explanation of why you may want to consider using the
277
- * 'strscpy' functions please see the function docstring for strscpy().
278
- *
279
- * Return: The number of characters copied (not including the trailing
280
- * %NUL) or -E2BIG if the destination buffer wasn't big enough.
281
- */
282
-ssize_t strscpy_pad(char *dest, const char *src, size_t count)
283
-{
284
- ssize_t written;
285
-
286
- written = strscpy(dest, src, count);
287
- if (written < 0 || written == count - 1)
288
- return written;
289
-
290
- memset(dest + written + 1, 0, count - written - 1);
291
-
292
- return written;
293
-}
294
-EXPORT_SYMBOL(strscpy_pad);
295298
296299 #ifndef __HAVE_ARCH_STRCAT
297300 /**
....@@ -423,6 +426,9 @@
423426 * strchr - Find the first occurrence of a character in a string
424427 * @s: The string to be searched
425428 * @c: The character to search for
429
+ *
430
+ * Note that the %NUL-terminator is considered part of the string, and can
431
+ * be searched for.
426432 */
427433 char *strchr(const char *s, int c)
428434 {
....@@ -452,6 +458,23 @@
452458 EXPORT_SYMBOL(strchrnul);
453459 #endif
454460
461
+/**
462
+ * strnchrnul - Find and return a character in a length limited string,
463
+ * or end of string
464
+ * @s: The string to be searched
465
+ * @count: The number of characters to be searched
466
+ * @c: The character to search for
467
+ *
468
+ * Returns pointer to the first occurrence of 'c' in s. If c is not found,
469
+ * then return a pointer to the last character of the string.
470
+ */
471
+char *strnchrnul(const char *s, size_t count, int c)
472
+{
473
+ while (count-- && *s && *s != (char)c)
474
+ s++;
475
+ return (char *)s;
476
+}
477
+
455478 #ifndef __HAVE_ARCH_STRRCHR
456479 /**
457480 * strrchr - Find the last occurrence of a character in a string
....@@ -476,12 +499,18 @@
476499 * @s: The string to be searched
477500 * @count: The number of characters to be searched
478501 * @c: The character to search for
502
+ *
503
+ * Note that the %NUL-terminator is considered part of the string, and can
504
+ * be searched for.
479505 */
480506 char *strnchr(const char *s, size_t count, int c)
481507 {
482
- for (; count-- && *s != '\0'; ++s)
508
+ while (count--) {
483509 if (*s == (char)c)
484510 return (char *)s;
511
+ if (*s++ == '\0')
512
+ break;
513
+ }
485514 return NULL;
486515 }
487516 EXPORT_SYMBOL(strnchr);
....@@ -694,6 +723,14 @@
694723 * @n: number of strings in the array or -1 for NULL terminated arrays
695724 * @string: string to match with
696725 *
726
+ * This routine will look for a string in an array of strings up to the
727
+ * n-th element in the array or until the first NULL element.
728
+ *
729
+ * Historically the value of -1 for @n, was used to search in arrays that
730
+ * are NULL terminated. However, the function does not make a distinction
731
+ * when finishing the search: either @n elements have been compared OR
732
+ * the first NULL element was found.
733
+ *
697734 * Return:
698735 * index of a @string in the @array if matches, or %-EINVAL otherwise.
699736 */
....@@ -722,6 +759,14 @@
722759 *
723760 * Returns index of @str in the @array or -EINVAL, just like match_string().
724761 * Uses sysfs_streq instead of strcmp for matching.
762
+ *
763
+ * This routine will look for a string in an array of strings up to the
764
+ * n-th element in the array or until the first NULL element.
765
+ *
766
+ * Historically the value of -1 for @n, was used to search in arrays that
767
+ * are NULL terminated. However, the function does not make a distinction
768
+ * when finishing the search: either @n elements have been compared OR
769
+ * the first NULL element was found.
725770 */
726771 int __sysfs_match_string(const char * const *array, size_t n, const char *str)
727772 {
....@@ -759,27 +804,6 @@
759804 }
760805 EXPORT_SYMBOL(memset);
761806 #endif
762
-
763
-/**
764
- * memzero_explicit - Fill a region of memory (e.g. sensitive
765
- * keying data) with 0s.
766
- * @s: Pointer to the start of the area.
767
- * @count: The size of the area.
768
- *
769
- * Note: usually using memset() is just fine (!), but in cases
770
- * where clearing out _local_ data at the end of a scope is
771
- * necessary, memzero_explicit() should be used instead in
772
- * order to prevent the compiler from optimising away zeroing.
773
- *
774
- * memzero_explicit() doesn't need an arch-specific version as
775
- * it just invokes the one of memset() implicitly.
776
- */
777
-void memzero_explicit(void *s, size_t count)
778
-{
779
- memset(s, 0, count);
780
- barrier_data(s);
781
-}
782
-EXPORT_SYMBOL(memzero_explicit);
783807
784808 #ifndef __HAVE_ARCH_MEMSET16
785809 /**