Add a wrapper function that bound checks writes to the dump device.
This commit is contained in:
parent
2a2d8bde46
commit
910410640b
@ -140,7 +140,7 @@ buf_write(struct dumperinfo *di, char *ptr, size_t sz)
|
||||
ptr += len;
|
||||
sz -= len;
|
||||
if (fragsz == DEV_BSIZE) {
|
||||
error = di->dumper(di->priv, buffer, 0, dumplo,
|
||||
error = dump_write(di, buffer, 0, dumplo,
|
||||
DEV_BSIZE);
|
||||
if (error)
|
||||
return error;
|
||||
@ -160,7 +160,7 @@ buf_flush(struct dumperinfo *di)
|
||||
if (fragsz == 0)
|
||||
return (0);
|
||||
|
||||
error = di->dumper(di->priv, buffer, 0, dumplo, DEV_BSIZE);
|
||||
error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE);
|
||||
dumplo += DEV_BSIZE;
|
||||
fragsz = 0;
|
||||
return (error);
|
||||
@ -201,7 +201,7 @@ cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg)
|
||||
a = pa + i * PAGE_SIZE;
|
||||
va = pmap_kenter_temporary(trunc_page(a), i);
|
||||
}
|
||||
error = di->dumper(di->priv, va, 0, dumplo, sz);
|
||||
error = dump_write(di, va, 0, dumplo, sz);
|
||||
if (error)
|
||||
break;
|
||||
dumplo += sz;
|
||||
@ -327,7 +327,7 @@ dumpsys(struct dumperinfo *di)
|
||||
ehdr.e_phnum);
|
||||
|
||||
/* Dump leader */
|
||||
error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
goto fail;
|
||||
dumplo += sizeof(kdh);
|
||||
@ -358,12 +358,12 @@ dumpsys(struct dumperinfo *di)
|
||||
goto fail;
|
||||
|
||||
/* Dump trailer */
|
||||
error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
/* Signal completion, signoff and exit stage left. */
|
||||
di->dumper(di->priv, NULL, 0, 0, 0);
|
||||
dump_write(di, NULL, 0, 0, 0);
|
||||
printf("\nDump complete\n");
|
||||
return;
|
||||
|
||||
|
@ -111,7 +111,7 @@ blk_flush(struct dumperinfo *di)
|
||||
if (fragsz == 0)
|
||||
return (0);
|
||||
|
||||
error = di->dumper(di->priv, dump_va, 0, dumplo, fragsz);
|
||||
error = dump_write(di, dump_va, 0, dumplo, fragsz);
|
||||
dumplo += fragsz;
|
||||
fragsz = 0;
|
||||
return (error);
|
||||
@ -153,7 +153,7 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
|
||||
counter &= (1<<24) - 1;
|
||||
}
|
||||
if (ptr) {
|
||||
error = di->dumper(di->priv, ptr, 0, dumplo, len);
|
||||
error = dump_write(di, ptr, 0, dumplo, len);
|
||||
if (error)
|
||||
return (error);
|
||||
dumplo += len;
|
||||
@ -284,7 +284,7 @@ minidumpsys(struct dumperinfo *di)
|
||||
printf("Dumping %llu MB:", (long long)dumpsize >> 20);
|
||||
|
||||
/* Dump leader */
|
||||
error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
goto fail;
|
||||
dumplo += sizeof(kdh);
|
||||
@ -375,13 +375,13 @@ minidumpsys(struct dumperinfo *di)
|
||||
goto fail;
|
||||
|
||||
/* Dump trailer */
|
||||
error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
goto fail;
|
||||
dumplo += sizeof(kdh);
|
||||
|
||||
/* Signal completion, signoff and exit stage left. */
|
||||
di->dumper(di->priv, NULL, 0, 0, 0);
|
||||
dump_write(di, NULL, 0, 0, 0);
|
||||
printf("\nDump complete\n");
|
||||
return;
|
||||
|
||||
|
@ -138,7 +138,7 @@ buf_write(struct dumperinfo *di, char *ptr, size_t sz)
|
||||
ptr += len;
|
||||
sz -= len;
|
||||
if (fragsz == DEV_BSIZE) {
|
||||
error = di->dumper(di->priv, buffer, 0, dumplo,
|
||||
error = dump_write(di, buffer, 0, dumplo,
|
||||
DEV_BSIZE);
|
||||
if (error)
|
||||
return error;
|
||||
@ -158,7 +158,7 @@ buf_flush(struct dumperinfo *di)
|
||||
if (fragsz == 0)
|
||||
return (0);
|
||||
|
||||
error = di->dumper(di->priv, buffer, 0, dumplo, DEV_BSIZE);
|
||||
error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE);
|
||||
dumplo += DEV_BSIZE;
|
||||
fragsz = 0;
|
||||
return (error);
|
||||
@ -207,7 +207,7 @@ cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg)
|
||||
cpu_tlb_flushID_SE(0);
|
||||
cpu_cpwait();
|
||||
}
|
||||
error = di->dumper(di->priv,
|
||||
error = dump_write(di,
|
||||
(void *)(pa - (pa & L1_ADDR_BITS)),0, dumplo, sz);
|
||||
if (error)
|
||||
break;
|
||||
@ -330,7 +330,7 @@ dumpsys(struct dumperinfo *di)
|
||||
ehdr.e_phnum);
|
||||
|
||||
/* Dump leader */
|
||||
error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
goto fail;
|
||||
dumplo += sizeof(kdh);
|
||||
@ -361,12 +361,12 @@ dumpsys(struct dumperinfo *di)
|
||||
goto fail;
|
||||
|
||||
/* Dump trailer */
|
||||
error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
/* Signal completion, signoff and exit stage left. */
|
||||
di->dumper(di->priv, NULL, 0, 0, 0);
|
||||
dump_write(di, NULL, 0, 0, 0);
|
||||
printf("\nDump complete\n");
|
||||
return;
|
||||
|
||||
|
@ -140,7 +140,7 @@ buf_write(struct dumperinfo *di, char *ptr, size_t sz)
|
||||
ptr += len;
|
||||
sz -= len;
|
||||
if (fragsz == DEV_BSIZE) {
|
||||
error = di->dumper(di->priv, buffer, 0, dumplo,
|
||||
error = dump_write(di, buffer, 0, dumplo,
|
||||
DEV_BSIZE);
|
||||
if (error)
|
||||
return error;
|
||||
@ -160,7 +160,7 @@ buf_flush(struct dumperinfo *di)
|
||||
if (fragsz == 0)
|
||||
return (0);
|
||||
|
||||
error = di->dumper(di->priv, buffer, 0, dumplo, DEV_BSIZE);
|
||||
error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE);
|
||||
dumplo += DEV_BSIZE;
|
||||
fragsz = 0;
|
||||
return (error);
|
||||
@ -201,7 +201,7 @@ cb_dumpdata(struct md_pa *mdp, int seqnr, void *arg)
|
||||
a = pa + i * PAGE_SIZE;
|
||||
va = pmap_kenter_temporary(trunc_page(a), i);
|
||||
}
|
||||
error = di->dumper(di->priv, va, 0, dumplo, sz);
|
||||
error = dump_write(di, va, 0, dumplo, sz);
|
||||
if (error)
|
||||
break;
|
||||
dumplo += sz;
|
||||
@ -327,7 +327,7 @@ dumpsys(struct dumperinfo *di)
|
||||
ehdr.e_phnum);
|
||||
|
||||
/* Dump leader */
|
||||
error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
goto fail;
|
||||
dumplo += sizeof(kdh);
|
||||
@ -358,12 +358,12 @@ dumpsys(struct dumperinfo *di)
|
||||
goto fail;
|
||||
|
||||
/* Dump trailer */
|
||||
error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
/* Signal completion, signoff and exit stage left. */
|
||||
di->dumper(di->priv, NULL, 0, 0, 0);
|
||||
dump_write(di, NULL, 0, 0, 0);
|
||||
printf("\nDump complete\n");
|
||||
return;
|
||||
|
||||
|
@ -109,7 +109,7 @@ blk_flush(struct dumperinfo *di)
|
||||
if (fragsz == 0)
|
||||
return (0);
|
||||
|
||||
error = di->dumper(di->priv, dump_va, 0, dumplo, fragsz);
|
||||
error = dump_write(di, dump_va, 0, dumplo, fragsz);
|
||||
dumplo += fragsz;
|
||||
fragsz = 0;
|
||||
return (error);
|
||||
@ -151,7 +151,7 @@ blk_write(struct dumperinfo *di, char *ptr, vm_paddr_t pa, size_t sz)
|
||||
counter &= (1<<24) - 1;
|
||||
}
|
||||
if (ptr) {
|
||||
error = di->dumper(di->priv, ptr, 0, dumplo, len);
|
||||
error = dump_write(di, ptr, 0, dumplo, len);
|
||||
if (error)
|
||||
return (error);
|
||||
dumplo += len;
|
||||
@ -281,7 +281,7 @@ minidumpsys(struct dumperinfo *di)
|
||||
printf("Dumping %llu MB:", (long long)dumpsize >> 20);
|
||||
|
||||
/* Dump leader */
|
||||
error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
goto fail;
|
||||
dumplo += sizeof(kdh);
|
||||
@ -359,13 +359,13 @@ minidumpsys(struct dumperinfo *di)
|
||||
goto fail;
|
||||
|
||||
/* Dump trailer */
|
||||
error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
goto fail;
|
||||
dumplo += sizeof(kdh);
|
||||
|
||||
/* Signal completion, signoff and exit stage left. */
|
||||
di->dumper(di->priv, NULL, 0, 0, 0);
|
||||
dump_write(di, NULL, 0, 0, 0);
|
||||
printf("\nDump complete\n");
|
||||
return;
|
||||
|
||||
|
@ -95,7 +95,7 @@ buf_write(struct dumperinfo *di, char *ptr, size_t sz)
|
||||
ptr += len;
|
||||
sz -= len;
|
||||
if (fragsz == DEV_BSIZE) {
|
||||
error = di->dumper(di->priv, buffer, 0, dumplo,
|
||||
error = dump_write(di, buffer, 0, dumplo,
|
||||
DEV_BSIZE);
|
||||
if (error)
|
||||
return error;
|
||||
@ -115,7 +115,7 @@ buf_flush(struct dumperinfo *di)
|
||||
if (fragsz == 0)
|
||||
return (0);
|
||||
|
||||
error = di->dumper(di->priv, buffer, 0, dumplo, DEV_BSIZE);
|
||||
error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE);
|
||||
dumplo += DEV_BSIZE;
|
||||
fragsz = 0;
|
||||
return (error);
|
||||
@ -146,7 +146,7 @@ cb_dumpdata(struct efi_md *mdp, int seqnr, void *arg)
|
||||
printf("%c\b", "|/-\\"[twiddle++ & 3]);
|
||||
counter &= (1<<24) - 1;
|
||||
}
|
||||
error = di->dumper(di->priv, (void*)pa, 0, dumplo, sz);
|
||||
error = dump_write(di, (void*)pa, 0, dumplo, sz);
|
||||
if (error)
|
||||
break;
|
||||
dumplo += sz;
|
||||
@ -266,7 +266,7 @@ dumpsys(struct dumperinfo *di)
|
||||
ehdr.e_phnum);
|
||||
|
||||
/* Dump leader */
|
||||
error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
goto fail;
|
||||
dumplo += sizeof(kdh);
|
||||
@ -297,12 +297,12 @@ dumpsys(struct dumperinfo *di)
|
||||
goto fail;
|
||||
|
||||
/* Dump trailer */
|
||||
error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
/* Signal completion, signoff and exit stage left. */
|
||||
di->dumper(di->priv, NULL, 0, 0, 0);
|
||||
dump_write(di, NULL, 0, 0, 0);
|
||||
printf("\nDump complete\n");
|
||||
return;
|
||||
|
||||
|
@ -661,6 +661,20 @@ set_dumper(struct dumperinfo *di)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Call dumper with bounds checking. */
|
||||
int
|
||||
dump_write(struct dumperinfo *di, void *virtual, vm_offset_t physical,
|
||||
off_t offset, size_t length)
|
||||
{
|
||||
|
||||
if (length != 0 && (offset < di->mediaoffset ||
|
||||
offset - di->mediaoffset + length > di->mediasize)) {
|
||||
printf("Attempt to write outside dump device boundaries.\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
return (di->dumper(di->priv, virtual, physical, offset, length));
|
||||
}
|
||||
|
||||
#if defined(__powerpc__)
|
||||
void
|
||||
dumpsys(struct dumperinfo *di __unused)
|
||||
|
@ -91,7 +91,7 @@ buf_write(struct dumperinfo *di, char *ptr, size_t sz)
|
||||
ptr += len;
|
||||
sz -= len;
|
||||
if (fragsz == DEV_BSIZE) {
|
||||
error = di->dumper(di->priv, buffer, 0, dumplo,
|
||||
error = dump_write(di, buffer, 0, dumplo,
|
||||
DEV_BSIZE);
|
||||
if (error)
|
||||
return error;
|
||||
@ -111,7 +111,7 @@ buf_flush(struct dumperinfo *di)
|
||||
if (fragsz == 0)
|
||||
return (0);
|
||||
|
||||
error = di->dumper(di->priv, buffer, 0, dumplo, DEV_BSIZE);
|
||||
error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE);
|
||||
dumplo += DEV_BSIZE;
|
||||
return (error);
|
||||
}
|
||||
@ -145,7 +145,7 @@ blk_dump(struct dumperinfo *di, vm_paddr_t pa, vm_size_t size)
|
||||
rsz = size - pos;
|
||||
rsz = (rsz > MAXDUMPSZ) ? MAXDUMPSZ : rsz;
|
||||
va = TLB_PHYS_TO_DIRECT(pa + pos);
|
||||
error = di->dumper(di->priv, (void *)va, 0, dumplo, rsz);
|
||||
error = dump_write(di, (void *)va, 0, dumplo, rsz);
|
||||
if (error)
|
||||
break;
|
||||
dumplo += rsz;
|
||||
@ -195,7 +195,7 @@ dumpsys(struct dumperinfo *di)
|
||||
printf("Dumping %lu MB (%d chunks)\n", (u_long)(size >> 20), nreg);
|
||||
|
||||
/* Dump leader */
|
||||
error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
goto fail;
|
||||
dumplo += sizeof(kdh);
|
||||
@ -229,12 +229,12 @@ dumpsys(struct dumperinfo *di)
|
||||
}
|
||||
|
||||
/* Dump trailer */
|
||||
error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
/* Signal completion, signoff and exit stage left. */
|
||||
di->dumper(di->priv, NULL, 0, 0, 0);
|
||||
dump_write(di, NULL, 0, 0, 0);
|
||||
printf("\nDump complete\n");
|
||||
return;
|
||||
|
||||
|
@ -92,7 +92,7 @@ buf_write(struct dumperinfo *di, char *ptr, size_t sz)
|
||||
ptr += len;
|
||||
sz -= len;
|
||||
if (fragsz == DEV_BSIZE) {
|
||||
error = di->dumper(di->priv, buffer, 0, dumplo,
|
||||
error = dump_write(di, buffer, 0, dumplo,
|
||||
DEV_BSIZE);
|
||||
if (error)
|
||||
return error;
|
||||
@ -112,7 +112,7 @@ buf_flush(struct dumperinfo *di)
|
||||
if (fragsz == 0)
|
||||
return (0);
|
||||
|
||||
error = di->dumper(di->priv, buffer, 0, dumplo, DEV_BSIZE);
|
||||
error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE);
|
||||
dumplo += DEV_BSIZE;
|
||||
return (error);
|
||||
}
|
||||
@ -148,7 +148,7 @@ blk_dump(struct dumperinfo *di, vm_paddr_t pa, vm_size_t size)
|
||||
#ifdef notyet
|
||||
va = TLB_PHYS_TO_DIRECT(pa + pos);
|
||||
#endif
|
||||
error = di->dumper(di->priv, (void *)va, 0, dumplo, rsz);
|
||||
error = dump_write(di, (void *)va, 0, dumplo, rsz);
|
||||
if (error)
|
||||
break;
|
||||
dumplo += rsz;
|
||||
@ -198,7 +198,7 @@ dumpsys(struct dumperinfo *di)
|
||||
printf("Dumping %lu MB (%d chunks)\n", (u_long)(size >> 20), nreg);
|
||||
|
||||
/* Dump leader */
|
||||
error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
goto fail;
|
||||
dumplo += sizeof(kdh);
|
||||
@ -234,12 +234,12 @@ dumpsys(struct dumperinfo *di)
|
||||
}
|
||||
|
||||
/* Dump trailer */
|
||||
error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
/* Signal completion, signoff and exit stage left. */
|
||||
di->dumper(di->priv, NULL, 0, 0, 0);
|
||||
dump_write(di, NULL, 0, 0, 0);
|
||||
printf("\nDump complete\n");
|
||||
return;
|
||||
|
||||
|
@ -304,6 +304,7 @@ struct dumperinfo {
|
||||
};
|
||||
|
||||
int set_dumper(struct dumperinfo *);
|
||||
int dump_write(struct dumperinfo *, void *, vm_offset_t, off_t, size_t);
|
||||
void dumpsys(struct dumperinfo *);
|
||||
extern int dumping; /* system is dumping */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user