Merge branch 'strscpy' of git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile

Pull strscpy string copy function implementation from Chris Metcalf.

Chris sent this during the merge window, but I waffled back and forth on
the pull request, which is why it's going in only now.

The new "strscpy()" function is definitely easier to use and more secure
than either strncpy() or strlcpy(), both of which are horrible nasty
interfaces that have serious and irredeemable problems.

strncpy() has a useless return value, and doesn't NUL-terminate an
overlong result. To make matters worse, it pads a short result with
zeroes, which is a performance disaster if you have big buffers.

strlcpy(), by contrast, is a mis-designed "fix" for strlcpy(), lacking
the insane NUL padding, but having a differently broken return value
which returns the original length of the source string. Which means
that it will read characters past the count from the source buffer, and
you have to trust the source to be properly terminated. It also makes
error handling fragile, since the test for overflow is unnecessarily
subtle.

strscpy() avoids both these problems, guaranteeing the NUL termination
(but not excessive padding) if the destination size wasn't zero, and
making the overflow condition very obvious by returning -E2BIG. It also
doesn't read past the size of the source, and can thus be used for
untrusted source data too.

So why did I waffle about this for so long?

Every time we introduce a new-and-improved interface, people start doing
these interminable series of trivial conversion patches.

And every time that happens, somebody does some silly mistake, and the
conversion patch to the improved interface actually makes things worse.
Because the patch is mindnumbing and trivial, nobody has the attention
span to look at it carefully, and it's usually done over large swatches
of source code which means that not every conversion gets tested.

So I'm pulling the strscpy() support because it *is* a better interface.
But I will refuse to pull mindless conversion patches. Use this in
places where it makes sense, but don't do trivial patches to fix things
that aren't actually known to be broken.

* 'strscpy' of git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile:
tile: use global strscpy() rather than private copy
string: provide strscpy()
Make asm/word-at-a-time.h available on all architectures

Changed files
+188 -37
arch
arc
include
asm
avr32
include
asm
blackfin
include
asm
c6x
include
asm
cris
include
asm
frv
include
asm
hexagon
include
asm
ia64
include
asm
m32r
include
asm
metag
include
asm
microblaze
include
asm
mips
include
asm
mn10300
include
asm
nios2
include
asm
powerpc
include
asm
s390
include
asm
score
include
asm
tile
gxio
include
asm
um
include
asm
unicore32
include
asm
xtensa
include
asm
include
asm-generic
linux
lib
+1
arch/arc/include/asm/Kbuild
··· 48 48 generic-y += ucontext.h 49 49 generic-y += user.h 50 50 generic-y += vga.h 51 + generic-y += word-at-a-time.h 51 52 generic-y += xor.h
+1
arch/avr32/include/asm/Kbuild
··· 20 20 generic-y += topology.h 21 21 generic-y += trace_clock.h 22 22 generic-y += vga.h 23 + generic-y += word-at-a-time.h 23 24 generic-y += xor.h
+1
arch/blackfin/include/asm/Kbuild
··· 46 46 generic-y += ucontext.h 47 47 generic-y += unaligned.h 48 48 generic-y += user.h 49 + generic-y += word-at-a-time.h 49 50 generic-y += xor.h
+1
arch/c6x/include/asm/Kbuild
··· 59 59 generic-y += ucontext.h 60 60 generic-y += user.h 61 61 generic-y += vga.h 62 + generic-y += word-at-a-time.h 62 63 generic-y += xor.h
+1
arch/cris/include/asm/Kbuild
··· 43 43 generic-y += trace_clock.h 44 44 generic-y += types.h 45 45 generic-y += vga.h 46 + generic-y += word-at-a-time.h 46 47 generic-y += xor.h
+1
arch/frv/include/asm/Kbuild
··· 7 7 generic-y += mm-arch-hooks.h 8 8 generic-y += preempt.h 9 9 generic-y += trace_clock.h 10 + generic-y += word-at-a-time.h
+1
arch/hexagon/include/asm/Kbuild
··· 58 58 generic-y += ucontext.h 59 59 generic-y += unaligned.h 60 60 generic-y += vga.h 61 + generic-y += word-at-a-time.h 61 62 generic-y += xor.h
+1
arch/ia64/include/asm/Kbuild
··· 8 8 generic-y += preempt.h 9 9 generic-y += trace_clock.h 10 10 generic-y += vtime.h 11 + generic-y += word-at-a-time.h
+1
arch/m32r/include/asm/Kbuild
··· 9 9 generic-y += preempt.h 10 10 generic-y += sections.h 11 11 generic-y += trace_clock.h 12 + generic-y += word-at-a-time.h
+1
arch/metag/include/asm/Kbuild
··· 54 54 generic-y += unaligned.h 55 55 generic-y += user.h 56 56 generic-y += vga.h 57 + generic-y += word-at-a-time.h 57 58 generic-y += xor.h
+1
arch/microblaze/include/asm/Kbuild
··· 10 10 generic-y += preempt.h 11 11 generic-y += syscalls.h 12 12 generic-y += trace_clock.h 13 + generic-y += word-at-a-time.h
+1
arch/mips/include/asm/Kbuild
··· 17 17 generic-y += serial.h 18 18 generic-y += trace_clock.h 19 19 generic-y += user.h 20 + generic-y += word-at-a-time.h 20 21 generic-y += xor.h
+1
arch/mn10300/include/asm/Kbuild
··· 9 9 generic-y += preempt.h 10 10 generic-y += sections.h 11 11 generic-y += trace_clock.h 12 + generic-y += word-at-a-time.h
+1
arch/nios2/include/asm/Kbuild
··· 61 61 generic-y += unaligned.h 62 62 generic-y += user.h 63 63 generic-y += vga.h 64 + generic-y += word-at-a-time.h 64 65 generic-y += xor.h
+1
arch/powerpc/include/asm/Kbuild
··· 7 7 generic-y += preempt.h 8 8 generic-y += rwsem.h 9 9 generic-y += vtime.h 10 + generic-y += word-at-a-time.h
+1
arch/s390/include/asm/Kbuild
··· 6 6 generic-y += mm-arch-hooks.h 7 7 generic-y += preempt.h 8 8 generic-y += trace_clock.h 9 + generic-y += word-at-a-time.h
+1
arch/score/include/asm/Kbuild
··· 13 13 generic-y += trace_clock.h 14 14 generic-y += xor.h 15 15 generic-y += serial.h 16 + generic-y += word-at-a-time.h
+4 -29
arch/tile/gxio/mpipe.c
··· 19 19 #include <linux/errno.h> 20 20 #include <linux/io.h> 21 21 #include <linux/module.h> 22 + #include <linux/string.h> 22 23 23 24 #include <gxio/iorpc_globals.h> 24 25 #include <gxio/iorpc_mpipe.h> ··· 29 28 30 29 /* HACK: Avoid pointless "shadow" warnings. */ 31 30 #define link link_shadow 32 - 33 - /** 34 - * strscpy - Copy a C-string into a sized buffer, but only if it fits 35 - * @dest: Where to copy the string to 36 - * @src: Where to copy the string from 37 - * @size: size of destination buffer 38 - * 39 - * Use this routine to avoid copying too-long strings. 40 - * The routine returns the total number of bytes copied 41 - * (including the trailing NUL) or zero if the buffer wasn't 42 - * big enough. To ensure that programmers pay attention 43 - * to the return code, the destination has a single NUL 44 - * written at the front (if size is non-zero) when the 45 - * buffer is not big enough. 46 - */ 47 - static size_t strscpy(char *dest, const char *src, size_t size) 48 - { 49 - size_t len = strnlen(src, size) + 1; 50 - if (len > size) { 51 - if (size) 52 - dest[0] = '\0'; 53 - return 0; 54 - } 55 - memcpy(dest, src, len); 56 - return len; 57 - } 58 31 59 32 int gxio_mpipe_init(gxio_mpipe_context_t *context, unsigned int mpipe_index) 60 33 { ··· 515 540 if (!context) 516 541 return GXIO_ERR_NO_DEVICE; 517 542 518 - if (strscpy(name.name, link_name, sizeof(name.name)) == 0) 543 + if (strscpy(name.name, link_name, sizeof(name.name)) < 0) 519 544 return GXIO_ERR_NO_DEVICE; 520 545 521 546 return gxio_mpipe_info_instance_aux(context, name); ··· 534 559 535 560 rv = gxio_mpipe_info_enumerate_aux(context, idx, &name, &mac); 536 561 if (rv >= 0) { 537 - if (strscpy(link_name, name.name, sizeof(name.name)) == 0) 562 + if (strscpy(link_name, name.name, sizeof(name.name)) < 0) 538 563 return GXIO_ERR_INVAL_MEMORY_SIZE; 539 564 memcpy(link_mac, mac.mac, sizeof(mac.mac)); 540 565 } ··· 551 576 _gxio_mpipe_link_name_t name; 552 577 int rv; 553 578 554 - if (strscpy(name.name, link_name, sizeof(name.name)) == 0) 579 + if (strscpy(name.name, link_name, sizeof(name.name)) < 0) 555 580 return GXIO_ERR_NO_DEVICE; 556 581 557 582 rv = gxio_mpipe_link_open_aux(context, name, flags);
+1
arch/tile/include/asm/Kbuild
··· 40 40 generic-y += termios.h 41 41 generic-y += trace_clock.h 42 42 generic-y += types.h 43 + generic-y += word-at-a-time.h 43 44 generic-y += xor.h
+1
arch/um/include/asm/Kbuild
··· 25 25 generic-y += switch_to.h 26 26 generic-y += topology.h 27 27 generic-y += trace_clock.h 28 + generic-y += word-at-a-time.h 28 29 generic-y += xor.h
+1
arch/unicore32/include/asm/Kbuild
··· 62 62 generic-y += unaligned.h 63 63 generic-y += user.h 64 64 generic-y += vga.h 65 + generic-y += word-at-a-time.h 65 66 generic-y += xor.h
+1
arch/xtensa/include/asm/Kbuild
··· 28 28 generic-y += termios.h 29 29 generic-y += topology.h 30 30 generic-y += trace_clock.h 31 + generic-y += word-at-a-time.h 31 32 generic-y += xor.h
+72 -8
include/asm-generic/word-at-a-time.h
··· 1 1 #ifndef _ASM_WORD_AT_A_TIME_H 2 2 #define _ASM_WORD_AT_A_TIME_H 3 3 4 - /* 5 - * This says "generic", but it's actually big-endian only. 6 - * Little-endian can use more efficient versions of these 7 - * interfaces, see for example 8 - * arch/x86/include/asm/word-at-a-time.h 9 - * for those. 10 - */ 11 - 12 4 #include <linux/kernel.h> 5 + #include <asm/byteorder.h> 6 + 7 + #ifdef __BIG_ENDIAN 13 8 14 9 struct word_at_a_time { 15 10 const unsigned long high_bits, low_bits; ··· 47 52 #ifndef zero_bytemask 48 53 #define zero_bytemask(mask) (~1ul << __fls(mask)) 49 54 #endif 55 + 56 + #else 57 + 58 + /* 59 + * The optimal byte mask counting is probably going to be something 60 + * that is architecture-specific. If you have a reliably fast 61 + * bit count instruction, that might be better than the multiply 62 + * and shift, for example. 63 + */ 64 + struct word_at_a_time { 65 + const unsigned long one_bits, high_bits; 66 + }; 67 + 68 + #define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) } 69 + 70 + #ifdef CONFIG_64BIT 71 + 72 + /* 73 + * Jan Achrenius on G+: microoptimized version of 74 + * the simpler "(mask & ONEBYTES) * ONEBYTES >> 56" 75 + * that works for the bytemasks without having to 76 + * mask them first. 77 + */ 78 + static inline long count_masked_bytes(unsigned long mask) 79 + { 80 + return mask*0x0001020304050608ul >> 56; 81 + } 82 + 83 + #else /* 32-bit case */ 84 + 85 + /* Carl Chatfield / Jan Achrenius G+ version for 32-bit */ 86 + static inline long count_masked_bytes(long mask) 87 + { 88 + /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */ 89 + long a = (0x0ff0001+mask) >> 23; 90 + /* Fix the 1 for 00 case */ 91 + return a & mask; 92 + } 93 + 94 + #endif 95 + 96 + /* Return nonzero if it has a zero */ 97 + static inline unsigned long has_zero(unsigned long a, unsigned long *bits, const struct word_at_a_time *c) 98 + { 99 + unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits; 100 + *bits = mask; 101 + return mask; 102 + } 103 + 104 + static inline unsigned long prep_zero_mask(unsigned long a, unsigned long bits, const struct word_at_a_time *c) 105 + { 106 + return bits; 107 + } 108 + 109 + static inline unsigned long create_zero_mask(unsigned long bits) 110 + { 111 + bits = (bits - 1) & ~bits; 112 + return bits >> 7; 113 + } 114 + 115 + /* The mask we created is directly usable as a bytemask */ 116 + #define zero_bytemask(mask) (mask) 117 + 118 + static inline unsigned long find_zero(unsigned long mask) 119 + { 120 + return count_masked_bytes(mask); 121 + } 122 + 123 + #endif /* __BIG_ENDIAN */ 50 124 51 125 #endif /* _ASM_WORD_AT_A_TIME_H */
+3
include/linux/string.h
··· 25 25 #ifndef __HAVE_ARCH_STRLCPY 26 26 size_t strlcpy(char *, const char *, size_t); 27 27 #endif 28 + #ifndef __HAVE_ARCH_STRSCPY 29 + ssize_t __must_check strscpy(char *, const char *, size_t); 30 + #endif 28 31 #ifndef __HAVE_ARCH_STRCAT 29 32 extern char * strcat(char *, const char *); 30 33 #endif
+88
lib/string.c
··· 27 27 #include <linux/bug.h> 28 28 #include <linux/errno.h> 29 29 30 + #include <asm/byteorder.h> 31 + #include <asm/word-at-a-time.h> 32 + #include <asm/page.h> 33 + 30 34 #ifndef __HAVE_ARCH_STRNCASECMP 31 35 /** 32 36 * strncasecmp - Case insensitive, length-limited string comparison ··· 148 144 return ret; 149 145 } 150 146 EXPORT_SYMBOL(strlcpy); 147 + #endif 148 + 149 + #ifndef __HAVE_ARCH_STRSCPY 150 + /** 151 + * strscpy - Copy a C-string into a sized buffer 152 + * @dest: Where to copy the string to 153 + * @src: Where to copy the string from 154 + * @count: Size of destination buffer 155 + * 156 + * Copy the string, or as much of it as fits, into the dest buffer. 157 + * The routine returns the number of characters copied (not including 158 + * the trailing NUL) or -E2BIG if the destination buffer wasn't big enough. 159 + * The behavior is undefined if the string buffers overlap. 160 + * The destination buffer is always NUL terminated, unless it's zero-sized. 161 + * 162 + * Preferred to strlcpy() since the API doesn't require reading memory 163 + * from the src string beyond the specified "count" bytes, and since 164 + * the return value is easier to error-check than strlcpy()'s. 165 + * In addition, the implementation is robust to the string changing out 166 + * from underneath it, unlike the current strlcpy() implementation. 167 + * 168 + * Preferred to strncpy() since it always returns a valid string, and 169 + * doesn't unnecessarily force the tail of the destination buffer to be 170 + * zeroed. If the zeroing is desired, it's likely cleaner to use strscpy() 171 + * with an overflow test, then just memset() the tail of the dest buffer. 172 + */ 173 + ssize_t strscpy(char *dest, const char *src, size_t count) 174 + { 175 + const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; 176 + size_t max = count; 177 + long res = 0; 178 + 179 + if (count == 0) 180 + return -E2BIG; 181 + 182 + #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 183 + /* 184 + * If src is unaligned, don't cross a page boundary, 185 + * since we don't know if the next page is mapped. 186 + */ 187 + if ((long)src & (sizeof(long) - 1)) { 188 + size_t limit = PAGE_SIZE - ((long)src & (PAGE_SIZE - 1)); 189 + if (limit < max) 190 + max = limit; 191 + } 192 + #else 193 + /* If src or dest is unaligned, don't do word-at-a-time. */ 194 + if (((long) dest | (long) src) & (sizeof(long) - 1)) 195 + max = 0; 196 + #endif 197 + 198 + while (max >= sizeof(unsigned long)) { 199 + unsigned long c, data; 200 + 201 + c = *(unsigned long *)(src+res); 202 + *(unsigned long *)(dest+res) = c; 203 + if (has_zero(c, &data, &constants)) { 204 + data = prep_zero_mask(c, data, &constants); 205 + data = create_zero_mask(data); 206 + return res + find_zero(data); 207 + } 208 + res += sizeof(unsigned long); 209 + count -= sizeof(unsigned long); 210 + max -= sizeof(unsigned long); 211 + } 212 + 213 + while (count) { 214 + char c; 215 + 216 + c = src[res]; 217 + dest[res] = c; 218 + if (!c) 219 + return res; 220 + res++; 221 + count--; 222 + } 223 + 224 + /* Hit buffer length without finding a NUL; force NUL-termination. */ 225 + if (res) 226 + dest[res-1] = '\0'; 227 + 228 + return -E2BIG; 229 + } 230 + EXPORT_SYMBOL(strscpy); 151 231 #endif 152 232 153 233 #ifndef __HAVE_ARCH_STRCAT