* Copyright (C) 2004, Christophe Saout <christophe@saout.de>
* Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2012, Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2009-2012, Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
int devfd, r = 0;
struct stat st;
- if(stat(device, &st) < 0) {
- log_err(NULL, _("Device %s doesn't exist or access denied.\n"), device);
- return -EINVAL;
- }
-
- if (!S_ISBLK(st.st_mode))
- return S_ISREG(st.st_mode) ? -ENOTBLK : -EINVAL;
-
log_dbg("Trying to open and read device %s.", device);
devfd = open(device, O_RDONLY | O_DIRECT | O_SYNC);
- if(devfd < 0) {
- log_err(NULL, _("Cannot open device %s.\n"), device);
+ if (devfd < 0) {
+ log_err(NULL, _("Device %s doesn't exist or access denied.\n"), device);
return -EINVAL;
}
+ if (fstat(devfd, &st) < 0)
+ r = -EINVAL;
+ else if (!S_ISBLK(st.st_mode))
+ r = S_ISREG(st.st_mode) ? -ENOTBLK : -EINVAL;
close(devfd);
return r;
flags |= O_EXCL;
/* Try to open read-write to check whether it is a read-only device */
+ /* coverity[toctou] */
fd = open(device->path, O_RDWR | flags);
if (fd == -1 && errno == EROFS) {
*readonly = 1;
if (device->init_done)
return 0;
- log_dbg("Allocating free loop device.");
+ log_dbg("Allocating a free loop device.");
loop_device = crypt_loop_get_device();
if (!loop_device) {
- log_err(cd, _("Cannot find a free loopback device.\n"));
- return -EINVAL;
+ if (getuid() || geteuid())
+ log_err(cd, _("Cannot use a loopback device, "
+ "running as non-root user.\n"));
+ else
+ log_err(cd, _("Cannot find a free loopback device.\n"));
+ return -ENOTSUP;
}
/* Keep the loop open, dettached on last close. */
*size, real_readonly ? "RO" : "RW", device_offset);
return 0;
}
+
+size_t size_round_up(size_t size, unsigned int block)
+{
+ size_t s = (size + (block - 1)) / block;
+ return s * block;
+}