diff options
| author | Jim Meyering <meyering@redhat.com> | 2012-07-03 17:06:46 +0200 | 
|---|---|---|
| committer | Anand Avati <avati@redhat.com> | 2012-07-12 00:27:15 -0700 | 
| commit | c76b49047aa396c0296a6ba2120e14abc0d27491 (patch) | |
| tree | 11b2a48b5ffb430f473a194feeb399f768c9d257 | |
| parent | ee480749ee61af01b18ddb37e80a73153c7de92e (diff) | |
geo-rep: don't let unexpected status provoke undefined behavior
glusterd_gsync_read_frm_status reads what is expected to be a NUL-
terminated status string from the specified file, but makes two
mistakes when trying to do the favor of trimming trailing spaces.
Do not let a leading NUL byte of status cause us to read buf[-1]
and possibly to clear that and any preceding "trailing" spaces.
Do not let a blen-byte input (with no NUL byte) cause our use of
strlen to access beyond the end of non-NUL-terminated buffer.
I looked at this code because coverity reported that it was
assuming a read-provided buffer to be NUL-terminated.
Change-Id: I140be0948e31196e5be08766d4e6400bf6f4dfa1
BUG: 789278
Signed-off-by: Jim Meyering <meyering@redhat.com>
Reviewed-on: http://review.gluster.com/3647
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Anand Avati <avati@redhat.com>
| -rw-r--r-- | xlators/mgmt/glusterd/src/glusterd-geo-rep.c | 15 | 
1 files changed, 10 insertions, 5 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c index 62122dbc27f..901e5e1e6c2 100644 --- a/xlators/mgmt/glusterd/src/glusterd-geo-rep.c +++ b/xlators/mgmt/glusterd/src/glusterd-geo-rep.c @@ -1362,7 +1362,6 @@ glusterd_gsync_read_frm_status (char *path, char *buf, size_t blen)  {          int                 ret = 0;          int           status_fd = -1; -        char                 *p = NULL;          GF_ASSERT (path);          GF_ASSERT (buf); @@ -1374,10 +1373,16 @@ glusterd_gsync_read_frm_status (char *path, char *buf, size_t blen)          }          ret = read (status_fd, buf, blen - 1);          if (ret > 0) { -                p = buf + strlen (buf) - 1; -                while (isspace (*p)) -                        *p-- = '\0'; -                ret = 0; +                size_t len = strnlen (buf, ret); +                /* Ensure there is a NUL byte and that it's not the first.  */ +                if (len == 0 || len == blen - 1) { +                        ret = -1; +                } else { +                        char *p = buf + len - 1; +                        while (isspace (*p)) +                                *p-- = '\0'; +                        ret = 0; +                }          } else if (ret < 0)                  gf_log ("", GF_LOG_ERROR, "Status file of gsyncd is corrupt");  | 
