socsvn commit: r255272 - in soc2013/def/crashdump-head: sbin/savecore sys/kern sys/sys
def at FreeBSD.org
def at FreeBSD.org
Sun Jul 28 17:49:07 UTC 2013
Author: def
Date: Sun Jul 28 17:49:06 2013
New Revision: 255272
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=255272
Log:
Save a decrypted crash dump using funopen(3). Encrypt with offset set to 0 in the beginning.
Added:
soc2013/def/crashdump-head/sbin/savecore/decryptfile.c
soc2013/def/crashdump-head/sbin/savecore/decryptfile.h
Modified:
soc2013/def/crashdump-head/sbin/savecore/Makefile
soc2013/def/crashdump-head/sbin/savecore/savecore.c
soc2013/def/crashdump-head/sys/kern/kern_shutdown.c
soc2013/def/crashdump-head/sys/sys/conf.h
Modified: soc2013/def/crashdump-head/sbin/savecore/Makefile
==============================================================================
--- soc2013/def/crashdump-head/sbin/savecore/Makefile Sun Jul 28 17:24:37 2013 (r255271)
+++ soc2013/def/crashdump-head/sbin/savecore/Makefile Sun Jul 28 17:49:06 2013 (r255272)
@@ -4,7 +4,7 @@
.PATH: ${SYS}/crypto/camellia ${SYS}/crypto/rijndael ${SYS}/crypto
PROG= savecore
-SRCS= ${PROG}.c
+SRCS= ${PROG}.c decryptfile.c
SRCS+= rijndael-api.c rijndael-api-fst.c rijndael-alg-fst.c
SRCS+= camellia.c
SRCS+= xts.c
Added: soc2013/def/crashdump-head/sbin/savecore/decryptfile.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ soc2013/def/crashdump-head/sbin/savecore/decryptfile.c Sun Jul 28 17:49:06 2013 (r255272)
@@ -0,0 +1,99 @@
+#include <sys/param.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "decryptfile.h"
+
+int
+dwrite(void *cookie, const char *data, int size)
+{
+ decFile *fd = (decFile *)cookie;
+ int resid, saved;
+
+ saved = 0;
+
+ while (size + fd->buf_used >= PEFS_SECTOR_SIZE) {
+ resid = PEFS_SECTOR_SIZE - fd->buf_used;
+ memcpy(fd->buf + fd->buf_used, data, resid);
+ fd->buf_used += resid;
+
+ xts_block_decrypt(&xts_alg_aes, (struct xts_ctx *)&fd->tweak_ctx, (struct xts_ctx *)&fd->data_ctx,
+ fd->offset, fd->tweak, PEFS_SECTOR_SIZE,
+ fd->buf, fd->buf);
+
+ if (fwrite(fd->buf, 1, PEFS_SECTOR_SIZE, fd->fp) != PEFS_SECTOR_SIZE)
+ return (0);
+
+ data += resid;
+ size -= resid;
+ fd->buf_used = 0;
+ fd->offset += PEFS_SECTOR_SIZE;
+ saved += resid;
+ }
+
+ if (size > 0) {
+ memcpy(fd->buf + fd->buf_used, data, size);
+ fd->buf_used += size;
+ saved += size;
+ }
+
+ return (saved);
+}
+
+FILE *
+dopen(const char *fname, const char *mode, const struct kerneldumpheader *h)
+{
+ decFile *fd;
+ FILE *fp;
+
+ /* Currently other modes are not implemented. */
+ if (*mode != 'w')
+ return (NULL);
+
+ fp = fopen(fname, mode);
+
+ if (fp == NULL)
+ return (NULL);
+
+ fd = (decFile *)malloc(sizeof(decFile));
+ fd->fp = fp;
+ fd->keysize = h->keysize;
+ memcpy(fd->key, h->key, KERNELDUMP_KEY_SIZE);
+ fd->tweaksize = h->tweaksize;
+ memcpy(fd->tweak, h->tweak, KERNELDUMP_TWEAK_SIZE);
+ fd->offset = 0;
+ fd->buf_used = 0;
+
+ rijndael_set_key(&fd->tweak_ctx, fd->key, fd->keysize << 3);
+ rijndael_set_key(&fd->data_ctx, fd->key, fd->keysize << 3);
+
+ return (funopen(fd, NULL, dwrite, NULL, dclose));
+}
+
+int
+dclose(void *cookie)
+{
+ decFile *fd = (decFile *)cookie;
+ int error;
+
+ if (fd->buf_used > 0) {
+ xts_block_decrypt(&xts_alg_aes, (struct xts_ctx *)&fd->tweak_ctx, (struct xts_ctx *)&fd->data_ctx,
+ fd->offset, fd->tweak, fd->buf_used,
+ fd->buf, fd->buf);
+
+ if (fwrite(fd->buf, 1, fd->buf_used, fd->fp) != 1)
+ return (0);
+
+ fd->offset += fd->buf_used;
+ fd->buf_used = 0;
+ }
+
+ error = fclose(fd->fp);
+
+ if (error < 0)
+ return (error);
+
+ free(fd);
+
+ return (error);
+}
Added: soc2013/def/crashdump-head/sbin/savecore/decryptfile.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ soc2013/def/crashdump-head/sbin/savecore/decryptfile.h Sun Jul 28 17:49:06 2013 (r255272)
@@ -0,0 +1,25 @@
+#ifndef _FILEDECRYPT_H
+#define _FILEDECRYPT_H
+
+#include <sys/kerneldump.h>
+#include <crypto/xts.h>
+
+typedef struct _decFile {
+ FILE *fp;
+ int keysize;
+ char key[KERNELDUMP_KEY_SIZE];
+ int tweaksize;
+ char tweak[KERNELDUMP_TWEAK_SIZE];
+ rijndael_ctx tweak_ctx;
+ rijndael_ctx data_ctx;
+ off_t offset;
+#define PEFS_SECTOR_SIZE 4096
+ char buf[PEFS_SECTOR_SIZE];
+ int buf_used;
+} decFile;
+
+int dwrite(void *cookie, const char *data, int size);
+FILE *dopen(const char *fname, const char *mode, const struct kerneldumpheader *h);
+int dclose(void *cookie);
+
+#endif /* _FILEDECRYPT_H */
Modified: soc2013/def/crashdump-head/sbin/savecore/savecore.c
==============================================================================
--- soc2013/def/crashdump-head/sbin/savecore/savecore.c Sun Jul 28 17:24:37 2013 (r255271)
+++ soc2013/def/crashdump-head/sbin/savecore/savecore.c Sun Jul 28 17:49:06 2013 (r255272)
@@ -68,7 +68,6 @@
#include <sys/kerneldump.h>
#include <sys/mount.h>
#include <sys/stat.h>
-#include <crypto/xts.h>
#include <errno.h>
#include <fcntl.h>
#include <fstab.h>
@@ -81,6 +80,7 @@
#include <syslog.h>
#include <time.h>
#include <unistd.h>
+#include "decryptfile.h"
/* The size of the buffer used for I/O. */
#define BUFFERSIZE (1024*1024)
@@ -89,7 +89,7 @@
#define STATUS_GOOD 1
#define STATUS_UNKNOWN 2
-static int checkfor, compress, clear, force, keep, verbose; /* flags */
+static int checkfor, compress, clear, decrypt, force, keep, verbose; /* flags */
static int nfound, nsaved, nerr; /* statistics */
static int maxdumps;
@@ -292,22 +292,16 @@
static int
DoRegularFile(int fd, off_t dumpsize, char *buf, const char *device,
- const char *filename, FILE *fp, FILE *fp_enc, struct kerneldumpheader *kdh,
- off_t offset)
+ const char *filename, FILE *fp)
{
int he, hs, nr, nw, wl;
off_t dmpcnt, origsize;
- rijndael_ctx tweak_ctx, data_ctx;
-
- rijndael_set_key(&tweak_ctx, kdh->key, kdh->keysize << 3);
- rijndael_set_key(&data_ctx, kdh->key, kdh->keysize << 3);
dmpcnt = 0;
origsize = dumpsize;
he = 0;
while (dumpsize > 0) {
- // wl = BUFFERSIZE;
- wl = 512;
+ wl = BUFFERSIZE;
if (wl > dumpsize)
wl = dumpsize;
nr = read(fd, buf, wl);
@@ -322,6 +316,8 @@
}
if (compress) {
nw = fwrite(buf, 1, wl, fp);
+ } else if (decrypt) {
+ nw = fwrite(buf, 1, wl, fp);
} else {
for (nw = 0; nw < nr; nw = he) {
/* find a contiguous block of zeroes */
@@ -352,18 +348,10 @@
* If hs > nw, buf[nw..hs] contains non-zero data.
* If he > hs, buf[hs..he] is all zeroes.
*/
- if (hs > nw) {
- if (fwrite(buf + nw, hs - nw, 1, fp_enc)
- != 1)
- break;
- xts_block_decrypt(&xts_alg_aes, (struct xts_ctx *)&tweak_ctx, (struct xts_ctx *)&data_ctx,
- offset, kdh->tweak, hs - nw,
- buf + nw, buf + nw);
- offset += hs - nw;
+ if (hs > nw)
if (fwrite(buf + nw, hs - nw, 1, fp)
!= 1)
break;
- }
if (he > hs)
if (fseeko(fp, he - hs, SEEK_CUR) == -1)
break;
@@ -447,12 +435,11 @@
static void
DoFile(const char *savedir, const char *device)
{
- static char infoname[PATH_MAX], corename[PATH_MAX],
- corename_enc[PATH_MAX], linkname[PATH_MAX];
+ static char infoname[PATH_MAX], corename[PATH_MAX], linkname[PATH_MAX];
static char *buf = NULL;
struct kerneldumpheader kdhf, kdhl;
off_t mediasize, dumpsize, firsthd, lasthd;
- FILE *info, *fp, *fp_enc;
+ FILE *info, *fp;
mode_t oumask;
int fd, fdinfo, error;
int bounds, status;
@@ -645,15 +632,16 @@
snprintf(corename, sizeof(corename), "%s.%d.gz",
istextdump ? "textdump.tar" : "vmcore", bounds);
fp = zopen(corename, "w");
- } else {
+ } else if (decrypt) {
snprintf(corename, sizeof(corename), "%s.%d",
istextdump ? "textdump.tar" : "vmcore", bounds);
- snprintf(corename_enc, sizeof(corename_enc), "%s_encrypted.%d",
+ fp = dopen(corename, "w", &kdhl);
+ } else {
+ snprintf(corename, sizeof(corename), "%s.%d",
istextdump ? "textdump.tar" : "vmcore", bounds);
fp = fopen(corename, "w");
- fp_enc = fopen(corename_enc, "w");
}
- if (fp == NULL || fp_enc == NULL) {
+ if (fp == NULL) {
syslog(LOG_ERR, "%s: %m", corename);
close(fdinfo);
nerr++;
@@ -676,15 +664,14 @@
fclose(info);
syslog(LOG_NOTICE, "writing %score to %s/%s",
- compress ? "compressed " : "", savedir, corename);
+ compress ? "compressed " : (decrypt ? "decrypted " : ""), savedir, corename);
if (istextdump) {
if (DoTextdumpFile(fd, dumpsize, lasthd, buf, device,
corename, fp) < 0)
goto closeall;
} else {
- if (DoRegularFile(fd, dumpsize, buf, device, corename,
- fp, fp_enc, &kdhl, firsthd + sizeof(kdhf))
+ if (DoRegularFile(fd, dumpsize, buf, device, corename, fp)
< 0)
goto closeall;
}
@@ -697,12 +684,6 @@
goto closeall;
}
- if (fp_enc != NULL && fclose(fp_enc) < 0) {
- syslog(LOG_ERR, "error on %s: %m", corename_enc);
- nerr++;
- goto closeall;
- }
-
symlinks_remove();
if (symlink(infoname, "info.last") == -1) {
syslog(LOG_WARNING, "unable to create symlink %s/%s: %m",
@@ -711,6 +692,9 @@
if (compress) {
snprintf(linkname, sizeof(linkname), "%s.last.gz",
istextdump ? "textdump.tar" : "vmcore");
+ } else if (decrypt) {
+ snprintf(linkname, sizeof(linkname), "%s.last",
+ istextdump ? "textdump.tar" : "vmcore");
} else {
snprintf(linkname, sizeof(linkname), "%s.last",
istextdump ? "textdump.tar" : "vmcore");
@@ -741,7 +725,6 @@
closeall:
fclose(fp);
- fclose(fp_enc);
closefd:
close(fd);
@@ -753,7 +736,7 @@
fprintf(stderr, "%s\n%s\n%s\n",
"usage: savecore -c [-v] [device ...]",
" savecore -C [-v] [device ...]",
- " savecore [-fkvz] [-m maxdumps] [directory [device ...]]");
+ " savecore [-dfkvz] [-m maxdumps] [directory [device ...]]");
exit(1);
}
@@ -764,13 +747,13 @@
struct fstab *fsp;
int i, ch, error;
- checkfor = compress = clear = force = keep = verbose = 0;
+ checkfor = compress = clear = decrypt = force = keep = verbose = 0;
nfound = nsaved = nerr = 0;
openlog("savecore", LOG_PERROR, LOG_DAEMON);
signal(SIGINFO, infohandler);
- while ((ch = getopt(argc, argv, "Ccfkm:vz")) != -1)
+ while ((ch = getopt(argc, argv, "Ccdfkm:vz")) != -1)
switch(ch) {
case 'C':
checkfor = 1;
@@ -778,6 +761,9 @@
case 'c':
clear = 1;
break;
+ case 'd':
+ decrypt = 1;
+ break;
case 'f':
force = 1;
break;
Modified: soc2013/def/crashdump-head/sys/kern/kern_shutdown.c
==============================================================================
--- soc2013/def/crashdump-head/sys/kern/kern_shutdown.c Sun Jul 28 17:24:37 2013 (r255271)
+++ soc2013/def/crashdump-head/sys/kern/kern_shutdown.c Sun Jul 28 17:49:06 2013 (r255272)
@@ -880,8 +880,9 @@
}
/* Write kernel dump headers. */
- if (di->offset == 0 || offset == di->kdhoffset) {
- di->offset = offset + length;
+ if (di->realoffset == 0 || offset == di->mediaoffset + di->mediasize -
+ sizeof(struct kerneldumpheader)) {
+ di->realoffset = offset + length;
return (di->dumper(di->priv, virtual, physical, offset, length));
}
@@ -890,28 +891,28 @@
xts_block_encrypt(&xts_alg_aes, di->tweak_ctx, di->data_ctx,
di->offset, di->tweak, di->buf_used,
di->buf, di->buf);
- return (di->dumper(di->priv, di->buf, physical, di->offset, di->buf_used));
+ return (di->dumper(di->priv, di->buf, physical, di->realoffset, di->buf_used));
}
- offset = di->offset;
-
- while (length + di->buf_used >= di->blocksize) {
- resid = qmin(length, di->blocksize - di->buf_used);
+ while (length + di->buf_used >= DUMPER_BUFSIZE) {
+ resid = DUMPER_BUFSIZE - di->buf_used;
memcpy(di->buf + di->buf_used, virtual, resid);
di->buf_used += resid;
+
xts_block_encrypt(&xts_alg_aes, di->tweak_ctx, di->data_ctx,
- offset, di->tweak, di->blocksize,
+ di->offset, di->tweak, DUMPER_BUFSIZE,
di->buf, di->buf);
- error = (di->dumper(di->priv, di->buf, physical, offset, di->buf_used));
+
+ error = (di->dumper(di->priv, di->buf, physical, di->realoffset, DUMPER_BUFSIZE));
if (error)
return (error);
virtual = (void *)((char *)virtual + resid);
- offset += resid;
length -= resid;
di->buf_used = 0;
- di->offset = offset;
+ di->realoffset += resid;
+ di->offset += DUMPER_BUFSIZE;
}
/* We still have less than blocksize of data to dump. */
@@ -933,8 +934,8 @@
di->tweak_ctx = &dumper_tweak_ctx;
di->data_ctx = &dumper_data_ctx;
di->buf_used = 0;
+ di->realoffset = 0;
di->offset = 0;
- di->kdhoffset = 0;
rijndael_set_key(di->tweak_ctx, di->key, KERNELDUMP_KEY_SIZE << 3);
rijndael_set_key(di->data_ctx, di->key, KERNELDUMP_KEY_SIZE << 3);
}
@@ -961,6 +962,4 @@
kdh->tweaksize = KERNELDUMP_TWEAK_SIZE;
strncpy(kdh->tweak, dumper.tweak, kdh->tweaksize);
kdh->parity = kerneldump_parity(kdh);
-
- dumper.kdhoffset = dumper.mediaoffset + dumper.mediasize - sizeof(*kdh);
}
Modified: soc2013/def/crashdump-head/sys/sys/conf.h
==============================================================================
--- soc2013/def/crashdump-head/sys/sys/conf.h Sun Jul 28 17:24:37 2013 (r255271)
+++ soc2013/def/crashdump-head/sys/sys/conf.h Sun Jul 28 17:49:06 2013 (r255272)
@@ -323,22 +323,23 @@
EVENTHANDLER_DECLARE(dev_clone, dev_clone_fn);
/* Stuff relating to kernel-dump */
+#define DUMPER_BUFSIZE 4096
struct dumperinfo {
- dumper_t *dumper; /* Dumping function. */
- void *priv; /* Private parts. */
- u_int blocksize; /* Size of block in bytes. */
- u_int maxiosize; /* Max size allowed for an individual I/O */
- off_t mediaoffset; /* Initial offset in bytes. */
- off_t mediasize; /* Space available in bytes. */
- char *key; /* Key information. */
- char *tweak; /* Tweak. */
- void *tweak_ctx; /* Tweak context. */
- void *data_ctx; /* Data context. */
- uint8_t buf[512]; /* Raw data buffer. */
- u_int buf_used; /* Number of bytes used in the buffer. */
- off_t offset; /* Last used offset in a dump_write call. */
- off_t kdhoffset; /* Offset of the second kernel dump header. */
+ dumper_t *dumper; /* Dumping function. */
+ void *priv; /* Private parts. */
+ u_int blocksize; /* Size of block in bytes. */
+ u_int maxiosize; /* Max size allowed for an individual I/O */
+ off_t mediaoffset; /* Initial offset in bytes. */
+ off_t mediasize; /* Space available in bytes. */
+ char *key; /* Key information. */
+ char *tweak; /* Tweak. */
+ void *tweak_ctx; /* Tweak context. */
+ void *data_ctx; /* Data context. */
+ uint8_t buf[DUMPER_BUFSIZE]; /* Raw data buffer. */
+ u_int buf_used; /* Number of bytes used in the buffer. */
+ off_t offset; /* Last used offset in a xts_block_encrypt call. */
+ off_t realoffset; /* Last used offset in a dump_write call. */
};
int set_dumper(struct dumperinfo *, const char *_devname);
More information about the svn-soc-all
mailing list