diff options
author | Jim Meyering <meyering@redhat.com> | 2007-11-23 13:36:01 +0100 |
---|---|---|
committer | Jim Meyering <meyering@redhat.com> | 2007-11-24 15:10:28 +0100 |
commit | ada15fc8232ab3ae5e7f515e368277efe77d3c83 (patch) | |
tree | 60feb7ff0ff204c867aa29d72927a9182c8db323 | |
parent | 0125fd0fcbbc2d54e6c5b50ee8e97f1c7c4b4173 (diff) | |
download | coreutils-ada15fc8232ab3ae5e7f515e368277efe77d3c83.tar.xz |
setuidgid: minor clean-up.
* setuidgid.c: Include "xstrtoul.h".
(main): Detect overflow in string-to-gid_t and -to-uid_t conversions.
Improve diagnostics.
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | src/setuidgid.c | 44 |
2 files changed, 35 insertions, 14 deletions
@@ -1,5 +1,10 @@ 2007-11-24 Jim Meyering <meyering@redhat.com> + setuidgid: minor clean-up. + * setuidgid.c: Include "xstrtoul.h". + (main): Detect overflow in string-to-gid_t and -to-uid_t conversions. + Improve diagnostics. + * src/setuidgid.c: Normalize leading white space: no more TABs. Test the new feature: cp -p preserves the GID whenever possible. diff --git a/src/setuidgid.c b/src/setuidgid.c index 71198a4bf..6e3bd92c1 100644 --- a/src/setuidgid.c +++ b/src/setuidgid.c @@ -29,6 +29,7 @@ #include "long-options.h" #include "getugroups.h" #include "quote.h" +#include "xstrtol.h" #define PROGRAM_NAME "setuidgid" @@ -95,23 +96,31 @@ main (int argc, char **argv) { case 'g': { - char *ptr = optarg; - while (*ptr != '\0') + unsigned long int tmp_ul; + char *gr = optarg; + char *ptr; + while (true) { if (gids_count == NGROUPS) { - error (0, 0, _("invalid argument %s"), quote (optarg)); + error (0, 0, _("too many groups: %s"), quote (optarg)); usage (SETUIDGID_FAILURE); } - /* FIXME: Integer overflow */ - gids[gids_count++] = strtoul (ptr, &ptr, 10); + if (! (xstrtoul (gr, &ptr, 10, &tmp_ul, NULL) == LONGINT_OK + && tmp_ul <= GID_T_MAX)) + error (EXIT_FAILURE, 0, _("invalid group %s"), + quote (gr)); + gids[gids_count++] = tmp_ul; - if (*ptr != '\0' && *ptr++ != ',') + if (*ptr == '\0') + break; + if (*ptr != ',') { - error (0, 0, _("invalid argument %s"), quote (optarg)); + error (0, 0, _("invalid group %s"), quote (gr)); usage (SETUIDGID_FAILURE); } + gr = ptr + 1; } break; } @@ -133,17 +142,25 @@ main (int argc, char **argv) { const struct passwd *pwd; + unsigned long int tmp_ul; + char *user = argv[optind]; char *ptr; + bool have_uid = false; - /* FIXME: Integer overflow */ - uid = strtoul (argv[optind], &ptr, 10); - if (*ptr != '\0') + if (xstrtoul (user, &ptr, 10, &tmp_ul, "") == LONGINT_OK + && tmp_ul <= UID_T_MAX) { - pwd = getpwnam (argv[optind]); + uid = tmp_ul; + have_uid = true; + } + + if (!have_uid) + { + pwd = getpwnam (user); if (pwd == NULL) { error (SETUIDGID_FAILURE, errno, - _("unknown user-ID: %s"), quote (argv[optind])); + _("unknown user-ID: %s"), quote (user)); usage (SETUIDGID_FAILURE); } uid = pwd->pw_uid; @@ -155,8 +172,7 @@ main (int argc, char **argv) if (pwd == NULL) { error (SETUIDGID_FAILURE, errno, - _("to use user-ID %s you need to use -g too"), - quote (argv[optind])); + _("to use user-ID %s you need to use -g too"), quote (user)); usage (SETUIDGID_FAILURE); } } |