devfs: fix cryptio memory leak
This commit is contained in:
parent
bf3476d661
commit
304ee3b2b5
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue