Commit 4e471a9b authored by Milan Broz's avatar Milan Broz

* Move memory locking and dm initialization to command layer.

* Increase priority of process if memory is locked.
Signed-off-by: Milan Broz's avatarMilan Broz <mbroz@redhat.com>

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@91 36d66b0a-2a48-0410-832c-cd162a569da5
parent ab953b3f
2009-08-30 Milan Broz <mbroz@redhat.com>
* Require device device-mapper to build and do not use backend wrapper for dm calls.
* Move memory locking and dm initialization to command layer.
* Increase priority of process if memory is locked.
2009-08-17 Milan Broz <mbroz@redhat.com>
* Fix PBKDF2 speed calculation for large passhrases.
......
......@@ -9,6 +9,10 @@
#include <stdarg.h>
#include <unistd.h>
#include <libintl.h>
#include <locale.h>
#define _(String) gettext((String))
#define SECTOR_SHIFT 9
#define SECTOR_SIZE (1 << SECTOR_SHIFT)
#define DEFAULT_ALIGNMENT 4096
......@@ -80,4 +84,7 @@ ssize_t write_lseek_blockwise(int fd, const char *buf, size_t count, off_t offse
int get_key(char *prompt, char **key, unsigned int *passLen, int key_size,
const char *key_file, int passphrase_fd, int timeout, int how2verify);
int memlock_inc(struct crypt_device *ctx);
int memlock_dec(struct crypt_device *ctx);
#endif /* INTERNAL_H */
......@@ -21,8 +21,6 @@ struct device_infos {
int readonly;
};
static int memory_unsafe = 0;
#define at_least_one(a) ({ __typeof__(a) __at_least_one=(a); (__at_least_one)?__at_least_one:1; })
static void logger(struct crypt_options *options, int class, char *format, ...) {
......@@ -45,35 +43,6 @@ static void hexprintICB(struct crypt_options *options, int class, char *d, int n
logger(options, class, "%02hhx ", (char)d[i]);
}
static int setup_enter(void (*log)(int, char *))
{
int r;
/*
* from here we could have sensible data in memory
* so protect it from being swapped out
*/
r = mlockall(MCL_CURRENT | MCL_FUTURE);
if (r < 0) {
perror("mlockall failed");
log(CRYPT_LOG_ERROR, "WARNING!!! Possibly insecure memory. Are you root?\n");
memory_unsafe = 1;
}
set_error(NULL);
return 0;
}
static int setup_leave(void)
{
/* dangerous, we can't wipe all the memory */
if (!memory_unsafe)
munlockall();
return 0;
}
/*
* Password processing behaviour matrix of process_key
*
......@@ -771,20 +740,12 @@ static int __crypt_luks_remove_key(int arg, struct crypt_options *options) {
return luks_remove_helper(arg, options, 1);
}
static int crypt_job(int (*job)(int arg, struct crypt_options *options),
int arg, struct crypt_options *options)
{
int r;
if (setup_enter(options->icb->log) < 0) {
r = -ENOSYS;
goto out;
}
r = job(arg, options);
out:
setup_leave();
if (r >= 0)
set_error(NULL);
......
......@@ -12,6 +12,8 @@
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include "libcryptsetup.h"
#include "internal.h"
......@@ -507,3 +509,39 @@ out_err:
return 0;
}
/* MEMLOCK */
#define DEFAULT_PROCESS_PRIORITY -18
static int _priority;
static int _memlock_count = 0;
// return 1 if memory is locked
int memlock_inc(struct crypt_device *ctx)
{
if (!_memlock_count++) {
if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
set_error(_("WARNING!!! Possibly insecure memory. Are you root?\n"));
_memlock_count--;
return 0;
}
errno = 0;
if (((_priority = getpriority(PRIO_PROCESS, 0)) == -1) && errno)
set_error(_("Cannot get process priority.\n"));
else
if (setpriority(PRIO_PROCESS, 0, DEFAULT_PROCESS_PRIORITY))
set_error(_("setpriority %u failed: %s"),
DEFAULT_PROCESS_PRIORITY, strerror(errno));
}
return _memlock_count ? 1 : 0;
}
int memlock_dec(struct crypt_device *ctx)
{
if (_memlock_count && (!--_memlock_count)) {
if (munlockall())
set_error(_("Cannot unlock memory."));
if (setpriority(PRIO_PROCESS, 0, _priority))
set_error(_("setpriority %u failed: %s"), _priority, strerror(errno));
}
return _memlock_count ? 1 : 0;
}
......@@ -41,10 +41,6 @@
/* Actually we need only 37, but we don't want struct autoaligning to kick in */
#define UUID_STRING_L 40
/* We don't have gettext support in LUKS */
#define _(Text) Text
/* Any integer values are stored in network byte order on disk and must be
converted */
......
......@@ -5,6 +5,7 @@
#include <inttypes.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <libcryptsetup.h>
......@@ -52,28 +53,31 @@ static int action_luksDump(int arg);
static struct action_type {
const char *type;
int (*handler)(int);
int (*handler)(int);
int arg;
int required_action_argc;
int required_dm_backend;
int required_memlock;
int show_status;
const char *arg_desc;
const char *desc;
} action_types[] = {
{ "create", action_create, 0, 2, N_("<name> <device>"), N_("create device") },
{ "remove", action_remove, 0, 1, N_("<name>"), N_("remove device") },
{ "resize", action_resize, 0, 1, N_("<name>"), N_("resize active device") },
{ "status", action_status, 0, 1, N_("<name>"), N_("show device status") },
{ "luksFormat", action_luksFormat, 0, 1, N_("<device> [<new key file>]"), N_("formats a LUKS device") },
{ "luksOpen", action_luksOpen, 0, 2, N_("<device> <name> "), N_("open LUKS device as mapping <name>") },
{ "luksAddKey", action_luksAddKey, 0, 1, N_("<device> [<new key file>]"), N_("add key to LUKS device") },
{ "luksRemoveKey", action_luksRemoveKey, 0, 1, N_("<device> [<key file>]"), N_("removes supplied key or key file from LUKS device") },
{ "luksKillSlot", action_luksKillSlot, 0, 2, N_("<device> <key slot>"), N_("wipes key with number <key slot> from LUKS device") },
{ "luksUUID", action_luksUUID, 0, 1, N_("<device>"), N_("print UUID of LUKS device") },
{ "isLuks", action_isLuks, 0, 1, N_("<device>"), N_("tests <device> for LUKS partition header") },
{ "luksClose", action_remove, 0, 1, N_("<name>"), N_("remove LUKS mapping") },
{ "luksDump", action_luksDump, 0, 1, N_("<device>"), N_("dump LUKS partition information") },
{ "luksDelKey", action_luksDelKey, 0, 2, N_("<device> <key slot>"), N_("identical to luksKillSlot - DEPRECATED - see man page") },
{ "reload", action_create, 1, 2, N_("<name> <device>"), N_("modify active device - DEPRECATED - see man page") },
{ NULL, NULL, 0, 0, NULL }
{ "create", action_create, 0, 2, 1, 1, 1, N_("<name> <device>"),N_("create device") },
{ "remove", action_remove, 0, 1, 1, 0, 1, N_("<name>"), N_("remove device") },
{ "resize", action_resize, 0, 1, 1, 1, 1, N_("<name>"), N_("resize active device") },
{ "status", action_status, 0, 1, 1, 0, 1, N_("<name>"), N_("show device status") },
{ "luksFormat", action_luksFormat, 0, 1, 1, 1, 1, N_("<device> [<new key file>]"), N_("formats a LUKS device") },
{ "luksOpen", action_luksOpen, 0, 2, 1, 1, 1, N_("<device> <name> "), N_("open LUKS device as mapping <name>") },
{ "luksAddKey", action_luksAddKey, 0, 1, 1, 1, 1, N_("<device> [<new key file>]"), N_("add key to LUKS device") },
{ "luksRemoveKey",action_luksRemoveKey, 0, 1, 1, 1, 1, N_("<device> [<key file>]"), N_("removes supplied key or key file from LUKS device") },
{ "luksKillSlot", action_luksKillSlot, 0, 2, 1, 1, 1, N_("<device> <key slot>"), N_("wipes key with number <key slot> from LUKS device") },
{ "luksUUID", action_luksUUID, 0, 1, 0, 0, 1, N_("<device>"), N_("print UUID of LUKS device") },
{ "isLuks", action_isLuks, 0, 1, 0, 0, 0, N_("<device>"), N_("tests <device> for LUKS partition header") },
{ "luksClose", action_remove, 0, 1, 1, 0, 1, N_("<name>"), N_("remove LUKS mapping") },
{ "luksDump", action_luksDump, 0, 1, 0, 0, 1, N_("<device>"), N_("dump LUKS partition information") },
{ "luksDelKey", action_luksDelKey, 0, 2, 1, 1, 1, N_("<device> <key slot>"), N_("identical to luksKillSlot - DEPRECATED - see man page") },
{ "reload", action_create, 1, 2, 1, 1, 1, N_("<name> <device>"), N_("modify active device - DEPRECATED - see man page") },
{ NULL, NULL, 0, 0, 0, 0, 0, NULL, NULL }
};
/* Interface Callbacks */
......@@ -182,8 +186,7 @@ static int action_create(int reload)
r = crypt_update_device(&options);
else
r = crypt_create_device(&options);
if (r < 0)
show_status(-r);
return r;
}
......@@ -193,12 +196,8 @@ static int action_remove(int arg)
.name = action_argv[0],
.icb = &cmd_icb,
};
int r;
r = crypt_remove_device(&options);
if (r < 0)
show_status(-r);
return r;
return crypt_remove_device(&options);
}
static int action_resize(int arg)
......@@ -208,12 +207,8 @@ static int action_resize(int arg)
.size = opt_size,
.icb = &cmd_icb,
};
int r;
r = crypt_resize_device(&options);
if (r < 0)
show_status(-r);
return r;
return crypt_resize_device(&options);
}
static int action_status(int arg)
......@@ -225,11 +220,10 @@ static int action_status(int arg)
int r;
r = crypt_query_device(&options);
if (r < 0) {
/* error */
show_status(-r);
} else if (r == 0) {
if (r < 0)
return r;
if (r == 0) {
/* inactive */
printf("%s/%s is inactive.\n", crypt_get_dir(), options.name);
r = 1;
......@@ -254,10 +248,10 @@ static int action_status(int arg)
static int action_luksFormat(int arg)
{
struct crypt_options options = {
.key_size = (opt_key_size != 0 ? opt_key_size : DEFAULT_LUKS_KEY_SIZE) / 8,
.key_size = (opt_key_size ?: DEFAULT_LUKS_KEY_SIZE) / 8,
.key_slot = opt_key_slot,
.device = action_argv[0],
.cipher = opt_cipher?opt_cipher:DEFAULT_LUKS_CIPHER,
.cipher = opt_cipher ?: DEFAULT_LUKS_CIPHER,
.hash = opt_hash ?: DEFAULT_LUKS_HASH,
.new_key_file = action_argc > 1 ? action_argv[1] : NULL,
.flags = opt_verify_passphrase ? CRYPT_FLAG_VERIFY : (!opt_batch_mode?CRYPT_FLAG_VERIFY_IF_POSSIBLE : 0),
......@@ -266,7 +260,6 @@ static int action_luksFormat(int arg)
.align_payload = opt_align_payload,
.icb = &cmd_icb,
};
int r = 0; char *msg = NULL;
/* Avoid overwriting possibly wrong part of device than user requested by rejecting these options */
......@@ -277,12 +270,15 @@ static int action_luksFormat(int arg)
if(asprintf(&msg, _("This will overwrite data on %s irrevocably."), options.device) == -1) {
fputs(_("memory allocation error in action_luksFormat"), stderr);
} else {
r = yesDialog(msg) ? crypt_luksFormat(&options) : -EINVAL;
free(msg);
show_status(-r);
return -ENOMEM;
}
return r;
r = yesDialog(msg);
free(msg);
if (!r)
return -EINVAL;
return crypt_luksFormat(&options);
}
static int action_luksOpen(int arg)
......@@ -293,20 +289,15 @@ static int action_luksOpen(int arg)
.key_file = opt_key_file,
.key_size = opt_key_file ? (opt_key_size / 8) : 0, /* limit bytes read from keyfile */
.timeout = opt_timeout,
.tries = opt_tries,
.tries = opt_key_file ? 1 : opt_tries, /* verify is usefull only for tty */
.icb = &cmd_icb,
};
int r;
opt_verbose = 1;
options.flags = 0;
if (opt_readonly)
options.flags |= CRYPT_FLAG_READONLY;
if (opt_non_exclusive)
options.flags |= CRYPT_FLAG_NON_EXCLUSIVE_ACCESS;
r = crypt_luksOpen(&options);
show_status(-r);
return r;
return crypt_luksOpen(&options);
}
static int action_luksDelKey(int arg)
......@@ -325,12 +316,8 @@ static int action_luksKillSlot(int arg)
.flags = !opt_batch_mode?CRYPT_FLAG_VERIFY_ON_DELKEY : 0,
.icb = &cmd_icb,
};
int r;
opt_verbose = 1;
r = crypt_luksKillSlot(&options);
show_status(-r);
return r;
return crypt_luksKillSlot(&options);
}
static int action_luksRemoveKey(int arg)
......@@ -343,12 +330,8 @@ static int action_luksRemoveKey(int arg)
.flags = !opt_batch_mode?CRYPT_FLAG_VERIFY_ON_DELKEY : 0,
.icb = &cmd_icb,
};
int r;
opt_verbose = 1;
r = crypt_luksRemoveKey(&options);
show_status(-r);
return r;
return crypt_luksRemoveKey(&options);
}
static int action_luksAddKey(int arg)
......@@ -363,12 +346,8 @@ static int action_luksAddKey(int arg)
.timeout = opt_timeout,
.icb = &cmd_icb,
};
int r;
opt_verbose = 1;
r = crypt_luksAddKey(&options);
show_status(-r);
return r;
return crypt_luksAddKey(&options);
}
static int action_isLuks(int arg)
......@@ -377,6 +356,7 @@ static int action_isLuks(int arg)
.device = action_argv[0],
.icb = &cmd_icb,
};
return crypt_isLuks(&options);
}
......@@ -386,12 +366,8 @@ static int action_luksUUID(int arg)
.device = action_argv[0],
.icb = &cmd_icb,
};
int r;
r = crypt_luksUUID(&options);
if (r < 0)
show_status(-r);
return r;
return crypt_luksUUID(&options);
}
static int action_luksDump(int arg)
......@@ -400,12 +376,8 @@ static int action_luksDump(int arg)
.device = action_argv[0],
.icb = &cmd_icb,
};
int r;
r = crypt_luksDump(&options);
if (r < 0)
show_status(-r);
return r;
return crypt_luksDump(&options);
}
static void usage(poptContext popt_context, int exitcode,
......@@ -442,7 +414,33 @@ static void help(poptContext popt_context, enum poptCallbackReason reason,
exit(0);
} else
usage(popt_context, 0, NULL, NULL);
}
}
static int run_action(struct action_type *action)
{
int r;
if (dm_init(NULL, action->required_dm_backend) < 1) {
fprintf(stderr,_("Cannot communicate with device-mapper. Is dm_mod kernel module loaded?\n"));
return -ENOSYS;
}
if (action->required_memlock)
memlock_inc(NULL);
r = action->handler(action->arg);
if (action->required_memlock)
memlock_dec(NULL);
if (action->required_dm_backend)
dm_exit();
if (r < 0 && (opt_verbose || action->show_status))
show_status(-r);
return r;
}
int main(int argc, char **argv)
{
......@@ -553,11 +551,7 @@ int main(int argc, char **argv)
snprintf(buf, 128,_("%s: requires %s as arguments"), action->type, action->arg_desc);
usage(popt_context, 1, buf,
poptGetInvocationName(popt_context));
}
return action->handler(action->arg);
}
}
// Local Variables:
// c-basic-offset: 8
// indent-tabs-mode: nil
// End:
return run_action(action);
}
......@@ -33,4 +33,11 @@
#define DEFAULT_KEY_SIZE 256
#define DEFAULT_LUKS_KEY_SIZE 128
/* Helper funcions provided by internal libcryptsetup objects */
struct crypt_device;
extern int memlock_inc(struct crypt_device *ctx);
extern int memlock_dec(struct crypt_device *ctx);
extern int dm_init(struct crypt_device *context, int check_kernel);
extern void dm_exit(void);
#endif /* CRYPTSETUP_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment