ref: de82370216ca9a24413ba3bd2fc9d4d996484483
parent: 4f1e758b105139ec47911442174ef167fd4004cf
author: cinap_lenrek <cinap_lenrek@centraldogma>
date: Mon Dec 12 14:17:24 EST 2011
devfs: fix cryptio memory leak
--- a/sys/src/9/port/devfs.c
+++ b/sys/src/9/port/devfs.c
@@ -1013,57 +1013,59 @@
static long
cryptio(Fsdev *mp, int isread, uchar *a, long l, vlong off)
{- long wl, ws, wo;
+ long wl, ws, wo, wb;
uchar *buf;
- Chan *mc;
+ Chan *mc;
Inner *in;
Key *k;
+ enum {+ Sectsz = 512,
+ Maxbuf = 32*Sectsz,
+ };
- in = mp->inner[0];
- // Header
- off += 64*1024;
+ if(off < 0 || len <= 0 || ((off|len) & (Sectsz-1)))
+ error(Ebadarg);
+ k = mp->extra;
+ in = mp->inner[0];
mc = in->idev;
if(mc == nil)
error(Egone);
- if (waserror()) {+ off += 64*1024; // Header
+ wb = l;
+ if(wb > Maxbuf)
+ wb = Maxbuf;
+ buf = smalloc(wb);
+ if(waserror()) {+ free(buf);
print("#k: %s: byte %,lld count %ld (of #k/%s): %s error: %s\n",in->iname, off, l, mp->name, (isread? "read": "write"),
(up && up->errstr? up->errstr: ""));
nexterror();
}
-
- if(off % 512 != 0 || l%512 !=0)
- error(Eio);
-
- wo = (l > 16384) ? 16384 : l;
- buf = mallocz(wo, 1);
- if(!buf)
- error(Enomem);
- k = (Key*)(mp->extra);
-
- for(ws = 0; ws < l; ws+=wo) {+ for(ws = 0; ws < l; ws += wo){+ wo = l - ws;
+ if(wo > wb)
+ wo = wb;
if (isread) {- wl = devtab[mc->type]->read(mc, buf, wo, off);
- if(wl!=wo)
- error(Eio);
- for(wl=0; wl<wo; wl+=512) {- aes_xts_decrypt(k->tweak.ekey, k->ecb.dkey, off, buf+wl, a+ws+wl, 512);
- off += 512;
- }
+ wo = devtab[mc->type]->read(mc, buf, wo, off);
+ if(wo < Sectsz)
+ break;
+ wo &= ~(Sectsz-1);
+ for(wl=0; wl<wo; wl+=Sectsz)
+ aes_xts_decrypt(k->tweak.ekey, k->ecb.dkey, off+wl, buf+wl, a+wl, Sectsz);
} else {- for(wl=0; wl<wo; wl+=512) {- aes_xts_encrypt(k->tweak.ekey, k->ecb.ekey, off, a+ws+wl, buf+wl, 512);
- off += 512;
- }
-
- wl = devtab[mc->type]->write(mc, buf, wo, off-wo);
- if(wl!=wo)
+ for(wl=0; wl<wo; wl+=Sectsz)
+ aes_xts_encrypt(k->tweak.ekey, k->ecb.ekey, off+wl, a+wl, buf+wl, Sectsz);
+ if(devtab[mc->type]->write(mc, buf, wo, off) != wo)
error(Eio);
}
+ off += wo;
+ a += wo;
}
- free(buf);
poperror();
+ free(buf);
+
return ws;
}
--
⑨