aboutsummaryrefslogtreecommitdiffstats
path: root/main/cryptsetup/direct-io.patch
blob: 25a242575f90bc4e83bf7a8e2044d370af720b22 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
From 89f795d7b453acf347c0b293d09746a8c0d48d12 Mon Sep 17 00:00:00 2001
From: Milan Broz <gmazyland@gmail.com>
Date: Fri, 8 Aug 2014 14:49:38 +0200
Subject: [PATCH] Fix keyslot device access for devices not supporting
 O_DIRECT.

---
 lib/luks1/keyencryption.c | 55 ++++++++++++++++++++++++++++-------------------
 lib/utils_device.c        |  6 ++++++
 2 files changed, 39 insertions(+), 22 deletions(-)

diff --git a/lib/luks1/keyencryption.c b/lib/luks1/keyencryption.c
index 66e942e..3bc9c33 100644
--- a/lib/luks1/keyencryption.c
+++ b/lib/luks1/keyencryption.c
@@ -136,7 +136,7 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
 
 	struct device *device = crypt_metadata_device(ctx);
 	struct crypt_storage *s;
-	int devfd, bsize, r = 0;
+	int devfd = -1, bsize, r = 0;
 
 	/* Only whole sector writes supported */
 	if (srcLength % SECTOR_SIZE)
@@ -164,25 +164,33 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
 
 	r = crypt_storage_encrypt(s, 0, srcLength / SECTOR_SIZE, src);
 	crypt_storage_destroy(s);
+
 	if (r)
 		return r;
 
+	r = -EIO;
+
 	/* Write buffer to device */
 	bsize = device_block_size(device);
 	if (bsize <= 0)
-		return -EIO;
+		goto out;
 
-	devfd = open(device_path(device), O_RDWR | O_DIRECT);
+	devfd = device_open(device, O_RDWR);
 	if (devfd == -1)
-		return -EIO;
+		goto out;
 
 	if (lseek(devfd, sector * SECTOR_SIZE, SEEK_SET) == -1 ||
 	    write_blockwise(devfd, bsize, src, srcLength) == -1)
-		r = -EIO;
+		goto out;
 
-	close(devfd);
-	return r;
+	r = 0;
+out:
+	if(devfd != -1)
+		close(devfd);
+	if (r)
+		log_err(ctx, _("IO error while encrypting keyslot.\n"));
 
+	return r;
 }
 
 int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
@@ -194,7 +202,7 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
 {
 	struct device *device = crypt_metadata_device(ctx);
 	struct crypt_storage *s;
-	int devfd, bsize, r = 0;
+	int devfd = -1, bsize, r = 0;
 
 	/* Only whole sector reads supported */
 	if (dstLength % SECTOR_SIZE)
@@ -219,25 +227,20 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
 
 	log_dbg("Using userspace crypto wrapper to access keyslot area.");
 
+	r = -EIO;
+
 	/* Read buffer from device */
 	bsize = device_block_size(device);
-	if (bsize <= 0) {
-		crypt_storage_destroy(s);
-		return -EIO;
-	}
+	if (bsize <= 0)
+		goto bad;
 
-	devfd = open(device_path(device), O_RDONLY | O_DIRECT);
-	if (devfd == -1) {
-		crypt_storage_destroy(s);
-		return -EIO;
-	}
+	devfd = device_open(device, O_RDONLY);
+	if (devfd == -1)
+		goto bad;
 
 	if (lseek(devfd, sector * SECTOR_SIZE, SEEK_SET) == -1 ||
-	    read_blockwise(devfd, bsize, dst, dstLength) == -1) {
-		crypt_storage_destroy(s);
-		close(devfd);
-		return -EIO;
-	}
+	    read_blockwise(devfd, bsize, dst, dstLength) == -1)
+		goto bad;
 
 	close(devfd);
 
@@ -246,4 +249,12 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
 	crypt_storage_destroy(s);
 
 	return r;
+bad:
+	if(devfd != -1)
+		close(devfd);
+
+	log_err(ctx, _("IO error while decrypting keyslot.\n"));
+	crypt_storage_destroy(s);
+
+	return r;
 }
diff --git a/lib/utils_device.c b/lib/utils_device.c
index d74149a..491a026 100644
--- a/lib/utils_device.c
+++ b/lib/utils_device.c
@@ -72,6 +72,9 @@ int device_open(struct device *device, int flags)
 		devfd = open(device_path(device), flags | O_SYNC);
 	}
 
+	if (devfd < 0)
+		log_dbg("Cannot open device %s.", device_path(device));
+
 	return devfd;
 }
 
@@ -229,6 +232,9 @@ int device_block_size(struct device *device)
 	if (ioctl(fd, BLKSSZGET, &bsize) >= 0)
 		r = bsize;
 out:
+	if (r <= 0)
+		log_dbg("Cannot get block size for device %s.", device_path(device));
+
 	close(fd);
 	return r;
 }
-- 
2.0.3