Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A number of fixes around strto*() usage #5827

Closed
wants to merge 4 commits into from

Conversation

alexey-tikhonov
Copy link
Member

No description provided.

@alexey-tikhonov
Copy link
Member Author

Copy link
Contributor

@elkoniu elkoniu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are few more places where strtouint*() is called with 2nd parameter set to NULL:

src/sbus/sbus_errors.c                                                          
74:        ret = strtouint32(error->message, NULL, 10);                            
                                                                                   
src/responder/kcm/kcmsrv_ccache_secdb.c                                            
846:        uid = strtouint32(uid_list[i], NULL, 10);                              
                                                                                   
src/tests/cwrap/test_server.c                                                      
79:    tmp = strtouint32(buf, NULL, 10);                                           
                                                                                   
src/providers/ldap/ldap_id_services.c                                              
266:            port = strtouint16(state->name, NULL, 10);                         
                                                                                   
src/providers/ldap/sdap_access.c                                                   
1859:            duration = strtouint32(pwdAccountLockedDurationTime, NULL, 0);

If those are outside of the scope of this PR?

Copy link
Contributor

@elkoniu elkoniu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found call for strtoul() in one more place:

src/providers/ldap/sdap_sudo_shared.c                                           
194:            strtoul(srv_opts->max_sudo_value, &timezone, 10);               
204:        usn_number = strtoul(usn, &timezone, 10);

I think in the 2nd case evaluation against > UINT32_MAX is missing.

@elkoniu
Copy link
Contributor

elkoniu commented Oct 17, 2021

Generally LGTM, just two minor questions.

@alexey-tikhonov
Copy link
Member Author

alexey-tikhonov commented Oct 18, 2021

There are few more places where strtouint*() is called with 2nd parameter set to NULL:

I don't have very strong justification but will try my best to explain why I missed those.

src/sbus/sbus_errors.c
74: ret = strtouint32(error->message, NULL, 10);

This is a case dbus_error_has_name(error, SBUS_ERROR_ERRNO), i.e. (IIUC) error->message is set by another SSSD process, i.e. can be treated as a more or less "safe" source.
But imagine we want to be prudent and catch a case "123abc". How are we going to handle this?
This is a helper function that translates error to error code. So instead of 123 in this case of malformed error text we can return, for example, ERR_INTERNAL. Does it make some sense? Perhaps. Much sense? Imo, no.

src/responder/kcm/kcmsrv_ccache_secdb.c
846: uid = strtouint32(uid_list[i], NULL, 10);

uid_list originates from sssd-kcm ccache DB, so again, more or less reliable.

src/tests/cwrap/test_server.c
79: tmp = strtouint32(buf, NULL, 10);

That's a test. It's not that I don't care at all, but it really can be not as strict.

src/providers/ldap/ldap_id_services.c
266: port = strtouint16(state->name, NULL, 10);

Again, internal stuff. But ok, to be consistent I will add checks here...

src/providers/ldap/sdap_access.c
1859: duration = strtouint32(pwdAccountLockedDurationTime, NULL, 0);

This value is from LDAP - "pwdLockoutDuration" . I just wasn't sure what weird format it might have...
But it looks https://ldapwiki.com/wiki/PwdLockoutDuration says "Integer" so ok, I will update this as well.

@alexey-tikhonov
Copy link
Member Author

I found call for strtoul() in one more place:

src/providers/ldap/sdap_sudo_shared.c                                           
194:            strtoul(srv_opts->max_sudo_value, &timezone, 10);               
204:        usn_number = strtoul(usn, &timezone, 10);

I think in the 2nd case evaluation against > UINT32_MAX is missing.

Why?
https://ldapwiki.com/wiki/Update%20Sequence%20Number says Update Sequence Number (USN) is a 64-bit number .

@alexey-tikhonov
Copy link
Member Author

src/providers/ldap/ldap_id_services.c
266: port = strtouint16(state->name, NULL, 10);

Again, internal stuff. But ok, to be consistent I will add checks here...

src/providers/ldap/sdap_access.c
1859: duration = strtouint32(pwdAccountLockedDurationTime, NULL, 0);

This value is from LDAP - "pwdLockoutDuration" . I just wasn't sure what weird format it might have... But it looks https://ldapwiki.com/wiki/PwdLockoutDuration says "Integer" so ok, I will update this as well.

Done.

Copy link
Contributor

@elkoniu elkoniu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexey-tikhonov thank you for explanation, code vise LGTM, upstream CI is still spinning but if it will end up green ACK from me.

@elkoniu
Copy link
Contributor

elkoniu commented Oct 20, 2021

CI is green, ACK from me.

@pbrezina
Copy link
Member

Hi, it would be nice to have some description in the commit message that would make clear why the changes are required/correct without the need to peek into man page.

To properly check for an error during string to number conversion
one needs to:
 - check `errno`
 - check that something was really converted (i.e. start != end)
 - (if this is expected) check that entire string was consumed

Some of those error conditions weren't checked in various locations
over the code.
To properly check for an error during string to number conversion
one needs to:
 - check `errno`
 - check that something was really converted (i.e. start != end)
 - (if this is expected) check that entire string was consumed

Some of those error conditions weren't checked in various locations
over the code.
Previously result of `AS_STR(OFFLINE_TIMEOUT)` was "OFFLINE_TIMEOUT"
instead of expected integer value.
@alexey-tikhonov
Copy link
Member Author

Hi, it would be nice to have some description in the commit message that would make clear why the changes are required/correct without the need to peek into man page.

Done.

Copy link
Contributor

@elkoniu elkoniu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just one small question.

@@ -571,9 +571,9 @@ static void enum_users_done(struct tevent_req *subreq)
talloc_zfree(state->ctx->srv_opts->max_user_value);
state->ctx->srv_opts->max_user_value =
talloc_steal(state->ctx, usn_value);

errno = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small question: if in cases like this EOK should not be used instead of 0?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess errno == 0 is so common that there is no point to use EOK here explicit.

Copy link
Member Author

@alexey-tikhonov alexey-tikhonov Oct 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tl,dr: no, it shouldn't. See man page: the calling program should set errno to 0 before the call.

strto*() set errno in case specific errors happens, leave intact otherwise. Caller is required to reset errno before the call. This means to set it to a value that doesn't indicate any error. 0 is typically used for this purpose. Using EOK here is semantically wrong.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for detailed explanation.

@elkoniu elkoniu self-assigned this Oct 25, 2021
@pbrezina pbrezina added the Ready to push Ready to push label Oct 25, 2021
@pbrezina
Copy link
Member

Pushed PR: #5827

  • master
    • a664e9c - TESTS: fixed a bug in define->string conversion
    • 3c17a57 - 'strto*()': usage sanitization
    • a2cc7da - 'strtonum' helpers: usage sanitization
    • de6eba3 - Removed excessive includes around 'strtonum'

@pbrezina pbrezina added Pushed and removed Accepted Ready to push Ready to push labels Oct 25, 2021
@pbrezina pbrezina closed this Oct 25, 2021
@alexey-tikhonov alexey-tikhonov deleted the bz1977803 branch March 31, 2022 10:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants