Zero out blocks if BLKSECDISCARD fails
On a device where we can't BLKSECDISCARD sectors, we "overwrite" them with zeroes. This changes the FTL to remap those sectors to new locations. With this done, the old contents are accessible only given a compromise of flash firmware or a die level attack. Bug: 26021231 Change-Id: Ia065921389886fac1ba456c19c138187237c2561
This commit is contained in:
parent
6abe6831b5
commit
2143ee8d61
1 changed files with 32 additions and 9 deletions
|
@ -43,11 +43,12 @@ constexpr uint32_t max_extents = 32;
|
|||
|
||||
bool read_command_line(int argc, const char * const argv[], Options &options);
|
||||
void usage(const char *progname);
|
||||
int secdiscard_path(const std::string &path);
|
||||
bool secdiscard_path(const std::string &path);
|
||||
std::unique_ptr<struct fiemap> path_fiemap(const std::string &path, uint32_t extent_count);
|
||||
bool check_fiemap(const struct fiemap &fiemap, const std::string &path);
|
||||
std::unique_ptr<struct fiemap> alloc_fiemap(uint32_t extent_count);
|
||||
std::string block_device_for_path(const std::string &path);
|
||||
bool overwrite_with_zeros(int fd, off64_t start, off64_t length);
|
||||
|
||||
}
|
||||
|
||||
|
@ -58,9 +59,11 @@ int main(int argc, const char * const argv[]) {
|
|||
usage(argv[0]);
|
||||
return -1;
|
||||
}
|
||||
for (auto target: options.targets) {
|
||||
for (auto const &target: options.targets) {
|
||||
LOG(DEBUG) << "Securely discarding '" << target << "' unlink=" << options.unlink;
|
||||
secdiscard_path(target);
|
||||
if (!secdiscard_path(target)) {
|
||||
LOG(ERROR) << "Secure discard failed for: " << target;
|
||||
}
|
||||
if (options.unlink) {
|
||||
if (unlink(target.c_str()) != 0 && errno != ENOENT) {
|
||||
PLOG(ERROR) << "Unable to unlink: " << target;
|
||||
|
@ -95,19 +98,19 @@ void usage(const char *progname) {
|
|||
}
|
||||
|
||||
// BLKSECDISCARD all content in "path", if it's small enough.
|
||||
int secdiscard_path(const std::string &path) {
|
||||
bool secdiscard_path(const std::string &path) {
|
||||
auto fiemap = path_fiemap(path, max_extents);
|
||||
if (!fiemap || !check_fiemap(*fiemap, path)) {
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
auto block_device = block_device_for_path(path);
|
||||
if (block_device.empty()) {
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
AutoCloseFD fs_fd(block_device, O_RDWR | O_LARGEFILE);
|
||||
if (!fs_fd) {
|
||||
PLOG(ERROR) << "Failed to open device " << block_device;
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
for (uint32_t i = 0; i < fiemap->fm_mapped_extents; i++) {
|
||||
uint64_t range[2];
|
||||
|
@ -115,10 +118,11 @@ int secdiscard_path(const std::string &path) {
|
|||
range[1] = fiemap->fm_extents[i].fe_length;
|
||||
if (ioctl(fs_fd.get(), BLKSECDISCARD, range) == -1) {
|
||||
PLOG(ERROR) << "Unable to BLKSECDISCARD " << path;
|
||||
return -1;
|
||||
if (!overwrite_with_zeros(fs_fd.get(), range[0], range[1])) return false;
|
||||
LOG(DEBUG) << "Used zero overwrite";
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Read the file's FIEMAP
|
||||
|
@ -206,4 +210,23 @@ std::string block_device_for_path(const std::string &path)
|
|||
return result;
|
||||
}
|
||||
|
||||
bool overwrite_with_zeros(int fd, off64_t start, off64_t length) {
|
||||
if (lseek64(fd, start, SEEK_SET) != start) {
|
||||
PLOG(ERROR) << "Seek failed for zero overwrite";
|
||||
return false;
|
||||
}
|
||||
char buf[BUFSIZ];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
while (length > 0) {
|
||||
size_t wlen = static_cast<size_t>(std::min(static_cast<off64_t>(sizeof(buf)), length));
|
||||
auto written = write(fd, buf, wlen);
|
||||
if (written < 1) {
|
||||
PLOG(ERROR) << "Write of zeroes failed";
|
||||
return false;
|
||||
}
|
||||
length -= written;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue