Don't decrypt a core if a vmcore file already exists by default.

Allow to change this behaviour using the -f flag.

Approved by:	pjd (mentor)
This commit is contained in:
Konrad Witaszczyk 2017-02-08 23:17:23 +00:00
parent 0bce01b269
commit 4b30cd46a5
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=313459
2 changed files with 50 additions and 26 deletions

View file

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd December 13, 2016
.Dd February 9, 2017
.Dt DECRYPTCORE 8
.Os
.Sh NAME
@ -32,13 +32,13 @@
.Nd "decrypt a core dump of the operating system"
.Sh SYNOPSIS
.Nm
.Op Fl Lv
.Op Fl fLv
.Fl p Ar privatekeyfile
.Fl k Ar keyfile
.Fl e Ar encryptedcore
.Fl c Ar core
.Nm
.Op Fl Lv
.Op Fl fLv
.Op Fl d Ar crashdir
.Fl p Ar privatekeyfile
.Fl n Ar dumpnr
@ -70,10 +70,20 @@ file where
corresponds to
.Ar dumpnr .
.Pp
By default
.Nm
does not overwrite an old core dump as a user might want to store the core
somewhere else for the future.
This behaviour can be changed using the
.Fl f
flag.
.Pp
The
.Nm
utility can be started with the following command line arguments:
.Bl -tag -width ".Fl e Ar encryptedcore"
.It Fl f
Remove a decryped core dump if it already exists.
.It Fl L
Write log messages to
.Xr syslogd 8 .

View file

@ -55,8 +55,8 @@ usage(void)
{
pjdlog_exitx(1,
"usage: decryptcore [-Lv] -p privatekeyfile -k keyfile -e encryptedcore -c core\n"
" decryptcore [-Lv] [-d crashdir] -p privatekeyfile -n dumpnr");
"usage: decryptcore [-fLv] -p privatekeyfile -k keyfile -e encryptedcore -c core\n"
" decryptcore [-fLv] [-d crashdir] -p privatekeyfile -n dumpnr");
}
static int
@ -115,8 +115,8 @@ read_key(int kfd)
}
static bool
decrypt(const char *privkeyfile, const char *keyfile, const char *input,
const char *output)
decrypt(int ofd, const char *privkeyfile, const char *keyfile,
const char *input)
{
uint8_t buf[KERNELDUMP_BUFFER_SIZE], key[KERNELDUMP_KEY_MAX_SIZE];
EVP_CIPHER_CTX ctx;
@ -124,14 +124,14 @@ decrypt(const char *privkeyfile, const char *keyfile, const char *input,
FILE *fp;
struct kerneldumpkey *kdk;
RSA *privkey;
int ifd, kfd, ofd, olen, privkeysize;
int ifd, kfd, olen, privkeysize;
ssize_t bytes;
pid_t pid;
PJDLOG_ASSERT(ofd >= 0);
PJDLOG_ASSERT(privkeyfile != NULL);
PJDLOG_ASSERT(keyfile != NULL);
PJDLOG_ASSERT(input != NULL);
PJDLOG_ASSERT(output != NULL);
privkey = NULL;
@ -142,11 +142,14 @@ decrypt(const char *privkeyfile, const char *keyfile, const char *input,
pid = fork();
if (pid == -1) {
pjdlog_errno(LOG_ERR, "Unable to create child process");
close(ofd);
return (false);
}
if (pid > 0)
if (pid > 0) {
close(ofd);
return (wait_for_process(pid) == 0);
}
kfd = open(keyfile, O_RDONLY);
if (kfd == -1) {
@ -158,11 +161,6 @@ decrypt(const char *privkeyfile, const char *keyfile, const char *input,
pjdlog_errno(LOG_ERR, "Unable to open %s", input);
goto failed;
}
ofd = open(output, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (ofd == -1) {
pjdlog_errno(LOG_ERR, "Unable to open %s", output);
goto failed;
}
fp = fopen(privkeyfile, "r");
if (fp == NULL) {
pjdlog_errno(LOG_ERR, "Unable to open %s", privkeyfile);
@ -247,8 +245,7 @@ decrypt(const char *privkeyfile, const char *keyfile, const char *input,
}
if (olen > 0 && write(ofd, buf, olen) != olen) {
pjdlog_errno(LOG_ERR, "Unable to write data to %s",
output);
pjdlog_errno(LOG_ERR, "Unable to write core");
goto failed;
}
} while (bytes > 0);
@ -269,9 +266,11 @@ main(int argc, char **argv)
{
char core[PATH_MAX], encryptedcore[PATH_MAX], keyfile[PATH_MAX];
const char *crashdir, *dumpnr, *privatekey;
int ch, debug;
int ch, debug, error, ofd;
size_t ii;
bool usesyslog;
bool force, usesyslog;
error = 1;
pjdlog_init(PJDLOG_MODE_STD);
pjdlog_prefix_set("(decryptcore) ");
@ -281,10 +280,11 @@ main(int argc, char **argv)
crashdir = NULL;
dumpnr = NULL;
*encryptedcore = '\0';
force = false;
*keyfile = '\0';
privatekey = NULL;
usesyslog = false;
while ((ch = getopt(argc, argv, "Lc:d:e:k:n:p:v")) != -1) {
while ((ch = getopt(argc, argv, "Lc:d:e:fk:n:p:v")) != -1) {
switch (ch) {
case 'L':
usesyslog = true;
@ -302,6 +302,9 @@ main(int argc, char **argv)
pjdlog_exitx(1, "Encrypted core file path is too long.");
}
break;
case 'f':
force = true;
break;
case 'k':
if (strlcpy(keyfile, optarg, sizeof(keyfile)) >=
sizeof(keyfile)) {
@ -361,13 +364,24 @@ main(int argc, char **argv)
pjdlog_mode_set(PJDLOG_MODE_SYSLOG);
pjdlog_debug_set(debug);
if (!decrypt(privatekey, keyfile, encryptedcore, core)) {
if (unlink(core) == -1 && errno != ENOENT)
pjdlog_exit(1, "Unable to remove core");
exit(1);
if (force && unlink(core) == -1 && errno != ENOENT) {
pjdlog_errno(LOG_ERR, "Unable to remove old core");
goto out;
}
ofd = open(core, O_WRONLY | O_CREAT | O_EXCL, 0600);
if (ofd == -1) {
pjdlog_errno(LOG_ERR, "Unable to open %s", core);
goto out;
}
pjdlog_fini();
if (!decrypt(ofd, privatekey, keyfile, encryptedcore)) {
if (unlink(core) == -1 && errno != ENOENT)
pjdlog_errno(LOG_ERR, "Unable to remove core");
goto out;
}
exit(0);
error = 0;
out:
pjdlog_fini();
exit(error);
}