ref: 16d61d3c974b1d287db8d548cc13078341019730
parent: d9394b0d87169ef7aa7796344af421c757bc3749
author: cinap_lenrek <[email protected]>
date: Thu Oct 11 13:29:16 EDT 2012
kernel: try to catch some (rare) mistakes kstrcpy() did not null terminate for < 4 byte buffers. fixed, but i dont think there is any case where this can happen in practice. always set malloctag in kstrdup(), cleanup. always use ERRMAX bounded kstrcpy() to set up->errstr, q->err and note[]->msg. paranoia. instead of silently truncating interface name in netifinit(), panic the kernel if interface name is too long as this case is clearly a mistake. panic kernel when filename is too long for addbootfile() in devroot. this might happen if your kernel configuration is messed up.
--- a/sys/src/9/port/chan.c
+++ b/sys/src/9/port/chan.c
@@ -114,7 +114,6 @@
unlock(r);
if(x < 0)
panic("decref pc=%#p", getcallerpc(&r));
-
return x;
}
@@ -130,20 +129,19 @@
int nt;
nt = strlen(t);
- if(nt+1 <= ns){
- memmove(s, t, nt+1);
+ if(nt < ns){
+ memmove(s, t, nt);
+ s[nt] = '\0';
return;
}
- /* too long */
- if(ns < 4){
- /* but very short! */
- strncpy(s, t, ns);
- return;
- }
- /* truncate with ... at character boundary (very rare case) */
- memmove(s, t, ns-4);
+ /* too long, truncate */
+ nt = ns-1;
+ memmove(s, t, nt);
+ s[nt] = '\0';
+ /* append ... if there is space */
ns -= 4;
- s[ns] = '\0';
+ if(ns < 0)
+ return;
/* look for first byte of UTF-8 sequence by skipping continuation bytes */
while(ns>0 && (s[--ns]&0xC0)==0x80)
;
@@ -169,17 +167,18 @@
int n;
char *t, *prev;
- n = strlen(s)+1;
+ n = strlen(s);
/* if it's a user, we can wait for memory; if not, something's very wrong */
- if(up){
- t = smalloc(n);
- setmalloctag(t, getcallerpc(&p));
- }else{
- t = malloc(n);
+ if(up != nil)
+ t = smalloc(n+1);
+ else{
+ t = malloc(n+1);
if(t == nil)
panic("kstrdup: no memory");
}
+ setmalloctag(t, getcallerpc(&p));
memmove(t, s, n);
+ t[n] = '\0';
prev = *p;
*p = t;
free(prev);
@@ -1002,7 +1001,7 @@
*nerror = nhave;
pathclose(path);
cclose(c);
- strcpy(up->errstr, Enotdir);
+ kstrcpy(up->errstr, Enotdir, ERRMAX);
if(mh != nil)
putmhead(mh);
return -1;
@@ -1083,11 +1082,11 @@
if(wq->nqid==0 || (wq->qid[wq->nqid-1].type&QTDIR)){
if(nerror)
*nerror = nhave+wq->nqid+1;
- strcpy(up->errstr, Edoesnotexist);
+ kstrcpy(up->errstr, Edoesnotexist, ERRMAX);
}else{
if(nerror)
*nerror = nhave+wq->nqid;
- strcpy(up->errstr, Enotdir);
+ kstrcpy(up->errstr, Enotdir, ERRMAX);
}
free(wq);
if(mh != nil)
--- a/sys/src/9/port/devaoe.c
+++ b/sys/src/9/port/devaoe.c
@@ -2168,7 +2168,7 @@
netrdaoeproc(void *v)
{
int idx;
- char name[Maxpath+1], *s;
+ char name[Maxpath], *s;
Aoehdr *h;
Block *b;
Netlink *nl;
--- a/sys/src/9/port/devroot.c
+++ b/sys/src/9/port/devroot.c
@@ -63,6 +63,8 @@
panic("too many root files");
l->data[l->ndir] = contents;
d = &l->dir[l->ndir];
+ if(strlen(name) >= sizeof d->name)
+ panic("root file name too long: %s", name);
strcpy(d->name, name);
d->length = len;
d->perm = perm;
--- a/sys/src/9/port/netif.c
+++ b/sys/src/9/port/netif.c
@@ -18,8 +18,9 @@
void
netifinit(Netif *nif, char *name, int nfile, ulong limit)
{
- strncpy(nif->name, name, KNAMELEN-1);
- nif->name[KNAMELEN-1] = 0;
+ if(strlen(name) >= sizeof nif->name)
+ panic("netifinit: name too long: %s", name);
+ strcpy(nif->name, name);
nif->nfile = nfile;
nif->f = xalloc(nfile*sizeof(Netfile*));
if (nif->f == nil)
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -913,7 +913,7 @@
ret = 0;
if(p->nnote < NNOTE && n != nil) {
- strcpy(p->note[p->nnote].msg, n);
+ kstrcpy(p->note[p->nnote].msg, n, ERRMAX);
p->note[p->nnote++].flag = flag;
ret = 1;
}
--- a/sys/src/9/port/qio.c
+++ b/sys/src/9/port/qio.c
@@ -1391,7 +1391,7 @@
ilock(q);
q->state |= Qclosed;
q->state &= ~(Qflow|Qstarve);
- strcpy(q->err, Ehungup);
+ kstrcpy(q->err, Ehungup, ERRMAX);
bfirst = q->bfirst;
q->bfirst = 0;
q->len = 0;
@@ -1417,12 +1417,9 @@
/* mark it */
ilock(q);
q->state |= Qclosed;
- if(msg == 0 || *msg == 0)
- strcpy(q->err, Ehungup);
- else {
- strncpy(q->err, msg, ERRMAX-1);
- q->err[ERRMAX-1] = 0;
- }
+ if(msg == 0 || *msg == '\0')
+ msg = Ehungup;
+ kstrcpy(q->err, msg, ERRMAX);
iunlock(q);
/* wake up readers/writers */