Skip to content

Commit ef95159

Browse files
keestorvalds
authored andcommitted
lib: move strtobool() to kstrtobool()
Create the kstrtobool_from_user() helper and move strtobool() logic into the new kstrtobool() (matching all the other kstrto* functions). Provides an inline wrapper for existing strtobool() callers. Signed-off-by: Kees Cook <keescook@chromium.org> Cc: Joe Perches <joe@perches.com> Cc: Andy Shevchenko <andy.shevchenko@gmail.com> Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: Amitkumar Karwar <akarwar@marvell.com> Cc: Nishant Sarmukadam <nishants@marvell.com> Cc: Kalle Valo <kvalo@codeaurora.org> Cc: Steve French <sfrench@samba.org> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent e3bde95 commit ef95159

File tree

4 files changed

+57
-30
lines changed

4 files changed

+57
-30
lines changed

include/linux/kernel.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ int __must_check kstrtou16(const char *s, unsigned int base, u16 *res);
357357
int __must_check kstrtos16(const char *s, unsigned int base, s16 *res);
358358
int __must_check kstrtou8(const char *s, unsigned int base, u8 *res);
359359
int __must_check kstrtos8(const char *s, unsigned int base, s8 *res);
360+
int __must_check kstrtobool(const char *s, bool *res);
360361

361362
int __must_check kstrtoull_from_user(const char __user *s, size_t count, unsigned int base, unsigned long long *res);
362363
int __must_check kstrtoll_from_user(const char __user *s, size_t count, unsigned int base, long long *res);
@@ -368,6 +369,7 @@ int __must_check kstrtou16_from_user(const char __user *s, size_t count, unsigne
368369
int __must_check kstrtos16_from_user(const char __user *s, size_t count, unsigned int base, s16 *res);
369370
int __must_check kstrtou8_from_user(const char __user *s, size_t count, unsigned int base, u8 *res);
370371
int __must_check kstrtos8_from_user(const char __user *s, size_t count, unsigned int base, s8 *res);
372+
int __must_check kstrtobool_from_user(const char __user *s, size_t count, bool *res);
371373

372374
static inline int __must_check kstrtou64_from_user(const char __user *s, size_t count, unsigned int base, u64 *res)
373375
{

include/linux/string.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,11 @@ extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
128128
extern void argv_free(char **argv);
129129

130130
extern bool sysfs_streq(const char *s1, const char *s2);
131-
extern int strtobool(const char *s, bool *res);
131+
extern int kstrtobool(const char *s, bool *res);
132+
static inline int strtobool(const char *s, bool *res)
133+
{
134+
return kstrtobool(s, res);
135+
}
132136

133137
int match_string(const char * const *array, size_t n, const char *string);
134138

lib/kstrtox.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,56 @@ int kstrtos8(const char *s, unsigned int base, s8 *res)
321321
}
322322
EXPORT_SYMBOL(kstrtos8);
323323

324+
/**
325+
* kstrtobool - convert common user inputs into boolean values
326+
* @s: input string
327+
* @res: result
328+
*
329+
* This routine returns 0 iff the first character is one of 'Yy1Nn0'.
330+
* Otherwise it will return -EINVAL. Value pointed to by res is
331+
* updated upon finding a match.
332+
*/
333+
int kstrtobool(const char *s, bool *res)
334+
{
335+
if (!s)
336+
return -EINVAL;
337+
338+
switch (s[0]) {
339+
case 'y':
340+
case 'Y':
341+
case '1':
342+
*res = true;
343+
return 0;
344+
case 'n':
345+
case 'N':
346+
case '0':
347+
*res = false;
348+
return 0;
349+
default:
350+
break;
351+
}
352+
353+
return -EINVAL;
354+
}
355+
EXPORT_SYMBOL(kstrtobool);
356+
357+
/*
358+
* Since "base" would be a nonsense argument, this open-codes the
359+
* _from_user helper instead of using the helper macro below.
360+
*/
361+
int kstrtobool_from_user(const char __user *s, size_t count, bool *res)
362+
{
363+
/* Longest string needed to differentiate, newline, terminator */
364+
char buf[4];
365+
366+
count = min(count, sizeof(buf) - 1);
367+
if (copy_from_user(buf, s, count))
368+
return -EFAULT;
369+
buf[count] = '\0';
370+
return kstrtobool(buf, res);
371+
}
372+
EXPORT_SYMBOL(kstrtobool_from_user);
373+
324374
#define kstrto_from_user(f, g, type) \
325375
int f(const char __user *s, size_t count, unsigned int base, type *res) \
326376
{ \

lib/string.c

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -656,35 +656,6 @@ int match_string(const char * const *array, size_t n, const char *string)
656656
}
657657
EXPORT_SYMBOL(match_string);
658658

659-
/**
660-
* strtobool - convert common user inputs into boolean values
661-
* @s: input string
662-
* @res: result
663-
*
664-
* This routine returns 0 iff the first character is one of 'Yy1Nn0'.
665-
* Otherwise it will return -EINVAL. Value pointed to by res is
666-
* updated upon finding a match.
667-
*/
668-
int strtobool(const char *s, bool *res)
669-
{
670-
switch (s[0]) {
671-
case 'y':
672-
case 'Y':
673-
case '1':
674-
*res = true;
675-
break;
676-
case 'n':
677-
case 'N':
678-
case '0':
679-
*res = false;
680-
break;
681-
default:
682-
return -EINVAL;
683-
}
684-
return 0;
685-
}
686-
EXPORT_SYMBOL(strtobool);
687-
688659
#ifndef __HAVE_ARCH_MEMSET
689660
/**
690661
* memset - Fill a region of memory with the given value

0 commit comments

Comments
 (0)