On 5 Jun 2025, at 19:21, Aaron Conole wrote:
> Eelco Chaudron via dev <ovs-dev@openvswitch.org> writes:
>
>> Coverity reports that daemon_set_new_user() may receive a large
>> unsigned value from get_sysconf_buffer_size(), due to sysconf()
>> returning -1 and being cast to size_t.
>
> That's weird that it's complaining about the upcast. I might be
> misremembering the casting rules, though. I did check the latest
> c-standard (c22) and it did have this to say in 6.3.1.8 about
> conversions in comparisons::
>
> Otherwise, if the operand that has unsigned integer type has rank
> greater or equal to the rank of the type of the other operand, then
> the operand with signed integer type is converted to the type of the
> operand with unsigned integer type.
>
> That verbiage was adopted with c11, IIRC - and I think it means that the
> compiler would implicitly convert the types correctly (rather than the
> older conversion rules that would have resulted in the -1 being
> UINT_MAX, again assuming I'm reading it correctly).
Yes, I was (am) confused also, just to make sure it clear, I converted the
result code to long as per API and it will be clear what we are trying to do
here.
>> Although this would likely lead to an allocation failure and abort,
>> it's better to handle the error in place.
>>
>> Signed-off-by: Eelco Chaudron <echau...@redhat.com>
>> ---
>> lib/daemon-unix.c | 8 +++++++-
>> 1 file changed, 7 insertions(+), 1 deletion(-)
>>
>> diff --git a/lib/daemon-unix.c b/lib/daemon-unix.c
>> index 4fdc6e3c4..78a013645 100644
>> --- a/lib/daemon-unix.c
>> +++ b/lib/daemon-unix.c
>> @@ -915,8 +915,9 @@ daemon_become_new_user(bool access_datapath, bool
>> access_hardware_ports)
>> static size_t
>> get_sysconf_buffer_size(void)
>> {
>> - size_t bufsize, pwd_bs = 0, grp_bs = 0;
>> const size_t default_bufsize = 1024;
>> + long pwd_bs = 0, grp_bs = 0;
>> + size_t bufsize;
>>
>> errno = 0;
>> if ((pwd_bs = sysconf(_SC_GETPW_R_SIZE_MAX)) == -1) {
>> @@ -924,14 +925,19 @@ get_sysconf_buffer_size(void)
>> VLOG_FATAL("%s: Read initial passwordd struct size "
>> "failed (%s), aborting. ", pidfile,
>> ovs_strerror(errno));
>> + } else {
>> + pwd_bs = default_bufsize;
>> }
>> }
>>
>> + errno = 0;
>> if ((grp_bs = sysconf(_SC_GETGR_R_SIZE_MAX)) == -1) {
>> if (errno) {
>> VLOG_FATAL("%s: Read initial group struct size "
>> "failed (%s), aborting. ", pidfile,
>> ovs_strerror(errno));
>> + } else {
>> + grp_bs = default_bufsize;
>> }
>> }
>
> Won't the snippet at the bottom handle the else cases here:
>
> bufsize = MAX(pwd_bs, grp_bs);
> return bufsize ? bufsize : default_bufsize;
No, it does not, as -1 can be returned without an error, meaning the value is
not defined. So in that case, it will be set to SIZE_MAX.
> The rest of the code that uses get_pwname_r / get_pwuid_r also will loop
> through correctly if the buffersize is unsufficient.
>
> If I understand correcly, could this all be avoided by casting the -1 to
> size_t in the 'if' conditions?
Not sure what you mean, this;
if ((pwd_bs = sysconf(_SC_GETPW_R_SIZE_MAX)) == (size_t) -1) {
This will not take care of the case when it returns -1 without an error.
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev