diff options
Diffstat (limited to 'contrib/cvs/src/server.c')
-rw-r--r-- | contrib/cvs/src/server.c | 76 |
1 files changed, 66 insertions, 10 deletions
diff --git a/contrib/cvs/src/server.c b/contrib/cvs/src/server.c index 27debb9..e186c34 100644 --- a/contrib/cvs/src/server.c +++ b/contrib/cvs/src/server.c @@ -924,7 +924,7 @@ serve_max_dotdot (arg) int i; char *p; - if (lim < 0) + if (lim < 0 || lim > 10000) return; p = xmalloc (strlen (server_temp_dir) + 2 * lim + 10); if (p == NULL) @@ -1629,8 +1629,7 @@ serve_unchanged (arg) char *cp; char *timefield; - if (error_pending ()) - return; + if (error_pending ()) return; if (outside_dir (arg)) return; @@ -1644,7 +1643,16 @@ serve_unchanged (arg) && strlen (arg) == cp - name && strncmp (arg, name, cp - name) == 0) { - timefield = strchr (cp + 1, '/') + 1; + if (!(timefield = strchr (cp + 1, '/')) || *++timefield == '\0') + { + /* We didn't find the record separator or it is followed by + * the end of the string, so just exit. + */ + if (alloc_pending (80)) + sprintf (pending_error_text, + "E Malformed Entry encountered."); + return; + } /* If the time field is not currently empty, then one of * serve_modified, serve_is_modified, & serve_unchanged were * already called for this file. We would like to ignore the @@ -1691,8 +1699,7 @@ serve_is_modified (arg) /* Have we found this file in "entries" yet. */ int found; - if (error_pending ()) - return; + if (error_pending ()) return; if (outside_dir (arg)) return; @@ -1707,7 +1714,16 @@ serve_is_modified (arg) && strlen (arg) == cp - name && strncmp (arg, name, cp - name) == 0) { - timefield = strchr (cp + 1, '/') + 1; + if (!(timefield = strchr (cp + 1, '/')) || *++timefield == '\0') + { + /* We didn't find the record separator or it is followed by + * the end of the string, so just exit. + */ + if (alloc_pending (80)) + sprintf (pending_error_text, + "E Malformed Entry encountered."); + return; + } /* If the time field is not currently empty, then one of * serve_modified, serve_is_modified, & serve_unchanged were * already called for this file. We would like to ignore the @@ -1792,8 +1808,29 @@ serve_entry (arg) { struct an_entry *p; char *cp; + int i = 0; if (error_pending()) return; - p = (struct an_entry *) xmalloc (sizeof (struct an_entry)); + + /* Verify that the entry is well-formed. This can avoid problems later. + * At the moment we only check that the Entry contains five slashes in + * approximately the correct locations since some of the code makes + * assumptions about this. + */ + cp = arg; + if (*cp == 'D') cp++; + while (i++ < 5) + { + if (!cp || *cp != '/') + { + if (alloc_pending (80)) + sprintf (pending_error_text, + "E protocol error: Malformed Entry"); + return; + } + cp = strchr (cp + 1, '/'); + } + + p = xmalloc (sizeof (struct an_entry)); if (p == NULL) { pending_error = ENOMEM; @@ -2025,6 +2062,9 @@ serve_notify (arg) { char *cp; + if (!data[0]) + goto error; + if (strchr (data, '+')) goto error; @@ -2156,6 +2196,14 @@ serve_argument (arg) char *p; if (error_pending()) return; + + if (argument_count >= 10000) + { + if (alloc_pending (80)) + sprintf (pending_error_text, + "E Protocol error: too many arguments"); + return; + } if (argument_vector_size <= argument_count) { @@ -2186,6 +2234,14 @@ serve_argumentx (arg) char *p; if (error_pending()) return; + + if (argument_count <= 1) + { + if (alloc_pending (80)) + sprintf (pending_error_text, + "E Protocol error: called argumentx without prior call to argument"); + return; + } p = argument_vector[argument_count - 1]; p = xrealloc (p, strlen (p) + 1 + strlen (arg) + 1); @@ -2519,7 +2575,7 @@ check_command_legal_p (cmd_name) save some code here... -kff */ /* Chop newline by hand, for strcmp()'s sake. */ - if (linebuf[num_red - 1] == '\n') + if (num_red > 0 && linebuf[num_red - 1] == '\n') linebuf[num_red - 1] = '\0'; if (strcmp (linebuf, CVS_Username) == 0) @@ -2574,7 +2630,7 @@ check_command_legal_p (cmd_name) while ((num_red = getline (&linebuf, &linebuf_len, fp)) >= 0) { /* Chop newline by hand, for strcmp()'s sake. */ - if (linebuf[num_red - 1] == '\n') + if (num_red > 0 && linebuf[num_red - 1] == '\n') linebuf[num_red - 1] = '\0'; if (strcmp (linebuf, CVS_Username) == 0) |