Hi,
chmod doesn't check if the program name is at least 3 characters long
before checking its index 2.
Also, there is a compiler warning about signed vs unsigned when "val"
is used. In one instance, it's used with strtoul, in another with strtol,
checking its ranges. It's okay due to automatic casting but definitely
no clean code.
Tobias
Index: chmod.c
===================================================================
RCS file: /cvs/src/bin/chmod/chmod.c,v
retrieving revision 1.31
diff -u -p -u -p -r1.31 chmod.c
--- chmod.c 6 Oct 2014 17:37:34 -0000 1.31
+++ chmod.c 12 Dec 2014 17:10:29 -0000
@@ -58,7 +58,7 @@ main(int argc, char *argv[])
FTS *ftsp;
FTSENT *p;
void *set;
- long val;
+ unsigned long val;
int oct;
mode_t omode;
int Hflag, Lflag, Rflag, ch, fflag, fts_options, hflag, rval;
@@ -69,10 +69,12 @@ main(int argc, char *argv[])
setlocale(LC_ALL, "");
- ischown = __progname[2] == 'o';
- ischgrp = __progname[2] == 'g';
- ischmod = __progname[2] == 'm';
- ischflags = __progname[2] == 'f';
+ if (strlen(__progname) > 2) {
+ ischown = __progname[2] == 'o';
+ ischgrp = __progname[2] == 'g';
+ ischmod = __progname[2] == 'm';
+ ischflags = __progname[2] == 'f';
+ }
uid = (uid_t)-1;
gid = (gid_t)-1;
@@ -171,8 +173,8 @@ done:
mode = *argv;
if (*mode >= '0' && *mode <= '7') {
errno = 0;
- val = strtol(mode, &ep, 8);
- if (val > INT_MAX || val < 0)
+ val = strtoul(mode, &ep, 8);
+ if (val > INT_MAX)
errno = ERANGE;
if (errno)
err(1, "invalid file mode: %s", mode);