-
Notifications
You must be signed in to change notification settings - Fork 230
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
Fix coverity unbounded source buffer issues #989
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,7 +34,7 @@ | |
#include "shadowlog.h" | ||
#include "string/sprintf.h" | ||
#include "string/strtcpy.h" | ||
|
||
#include "chkname.h" | ||
|
||
/* | ||
* Global variables. | ||
|
@@ -648,11 +648,17 @@ int main (int argc, char **argv) | |
* name, or the name getlogin() returns. | ||
*/ | ||
if (optind < argc) { | ||
user = argv[optind]; | ||
if (!is_valid_user_name (argv[optind])) { | ||
fprintf (stderr, _("%s: Provided user name is not a valid name\n"), Prog); | ||
fail_exit (E_NOPERM); | ||
} | ||
user = xstrdup (argv[optind]); | ||
|
||
pw = xgetpwnam (user); | ||
if (NULL == pw) { | ||
fprintf (stderr, _("%s: user '%s' does not exist\n"), Prog, | ||
user); | ||
free (user); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't need to free(3) in these early exit() points. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not really. I still see it there. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are correct, just the memory was already allocated, so I added free before exiting. Why we should not do free at early exit stage? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we do not do free for any allocated memory, we get issues in other code analyses tools (for example using gcc compiler with allocation checks flags). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Because exit(3) makes sure all memory is released. And it's just simpler (no need for having dozens of free(3) calls on the same resource). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Please show those warnings. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some comment to exit(3):
Anyway, in this exact sample from the proposed changes, I can do remove free from the code. Please, confirm that this is the general practice for that repo. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
free(3) is guaranteed by ISO C to free all allocated memory, IIRC.
Having 13 different points where we |
||
fail_exit (E_NOPERM); | ||
} | ||
} else { | ||
|
@@ -665,6 +671,7 @@ int main (int argc, char **argv) | |
(unsigned long) getuid ())); | ||
fail_exit (E_NOPERM); | ||
} | ||
|
||
user = xstrdup (pw->pw_name); | ||
} | ||
|
||
|
@@ -708,6 +715,8 @@ int main (int argc, char **argv) | |
|
||
SYSLOG ((LOG_INFO, "changed user '%s' information", user)); | ||
|
||
free (user); | ||
|
||
nscd_flush_cache ("passwd"); | ||
sssd_flush_cache (SSSD_DB_PASSWD); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we want a copy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copy will make sure that the program can accommodate proper string length, which is passed further to syslog function. This should prevent any further issues with unbound buffers during static analyses.
Also, notice that user is allocated further in the code in other branch:
user = xstrdup (pw->pw_name);
So, with the proposed change user variable will contain allocated value in each case. And then we can safely make free before exiting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is true. The check right above already makes sure the length is good.
This makes sense, but please fix it in a separate PR after we merge the first one.