Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 242778
Collapse All | Expand All

(-)lib/setup.c (-2 / +5 lines)
Lines 396-402 static int __crypt_remove_device(int arg Link Here
396
		return -EBUSY;
396
		return -EBUSY;
397
	}
397
	}
398
398
399
	return backend->remove(options);
399
	return backend->remove(0, options);
400
}
400
}
401
401
402
static int __crypt_luks_format(int arg, struct setup_backend *backend, struct crypt_options *options)
402
static int __crypt_luks_format(int arg, struct setup_backend *backend, struct crypt_options *options)
Lines 705-711 static int crypt_job(int (*job)(int arg, Link Here
705
705
706
	backend = get_setup_backend(default_backend);
706
	backend = get_setup_backend(default_backend);
707
707
708
	setup_enter(backend,options->icb->log);
708
	if (setup_enter(backend,options->icb->log) < 0) {
709
		r = -ENOSYS;
710
		goto out;
711
	}
709
712
710
	if (!backend) {
713
	if (!backend) {
711
		set_error("No setup backend available");
714
		set_error("No setup backend available");
(-)lib/internal.h (-1 / +1 lines)
Lines 40-46 struct setup_backend { Link Here
40
			          const char *key);
40
			          const char *key);
41
	int		(*status)(int details, struct crypt_options *options,
41
	int		(*status)(int details, struct crypt_options *options,
42
			          char **key);
42
			          char **key);
43
	int		(*remove)(struct crypt_options *options);
43
	int		(*remove)(int force, struct crypt_options *options);
44
44
45
	const char *	(*dir)(void);
45
	const char *	(*dir)(void);
46
};
46
};
(-)lib/libdevmapper.c (-46 / +97 lines)
Lines 17-29 Link Here
17
#define DEVICE_DIR	"/dev"
17
#define DEVICE_DIR	"/dev"
18
18
19
#define	CRYPT_TARGET	"crypt"
19
#define	CRYPT_TARGET	"crypt"
20
20
#define	RETRY_COUNT	5
21
#define UDEVSETTLE	"/sbin/udevsettle"
22
23
static void run_udevsettle(void)
24
{
25
	system(UDEVSETTLE);
26
}
27
21
28
static void set_dm_error(int level, const char *file, int line,
22
static void set_dm_error(int level, const char *file, int line,
29
                         const char *f, ...)
23
                         const char *f, ...)
Lines 38-46 static void set_dm_error(int level, cons Link Here
38
	va_end(va);
32
	va_end(va);
39
}
33
}
40
34
35
static int _dm_simple(int task, const char *name);
36
41
static int dm_init(void)
37
static int dm_init(void)
42
{
38
{
43
	dm_log_init(set_dm_error);
39
	dm_log_init(set_dm_error);
40
	if (!_dm_simple(DM_DEVICE_LIST_VERSIONS, "test")) {
41
		set_error("Cannot communicate with device-mapper. Is the dm_mod module loaded?");
42
		return -1;
43
	}
44
44
	return 1;	/* unsafe memory */
45
	return 1;	/* unsafe memory */
45
}
46
}
46
47
Lines 50-65 static void dm_exit(void) Link Here
50
	dm_lib_release();
51
	dm_lib_release();
51
}
52
}
52
53
53
static void flush_dm_workqueue(void)
54
{
55
	/* 
56
	 * Unfortunately this is the only way to trigger libdevmapper's
57
	 * update_nodes function 
58
	 */ 
59
	dm_exit(); 
60
	dm_init();
61
}
62
63
static char *__lookup_dev(char *path, dev_t dev)
54
static char *__lookup_dev(char *path, dev_t dev)
64
{
55
{
65
	struct dirent *entry;
56
	struct dirent *entry;
Lines 152-157 out: Link Here
152
	return params;
143
	return params;
153
}
144
}
154
145
146
/* DM helpers */
147
static int _dm_simple(int task, const char *name)
148
{
149
	int r = 0;
150
	struct dm_task *dmt;
151
152
	if (!(dmt = dm_task_create(task)))
153
		return 0;
154
155
	if (!dm_task_set_name(dmt, name))
156
		goto out;
157
158
	r = dm_task_run(dmt);
159
160
      out:
161
	dm_task_destroy(dmt);
162
	return r;
163
}
164
165
static int _error_device(struct crypt_options *options)
166
{
167
	struct dm_task *dmt;
168
	int r = 0;
169
170
	if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
171
		return 0;
172
173
	if (!dm_task_set_name(dmt, options->name))
174
		goto error;
175
176
	if (!dm_task_add_target(dmt, UINT64_C(0), options->size, "error", ""))
177
		goto error;
178
179
	if (!dm_task_set_ro(dmt))
180
		goto error;
181
182
	if (!dm_task_no_open_count(dmt))
183
		goto error;
184
185
	if (!dm_task_run(dmt))
186
		goto error;
187
188
	if (!_dm_simple(DM_DEVICE_RESUME, options->name)) {
189
		_dm_simple(DM_DEVICE_CLEAR, options->name);
190
		goto error;
191
	}
192
193
	r = 1;
194
195
error:
196
	dm_task_destroy(dmt);
197
	return r;
198
}
199
200
static int _dm_remove(struct crypt_options *options, int force)
201
{
202
	int r = -EINVAL;
203
	int retries = force ? RETRY_COUNT : 1;
204
205
	/* If force flag is set, replace device with error, read-only target.
206
	 * it should stop processes from reading it and also removed underlying
207
	 * device from mapping, so it is usable again.
208
	 * Force flag should be used only for temporary devices, which are
209
	 * intended to work inside cryptsetup only!
210
	 * Anyway, if some process try to read temporary cryptsetup device,
211
	 * it is bug - no other process should try touch it (e.g. udev).
212
	 */
213
	if (force) {
214
		 _error_device(options);
215
		retries = RETRY_COUNT;
216
	}
217
218
	do {
219
		r = _dm_simple(DM_DEVICE_REMOVE, options->name) ? 0 : -EINVAL;
220
		if (--retries)
221
			sleep(1);
222
	} while (r == -EINVAL && retries);
223
224
	dm_task_update_nodes();
225
226
	return r;
227
}
228
155
static int dm_create_device(int reload, struct crypt_options *options,
229
static int dm_create_device(int reload, struct crypt_options *options,
156
                            const char *key)
230
                            const char *key)
157
{
231
{
Lines 191-214 static int dm_create_device(int reload, Link Here
191
	if (dmi.read_only)
265
	if (dmi.read_only)
192
		options->flags |= CRYPT_FLAG_READONLY;
266
		options->flags |= CRYPT_FLAG_READONLY;
193
267
194
	/* run udevsettle to avoid a race in libdevmapper causing busy dm devices */
195
	run_udevsettle();
196
197
	r = 0;
268
	r = 0;
198
	
199
out:
269
out:
200
	if (r < 0 && !reload) {
270
	if (r < 0 && !reload) {
201
		char *error = (char *)get_error();
271
		char *error = (char *)get_error();
202
		if (error)
272
		if (error)
203
			error = strdup(error);
273
			error = strdup(error);
204
		if (dmt)
205
			dm_task_destroy(dmt);
206
274
207
		if (!(dmt = dm_task_create(DM_DEVICE_REMOVE)))
275
		if (!_dm_remove(options, 0))
208
			goto out_restore_error;
209
		if (!dm_task_set_name(dmt, options->name))
210
			goto out_restore_error;
211
		if (!dm_task_run(dmt))
212
			goto out_restore_error;
276
			goto out_restore_error;
213
277
214
out_restore_error:
278
out_restore_error:
Lines 224-230 out_no_removal: Link Here
224
		dm_task_destroy(dmt);
288
		dm_task_destroy(dmt);
225
	if(dmt_query)
289
	if(dmt_query)
226
		dm_task_destroy(dmt_query);
290
		dm_task_destroy(dmt_query);
227
	flush_dm_workqueue();
291
	dm_task_update_nodes();
228
	return r;
292
	return r;
229
}
293
}
230
294
Lines 352-376 out: Link Here
352
	return r;
416
	return r;
353
}
417
}
354
418
355
static int dm_remove_device(struct crypt_options *options)
419
static int dm_remove_device(int force, struct crypt_options *options)
356
{
420
{
357
	struct dm_task *dmt;
421
	if (!options || !options->name)
358
	int r = -EINVAL;
422
		return -EINVAL;
359
360
	if (!(dmt = dm_task_create(DM_DEVICE_REMOVE)))
361
		goto out;
362
	if (!dm_task_set_name(dmt, options->name))
363
		goto out;
364
	if (!dm_task_run(dmt))
365
		goto out;
366
367
	r = 0;
368
423
369
out:	
424
	return _dm_remove(options, force);;
370
	if (dmt)
371
		dm_task_destroy(dmt);
372
	flush_dm_workqueue();
373
	return r;
374
}
425
}
375
426
376
427
(-)luks/keyencryption.c (-13 / +17 lines)
Lines 45-50 static inline int round_up_modulo(int x, Link Here
45
	return div_round_up(x, m) * m;
45
	return div_round_up(x, m) * m;
46
}
46
}
47
47
48
static struct setup_backend *cleaner_backend=NULL;
49
static const char *cleaner_name=NULL;
50
static uint64_t cleaner_size = 0;
51
static int devfd=-1;
52
48
static int setup_mapping(const char *cipher, const char *name, 
53
static int setup_mapping(const char *cipher, const char *name, 
49
			 const char *device, unsigned int payloadOffset,
54
			 const char *device, unsigned int payloadOffset,
50
			 const char *key, size_t keyLength, 
55
			 const char *key, size_t keyLength, 
Lines 52-58 static int setup_mapping(const char *cip Link Here
52
			 struct setup_backend *backend,
57
			 struct setup_backend *backend,
53
			 int mode)
58
			 int mode)
54
{
59
{
55
	struct crypt_options k;
60
	struct crypt_options k = {0};
56
	struct crypt_options *options = &k;
61
	struct crypt_options *options = &k;
57
	int device_sector_size = sector_size_for_device(device);
62
	int device_sector_size = sector_size_for_device(device);
58
	int r;
63
	int r;
Lines 66-71 static int setup_mapping(const char *cip Link Here
66
		return -EINVAL;
71
		return -EINVAL;
67
	}
72
	}
68
	options->size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
73
	options->size = round_up_modulo(srcLength,device_sector_size)/SECTOR_SIZE;
74
	cleaner_size = options->size;
69
75
70
	options->offset = sector;
76
	options->offset = sector;
71
	options->cipher = cipher;
77
	options->cipher = cipher;
Lines 87-110 static int setup_mapping(const char *cip Link Here
87
	return r;
93
	return r;
88
}
94
}
89
95
90
static int clear_mapping(const char *name, struct setup_backend *backend)
96
static int clear_mapping(const char *name, uint64_t size, struct setup_backend *backend)
91
{
97
{
92
	struct crypt_options options;
98
	struct crypt_options options = {0};
93
	options.name=name;
99
	options.name=name;
94
	return backend->remove(&options);
100
	options.size = size;
101
	return backend->remove(1, &options);
95
}
102
}
96
103
97
/* I miss closures in C! */
98
static struct setup_backend *cleaner_backend=NULL;
99
static const char *cleaner_name=NULL; 
100
static int devfd=0;
101
102
static void sigint_handler(int sig)
104
static void sigint_handler(int sig)
103
{
105
{
104
        if(devfd)
106
        if(devfd >= 0)
105
                close(devfd);
107
                close(devfd);
108
        devfd = -1;
106
        if(cleaner_backend && cleaner_name) 
109
        if(cleaner_backend && cleaner_name) 
107
                clear_mapping(cleaner_name, cleaner_backend);
110
                clear_mapping(cleaner_name, cleaner_size, cleaner_backend);
108
        signal(SIGINT, SIG_DFL);
111
        signal(SIGINT, SIG_DFL);
109
        kill(getpid(), SIGINT);
112
        kill(getpid(), SIGINT);
110
}
113
}
Lines 160-172 static int LUKS_endec_template(char *src Link Here
160
	r = 0;
163
	r = 0;
161
 out3:
164
 out3:
162
	close(devfd);
165
	close(devfd);
163
	devfd = 0;
166
	devfd = -1;
164
 out2:
167
 out2:
165
	clear_mapping(name,backend);
168
	clear_mapping(cleaner_name, cleaner_size, cleaner_backend);
166
 out1:
169
 out1:
167
	signal(SIGINT, SIG_DFL);
170
	signal(SIGINT, SIG_DFL);
168
	cleaner_name = NULL;
171
	cleaner_name = NULL;
169
	cleaner_backend = NULL;
172
	cleaner_backend = NULL;
173
	cleaner_size = 0;
170
	free(dmCipherSpec);
174
	free(dmCipherSpec);
171
	free(fullpath); 
175
	free(fullpath); 
172
	free(name); 
176
	free(name); 

Return to bug 242778