diff options
| author | Ingo Molnar <mingo@kernel.org> | 2024-12-02 13:52:59 +0300 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2024-12-02 13:52:59 +0300 |
| commit | bcfd5f644c5b933cfb3c488220e40a03e011e8a4 (patch) | |
| tree | 66717ce2352b3e9a14b94ffe804db93b073eb525 /lib/string.c | |
| parent | faac6f105ef169e2e5678c14e1ffebf2a7d780b6 (diff) | |
| parent | 40384c840ea1944d7c5a392e8975ed088ecf0b37 (diff) | |
| download | linux-bcfd5f644c5b933cfb3c488220e40a03e011e8a4.tar.xz | |
Merge tag 'v6.13-rc1' into perf/core, to refresh the branch
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'lib/string.c')
| -rw-r--r-- | lib/string.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/lib/string.c b/lib/string.c index 76327b51e36f..eb4486ed40d2 100644 --- a/lib/string.c +++ b/lib/string.c @@ -104,6 +104,12 @@ char *strncpy(char *dest, const char *src, size_t count) EXPORT_SYMBOL(strncpy); #endif +#ifdef __BIG_ENDIAN +# define ALLBUTLAST_BYTE_MASK (~255ul) +#else +# define ALLBUTLAST_BYTE_MASK (~0ul >> 8) +#endif + ssize_t sized_strscpy(char *dest, const char *src, size_t count) { const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; @@ -147,13 +153,18 @@ ssize_t sized_strscpy(char *dest, const char *src, size_t count) *(unsigned long *)(dest+res) = c & zero_bytemask(data); return res + find_zero(data); } + count -= sizeof(unsigned long); + if (unlikely(!count)) { + c &= ALLBUTLAST_BYTE_MASK; + *(unsigned long *)(dest+res) = c; + return -E2BIG; + } *(unsigned long *)(dest+res) = c; res += sizeof(unsigned long); - count -= sizeof(unsigned long); max -= sizeof(unsigned long); } - while (count) { + while (count > 1) { char c; c = src[res]; @@ -164,11 +175,11 @@ ssize_t sized_strscpy(char *dest, const char *src, size_t count) count--; } - /* Hit buffer length without finding a NUL; force NUL-termination. */ - if (res) - dest[res-1] = '\0'; + /* Force NUL-termination. */ + dest[res] = '\0'; - return -E2BIG; + /* Return E2BIG if the source didn't stop */ + return src[res] ? -E2BIG : res; } EXPORT_SYMBOL(sized_strscpy); |
