summaryrefslogtreecommitdiffstats
path: root/sbin/savecore/savecore.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/savecore/savecore.c')
-rw-r--r--sbin/savecore/savecore.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/sbin/savecore/savecore.c b/sbin/savecore/savecore.c
index 7809c58..1d00ed2 100644
--- a/sbin/savecore/savecore.c
+++ b/sbin/savecore/savecore.c
@@ -436,7 +436,7 @@ DoFile(const char *savedir, const char *device)
{
xo_handle_t *xostdout, *xoinfo;
static char infoname[PATH_MAX], corename[PATH_MAX], linkname[PATH_MAX];
- static char *buf = NULL;
+ static char *buf = NULL, *temp = NULL;
struct kerneldumpheader kdhf, kdhl;
off_t mediasize, dumpsize, firsthd, lasthd;
FILE *info, *fp;
@@ -490,14 +490,29 @@ DoFile(const char *savedir, const char *device)
printf("sectorsize = %u\n", sectorsize);
}
+ if (sectorsize < sizeof(kdhl)) {
+ syslog(LOG_ERR,
+ "Sector size is less the kernel dump header %zu",
+ sizeof(kdhl));
+ goto closefd;
+ }
+
lasthd = mediasize - sectorsize;
+ if (temp == NULL) {
+ temp = malloc(sectorsize);
+ if (temp == NULL) {
+ syslog(LOG_ERR, "%m");
+ return;
+ }
+ }
if (lseek(fd, lasthd, SEEK_SET) != lasthd ||
- read(fd, &kdhl, sizeof(kdhl)) != sizeof(kdhl)) {
+ read(fd, temp, sectorsize) != (ssize_t)sectorsize) {
syslog(LOG_ERR,
"error reading last dump header at offset %lld in %s: %m",
(long long)lasthd, device);
goto closefd;
}
+ memcpy(&kdhl, temp, sizeof(kdhl));
istextdump = 0;
if (strncmp(kdhl.magic, TEXTDUMPMAGIC, sizeof kdhl) == 0) {
if (verbose)
@@ -567,15 +582,16 @@ DoFile(const char *savedir, const char *device)
goto closefd;
}
dumpsize = dtoh64(kdhl.dumplength);
- firsthd = lasthd - dumpsize - sizeof kdhf;
+ firsthd = lasthd - dumpsize - sectorsize;
if (lseek(fd, firsthd, SEEK_SET) != firsthd ||
- read(fd, &kdhf, sizeof(kdhf)) != sizeof(kdhf)) {
+ read(fd, temp, sectorsize) != (ssize_t)sectorsize) {
syslog(LOG_ERR,
"error reading first dump header at offset %lld in %s: %m",
(long long)firsthd, device);
nerr++;
goto closefd;
}
+ memcpy(&kdhf, temp, sizeof(kdhf));
if (verbose >= 2) {
printf("First dump headers:\n");
@@ -586,7 +602,7 @@ DoFile(const char *savedir, const char *device)
printf("\n");
}
- if (memcmp(&kdhl, &kdhf, sizeof kdhl)) {
+ if (memcmp(&kdhl, &kdhf, sizeof(kdhl))) {
syslog(LOG_ERR,
"first and last dump headers disagree on %s", device);
nerr++;
@@ -603,7 +619,7 @@ DoFile(const char *savedir, const char *device)
exit(0);
}
- if (kdhl.panicstring[0])
+ if (kdhl.panicstring[0] != '\0')
syslog(LOG_ALERT, "reboot after panic: %*s",
(int)sizeof(kdhl.panicstring), kdhl.panicstring);
else
@@ -724,9 +740,10 @@ nuke:
if (!keep) {
if (verbose)
printf("clearing dump header\n");
- memcpy(kdhl.magic, KERNELDUMPMAGIC_CLEARED, sizeof kdhl.magic);
+ memcpy(kdhl.magic, KERNELDUMPMAGIC_CLEARED, sizeof(kdhl.magic));
+ memcpy(temp, &kdhl, sizeof(kdhl));
if (lseek(fd, lasthd, SEEK_SET) != lasthd ||
- write(fd, &kdhl, sizeof(kdhl)) != sizeof(kdhl))
+ write(fd, temp, sectorsize) != (ssize_t)sectorsize)
syslog(LOG_ERR,
"error while clearing the dump header: %m");
}
OpenPOWER on IntegriCloud