[PATCH v3 04/27] adduser: replace BB_EXECLP call with BB_EXECVP

d+busybox at adaptive-enterprises.com d+busybox at adaptive-enterprises.com
Mon Jan 27 08:13:48 UTC 2025


On Mon, 27 Jan 2025, Kang-Che Sung wrote:
> On Mon, Jan 27, 2025 at 12:18 PM <d+busybox at adaptive-enterprises.com> wrote:
>>> +     passwd_argv[0] = (char *) "passwd";
>>> +     passwd_argv[1] = (char *) "--";
>>> +     passwd_argv[2] = (char *) login_name;
>>> +     passwd_argv[3] = NULL;
>>
>> The type of a string literal is already char *, so the first two don't need
>> the cast. You could even write it more compactly, like this:
>>
>>         char *passwd_argv[] = { "passwd", "--", (char *)login_name, NULL };
>
> Technically, string literals are of type "const char *", not "char *".

Perhaps in C++ that is true, but not C. Ref C23, s6.4.5 "String literals",

     For character string literals, the array elements have type char, ...

You can try a few compiler experiments if you like.

> And when you assign string literals to "char *" like that,
> unpredictable behavior can happen when the strings get modified by
> some other function.

Yes. If they're allocated in rodata you'll likely get a SEGV.

> Perhaps what you really intended is this?
>
> const char *passwd_argv[] = { "passwd", "--", login_name, NULL };

That would be much more intuitive, readable, safer and so on, but then
you'll need a cast when pass it to the pre-const functions, 
eg (char **)passwd_argv.


More information about the busybox mailing list