shithub: riscv

Download patch

ref: d7613e356c55a3b7a1140a1f6d8aa6dca43b9d97
parent: 1e8eb61a3715b12d8bc1cfd866f5bb180f2941f2
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Wed Jun 24 15:18:37 EDT 2020

upas/fs: use memchr() instead of strchr() in hdrlen()

make sure we look for the end of the header within the
pointer range, and not accidentally read beyond hend.

also, messages are not null terminated, so this could
even go beyond the email data buffer.

get rid of mimeflag which was only used for some assert
checks.

take header length into account when comparing header
against ignored header strings.

--- a/sys/src/cmd/upas/fs/dat.h
+++ b/sys/src/cmd/upas/fs/dat.h
@@ -129,7 +129,6 @@
 	char	converted;
 	char	encoding;
 	char	decoded;
-	char	mimeflag;
 
 	Message	*next;
 	Message	*part;
--- a/sys/src/cmd/upas/fs/fs.c
+++ b/sys/src/cmd/upas/fs/fs.c
@@ -1517,12 +1517,12 @@
 	char	*str;
 	int	len;
 };
-Ignorance *ignorance;
+static Ignorance *ignorance;
 
 /*
  *  read the file of headers to ignore
  */
-void
+static void
 readignore(void)
 {
 	char *p;
@@ -1554,14 +1554,14 @@
 	Bterm(b);
 }
 
-int
-ignore(char *p)
+static int
+ignore(char *p, int n)
 {
 	Ignorance *i;
 
 	readignore();
 	for(i = ignorance; i != nil; i = i->next)
-		if(cistrncmp(i->str, p, i->len) == 0)
+		if(i->len <= n && cistrncmp(i->str, p, i->len) == 0)
 			return 1;
 	return 0;
 }
@@ -1580,9 +1580,9 @@
 
 	/* copy in good headers */
 	while(cnt > 0 && p < e){
-		n = hdrlen(p, e);
-		assert(n > 0);
-		if(ignore(p)){
+		if((n = hdrlen(p, e)) <= 0)
+			break;
+		if(ignore(p, n)){
 			p += n;
 			continue;
 		}
--- a/sys/src/cmd/upas/fs/header.c
+++ b/sys/src/cmd/upas/fs/header.c
@@ -10,7 +10,7 @@
 
 	ep = p;
 	do {
-		ep = strchr(ep, '\n');
+		ep = memchr(ep, '\n', e - ep);
 		if(ep == nil){
 			ep = e;
 			break;
--- a/sys/src/cmd/upas/fs/mbox.c
+++ b/sys/src/cmd/upas/fs/mbox.c
@@ -393,8 +393,6 @@
 {
 	for(m = m->part; m && i; i--)
 		m = m->next;
-	if(m)
-		m->mimeflag = 0;
 	return m;
 }
 
@@ -426,11 +424,8 @@
 			}
 			/* no boundary, we're done */
 			if(x == nil){
-				if(nm != nil){
+				if(nm != nil)
 					nm->rbend = nm->bend = nm->end = m->bend;
-					if(nm->end == nm->start)
-						nm->mimeflag |= Mtrunc;
-				}
 				break;
 			}
 			/* boundary must be at the start of a line */
@@ -475,8 +470,6 @@
 		assert(nm->ballocd == 0);
 		nm->start = nm->header = nm->body = nm->rbody = m->body;
 		nm->end = nm->bend = nm->rbend = m->bend;
-		if(nm->end == nm->start)
-			nm->mimeflag |= Mtrunc;
 		nm->size = nm->end - nm->start;
 		parse(mb, nm, 0, 0);
 		cachehash(mb, nm);			/* botchy place for this */
@@ -497,7 +490,7 @@
 		i0 = Mhead;
 	s = emalloc(2048);
 	e = s + 2048 - 1;
-	while((n = hdrlen(p, m->end)) != 0){
+	while((n = hdrlen(p, m->end)) > 0){
 		if(n > e - s){
 			s = erealloc(s, n);
 			e = s + n - 1;
@@ -598,7 +591,6 @@
 parse(Mailbox *mb, Message *m, int addfrom, int justmime)
 {
 	sanemsg(m);
-	assert(m->end - m->start > 0 || (m->mimeflag&Mtrunc) != 0 && m->end - m->start == 0);
 	if((m->cstate & Cheader) == 0)
 		parseheaders(mb, m, addfrom, justmime);
 	parsebody(m, mb);