devfs: fix cryptio memory leak

This commit is contained in:
cinap_lenrek 2011-12-12 19:17:24 +01:00
parent bf3476d661
commit 304ee3b2b5

View file

@ -1013,57 +1013,59 @@ io(Fsdev *mp, Inner *in, int isread, void *a, long l, vlong off)
static long static long
cryptio(Fsdev *mp, int isread, uchar *a, long l, vlong off) cryptio(Fsdev *mp, int isread, uchar *a, long l, vlong off)
{ {
long wl, ws, wo; long wl, ws, wo, wb;
uchar *buf; uchar *buf;
Chan *mc; Chan *mc;
Inner *in; Inner *in;
Key *k; Key *k;
enum {
Sectsz = 512,
Maxbuf = 32*Sectsz,
};
if(off < 0 || len <= 0 || ((off|len) & (Sectsz-1)))
error(Ebadarg);
k = mp->extra;
in = mp->inner[0]; in = mp->inner[0];
// Header
off += 64*1024;
mc = in->idev; mc = in->idev;
if(mc == nil) if(mc == nil)
error(Egone); 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", print("#k: %s: byte %,lld count %ld (of #k/%s): %s error: %s\n",
in->iname, off, l, mp->name, (isread? "read": "write"), in->iname, off, l, mp->name, (isread? "read": "write"),
(up && up->errstr? up->errstr: "")); (up && up->errstr? up->errstr: ""));
nexterror(); nexterror();
} }
for(ws = 0; ws < l; ws += wo){
if(off % 512 != 0 || l%512 !=0) wo = l - ws;
error(Eio); if(wo > wb)
wo = wb;
wo = (l > 16384) ? 16384 : l;
buf = mallocz(wo, 1);
if(!buf)
error(Enomem);
k = (Key*)(mp->extra);
for(ws = 0; ws < l; ws+=wo) {
if (isread) { if (isread) {
wl = devtab[mc->type]->read(mc, buf, wo, off); wo = devtab[mc->type]->read(mc, buf, wo, off);
if(wl!=wo) if(wo < Sectsz)
error(Eio); break;
for(wl=0; wl<wo; wl+=512) { wo &= ~(Sectsz-1);
aes_xts_decrypt(k->tweak.ekey, k->ecb.dkey, off, buf+wl, a+ws+wl, 512); for(wl=0; wl<wo; wl+=Sectsz)
off += 512; aes_xts_decrypt(k->tweak.ekey, k->ecb.dkey, off+wl, buf+wl, a+wl, Sectsz);
}
} else { } else {
for(wl=0; wl<wo; wl+=512) { for(wl=0; wl<wo; wl+=Sectsz)
aes_xts_encrypt(k->tweak.ekey, k->ecb.ekey, off, a+ws+wl, buf+wl, 512); aes_xts_encrypt(k->tweak.ekey, k->ecb.ekey, off+wl, a+wl, buf+wl, Sectsz);
off += 512; if(devtab[mc->type]->write(mc, buf, wo, off) != wo)
}
wl = devtab[mc->type]->write(mc, buf, wo, off-wo);
if(wl!=wo)
error(Eio); error(Eio);
} }
off += wo;
a += wo;
} }
free(buf);
poperror(); poperror();
free(buf);
return ws; return ws;
} }