rpms/cryptsetup-luks/devel cryptsetup-fix-fd.patch, NONE, 1.1 cryptsetup-remove-udev.patch, NONE, 1.1 cryptsetup-luks.spec, 1.60, 1.61

Milan Broz mbroz at fedoraproject.org
Sun Sep 7 08:55:22 UTC 2008


Author: mbroz

Update of /cvs/pkgs/rpms/cryptsetup-luks/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv4962

Modified Files:
	cryptsetup-luks.spec 
Added Files:
	cryptsetup-fix-fd.patch cryptsetup-remove-udev.patch 
Log Message:
Fix close of zero decriptor.
Fix udevsettle delays - use temporary crypt device remapping.



cryptsetup-fix-fd.patch:

--- NEW FILE cryptsetup-fix-fd.patch ---
Close file descriptor even if it is 0.
--- cryptsetup-1.0.6.old/luks/keyencryption.c	2008-01-25 23:00:30.000000000 +0100
+++ cryptsetup-1.0.6/luks/keyencryption.c	2008-09-06 14:24:21.000000000 +0200
@@ -97,12 +97,13 @@ static int clear_mapping(const char *nam
 /* I miss closures in C! */
 static struct setup_backend *cleaner_backend=NULL;
 static const char *cleaner_name=NULL; 
-static int devfd=0;
+static int devfd=-1;
 
 static void sigint_handler(int sig)
 {
-        if(devfd)
+        if(devfd >= 0)
                 close(devfd);
+        devfd = -1;
         if(cleaner_backend && cleaner_name) 
                 clear_mapping(cleaner_name, cleaner_backend);
         signal(SIGINT, SIG_DFL);
@@ -160,7 +161,7 @@ static int LUKS_endec_template(char *src
 	r = 0;
  out3:
 	close(devfd);
-	devfd = 0;
+	devfd = -1;
  out2:
 	clear_mapping(name,backend);
  out1:

cryptsetup-remove-udev.patch:

--- NEW FILE cryptsetup-remove-udev.patch ---
Replace udevsettle with remmaping to error target.

--- cryptsetup-1.0.6.old/lib/internal.h	2007-10-25 09:11:19.000000000 +0200
+++ cryptsetup-1.0.6/lib/internal.h	2008-09-06 14:27:41.000000000 +0200
@@ -40,7 +40,7 @@ struct setup_backend {
 			          const char *key);
 	int		(*status)(int details, struct crypt_options *options,
 			          char **key);
-	int		(*remove)(struct crypt_options *options);
+	int		(*remove)(int force, struct crypt_options *options);
 
 	const char *	(*dir)(void);
 };
--- cryptsetup-1.0.6.old/lib/libdevmapper.c	2007-10-25 09:11:19.000000000 +0200
+++ cryptsetup-1.0.6/lib/libdevmapper.c	2008-09-06 14:28:56.000000000 +0200
@@ -17,13 +17,7 @@
 #define DEVICE_DIR	"/dev"
 
 #define	CRYPT_TARGET	"crypt"
-
-#define UDEVSETTLE	"/sbin/udevsettle"
-
-static void run_udevsettle(void)
-{
-	system(UDEVSETTLE);
-}
+#define RETRY_COUNT	5
 
 static void set_dm_error(int level, const char *file, int line,
                          const char *f, ...)
@@ -50,16 +44,6 @@ static void dm_exit(void)
 	dm_lib_release();
 }
 
-static void flush_dm_workqueue(void)
-{
-	/* 
-	 * Unfortunately this is the only way to trigger libdevmapper's
-	 * update_nodes function 
-	 */ 
-	dm_exit(); 
-	dm_init();
-}
-
 static char *__lookup_dev(char *path, dev_t dev)
 {
 	struct dirent *entry;
@@ -152,6 +136,89 @@ out:
 	return params;
 }
 
+/* DM helpers */
+static int _dm_simple(int task, const char *name)
+{
+	int r = 0;
+	struct dm_task *dmt;
+
+	if (!(dmt = dm_task_create(task)))
+		return 0;
+
+	if (!dm_task_set_name(dmt, name))
+		goto out;
+
+	r = dm_task_run(dmt);
+
+      out:
+	dm_task_destroy(dmt);
+	return r;
+}
+
+static int _error_device(struct crypt_options *options)
+{
+	struct dm_task *dmt;
+	int r = 0;
+
+	if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
+		return 0;
+
+	if (!dm_task_set_name(dmt, options->name))
+		goto error;
+
+	if (!dm_task_add_target(dmt, UINT64_C(0), options->size, "error", ""))
+		goto error;
+
+	if (!dm_task_set_ro(dmt))
+		goto error;
+
+	if (!dm_task_no_open_count(dmt))
+		goto error;
+
+	if (!dm_task_run(dmt))
+		goto error;
+
+	if (!_dm_simple(DM_DEVICE_RESUME, options->name)) {
+		_dm_simple(DM_DEVICE_CLEAR, options->name);
+		goto error;
+	}
+
+	r = 1;
+
+error:
+	dm_task_destroy(dmt);
+	return r;
+}
+
+static int _dm_remove(struct crypt_options *options, int force)
+{
+	int r = -EINVAL;
+	int retries = force ? RETRY_COUNT : 1;
+
+	/* If force flag is set, replace device with error, read-only target.
+	 * it should stop processes from reading it and also removed underlying
+	 * device from mapping, so it is usable again.
+	 * Force flag should be used only for temporary devices, which are
+	 * intended to work inside cryptsetup only!
+	 * Anyway, if some process try to read temporary cryptsetup device,
+	 * it is bug - no other process should try touch it (e.g. udev).
+	 */
+	if (force) {
+		 _error_device(options);
+		retries = RETRY_COUNT;
+	}
+
+	do {
+		r = _dm_simple(DM_DEVICE_REMOVE, options->name) ? 0 : -EINVAL;
+		if (--retries)
+			sleep(1);
+	} while (r == -EINVAL && retries);
+
+	dm_task_update_nodes();
+
+	return r;
+}
+
 static int dm_create_device(int reload, struct crypt_options *options,
                             const char *key)
 {
@@ -191,24 +258,14 @@ static int dm_create_device(int reload, 
 	if (dmi.read_only)
 		options->flags |= CRYPT_FLAG_READONLY;
 
-	/* run udevsettle to avoid a race in libdevmapper causing busy dm devices */
-	run_udevsettle();
-
 	r = 0;
-	
 out:
 	if (r < 0 && !reload) {
 		char *error = (char *)get_error();
 		if (error)
 			error = strdup(error);
-		if (dmt)
-			dm_task_destroy(dmt);
 
-		if (!(dmt = dm_task_create(DM_DEVICE_REMOVE)))
-			goto out_restore_error;
-		if (!dm_task_set_name(dmt, options->name))
-			goto out_restore_error;
-		if (!dm_task_run(dmt))
+		if (!_dm_remove(options, 0))
 			goto out_restore_error;
 
 out_restore_error:
@@ -224,7 +281,7 @@ out_no_removal:
 		dm_task_destroy(dmt);
 	if(dmt_query)
 		dm_task_destroy(dmt_query);
-	flush_dm_workqueue();
+	dm_task_update_nodes();
 	return r;
 }
 
@@ -352,25 +409,12 @@ out:
 	return r;
 }
 
-static int dm_remove_device(struct crypt_options *options)
+static int dm_remove_device(int force, struct crypt_options *options)
 {
-	struct dm_task *dmt;
-	int r = -EINVAL;
+	if (!options || !options->name)
+		return -EINVAL;
 
-	if (!(dmt = dm_task_create(DM_DEVICE_REMOVE)))
-		goto out;
-	if (!dm_task_set_name(dmt, options->name))
-		goto out;
-	if (!dm_task_run(dmt))
-		goto out;
-
-	r = 0;
-
-out:	
-	if (dmt)
-		dm_task_destroy(dmt);
-	flush_dm_workqueue();
-	return r;
+	return _dm_remove(options, force);;
 }
 
 
--- cryptsetup-1.0.6.old/lib/setup.c	2008-09-06 14:20:24.000000000 +0200
+++ cryptsetup-1.0.6/lib/setup.c	2008-09-06 14:27:41.000000000 +0200
@@ -369,7 +369,7 @@ static int __crypt_remove_device(int arg
 		return -EBUSY;
 	}
 
-	return backend->remove(options);
+	return backend->remove(0, options);
 }
 
 static int __crypt_luks_format(int arg, struct setup_backend *backend, struct crypt_options *options)
--- cryptsetup-1.0.6.old/luks/keyencryption.c	2008-09-06 14:24:21.000000000 +0200
+++ cryptsetup-1.0.6/luks/keyencryption.c	2008-09-06 14:27:41.000000000 +0200
@@ -50,10 +50,8 @@ static int setup_mapping(const char *cip
 			 const char *key, size_t keyLength, 
 			 unsigned int sector, size_t srcLength, 
 			 struct setup_backend *backend,
-			 int mode)
+			 int mode, struct crypt_options *options)
 {
-	struct crypt_options k;
-	struct crypt_options *options = &k;
 	int device_sector_size = sector_size_for_device(device);
 	int r;
 
@@ -87,16 +85,14 @@ static int setup_mapping(const char *cip
 	return r;
 }
 
-static int clear_mapping(const char *name, struct setup_backend *backend)
+static int clear_mapping(struct crypt_options *options, struct setup_backend *backend)
 {
-	struct crypt_options options;
-	options.name=name;
-	return backend->remove(&options);
+	return backend->remove(1, options);
 }
 
 /* I miss closures in C! */
 static struct setup_backend *cleaner_backend=NULL;
-static const char *cleaner_name=NULL; 
+static struct crypt_options *cleaner_options = NULL;
 static int devfd=-1;
 
 static void sigint_handler(int sig)
@@ -104,8 +100,8 @@ static void sigint_handler(int sig)
         if(devfd >= 0)
                 close(devfd);
         devfd = -1;
-        if(cleaner_backend && cleaner_name) 
-                clear_mapping(cleaner_name, cleaner_backend);
+        if(cleaner_backend && cleaner_options)
+                clear_mapping(cleaner_options, cleaner_backend);
         signal(SIGINT, SIG_DFL);
         kill(getpid(), SIGINT);
 }
@@ -120,6 +116,7 @@ static int LUKS_endec_template(char *src
 			       ssize_t (*func)(int, void *, size_t),
 			       int mode)
 {
+	struct crypt_options options = {0};
 	char *name = NULL;
 	char *fullpath = NULL;
 	char *dmCipherSpec = NULL;
@@ -138,10 +135,11 @@ static int LUKS_endec_template(char *src
         }
 	
 	signal(SIGINT, sigint_handler);
-	cleaner_name = name;
+	options.name = name;
+	cleaner_options = &options;
 	cleaner_backend = backend;
 
-	r = setup_mapping(dmCipherSpec,name,device,hdr->payloadOffset,key,keyLength,sector,srcLength,backend,mode);
+	r = setup_mapping(dmCipherSpec,name,device,hdr->payloadOffset,key,keyLength,sector,srcLength,backend,mode,&options);
 	if(r < 0) {
 		if(!get_error())
 			set_error("Failed to setup dm-crypt key mapping.\nCheck kernel for support for the %s cipher spec and verify that %s contains at least %d sectors",
@@ -163,10 +161,10 @@ static int LUKS_endec_template(char *src
 	close(devfd);
 	devfd = -1;
  out2:
-	clear_mapping(name,backend);
+	clear_mapping(&options,backend);
  out1:
 	signal(SIGINT, SIG_DFL);
-	cleaner_name = NULL;
+	cleaner_options = NULL;
 	cleaner_backend = NULL;
 	free(dmCipherSpec);
 	free(fullpath); 


Index: cryptsetup-luks.spec
===================================================================
RCS file: /cvs/pkgs/rpms/cryptsetup-luks/devel/cryptsetup-luks.spec,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -r1.60 -r1.61
--- cryptsetup-luks.spec	28 May 2008 13:26:25 -0000	1.60
+++ cryptsetup-luks.spec	7 Sep 2008 08:54:51 -0000	1.61
@@ -3,16 +3,20 @@
 Summary: A utility for setting up encrypted filesystems
 Name: cryptsetup-luks
 Version: 1.0.6
-Release: 3%{?devrelease:.%{devrelease}}%{?dist}
+Release: 4%{?devrelease:.%{devrelease}}%{?dist}
 License: GPLv2
 Group: Applications/System
 URL: http://luks.endorphin.org/
 Source: http://luks.endorphin.org/source/cryptsetup-%{version}%{?devrelease:-%{devrelease}}.tar.bz2
 # 2008-04-15: sent to upstream via personal e-mail to Clemens Fruhwirth
-Patch: cryptsetup-prompt.patch
+Patch0: cryptsetup-prompt.patch
 # 2008-05-28: sent to upstream via newsgroup:
 # http://permalink.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/2735
 Patch1: cryptsetup-luks-1.0.6-duplicate_sentence.patch
+# http://permalink.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/2803
+Patch2: cryptsetup-fix-fd.patch
+# http://permalink.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/2804
+Patch3: cryptsetup-remove-udev.patch
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: libgcrypt-devel, popt-devel, device-mapper-devel
 BuildRequires: libgpg-error-devel, e2fsprogs-devel, libsepol-devel
@@ -40,8 +44,10 @@
 
 %prep
 %setup -q -n cryptsetup-%{version}%{?devrelease:-%{devrelease}}
-%patch -p1 -b .prompt
+%patch0 -p1 -b .prompt
 %patch1 -p1 -b .duplicate_sentence
+%patch2 -p1 -b .fd
+%patch3 -p1 -b .udev
 iconv -f latin1 -t utf8 ChangeLog > ChangeLog.new
 mv -f ChangeLog.new ChangeLog 
 
@@ -86,6 +92,10 @@
 
 
 %changelog
+* Sat Sep 06 2008 Milan Broz <mbroz at redhat.com> - 1.0.6-4
+- Fix close of zero decriptor.
+- Fix udevsettle delays - use temporary crypt device remapping.
+
 * Wed May 28 2008 Till Maas <opensource till name> - 1.0.6-3
 - remove a duplicate sentence from the manpage (RH #448705)
 - add patch metadata about upstream status




More information about the fedora-extras-commits mailing list