]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
misc: safer (and uniform) handling of return value
authorYuriy M. Kaminskiy <yumkam@gmail.com>
Sat, 27 Feb 2016 16:27:29 +0000 (19:27 +0300)
committerKarel Zak <kzak@redhat.com>
Mon, 7 Mar 2016 14:11:06 +0000 (15:11 +0100)
When `rc` is `INT_MAX`, `rc + 1` result in signed integer overflow.

Signed-off-by: Karel Zak <kzak@redhat.com>
13 files changed:
disk-utils/fsck.c
lib/at.c
lib/cpuset.c
lib/sysfs.c
libfdisk/src/ask.c
login-utils/login.c
login-utils/lslogins.c
misc-utils/cal.c
sys-utils/lscpu.c
sys-utils/mountpoint.c
term-utils/agetty.c
term-utils/ttymsg.c
term-utils/wall.c

index b4630c54115cddee3a04dd51b88e4e425dd89bee..6f9e78b342d6826bf0edb90e68ef20d52bd76cf5 100644 (file)
@@ -316,7 +316,7 @@ static int is_irrotational_disk(dev_t disk)
                        "/sys/dev/block/%d:%d/queue/rotational",
                        major(disk), minor(disk));
 
-       if (rc < 0 || (unsigned int) (rc + 1) > sizeof(path))
+       if (rc < 0 || (unsigned int) rc >= sizeof(path))
                return 0;
 
        f = fopen(path, "r");
index f7074bb74d2f7f352f03dc3b08206fe5465c3ea4..4086a2541e437498eea51a4f6e5d8e9e1a1d879c 100644 (file)
--- a/lib/at.c
+++ b/lib/at.c
@@ -31,7 +31,7 @@ int fstat_at(int dir __attribute__ ((__unused__)), const char *dirname,
                int len;
 
                len = snprintf(path, sizeof(path), "%s/%s", dirname, filename);
-               if (len < 0 || len + 1 > sizeof(path))
+               if (len < 0 || (size_t)len >= sizeof(path))
                        return -1;
 
                return nofollow ? lstat(path, st) : stat(path, st);
@@ -56,7 +56,7 @@ int open_at(int dir __attribute__((__unused__)), const char *dirname,
                int len;
 
                len = snprintf(path, sizeof(path), "%s/%s", dirname, filename);
-               if (len < 0 || len + 1 > sizeof(path))
+               if (len < 0 || (size_t)len >= sizeof(path))
                        return -1;
 
                return open(path, flags);
@@ -91,7 +91,7 @@ ssize_t readlink_at(int dir __attribute__((__unused__)), const char *dirname,
                int len;
 
                len = snprintf(path, sizeof(path), "%s/%s", dirname, pathname);
-               if (len < 0 || len + 1 > sizeof(path))
+               if (len < 0 || (size_t)len >= sizeof(path))
                        return -1;
 
                return readlink(path, buf, bufsiz);
index 41c0eed47010801705fa46a559892ead725fe247..7445ab43782a05655d18cb68cb819afa6516d3f0 100644 (file)
@@ -177,13 +177,10 @@ char *cpulist_create(char *str, size_t len,
                                rlen = snprintf(ptr, len, "%zu-%zu,", i, i + run);
                                i += run;
                        }
-                       if (rlen < 0 || (size_t) rlen + 1 > len)
+                       if (rlen < 0 || (size_t) rlen >= len)
                                return NULL;
                        ptr += rlen;
-                       if (rlen > 0 && len > (size_t) rlen)
-                               len -= rlen;
-                       else
-                               len = 0;
+                       len -= rlen;
                }
        }
        ptr -= entry_made;
index 9d761488090b6e391b7a54c12aad76becb63fe46..b6e0b7230ec3d7d5b76992235680cd9dc47ad193 100644 (file)
@@ -26,7 +26,7 @@ char *sysfs_devno_attribute_path(dev_t devno, char *buf,
                len = snprintf(buf, bufsiz, _PATH_SYS_DEVBLOCK "/%d:%d",
                        major(devno), minor(devno));
 
-       return (len < 0 || (size_t) len + 1 > bufsiz) ? NULL : buf;
+       return (len < 0 || (size_t) len >= bufsiz) ? NULL : buf;
 }
 
 int sysfs_devno_has_attribute(dev_t devno, const char *attr)
@@ -82,7 +82,7 @@ dev_t sysfs_devname_to_devno(const char *name, const char *parent)
                                _PATH_SYS_BLOCK "/%s/%s/dev", _parent, _name);
                free(_name);
                free(_parent);
-               if (len < 0 || (size_t) len + 1 > sizeof(buf))
+               if (len < 0 || (size_t) len >= sizeof(buf))
                        return 0;
                path = buf;
 
@@ -100,7 +100,7 @@ dev_t sysfs_devname_to_devno(const char *name, const char *parent)
                len = snprintf(buf, sizeof(buf),
                                _PATH_SYS_BLOCK "/%s/dev", _name);
                free(_name);
-               if (len < 0 || (size_t) len + 1 > sizeof(buf))
+               if (len < 0 || (size_t) len >= sizeof(buf))
                        return 0;
                path = buf;
        }
@@ -463,7 +463,7 @@ int sysfs_write_u64(struct sysfs_cxt *cxt, const char *attr, uint64_t num)
                return -errno;
 
        len = snprintf(buf, sizeof(buf), "%" PRIu64, num);
-       if (len < 0 || (size_t) len + 1 > sizeof(buf))
+       if (len < 0 || (size_t) len >= sizeof(buf))
                rc = len < 0 ? -errno : -E2BIG;
        else
                rc = write_all(fd, buf, len);
@@ -930,7 +930,7 @@ static char *sysfs_scsi_host_attribute_path(struct sysfs_cxt *cxt,
                len = snprintf(buf, bufsz, _PATH_SYS_CLASS "/%s_host/host%d",
                                type, host);
 
-       return (len < 0 || (size_t) len + 1 > bufsz) ? NULL : buf;
+       return (len < 0 || (size_t) len >= bufsz) ? NULL : buf;
 }
 
 char *sysfs_scsi_host_strdup_attribute(struct sysfs_cxt *cxt,
@@ -979,7 +979,7 @@ static char *sysfs_scsi_attribute_path(struct sysfs_cxt *cxt,
        else
                len = snprintf(buf, bufsz, _PATH_SYS_SCSI "/devices/%d:%d:%d:%d",
                                h,c,t,l);
-       return (len < 0 || (size_t) len + 1 > bufsz) ? NULL : buf;
+       return (len < 0 || (size_t) len >= bufsz) ? NULL : buf;
 }
 
 int sysfs_scsi_has_attribute(struct sysfs_cxt *cxt, const char *attr)
index 7d55b5488f91f8a4ba2f42eaeec7c9af0975bda0..225957f343fb6d15249e1bd84a569f1f55eca7b1 100644 (file)
@@ -383,15 +383,11 @@ static char *mk_string_list(char *ptr, size_t *len, size_t *begin,
                        snprintf(ptr, *len, "%c-%c,", tochar(*begin), tochar(*begin + *run)) :
                        snprintf(ptr, *len, "%zu-%zu,", *begin, *begin + *run);
 
-       if (rlen < 0 || (size_t) rlen + 1 > *len)
+       if (rlen < 0 || (size_t) rlen >= *len)
                return NULL;
 
        ptr += rlen;
-
-       if (rlen > 0 && *len > (size_t) rlen)
-               *len -= rlen;
-       else
-               *len = 0;
+       *len -= rlen;
 
        if (cur == -1 && *begin) {
                /* end of the list */
index c5ce1887eef08d0075d3dd5f2bbb238cc69be197..ac76f656307e1e2a7eebcde935a60eda7770a939 100644 (file)
@@ -1057,7 +1057,7 @@ static void init_environ(struct login_context *cxt)
 
        /* mailx will give a funny error msg if you forget this one */
        len = snprintf(tmp, sizeof(tmp), "%s/%s", _PATH_MAILDIR, pwd->pw_name);
-       if (len > 0 && (size_t) len + 1 <= sizeof(tmp))
+       if (len > 0 && (size_t) len < sizeof(tmp))
                setenv("MAIL", tmp, 0);
 
        /* LOGNAME is not documented in login(1) but HP-UX 6.5 does it. We'll
index f9b9d401d81c95fa8fe89bd67959497a201a6848..40a1343088fcb6e1da7342dedfe63833fa51f9d5 100644 (file)
@@ -397,7 +397,7 @@ again:
                        x = snprintf(p, len, "%s,", grp->gr_name);
                }
 
-               if (x < 0 || (size_t) x + 1 > len) {
+               if (x < 0 || (size_t) x >= len) {
                        size_t cur = p - res;
 
                        maxlen *= 2;
index b7f38275c4aa6a24937703483f04509eec1682bc..c687c6c9d1e396c560b695369a31c3a93c46f627 100644 (file)
@@ -514,10 +514,15 @@ static void headers_init(struct cal_control *ctl)
        size_t i, wd;
        char *cur_dh = day_headings;
        char tmp[FMT_ST_CHARS];
-       size_t year_len;
+       int year_len;
 
        year_len = snprintf(tmp, sizeof(tmp), "%d", ctl->req.year);
 
+       if (year_len < 0 || (size_t)year_len >= sizeof(tmp)) {
+               /* XXX impossible error */
+               return;
+       }
+
        for (i = 0; i < DAYS_IN_WEEK; i++) {
                size_t space_left;
                wd = (i + ctl->weekstart) % DAYS_IN_WEEK;
index 318249fe02a8ff609fd021914f0f30e4650ef1f2..fc327623b15964c4d2a78fed76ec3547080a79fa 100644 (file)
@@ -1273,12 +1273,14 @@ get_cell_data(struct lscpu_desc *desc, int idx, int col,
                        if (cpuset_ary_isset(cpu, ca->sharedmaps,
                                             ca->nsharedmaps, setsize, &i) == 0) {
                                int x = snprintf(p, sz, "%zu", i);
-                               if (x <= 0 || (size_t) x + 2 >= sz)
+                               if (x < 0 || (size_t) x >= sz)
                                        return NULL;
                                p += x;
                                sz -= x;
                        }
                        if (j != 0) {
+                               if (sz < 2)
+                                       return NULL;
                                *p++ = mod->compat ? ',' : ':';
                                *p = '\0';
                                sz--;
@@ -1346,11 +1348,13 @@ get_cell_header(struct lscpu_desc *desc, int col,
 
                for (i = desc->ncaches - 1; i >= 0; i--) {
                        int x = snprintf(p, sz, "%s", desc->caches[i].name);
-                       if (x <= 0 || (size_t) x + 2 > sz)
+                       if (x < 0 || (size_t) x >= sz)
                                return NULL;
                        sz -= x;
                        p += x;
                        if (i > 0) {
+                               if (sz < 2)
+                                       return NULL;
                                *p++ = mod->compat ? ',' : ':';
                                *p = '\0';
                                sz--;
index a43bfd6dd1e60a32aa219ca257c914511d4c6c9c..ad9c1da2e630cdfee6c2e3de0d52b9928b0402a2 100644 (file)
@@ -71,7 +71,7 @@ static int dir_to_device(struct mountpoint_control *ctl)
                len = snprintf(buf, sizeof(buf), "%s/..", cn ? cn : ctl->path);
                free(cn);
 
-               if (len < 0 || (size_t) len + 1 > sizeof(buf))
+               if (len < 0 || (size_t) len >= sizeof(buf))
                        return -1;
                if (stat(buf, &pst) !=0)
                        return -1;
index d88cdc1c0c69812293f79416f04df9c9ea46b30a..55a00e125e56333adee64efb84844c49d435a829 100644 (file)
@@ -1001,8 +1001,8 @@ static void open_tty(char *tty, struct termios *tp, struct options *op)
                if ((gr = getgrnam("tty")))
                        gid = gr->gr_gid;
 
-               if (((len = snprintf(buf, sizeof(buf), "/dev/%s", tty)) >=
-                    (int)sizeof(buf)) || (len < 0))
+               len = snprintf(buf, sizeof(buf), "/dev/%s", tty);
+               if (len < 0 || (size_t)len >= sizeof(buf))
                        log_err(_("/dev/%s: cannot open as standard input: %m"), tty);
 
                /* Open the tty as standard input. */
index 18a723f86739929da36eefecc8a8bf4adf4a4346..2aab69f106977b473429d2454a4280988519b66e 100644 (file)
@@ -90,7 +90,7 @@ ttymsg(struct iovec *iov, size_t iovcnt, char *line, int tmout) {
           also wrong since people use /dev/pts/xxx. */
 
        len = snprintf(device, sizeof(device), "%s%s", _PATH_DEV, line);
-       if (len < 0 || len + 1 > (ssize_t) sizeof(device)) {
+       if (len < 0 || (size_t)len >= sizeof(device)) {
                snprintf(errbuf, sizeof(errbuf), _("excessively long line arg"));
                return errbuf;
        }
@@ -104,7 +104,7 @@ ttymsg(struct iovec *iov, size_t iovcnt, char *line, int tmout) {
                        return NULL;
 
                len = snprintf(errbuf, sizeof(errbuf), "%s: %m", device);
-               if (len < 0 || len + 1 > (ssize_t) sizeof(errbuf))
+               if (len < 0 || (size_t)len >= sizeof(errbuf))
                        snprintf(errbuf, sizeof(errbuf), _("open failed"));
                return errbuf;
        }
@@ -145,7 +145,7 @@ ttymsg(struct iovec *iov, size_t iovcnt, char *line, int tmout) {
                        cpid = fork();
                        if (cpid < 0) {
                                len = snprintf(errbuf, sizeof(errbuf), _("fork: %m"));
-                               if (len < 0 || len + 1 > (ssize_t) sizeof(errbuf))
+                               if (len < 0 || (size_t)len >= sizeof(errbuf))
                                        snprintf(errbuf, sizeof(errbuf), _("cannot fork"));
                                close(fd);
                                return errbuf;
@@ -177,7 +177,7 @@ ttymsg(struct iovec *iov, size_t iovcnt, char *line, int tmout) {
                        _exit(EXIT_FAILURE);
 
                len = snprintf(errbuf, sizeof(errbuf), "%s: %m", device);
-               if (len < 0 || len + 1 > (ssize_t) sizeof(errbuf))
+               if (len < 0 || (size_t)len >= sizeof(errbuf))
                        snprintf(errbuf, sizeof(errbuf),
                                        _("%s: BAD ERROR, message is "
                                          "far too long"), device);
index 7d0dfe772d33fadefce2a631861e29fc1dc4eb87..1253d32cd7bd368baf2cad53eb4609cb1d9b7e99 100644 (file)
@@ -217,8 +217,8 @@ static void buf_printf(struct buffer *bs, const char *fmt, ...)
        rc = vsnprintf(bs->data + bs->used, limit, fmt, ap);
        va_end(ap);
 
-       if (rc > 0 && (size_t) rc + 1 > limit) {        /* not enoght, enlarge */
-               buf_enlarge(bs, rc + 1);
+       if (rc >= 0 && (size_t) rc >= limit) {  /* not enoght, enlarge */
+               buf_enlarge(bs, (size_t)rc + 1);
                limit = bs->sz - bs->used;
                va_start(ap, fmt);
                rc = vsnprintf(bs->data  + bs->used, limit, fmt, ap);;