Prevent cross-site forgery attacks on ftpd(8) due to splitting
long commands into multiple requests. [08:12] Avoid calling uninitialized function pointers in protocol switch code. [08:13] Merry Christmas everybody... Approved by: so (cperciva) Approved by: re (kensmith) Security: FreeBSD-SA-08:12.ftpd, FreeBSD-SA-08:13.protosw
This commit is contained in:
parent
d31572b0b8
commit
f0b40b1c97
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=186405
@ -46,7 +46,7 @@ void fatalerror(char *);
|
||||
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 *);
|
||||
|
@ -1191,7 +1191,7 @@ lookup(struct tab *p, char *cmd)
|
||||
/*
|
||||
* getline - a hacked up version of fgets to ignore TELNET escape codes.
|
||||
*/
|
||||
char *
|
||||
int
|
||||
getline(char *s, int n, FILE *iop)
|
||||
{
|
||||
int c;
|
||||
@ -1207,7 +1207,7 @@ getline(char *s, int n, FILE *iop)
|
||||
if (ftpdebug)
|
||||
syslog(LOG_DEBUG, "command: %s", s);
|
||||
tmpline[0] = '\0';
|
||||
return(s);
|
||||
return(0);
|
||||
}
|
||||
if (c == 0)
|
||||
tmpline[0] = '\0';
|
||||
@ -1244,13 +1244,24 @@ getline(char *s, int n, FILE *iop)
|
||||
}
|
||||
}
|
||||
*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) {
|
||||
@ -1270,7 +1281,7 @@ got_eof:
|
||||
syslog(LOG_DEBUG, "command: %.*s", len, s);
|
||||
}
|
||||
}
|
||||
return (s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1300,9 +1311,14 @@ yylex(void)
|
||||
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.");
|
||||
(void) alarm(0);
|
||||
continue;
|
||||
}
|
||||
(void) alarm(0);
|
||||
#ifdef SETPROCTITLE
|
||||
|
@ -2794,15 +2794,20 @@ static int
|
||||
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);
|
||||
}
|
||||
upper(cp);
|
||||
if (strcmp(cp, "ABOR\r\n") == 0) {
|
||||
|
@ -112,13 +112,18 @@ protosw_init(struct protosw *pr)
|
||||
|
||||
#define DEFAULT(foo, bar) if ((foo) == NULL) (foo) = (bar)
|
||||
DEFAULT(pu->pru_accept, pru_accept_notsupp);
|
||||
DEFAULT(pu->pru_bind, pru_bind_notsupp);
|
||||
DEFAULT(pu->pru_connect, pru_connect_notsupp);
|
||||
DEFAULT(pu->pru_connect2, pru_connect2_notsupp);
|
||||
DEFAULT(pu->pru_control, pru_control_notsupp);
|
||||
DEFAULT(pu->pru_disconnect, pru_disconnect_notsupp);
|
||||
DEFAULT(pu->pru_listen, pru_listen_notsupp);
|
||||
DEFAULT(pu->pru_peeraddr, pru_peeraddr_notsupp);
|
||||
DEFAULT(pu->pru_rcvd, pru_rcvd_notsupp);
|
||||
DEFAULT(pu->pru_rcvoob, pru_rcvoob_notsupp);
|
||||
DEFAULT(pu->pru_sense, pru_sense_null);
|
||||
DEFAULT(pu->pru_shutdown, pru_shutdown_notsupp);
|
||||
DEFAULT(pu->pru_sockaddr, pru_sockaddr_notsupp);
|
||||
DEFAULT(pu->pru_sosend, sosend_generic);
|
||||
DEFAULT(pu->pru_soreceive, soreceive_generic);
|
||||
DEFAULT(pu->pru_sopoll, sopoll_generic);
|
||||
|
Loading…
Reference in New Issue
Block a user