Skip to contentSkip to conversation

kstrto*: converting strings to integers done (hopefully) right

PATCH In review Alexey Dobriyan 2 participants 3 messages Feb 26, 2011 – Mar 2, 2011

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 kstrto*: converting strings to integers done (hopefully) right

1. simple_strto*() do not contain overflow checks and crufty, libc way to indicate failure.
2. strict_strto*() also do not have overflow checks but the name and comments pretend they do.
3. Both families have only "long long" and "long" variants, but users want strtou8()
4. Both "simple" and "strict" prefixes are wrong:
Simple doesn't exactly say what's so simple, strict should not exist because conversion should be strict by default.

The solution is to use "k" prefix and add convertors for more types. Enter

	kstrtoull()
	kstrtoll()
	kstrtoul()
	kstrtol()
	kstrtouint()
	kstrtoint()

	kstrtou64()
	kstrtos64()
	kstrtou32()
	kstrtos32()
	kstrtou16()
	kstrtos16()
	kstrtou8()
	kstrtos8()

Include runtime testsuite (somewhat incomplete) as well.

strict_strto*() become deprecated, stubbed to kstrto*() and eventually will be removed altogether.

Use kstrto*() in code today!

Note: on some archs _kstrtoul() and _kstrtol() are left in tree, even if
they'll be unused at runtime. This is temporarily solution, because I don't want to hardcode list of archs where these functions aren't needed. Current solution with sizeof() and __alignof__ at least always works.
---

Let's merge this into mainline, so I can send individual patches to subsystem maintainers. Whole tree is already converted locally.

 drivers/video/via/viafbdev.h |    3 -
 include/linux/kernel.h       |   70 ++++-
 lib/Kconfig.debug            |    3 +
 lib/Makefile                 |    2 +
 lib/kstrtox.c                |  227 +++++++++++++
 lib/test-kstrtox.c           |  739 ++++++++++++++++++++++++++++++++++++++++++
 lib/vsprintf.c               |  141 --------
 scripts/checkpatch.pl        |    4 +-
 8 files changed, 1039 insertions(+), 150 deletions(-)
 create mode 100644 lib/kstrtox.c
 create mode 100644 lib/test-kstrtox.c
drivers/video/via/viafbdev.h +0 -3
index d66f963..137996d 100644
@@ -94,9 +94,6 @@ extern int viafb_LCD_ON;
 extern int viafb_DVI_ON;
 extern int viafb_hotplug;
 
-extern int strict_strtoul(const char *cp, unsigned int base,
-	unsigned long *res);
-
 u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
 	*plvds_setting_info, struct lvds_chip_information
 	*plvds_chip_info, u8 index);
include/linux/kernel.h +66 -4

80 lines not on this page · raw message

lib/Kconfig.debug +3 -0
index 2b97418..d1b5951 100644
@@ -1236,3 +1236,6 @@ source "samples/Kconfig"
 source "lib/Kconfig.kgdb"
 
 source "lib/Kconfig.kmemcheck"
+
+config TEST_KSTRTOX
+	tristate "Test kstrto*() family of functions at runtime"
lib/Makefile +2 -0
index cbb774f..dfbf7d8 100644
@@ -22,6 +22,8 @@ lib-y	+= kobject.o kref.o klist.o
 obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
 	 bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
 	 string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o
+obj-y += kstrtox.o
+obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o
 
 ifeq ($(CONFIG_DEBUG_KOBJECT),y)
 CFLAGS_kobject.o += -DDEBUG
lib/kstrtox.c new file +227 -0

227 lines not on this page · raw message

lib/test-kstrtox.c new file +739 -0

739 lines not on this page · raw message

lib/vsprintf.c +0 -141

147 lines not on this page · raw message

scripts/checkpatch.pl +2 -2
index 4c0383d..58434b3 100755
@@ -2809,9 +2809,9 @@ sub process {
 			WARN("consider using a completion\n" . $herecurr);
 
 		}
-# recommend strict_strto* over simple_strto*
+# recommend kstrto* over simple_strto*
 		if ($line =~ /\bsimple_(strto.*?)\s*\(/) {
-			WARN("consider using strict_$1 in preference to simple_$1\n" . $herecurr);
+			WARN("consider using kstrto* in preference to simple_$1\n" . $herecurr);
 		}
 # check for __initcall(), use device_initcall() explicitly please
 		if ($line =~ /^.\s*__initcall\s*\(/) {
Signature · 1 line
1.7.3.4
maintainer
#1 lore raw
Quoted 28 lines · On Sat, 26 Feb 2011 14:47:08 +0200 Alexey Dobriyan <[email protected]> wrote:

1. simple_strto*() do not contain overflow checks and crufty, libc way to indicate failure.
2. strict_strto*() also do not have overflow checks but the name and comments pretend they do.
3. Both families have only "long long" and "long" variants, but users want strtou8()
4. Both "simple" and "strict" prefixes are wrong:
Simple doesn't exactly say what's so simple, strict should not exist because conversion should be strict by default.

The solution is to use "k" prefix and add convertors for more types. Enter

	kstrtoull()
	kstrtoll()
	kstrtoul()
	kstrtol()
	kstrtouint()
	kstrtoint()

	kstrtou64()
	kstrtos64()
	kstrtou32()
	kstrtos32()
	kstrtou16()
	kstrtos16()
	kstrtou8()
	kstrtos8()
Quoted 4 lines

Include runtime testsuite (somewhat incomplete) as well.

strict_strto*() become deprecated, stubbed to kstrto*() and eventually will be removed altogether.

Note that they're deprecated but not marked __deprecated. That's OK.

Quoted 1 line

Use kstrto*() in code today!

If you can stomach perl, please prepare a checkpatch patch which alerts people to the new regime.

Quoted 9 lines

Note: on some archs _kstrtoul() and _kstrtol() are left in tree, even if
they'll be unused at runtime. This is temporarily solution, because I don't want to hardcode list of archs where these functions aren't needed. Current solution with sizeof() and __alignof__ at least always works.
---

Let's merge this into mainline, so I can send individual patches to subsystem maintainers. Whole tree is already converted locally.

Talk to us about the tighter checking. There's a risk here that current userspace which "works" will cease to work if we add additional input checking. Even if that userspace was broken and just-happened-to-work, adding additional checks might cause disruption?

#2 lore raw
Quoted 7 lines · Andrew Morton
Quoted 1 line · On Sat, 26 Feb 2011 14:47:08 +0200 Alexey Dobriyan <[email protected]> wrote:

Use kstrto*() in code today!

If you can stomach perl, please prepare a checkpatch patch which alerts people to the new regime.

Ehh, checkpatch was updated.
scripts/checkpatch.pl | 4

Quoted 7 lines
Quoted 2 lines

Let's merge this into mainline, so I can send individual patches to subsystem maintainers. Whole tree is already converted locally.

Talk to us about the tighter checking. There's a risk here that current userspace which "works" will cease to work if we add additional input checking. Even if that userspace was broken and just-happened-to-work, adding additional checks might cause disruption?

What strict_ family of functions errorneously does is to not check for integer overflow in the result, so it'll happily eat a very long string full of _valid_ digits: "0xffffffffffffffffffffffffffffffffffffffffffff" will be converted to unsigned long even if it doesn't fit. But people don't use such long strings, so the risk is low.

Also, kstrto*() allow to use leading '+' for positive values, which is not restriction.

The rest should be the same.