drivers/crypto/intel/qat/qat_common/qat_uclo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
Use strscpy_pad() to copy the string and zero-pad the destination buffer
in a single step instead of zero-initializing the buffer first and then
immediately overwriting it using strscpy().
Replace the magic number 16 with sizeof(buf) and remove the redundant
parentheses around kstrtoul() while we're at it.
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
---
drivers/crypto/intel/qat/qat_common/qat_uclo.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/crypto/intel/qat/qat_common/qat_uclo.c b/drivers/crypto/intel/qat/qat_common/qat_uclo.c
index 18c3e4416dc5..41a7bd434e97 100644
--- a/drivers/crypto/intel/qat/qat_common/qat_uclo.c
+++ b/drivers/crypto/intel/qat/qat_common/qat_uclo.c
@@ -200,18 +200,18 @@ qat_uclo_cleanup_batch_init_list(struct icp_qat_fw_loader_handle *handle,
static int qat_uclo_parse_num(char *str, unsigned int *num)
{
- char buf[16] = {0};
+ char buf[16] = {};
unsigned long ae = 0;
int i;
- strscpy(buf, str, sizeof(buf));
- for (i = 0; i < 16; i++) {
+ strscpy_pad(buf, str);
+ for (i = 0; i < sizeof(buf); i++) {
if (!isdigit(buf[i])) {
buf[i] = '\0';
break;
}
}
- if ((kstrtoul(buf, 10, &ae)))
+ if (kstrtoul(buf, 10, &ae))
return -EFAULT;
*num = (unsigned int)ae;
--
2.51.0
On Wed, Oct 22, 2025 at 02:36:19PM +0200, Thorsten Blum wrote:
> Use strscpy_pad() to copy the string and zero-pad the destination buffer
> in a single step instead of zero-initializing the buffer first and then
> immediately overwriting it using strscpy().
>
> Replace the magic number 16 with sizeof(buf) and remove the redundant
> parentheses around kstrtoul() while we're at it.
I understand that you focused on strscpy*() conversions, but the below I think
needs a bigger refactoring, see my remarks.
...
> - char buf[16] = {0};
> + char buf[16] = {};
> unsigned long ae = 0;
> int i;
>
> - strscpy(buf, str, sizeof(buf));
> - for (i = 0; i < 16; i++) {
> + strscpy_pad(buf, str);
First of all, why do we need a _pad() version here? Is the data somehow being
used as a whole?
> + for (i = 0; i < sizeof(buf); i++) {
> if (!isdigit(buf[i])) {
> buf[i] = '\0';
> break;
> }
> }
> - if ((kstrtoul(buf, 10, &ae)))
> + if (kstrtoul(buf, 10, &ae))
> return -EFAULT;
Looking at this, it tries to work around the kstrtoul() inability to perform
partial parses. Instead, this should do something like
unsigned long long x;
const char *end;
simple_strtoull(...);
if (x > UINT_MAX || end == buf)
return $ERR; // wrong input / overflow
--
With Best Regards,
Andy Shevchenko
On 22. Oct 2025, at 20:17, Andy Shevchenko wrote:
> On Wed, Oct 22, 2025 at 02:36:19PM +0200, Thorsten Blum wrote:
>> Use strscpy_pad() to copy the string and zero-pad the destination buffer
>> in a single step instead of zero-initializing the buffer first and then
>> immediately overwriting it using strscpy().
>>
>> Replace the magic number 16 with sizeof(buf) and remove the redundant
>> parentheses around kstrtoul() while we're at it.
>
> I understand that you focused on strscpy*() conversions, but the below I think
> needs a bigger refactoring, see my remarks.
>
> ...
>
>> - char buf[16] = {0};
>> + char buf[16] = {};
Sorry, this should have been just 'char buf[16];' since {} and {0} are
equivalent and both zero-initialize the array.
>> unsigned long ae = 0;
>> int i;
>>
>> - strscpy(buf, str, sizeof(buf));
>> - for (i = 0; i < 16; i++) {
>> + strscpy_pad(buf, str);
>
> First of all, why do we need a _pad() version here? Is the data somehow being
> used as a whole?
I honestly didn't question this, but it looks like strscpy() would be
sufficient (with this approach at least).
>> + for (i = 0; i < sizeof(buf); i++) {
>> if (!isdigit(buf[i])) {
>> buf[i] = '\0';
>> break;
>> }
>> }
>> - if ((kstrtoul(buf, 10, &ae)))
>> + if (kstrtoul(buf, 10, &ae))
>> return -EFAULT;
>
> Looking at this, it tries to work around the kstrtoul() inability to perform
> partial parses. Instead, this should do something like
>
> unsigned long long x;
> const char *end;
>
> simple_strtoull(...);
> if (x > UINT_MAX || end == buf)
> return $ERR; // wrong input / overflow
How about this?
diff --git a/drivers/crypto/intel/qat/qat_common/qat_uclo.c b/drivers/crypto/intel/qat/qat_common/qat_uclo.c
index 18c3e4416dc5..04628dc01456 100644
--- a/drivers/crypto/intel/qat/qat_common/qat_uclo.c
+++ b/drivers/crypto/intel/qat/qat_common/qat_uclo.c
@@ -200,20 +200,12 @@ qat_uclo_cleanup_batch_init_list(struct icp_qat_fw_loader_handle *handle,
static int qat_uclo_parse_num(char *str, unsigned int *num)
{
- char buf[16] = {0};
- unsigned long ae = 0;
- int i;
-
- strscpy(buf, str, sizeof(buf));
- for (i = 0; i < 16; i++) {
- if (!isdigit(buf[i])) {
- buf[i] = '\0';
- break;
- }
- }
- if ((kstrtoul(buf, 10, &ae)))
- return -EFAULT;
+ unsigned long long ae;
+ char *end;
+ ae = simple_strtoull(str, &end, 10);
+ if (ae > UINT_MAX || str == end || (end - str) > 20)
+ return -EINVAL;
*num = (unsigned int)ae;
return 0;
}
On Thu, Oct 23, 2025 at 05:35:00PM +0200, Thorsten Blum wrote:
> On 22. Oct 2025, at 20:17, Andy Shevchenko wrote:
> > On Wed, Oct 22, 2025 at 02:36:19PM +0200, Thorsten Blum wrote:
...
> How about this?
LGTM, and that's what I had in mind, but please double check the behaviour of
kstrtox() on an empty strings.
> diff --git a/drivers/crypto/intel/qat/qat_common/qat_uclo.c b/drivers/crypto/intel/qat/qat_common/qat_uclo.c
> index 18c3e4416dc5..04628dc01456 100644
> --- a/drivers/crypto/intel/qat/qat_common/qat_uclo.c
> +++ b/drivers/crypto/intel/qat/qat_common/qat_uclo.c
> @@ -200,20 +200,12 @@ qat_uclo_cleanup_batch_init_list(struct icp_qat_fw_loader_handle *handle,
>
> static int qat_uclo_parse_num(char *str, unsigned int *num)
> {
> - char buf[16] = {0};
> - unsigned long ae = 0;
> - int i;
> -
> - strscpy(buf, str, sizeof(buf));
> - for (i = 0; i < 16; i++) {
> - if (!isdigit(buf[i])) {
> - buf[i] = '\0';
> - break;
> - }
> - }
> - if ((kstrtoul(buf, 10, &ae)))
> - return -EFAULT;
> + unsigned long long ae;
> + char *end;
>
> + ae = simple_strtoull(str, &end, 10);
> + if (ae > UINT_MAX || str == end || (end - str) > 20)
I would go with >= 20, the 64-bit value is approx. 1 * 10^19.
> + return -EINVAL;
> *num = (unsigned int)ae;
> return 0;
> }
--
With Best Regards,
Andy Shevchenko
Hi Andy, On 23. Oct 2025, at 20:44, Andy Shevchenko wrote: > On Thu, Oct 23, 2025 at 05:35:00PM +0200, Thorsten Blum wrote: >> On 22. Oct 2025, at 20:17, Andy Shevchenko wrote: >>> On Wed, Oct 22, 2025 at 02:36:19PM +0200, Thorsten Blum wrote: > > ... > >> How about this? > > LGTM, and that's what I had in mind, ... I was about to submit v2, but checkpatch warns me about simple_strtoull: WARNING: simple_strtoull is obsolete, use kstrtoull instead Any recommendations? Thanks, Thorsten
On Fri, Oct 24, 2025 at 08:47:02PM +0200, Thorsten Blum wrote:
> On 23. Oct 2025, at 20:44, Andy Shevchenko wrote:
> > On Thu, Oct 23, 2025 at 05:35:00PM +0200, Thorsten Blum wrote:
> >> On 22. Oct 2025, at 20:17, Andy Shevchenko wrote:
> >>> On Wed, Oct 22, 2025 at 02:36:19PM +0200, Thorsten Blum wrote:
...
> >> How about this?
> >
> > LGTM, and that's what I had in mind, ...
>
> I was about to submit v2, but checkpatch warns me about simple_strtoull:
>
> WARNING: simple_strtoull is obsolete, use kstrtoull instead
>
> Any recommendations?
Yes, fix checkpatch as per commit 885e68e8b7b1 ("kernel.h: update comment about
simple_strto<foo>() functions") or ignore this false positive.
--
With Best Regards,
Andy Shevchenko
On 27. Oct 2025, at 09:19, Andy Shevchenko wrote:
> On Fri, Oct 24, 2025 at 08:47:02PM +0200, Thorsten Blum wrote:
>> [...]
>> Any recommendations?
>
> Yes, fix checkpatch as per commit 885e68e8b7b1 ("kernel.h: update comment about
> simple_strto<foo>() functions") or ignore this false positive.
Thanks for the commit hash. I ignored it and submitted v2:
https://lore.kernel.org/lkml/20251026015710.1368-1-thorsten.blum@linux.dev/
On Thu, Oct 23, 2025 at 09:44:01PM +0300, Andy Shevchenko wrote:
> On Thu, Oct 23, 2025 at 05:35:00PM +0200, Thorsten Blum wrote:
> > On 22. Oct 2025, at 20:17, Andy Shevchenko wrote:
> > > On Wed, Oct 22, 2025 at 02:36:19PM +0200, Thorsten Blum wrote:
>
> ...
>
> > How about this?
>
> LGTM, and that's what I had in mind, but please double check the behaviour of
> kstrtox() on an empty strings.
LGTM as well.
I checked the behaviour of kstrtoul() when given an empty string. It
returns -EINVAL (-22). The result variable (the third parameter) is only
modified if the conversion is succesful.
Anyway, the caller will not provide a NULL string to this function [1].
> > diff --git a/drivers/crypto/intel/qat/qat_common/qat_uclo.c b/drivers/crypto/intel/qat/qat_common/qat_uclo.c
> > index 18c3e4416dc5..04628dc01456 100644
> > --- a/drivers/crypto/intel/qat/qat_common/qat_uclo.c
> > +++ b/drivers/crypto/intel/qat/qat_common/qat_uclo.c
> > @@ -200,20 +200,12 @@ qat_uclo_cleanup_batch_init_list(struct icp_qat_fw_loader_handle *handle,
> >
> > static int qat_uclo_parse_num(char *str, unsigned int *num)
> > {
> > - char buf[16] = {0};
> > - unsigned long ae = 0;
> > - int i;
> > -
> > - strscpy(buf, str, sizeof(buf));
> > - for (i = 0; i < 16; i++) {
> > - if (!isdigit(buf[i])) {
> > - buf[i] = '\0';
> > - break;
> > - }
> > - }
> > - if ((kstrtoul(buf, 10, &ae)))
> > - return -EFAULT;
> > + unsigned long long ae;
> > + char *end;
> >
> > + ae = simple_strtoull(str, &end, 10);
> > + if (ae > UINT_MAX || str == end || (end - str) > 20)
>
> I would go with >= 20, the 64-bit value is approx. 1 * 10^19.
Just an insight into the type of strings being parsed here. If they are
well-formed, the format looks like:
<AE_NUMBER>!<...>
Example:
11!l0000!lm_thread_ctrl_struct_base
This function just extract the first number. Currently, that is 2 digits [2],
and I believe it is unlikely to exceed 3 in future gens.
[1] https://elixir.bootlin.com/linux/v6.17.4/source/drivers/crypto/intel/qat/qat_common/qat_uclo.c#L237
[2] https://elixir.bootlin.com/linux/v6.17.4/source/drivers/crypto/intel/qat/qat_common/icp_qat_uclo.h#L11
Regards,
--
Giovanni
On Fri, Oct 24, 2025 at 09:50:11AM +0100, Giovanni Cabiddu wrote: > On Thu, Oct 23, 2025 at 09:44:01PM +0300, Andy Shevchenko wrote: > > On Thu, Oct 23, 2025 at 05:35:00PM +0200, Thorsten Blum wrote: > > > On 22. Oct 2025, at 20:17, Andy Shevchenko wrote: > > > > On Wed, Oct 22, 2025 at 02:36:19PM +0200, Thorsten Blum wrote: ... > > > How about this? > > > > LGTM, and that's what I had in mind, but please double check the behaviour of > > kstrtox() on an empty strings. > > LGTM as well. > > I checked the behaviour of kstrtoul() when given an empty string. It > returns -EINVAL (-22). The result variable (the third parameter) is only > modified if the conversion is succesful. Thanks for confirming! > Anyway, the caller will not provide a NULL string to this function [1]. > > > > + unsigned long long ae; > > > + char *end; > > > > > > + ae = simple_strtoull(str, &end, 10); > > > + if (ae > UINT_MAX || str == end || (end - str) > 20) > > > > I would go with >= 20, the 64-bit value is approx. 1 * 10^19. > > Just an insight into the type of strings being parsed here. If they are > well-formed, the format looks like: > > <AE_NUMBER>!<...> > > Example: > > 11!l0000!lm_thread_ctrl_struct_base > > This function just extract the first number. Currently, that is 2 digits [2], > and I believe it is unlikely to exceed 3 in future gens. Yep, but it is better to make code more robust (and esp. in case somebody copies'n'pastes to somewhere else). > [1] https://elixir.bootlin.com/linux/v6.17.4/source/drivers/crypto/intel/qat/qat_common/qat_uclo.c#L237 > [2] https://elixir.bootlin.com/linux/v6.17.4/source/drivers/crypto/intel/qat/qat_common/icp_qat_uclo.h#L11 -- With Best Regards, Andy Shevchenko
On Wed, Oct 22, 2025 at 09:17:22PM +0300, Andy Shevchenko wrote:
> On Wed, Oct 22, 2025 at 02:36:19PM +0200, Thorsten Blum wrote:
> > Use strscpy_pad() to copy the string and zero-pad the destination buffer
> > in a single step instead of zero-initializing the buffer first and then
> > immediately overwriting it using strscpy().
> >
> > Replace the magic number 16 with sizeof(buf) and remove the redundant
> > parentheses around kstrtoul() while we're at it.
>
> I understand that you focused on strscpy*() conversions, but the below I think
> needs a bigger refactoring, see my remarks.
...
> > - char buf[16] = {0};
> > + char buf[16] = {};
> > unsigned long ae = 0;
> > int i;
> >
> > - strscpy(buf, str, sizeof(buf));
> > - for (i = 0; i < 16; i++) {
> > + strscpy_pad(buf, str);
>
> First of all, why do we need a _pad() version here? Is the data somehow being
> used as a whole?
>
> > + for (i = 0; i < sizeof(buf); i++) {
> > if (!isdigit(buf[i])) {
> > buf[i] = '\0';
> > break;
> > }
> > }
> > - if ((kstrtoul(buf, 10, &ae)))
> > + if (kstrtoul(buf, 10, &ae))
> > return -EFAULT;
On top of that the function is called only from one place and returns different
error code, instead it would have returned what kstrtoul() gives...
> Looking at this, it tries to work around the kstrtoul() inability to perform
> partial parses. Instead, this should do something like
>
> unsigned long long x;
> const char *end;
>
> simple_strtoull(...);
> if (x > UINT_MAX || end == buf)
> return $ERR; // wrong input / overflow
Yeah, the overflow check here is not comprehensive, it won't catch the overflow
(wrap around) of 64-bit value. But we can add a check for the end not to be
farther than ~19 characters from the start, which would correspond the initial
copy of 16 characters.
--
With Best Regards,
Andy Shevchenko
© 2016 - 2026 Red Hat, Inc.