Re: Writing to a const pointer: is this supposed to happen?

From: Kars Mulder
Date: Sat Jul 04 2020 - 16:32:57 EST


On Saturday, July 04, 2020 16:39 CEST, Andy Shevchenko wrote:
> > I've searched for a function that parses an int from a string and
> > stores a pointer to the end; I can find some function simple_strtoul
> > that matches this criterion, but it's documented as
> >
> > "This function has caveats. Please use kstrtoul instead."
> >
> > ... and kstrtoul does not store a pointer to the end. The documentation
> > of kstrtoul describes simple_strtoul as obsolete as well.
>
>
> Where? We need to fix that, because using simple_strto*() is fairly legal
> in cases like this, but "has caveats".

In lib/vsprintf.c, the comments before the function's implementation say:

/**
* simple_strtoul - convert a string to an unsigned long
* @cp: The start of the string
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*
* This function has caveats. Please use kstrtoul instead.
*/

Many variants upon kstrtoul, such as kstrtoull, defined in lib/kstrtox.c,
describe the simple_strtoull function as obsolete:

/**
* kstrtoull - convert a string to an unsigned long long
* [...]
*
* Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
* Used as a replacement for the obsolete simple_strtoull. Return code must
* be checked.
*/

I seem to have been slightly inaccurate about my claim that "kstrtoul"
describes simple_strtoul as "obsolete" though, because in the specific
case of kstrtoul, include/linux/kernel.h only says:

/**
* kstrtoul - convert a string to an unsigned long
* [...]
*
* Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
* Used as a replacement for the simple_strtoull. Return code must be checked.
*/

(Also, there may be a documentation error here: all kstrto* functions in
kstrtox.c and kernel.h describe themselves as replacements of simple_strtoull.
E.g. kstrtol and kstrtoul also describe themselves as replacements of
simple_strtoull rather than as a replacements of simple_strtol and
simple_strtoul respectively.)

By the way, I found the documentation of the caveat somewhere in
include/linux/kernel.h:

/*
* Use kstrto<foo> instead.
*
* NOTE: simple_strto<foo> does not check for the range overflow and,
* depending on the input, may give interesting results.
*
* Use these functions if and only if you cannot use kstrto<foo>, because
* the conversion ends on the first non-digit character, which may be far
* beyond the supported range. It might be useful to parse the strings like
* 10x50 or 12:21 without altering original string or temporary buffer in use.
* Keep in mind above caveat.
*/