]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
term-utils: avoid error message string length couting errors
authorSami Kerola <kerolasa@iki.fi>
Sun, 11 May 2014 19:26:44 +0000 (20:26 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 12 May 2014 11:37:35 +0000 (13:37 +0200)
Remove various magic numbers with either a string lenght count, or a
symbolic variable that is recognized by gdb.

[kzak@redhat.com: - use snprintf() everywhere,
                  - check snprintf() return code rather than mess up
                    the code with strlens]

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Signed-off-by: Karel Zak <kzak@redhat.com>
term-utils/ttymsg.c

index fb2614ffd0494bcc226885aca9639153c7416a8e..18a723f86739929da36eefecc8a8bf4adf4a4346 100644 (file)
@@ -58,6 +58,8 @@
 #include "pathnames.h"
 #include "ttymsg.h"
 
+#define ERR_BUFLEN     (MAXNAMLEN + 1024)
+
 /*
  * Display the contents of a uio structure on a terminal.  Used by wall(1),
  * syslogd(8), and talkd(8).  Forks and finishes in child if write would block,
 char *
 ttymsg(struct iovec *iov, size_t iovcnt, char *line, int tmout) {
        static char device[MAXNAMLEN];
-       static char errbuf[MAXNAMLEN+1024];
+       static char errbuf[ERR_BUFLEN];
        size_t cnt, left;
        ssize_t wret;
        struct iovec localiov[6];
-       int fd, forked = 0, errsv;
+       int fd, forked = 0;
+       ssize_t len = 0;
 
-       if (iovcnt > sizeof(localiov) / sizeof(localiov[0]))
-               return (_("internal error: too many iov's"));
+       if (iovcnt > ARRAY_SIZE(localiov)) {
+               snprintf(errbuf, sizeof(errbuf), _("internal error: too many iov's"));
+               return errbuf;
+       }
 
        /* The old code here rejected the line argument when it contained a '/',
           saying: "A slash may be an attempt to break security...".
@@ -84,11 +89,11 @@ ttymsg(struct iovec *iov, size_t iovcnt, char *line, int tmout) {
           already. So, this test was worthless, and these days it is
           also wrong since people use /dev/pts/xxx. */
 
-       if (strlen(line) + sizeof(_PATH_DEV) + 1 > sizeof(device)) {
-               sprintf(errbuf, _("excessively long line arg"));
-               return (errbuf);
+       len = snprintf(device, sizeof(device), "%s%s", _PATH_DEV, line);
+       if (len < 0 || len + 1 > (ssize_t) sizeof(device)) {
+               snprintf(errbuf, sizeof(errbuf), _("excessively long line arg"));
+               return errbuf;
        }
-       sprintf(device, "%s%s", _PATH_DEV, line);
 
        /*
         * open will fail on slip lines or exclusive-use lines
@@ -96,12 +101,12 @@ ttymsg(struct iovec *iov, size_t iovcnt, char *line, int tmout) {
         */
        if ((fd = open(device, O_WRONLY|O_NONBLOCK, 0)) < 0) {
                if (errno == EBUSY || errno == EACCES)
-                       return (NULL);
-               if (strlen(strerror(errno)) > 1000)
-                       return (NULL);
-               sprintf(errbuf, "%s: %m", device);
-               errbuf[1024] = 0;
-               return (errbuf);
+                       return NULL;
+
+               len = snprintf(errbuf, sizeof(errbuf), "%s: %m", device);
+               if (len < 0 || len + 1 > (ssize_t) sizeof(errbuf))
+                       snprintf(errbuf, sizeof(errbuf), _("open failed"));
+               return errbuf;
        }
 
        for (cnt = left = 0; cnt < iovcnt; ++cnt)
@@ -139,19 +144,15 @@ ttymsg(struct iovec *iov, size_t iovcnt, char *line, int tmout) {
                        }
                        cpid = fork();
                        if (cpid < 0) {
-                               if (strlen(strerror(errno)) > 1000)
-                                       sprintf(errbuf, _("cannot fork"));
-                               else {
-                                       errsv = errno;
-                                       sprintf(errbuf,
-                                                _("fork: %s"), strerror(errsv));
-                               }
+                               len = snprintf(errbuf, sizeof(errbuf), _("fork: %m"));
+                               if (len < 0 || len + 1 > (ssize_t) sizeof(errbuf))
+                                       snprintf(errbuf, sizeof(errbuf), _("cannot fork"));
                                close(fd);
-                               return (errbuf);
+                               return errbuf;
                        }
                        if (cpid) {     /* parent */
                                close(fd);
-                               return (NULL);
+                               return NULL;
                        }
                        forked++;
                        /* wait at most tmout seconds */
@@ -174,19 +175,16 @@ ttymsg(struct iovec *iov, size_t iovcnt, char *line, int tmout) {
                        warn(_("write failed: %s"), device);
                if (forked)
                        _exit(EXIT_FAILURE);
-               if (strlen(strerror(errno)) > 1000)
-                       sprintf(errbuf, _("%s: BAD ERROR, message is "
-                                                "far too long"), device);
-               else {
-                       errsv = errno;
-                       sprintf(errbuf, "%s: %s", device,
-                                      strerror(errsv));
-               }
-               errbuf[1024] = 0;
-               return (errbuf);
+
+               len = snprintf(errbuf, sizeof(errbuf), "%s: %m", device);
+               if (len < 0 || len + 1 > (ssize_t) sizeof(errbuf))
+                       snprintf(errbuf, sizeof(errbuf),
+                                       _("%s: BAD ERROR, message is "
+                                         "far too long"), device);
+               return errbuf;
        }
 
        if (forked)
                _exit(EXIT_SUCCESS);
-       return (NULL);
+       return NULL;
 }