[Midnightbsd-cvs] src: libexec/ftpd: MFC: ftpd command buffer vuln fix.
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Tue Sep 30 00:13:42 EDT 2008
Log Message:
-----------
MFC: ftpd command buffer vuln fix.
Tags:
----
RELENG_0_1
Modified Files:
--------------
src/libexec/ftpd:
extern.h (r1.1.1.1 -> r1.1.1.1.2.1)
ftpcmd.y (r1.1.1.1 -> r1.1.1.1.2.1)
ftpd.c (r1.2 -> r1.2.2.1)
-------------- next part --------------
Index: ftpd.c
===================================================================
RCS file: /home/cvs/src/libexec/ftpd/ftpd.c,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -L libexec/ftpd/ftpd.c -L libexec/ftpd/ftpd.c -u -r1.2 -r1.2.2.1
--- libexec/ftpd/ftpd.c
+++ libexec/ftpd/ftpd.c
@@ -2797,15 +2797,20 @@
myoob(void)
{
char *cp;
+ int ret;
if (!transflag) {
syslog(LOG_ERR, "Internal: myoob() while no transfer");
return (0);
}
cp = tmpline;
- if (getline(cp, 7, stdin) == NULL) {
+ ret = getline(cp, 7, stdin);
+ if (ret == -1) {
reply(221, "You could at least say goodbye.");
dologout(0);
+ } else if (ret == -2) {
+ /* Ignore truncated command */
+ return 0; /* XXX This is not clear in Mewburn's patch */
}
upper(cp);
if (strcmp(cp, "ABOR\r\n") == 0) {
Index: extern.h
===================================================================
RCS file: /home/cvs/src/libexec/ftpd/extern.h,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -L libexec/ftpd/extern.h -L libexec/ftpd/extern.h -u -r1.1.1.1 -r1.1.1.1.2.1
--- libexec/ftpd/extern.h
+++ libexec/ftpd/extern.h
@@ -46,7 +46,7 @@
void ftpd_logwtmp(char *, char *, struct sockaddr *addr);
int ftpd_pclose(FILE *);
FILE *ftpd_popen(char *, char *);
-char *getline(char *, int, FILE *);
+int getline(char *, int, FILE *);
void lreply(int, const char *, ...) __printflike(2, 3);
void makedir(char *);
void nack(char *);
Index: ftpcmd.y
===================================================================
RCS file: /home/cvs/src/libexec/ftpd/ftpcmd.y,v
retrieving revision 1.1.1.1
retrieving revision 1.1.1.1.2.1
diff -L libexec/ftpd/ftpcmd.y -L libexec/ftpd/ftpcmd.y -u -r1.1.1.1 -r1.1.1.1.2.1
--- libexec/ftpd/ftpcmd.y
+++ libexec/ftpd/ftpcmd.y
@@ -1166,7 +1166,7 @@
/*
* getline - a hacked up version of fgets to ignore TELNET escape codes.
*/
-char *
+int
getline(char *s, int n, FILE *iop)
{
int c;
@@ -1182,7 +1182,7 @@
if (ftpdebug)
syslog(LOG_DEBUG, "command: %s", s);
tmpline[0] = '\0';
- return(s);
+ return(0);
}
if (c == 0)
tmpline[0] = '\0';
@@ -1219,13 +1219,24 @@
}
}
*cs++ = c;
- if (--n <= 0 || c == '\n')
+ if (--n <= 0) {
+ /*
+ * If command doesn't fit into buffer, discard the
+ * rest of the command and indicate truncation.
+ * This prevents the command to be split up into
+ * multiple commands.
+ */
+ while (c != '\n' && (c = getc(iop)) != EOF)
+ ;
+ return (-2);
+ }
+ if (c == '\n')
break;
}
got_eof:
sigprocmask(SIG_SETMASK, &osset, NULL);
if (c == EOF && cs == s)
- return (NULL);
+ return (-1);
*cs++ = '\0';
if (ftpdebug) {
if (!guest && strncasecmp("pass ", s, 5) == 0) {
@@ -1245,7 +1256,7 @@
syslog(LOG_DEBUG, "command: %.*s", len, s);
}
}
- return (s);
+ return (0);
}
static void
@@ -1275,9 +1286,14 @@
case CMD:
(void) signal(SIGALRM, toolong);
(void) alarm(timeout);
- if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
+ n = getline(cbuf, sizeof(cbuf) -1, stdin);
+ if (n == -1) {
reply(221, "You could at least say goodbye.");
dologout(0);
+ } else if (n == -2) {
+ reply(500, "Command too long.");
+ alarm(0);
+ continue;
}
(void) alarm(0);
#ifdef SETPROCTITLE
More information about the Midnightbsd-cvs
mailing list