mirror of
https://github.com/3proxy/3proxy.git
synced 2025-02-23 10:35:40 +08:00
Fix: out-of-bounds write and few more bugs in 'admin' configuration upload
This commit is contained in:
parent
d07500687c
commit
3b67dc8447
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
|
#define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
|
||||||
|
|
||||||
#define LINESIZE 2048
|
#define LINESIZE 65536
|
||||||
|
|
||||||
extern FILE *writable;
|
extern FILE *writable;
|
||||||
FILE * confopen();
|
FILE * confopen();
|
||||||
@ -341,7 +341,7 @@ void * adminchild(struct clientparam* param) {
|
|||||||
char *sb;
|
char *sb;
|
||||||
char *req = NULL;
|
char *req = NULL;
|
||||||
struct printparam pp;
|
struct printparam pp;
|
||||||
int contentlen = 0;
|
unsigned contentlen = 0;
|
||||||
int isform = 0;
|
int isform = 0;
|
||||||
|
|
||||||
pp.inbuf = 0;
|
pp.inbuf = 0;
|
||||||
@ -390,7 +390,8 @@ void * adminchild(struct clientparam* param) {
|
|||||||
else if(i > 15 && (!strncasecmp(buf, "content-length:", 15))){
|
else if(i > 15 && (!strncasecmp(buf, "content-length:", 15))){
|
||||||
sb = buf + 15;
|
sb = buf + 15;
|
||||||
while(isspace(*sb))sb++;
|
while(isspace(*sb))sb++;
|
||||||
contentlen = atoi(sb);
|
sscanf(sb, "%u", &contentlen);
|
||||||
|
if(contentlen > LINESIZE*1024) contentlen = 0;
|
||||||
}
|
}
|
||||||
else if(i > 13 && (!strncasecmp(buf, "content-type:", 13))){
|
else if(i > 13 && (!strncasecmp(buf, "content-type:", 13))){
|
||||||
sb = buf + 13;
|
sb = buf + 13;
|
||||||
@ -520,7 +521,7 @@ void * adminchild(struct clientparam* param) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
printstr(&pp, "<h3>Please be careful editing config file remotely</h3>");
|
printstr(&pp, "<h3>Please be careful editing config file remotely</h3>");
|
||||||
printstr(&pp, "<form method=\"POST\" action=\"/U\"><textarea cols=\"80\" rows=\"30\" name=\"conffile\">");
|
printstr(&pp, "<form method=\"POST\" action=\"/U\" enctype=\"application/x-www-form-urlencoded\"><textarea cols=\"80\" rows=\"30\" name=\"conffile\">");
|
||||||
while(fgets(buf, 256, fp)){
|
while(fgets(buf, 256, fp)){
|
||||||
printstr(&pp, buf);
|
printstr(&pp, buf);
|
||||||
}
|
}
|
||||||
@ -530,24 +531,23 @@ void * adminchild(struct clientparam* param) {
|
|||||||
}
|
}
|
||||||
case 'U':
|
case 'U':
|
||||||
{
|
{
|
||||||
int l=0;
|
unsigned l=0;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
if(!writable || fseek(writable, 0, 0)){
|
if(!writable || !contentlen || fseek(writable, 0, 0)){
|
||||||
error = 1;
|
error = 1;
|
||||||
}
|
}
|
||||||
while((i = sockgetlinebuf(param, CLIENT, (unsigned char *)buf, LINESIZE - 1, '+', conf.timeouts[STRING_S])) > 0){
|
while(l < contentlen && (i = sockgetlinebuf(param, CLIENT, (unsigned char *)buf, (contentlen - l) > LINESIZE - 1?LINESIZE - 1:contentlen - l, '+', conf.timeouts[STRING_S])) > 0){
|
||||||
if(i > (contentlen - l)) i = (contentlen - l);
|
if(i > (contentlen - l)) i = (contentlen - l);
|
||||||
buf[i] = 0;
|
|
||||||
if(!l){
|
if(!l){
|
||||||
if(strncasecmp(buf, "conffile=", 9)) error = 1;
|
if(i<9 || strncasecmp(buf, "conffile=", 9)) error = 1;
|
||||||
}
|
}
|
||||||
if(!error){
|
if(!error){
|
||||||
|
buf[i] = 0;
|
||||||
decodeurl((unsigned char *)buf, 1);
|
decodeurl((unsigned char *)buf, 1);
|
||||||
fprintf(writable, "%s", l? buf : buf + 9);
|
fprintf(writable, "%s", l? buf : buf + 9);
|
||||||
}
|
}
|
||||||
l += i;
|
l += i;
|
||||||
if(l >= contentlen) break;
|
|
||||||
}
|
}
|
||||||
if(writable && !error){
|
if(writable && !error){
|
||||||
fflush(writable);
|
fflush(writable);
|
||||||
|
Loading…
Reference in New Issue
Block a user