diff options
author | nectar <nectar@FreeBSD.org> | 2001-04-28 02:15:00 +0800 |
---|---|---|
committer | nectar <nectar@FreeBSD.org> | 2001-04-28 02:15:00 +0800 |
commit | c87c369f4279d8f0ea3db78a39de6386593cc7d3 (patch) | |
tree | 3edebdb530c2be60952220f91119ccabe8b7dfd1 /security/krb5/files | |
parent | 55c8e26895a0d2ef7a6876fb70aee86fe80e3703 (diff) | |
download | freebsd-ports-gnome-c87c369f4279d8f0ea3db78a39de6386593cc7d3.tar.gz freebsd-ports-gnome-c87c369f4279d8f0ea3db78a39de6386593cc7d3.tar.zst freebsd-ports-gnome-c87c369f4279d8f0ea3db78a39de6386593cc7d3.zip |
Security fix:
``Buffer overflows exist in the FTP daemon included with MIT krb5.''
See <URL:http://web.mit.edu/kerberos/www/advisories/ftpbuf.txt> and
<URL:http://web.mit.edu/kerberos/www/advisories/ftpbuf_122_patch.txt>.
Obtained from: MIT Kerberos mailing list
Diffstat (limited to 'security/krb5/files')
-rw-r--r-- | security/krb5/files/patch-ai | 276 |
1 files changed, 273 insertions, 3 deletions
diff --git a/security/krb5/files/patch-ai b/security/krb5/files/patch-ai index ddfff3d3aff9..634db6cdec73 100644 --- a/security/krb5/files/patch-ai +++ b/security/krb5/files/patch-ai @@ -1,6 +1,6 @@ ---- appl/gssftp/ftpd/ftpd.c.orig Wed Sep 1 13:38:40 1999 -+++ appl/gssftp/ftpd/ftpd.c Sat Sep 25 10:25:04 1999 -@@ -477,7 +477,13 @@ +--- appl/gssftp/ftpd/ftpd.c.orig Wed Feb 28 16:06:45 2001 ++++ appl/gssftp/ftpd/ftpd.c Fri Apr 27 10:18:01 2001 +@@ -485,7 +485,13 @@ #ifndef LOG_DAEMON #define LOG_DAEMON 0 #endif @@ -15,3 +15,273 @@ addrlen = sizeof (his_addr); if (getpeername(0, (struct sockaddr *)&his_addr, &addrlen) < 0) { +@@ -761,7 +767,16 @@ + int result; + #ifdef GSSAPI + if (auth_type && strcmp(auth_type, "GSSAPI") == 0) { ++ int len; + authorized = ftpd_gss_userok(&client_name, name) == 0; ++ len = sizeof("GSSAPI user is not authorized as " ++ "; Password required.") ++ + strlen(client_name.value) ++ + strlen(name); ++ if (len >= sizeof(buf)) { ++ syslog(LOG_ERR, "user: username too long"); ++ name = "[username too long]"; ++ } + sprintf(buf, "GSSAPI user %s is%s authorized as %s", + client_name.value, authorized ? "" : " not", + name); +@@ -772,7 +787,18 @@ + #endif /* GSSAPI */ + #ifdef KRB5_KRB4_COMPAT + if (auth_type && strcmp(auth_type, "KERBEROS_V4") == 0) { ++ int len; + authorized = kuserok(&kdata,name) == 0; ++ len = sizeof("Kerberos user .@ is not authorized as " ++ "; Password required.") ++ + strlen(kdata.pname) ++ + strlen(kdata.pinst) ++ + strlen(kdata.prealm) ++ + strlen(name); ++ if (len >= sizeof(buf)) { ++ syslog(LOG_ERR, "user: username too long"); ++ name = "[username too long]"; ++ } + sprintf(buf, "Kerberos user %s%s%s@%s is%s authorized as %s", + kdata.pname, *kdata.pinst ? "." : "", + kdata.pinst, kdata.prealm, +@@ -1179,6 +1205,11 @@ + } else { + char line[FTP_BUFSIZ]; + ++ if (strlen(cmd) + strlen(name) + 1 >= sizeof(line)) { ++ syslog(LOG_ERR, "retrieve: filename too long"); ++ reply(501, "filename too long"); ++ return; ++ } + (void) sprintf(line, cmd, name), name = line; + fin = ftpd_popen(line, "r"), closefunc = ftpd_pclose; + st.st_size = -1; +@@ -1417,6 +1448,10 @@ + return (file); + } + ++/* ++ * XXX callers need to limit total length of output string to ++ * FTP_BUFSIZ ++ */ + #ifdef STDARG + secure_error(char *fmt, ...) + #else +@@ -1616,13 +1651,19 @@ + { + char line[FTP_BUFSIZ]; + FILE *fin; +- int c; ++ int c, n; + char str[FTP_BUFSIZ], *p; + ++ if (strlen(filename) + sizeof("/bin/ls -lgA ") ++ >= sizeof(line)) { ++ reply(501, "filename too long"); ++ return; ++ } + (void) sprintf(line, "/bin/ls -lgA %s", filename); + fin = ftpd_popen(line, "r"); + lreply(211, "status of %s:", filename); + p = str; ++ n = 0; + while ((c = getc(fin)) != EOF) { + if (c == '\n') { + if (ferror(stdout)){ +@@ -1639,7 +1680,16 @@ + *p = '\0'; + reply(0, "%s", str); + p = str; +- } else *p++ = c; ++ n = 0; ++ } else { ++ *p++ = c; ++ n++; ++ if (n >= sizeof(str)) { ++ reply(551, "output line too long"); ++ (void) ftpd_pclose(fin); ++ return; ++ } ++ } + } + if (p != str) { + *p = '\0'; +@@ -1723,6 +1773,10 @@ + + char cont_char = ' '; + ++/* ++ * XXX callers need to limit total length of output string to ++ * FTP_BUFSIZ bytes for now. ++ */ + #ifdef STDARG + reply(int n, char *fmt, ...) + #else +@@ -1744,22 +1798,32 @@ + #endif + + if (auth_type) { +- char in[FTP_BUFSIZ], out[FTP_BUFSIZ]; ++ /* ++ * Deal with expansion in mk_{safe,priv}, ++ * radix_encode, gss_seal, plus slop. ++ */ ++ char in[FTP_BUFSIZ*3/2], out[FTP_BUFSIZ*3/2]; + int length, kerror; + if (n) sprintf(in, "%d%c", n, cont_char); + else in[0] = '\0'; + strncat(in, buf, sizeof (in) - strlen(in) - 1); + #ifdef KRB5_KRB4_COMPAT + if (strcmp(auth_type, "KERBEROS_V4") == 0) { +- if ((length = clevel == PROT_P ? +- krb_mk_priv((unsigned char *)in, +- (unsigned char *)out, +- strlen(in), schedule, &kdata.session, +- &ctrl_addr, &his_addr) +- : krb_mk_safe((unsigned char *)in, +- (unsigned char *)out, +- strlen(in), &kdata.session, +- &ctrl_addr, &his_addr)) == -1) { ++ if (clevel == PROT_P) ++ length = krb_mk_priv((unsigned char *)in, ++ (unsigned char *)out, ++ strlen(in), ++ schedule, &kdata.session, ++ &ctrl_addr, ++ &his_addr); ++ else ++ length = krb_mk_safe((unsigned char *)in, ++ (unsigned char *)out, ++ strlen(in), ++ &kdata.session, ++ &ctrl_addr, ++ &his_addr); ++ if (length == -1) { + syslog(LOG_ERR, + "krb_mk_%s failed for KERBEROS_V4", + clevel == PROT_P ? "priv" : "safe"); +@@ -1803,13 +1867,16 @@ + } + #endif /* GSSAPI */ + /* Other auth types go here ... */ +- if (kerror = radix_encode(out, in, &length, 0)) { ++ if (length >= sizeof(in) / 4 * 3) { ++ syslog(LOG_ERR, "input to radix_encode too long"); ++ fputs(in, stdout); ++ } else if (kerror = radix_encode(out, in, &length, 0)) { + syslog(LOG_ERR, "Couldn't encode reply (%s)", + radix_error(kerror)); + fputs(in,stdout); + } else +- printf("%s%c%s", clevel == PROT_P ? "632" : "631", +- n ? cont_char : '-', in); ++ printf("%s%c%s", clevel == PROT_P ? "632" : "631", ++ n ? cont_char : '-', in); + } else { + if (n) printf("%d%c", n, cont_char); + fputs(buf, stdout); +@@ -1822,6 +1889,10 @@ + } + } + ++/* ++ * XXX callers need to limit total length of output string to ++ * FTP_BUFSIZ ++ */ + #ifdef STDARG + lreply(int n, char *fmt, ...) + #else +@@ -1866,7 +1937,8 @@ + + if (cp = strchr(cbuf,'\n')) + *cp = '\0'; +- reply(500, "'%s': command not understood.", cbuf); ++ reply(500, "'%.*s': command not understood.", ++ FTP_BUFSIZ - sizeof("'': command not understood."), cbuf); + } + + delete_file(name) +@@ -2143,7 +2215,21 @@ + int code; + char *string; + { +- reply(code, "%s: %s.", string, strerror(errno)); ++ char *err_string; ++ size_t extra_len; ++ err_string = strerror(errno); ++ if (err_string == NULL) ++ err_string = "(unknown error)"; ++ extra_len = strlen(err_string) + sizeof("(truncated): ."); ++ /* ++ * XXX knows about FTP_BUFSIZ in reply() ++ */ ++ if (strlen(string) + extra_len > FTP_BUFSIZ) { ++ reply(code, "(truncated)%.*s: %s.", ++ FTP_BUFSIZ - extra_len, string, err_string); ++ } else { ++ reply(code, "%s: %s.", string, err_string); ++ } + } + + auth(type) +@@ -2226,6 +2312,10 @@ + secure_error("ADAT: krb_mk_safe failed"); + return(0); + } ++ if (length >= (FTP_BUFSIZ - sizeof("ADAT=")) / 4 * 3) { ++ secure_error("ADAT: reply too long"); ++ return(0); ++ } + if (kerror = radix_encode(out_buf, buf, &length, 0)) { + secure_error("Couldn't encode ADAT reply (%s)", + radix_error(kerror)); +@@ -2360,6 +2450,16 @@ + } + + if (out_tok.length) { ++ if (out_tok.length >= ((FTP_BUFSIZ - sizeof("ADAT=")) ++ / 4 * 3)) { ++ secure_error("ADAT: reply too long"); ++ syslog(LOG_ERR, "ADAT: reply too long"); ++ (void) gss_release_cred(&stat_min, &server_creds); ++ if (ret_flags & GSS_C_DELEG_FLAG) ++ (void) gss_release_cred(&stat_min, ++ &deleg_creds); ++ return(0); ++ } + if (kerror = radix_encode(out_tok.value, gbuf, &out_tok.length, 0)) { + secure_error("Couldn't encode ADAT reply (%s)", + radix_error(kerror)); +@@ -2458,6 +2558,9 @@ + * n>=0 on success + * -1 on error + * -2 on security error ++ * ++ * XXX callers need to limit total length of output string to ++ * FTP_BUFSIZ + */ + #ifdef STDARG + secure_fprintf(FILE *stream, char *fmt, ...) +@@ -2575,6 +2678,15 @@ + dir->d_name[2] == '\0') + continue; + ++ if (strlen(dirname) + strlen(dir->d_name) ++ + 1 /* slash */ ++ + 2 /* CRLF */ ++ + 1 > sizeof(nbuf)) { ++ syslog(LOG_ERR, ++ "send_file_list: pathname too long"); ++ ret = -2; /* XXX */ ++ goto data_err; ++ } + sprintf(nbuf, "%s/%s", dirname, dir->d_name); + + /* |