git: 9front

Download patch

ref: 1a565a4a99cfd7bdca74d16e5ac95832c6b4ec5a
parent: eecc8b1b6aa4621161df34aaa99681a38af9597f
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Tue Mar 15 18:31:03 EDT 2016

ppp: fix buffer overflow, set correct state after chap negotiation (thanks k0ga)

(ppp->secret comes from factotum and it can have any size)
This patch also sets the correct state after success and
failure cases in chap negotiation (without them the code was
working because it expected the other point to pass to net
phase or due to the timer).

--- a/sys/src/cmd/ip/ppp/ppp.c
+++ b/sys/src/cmd/ip/ppp/ppp.c
@@ -2103,12 +2103,15 @@
 		default:
 			abort();
 		case APmd5:
+			n = strlen(ppp->secret);
+			if(n + vlen + 1 > sizeof(md5buf)) {
+				netlog("PPP: chap: bad challenge len\n");
+				goto end;
+			}
 			md5buf[0] = m->id;
-			strcpy(md5buf+1, ppp->secret);
-			n = strlen(ppp->secret) + 1;
-			memmove(md5buf+n, m->data+1, vlen);
-			n += vlen;
-			md5((uchar*)md5buf, n, digest, nil);
+			memcpy(md5buf+1, ppp->secret, n);
+			memcpy(md5buf+1+n, m->data+1, vlen);
+			md5((uchar*)md5buf, n + vlen + 1, digest, nil);
 			resp = digest;
 			nresp = 16;
 			break;
@@ -2229,14 +2232,17 @@
 		break;
 	case Csuccess:
 		netlog("ppp: chap succeeded\n");
+		setphase(ppp, Pnet);
 		break;
 	case Cfailure:
 		netlog("ppp: chap failed\n");
+		terminate(ppp, 0);
 		break;
 	default:
 		syslog(0, LOG, "chap code %d?", m->code);
 		break;
 	}
+end:
 	qunlock(ppp);
 	freeb(b);
 }
--