diff -Nru ecryptfs-utils-96/debian/changelog ecryptfs-utils-96/debian/changelog --- ecryptfs-utils-96/debian/changelog 2012-04-18 09:52:47.000000000 -0500 +++ ecryptfs-utils-96/debian/changelog 2012-12-04 14:12:56.000000000 -0600 @@ -1,3 +1,14 @@ +ecryptfs-utils (96-0ubuntu3.1) precise-proposed; urgency=low + + * Fix encrypted home/private race condition that could result in encrypted + filenames not being decrypted, despite the directory being mounted + correctly otherwise. (LP: #1052038) + - debian/patches/fix-private-mount-race.patch: Fix race condition by only + opening the signature file once, rather than opening, reading, and + closing it for each key signature. + + -- Tyler Hicks Tue, 04 Dec 2012 14:12:55 -0600 + ecryptfs-utils (96-0ubuntu3) precise; urgency=low * src/utils/ecryptfs-setup-swap: Skip /dev/zram* swap devices diff -Nru ecryptfs-utils-96/debian/patches/fix-private-mount-race.patch ecryptfs-utils-96/debian/patches/fix-private-mount-race.patch --- ecryptfs-utils-96/debian/patches/fix-private-mount-race.patch 1969-12-31 18:00:00.000000000 -0600 +++ ecryptfs-utils-96/debian/patches/fix-private-mount-race.patch 2012-12-04 14:12:52.000000000 -0600 @@ -0,0 +1,241 @@ +Description: Fix encrypted private mount helper race conditions + Fix race condition bug in the encrypted private mount helper. It can result in + a user having their encrypted home or Private directory mounted while the + filenames remain encrypted. +Bug-Ubuntu: https://launchpad.net/bugs/1052038 +Origin: upstream, http://bazaar.launchpad.net/~ecryptfs/ecryptfs/trunk/revision/757 +Origin: upstream, http://bazaar.launchpad.net/~ecryptfs/ecryptfs/trunk/revision/756 +Origin: upstream, http://bazaar.launchpad.net/~ecryptfs/ecryptfs/trunk/revision/755 +Origin: upstream, http://bazaar.launchpad.net/~ecryptfs/ecryptfs/trunk/revision/754 +Origin: upstream, http://bazaar.launchpad.net/~ecryptfs/ecryptfs/trunk/revision/753 +Origin: upstream, http://bazaar.launchpad.net/~ecryptfs/ecryptfs/trunk/revision/752 +Origin: upstream, http://bazaar.launchpad.net/~ecryptfs/ecryptfs/trunk/revision/751 +Origin: upstream, http://bazaar.launchpad.net/~ecryptfs/ecryptfs/trunk/revision/736 +Origin: upstream, http://bazaar.launchpad.net/~ecryptfs/ecryptfs/trunk/revision/735 +Origin: upstream, http://bazaar.launchpad.net/~ecryptfs/ecryptfs/trunk/revision/733 +Index: ecryptfs-utils-96/src/utils/mount.ecryptfs_private.c +=================================================================== +--- ecryptfs-utils-96.orig/src/utils/mount.ecryptfs_private.c 2012-12-04 13:47:19.685804991 -0600 ++++ ecryptfs-utils-96/src/utils/mount.ecryptfs_private.c 2012-12-04 14:12:49.873797556 -0600 +@@ -53,8 +53,6 @@ + #define FSTYPE "ecryptfs" + #define TMP "/dev/shm" + +-int saved_errno; +- + int read_config(char *pw_dir, int uid, char *alias, char **s, char **d, char **o) { + /* Read an fstab(5) style config file */ + char *fnam; +@@ -130,71 +128,92 @@ + return 0; + } + +-char *fetch_sig(char *pw_dir, int entry, char *alias) { ++char **fetch_sig(char *pw_dir, char *alias, int mounting) { + /* Read ecryptfs signature from file and validate + * Return signature as a string, or NULL on failure + */ + char *sig_file; +- int c; +- FILE *fh; +- char *sig; +- int i; ++ FILE *fh = NULL; ++ char **sig = NULL; ++ int i, j; + /* Construct sig file name */ +- if ( +- asprintf(&sig_file, "%s/.ecryptfs/%s.sig", pw_dir, +- alias) < 0 +- ) { ++ if (asprintf(&sig_file, "%s/.ecryptfs/%s.sig", pw_dir, alias) < 0) { + perror("asprintf"); +- return NULL; ++ goto err; + } + fh = fopen(sig_file, "r"); + if (fh == NULL) { + perror("fopen"); +- return NULL; ++ goto err; + } +- if ((sig = (char *)malloc(KEY_BYTES*sizeof(char)+1)) == NULL) { ++ /* Read up to 2 lines from the file */ ++ if ((sig = malloc(sizeof(char*) * 2)) == NULL) { + perror("malloc"); +- return NULL; ++ goto err; + } +- /* Move to the correct line in the file */ +- if (entry == 1) { +- while ((c = fgetc(fh)) != EOF) { +- if (c == '\n') { +- break; ++ ++ sig[0] = NULL; ++ sig[1] = NULL; ++ for (i=0; i<2; i++) { ++ if ((sig[i] = (char *)malloc(KEY_BYTES*sizeof(char)+2)) == NULL) { ++ perror("malloc"); ++ goto err; ++ } ++ memset(sig[i], '\0', KEY_BYTES+2); ++ /* Read KEY_BYTES characters from line */ ++ if (fgets(sig[i], KEY_BYTES+2, fh) == NULL) { ++ if (i == 0) { ++ fputs("Missing file encryption signature", stderr); ++ goto err; ++ } else { ++ /* Filename encryption isn't in use */ ++ free(sig[i]); ++ sig[i] = NULL; ++ goto out; + } + } +- } +- i = 0; +- /* Read KEY_BYTES characters from file */ +- while ((c = fgetc(fh)) != EOF && i < KEY_BYTES) { +- if ((c>='0' && c<='9') || (c>='a' && c<='f') || +- (c>='A' && c<='F')) { +- sig[i] = (char)c; +- i++; +- } else { +- fputs("Invalid hex signature\n", stderr); +- return NULL; ++ /* Validate hex signature */ ++ for (j=0; j 0 && strlen(sig[i]) != KEY_BYTES) { + fputs("Invalid hex signature length\n", stderr); ++ goto err; ++ } ++ /* Validate that signature is in the current keyring, ++ * compile with -lkeyutils ++ */ ++ if (keyctl_search(KEY_SPEC_USER_KEYRING, "user", sig[i], 0) < 0) { ++ if (mounting) ++ fputs("Signature not found in user keyring\n" ++ "Perhaps try the interactive " ++ "'ecryptfs-mount-private'\n", stderr); ++ goto err; + } +- return NULL; + } +- sig[KEY_BYTES] = '\0'; +- /* Validate that signature is in the current keyring, +- * compile with -lkeyutils +- */ +- if (keyctl_search(KEY_SPEC_USER_KEYRING, "user", sig, 0) < 0) { +- saved_errno = errno; +- return NULL; ++out: ++ if (fh != NULL) { ++ fclose(fh); + } + return sig; ++err: ++ if (fh) { ++ fclose(fh); ++ } ++ /* Clean up malloc'd memory if failure */ ++ if (sig) { ++ free(sig[0]); ++ free(sig[1]); ++ free(sig); ++ } ++ return NULL; + } + + int check_ownership_mnt(int uid, char **mnt) { +@@ -486,7 +505,8 @@ + int force = 0; + struct passwd *pwd; + char *alias, *src, *dest, *opt, *opts2; +- char *sig, *sig_fnek; ++ char *sig_fekek = NULL, *sig_fnek = NULL; ++ char **sigs; + FILE *fh_counter = NULL; + + uid = getuid(); +@@ -564,27 +584,23 @@ + + /* Fetch signatures from file */ + /* First line is the file content encryption key signature */ +- sig = fetch_sig(pwd->pw_dir, 0, alias); +- if (sig == NULL) { ++ /* Second line, if present, is the filename encryption key signature */ ++ sigs = fetch_sig(pwd->pw_dir, alias, mounting); ++ if (!sigs && mounting) { + /* if umounting, no sig is ok */ +- if (mounting) { +- errno = saved_errno; +- perror("keyctl_search"); +- fputs("Perhaps try the interactive 'ecryptfs-mount-private'\n", +- stderr); +- goto fail; +- } ++ goto fail; ++ } else if (sigs) { ++ sig_fekek = sigs[0]; ++ sig_fnek = sigs[1]; + } +- /* Second line, if present, is the filename encryption key signature */ +- sig_fnek = fetch_sig(pwd->pw_dir, 1, alias); + + /* Build mount options */ + if ( + (asprintf(&opt, "ecryptfs_check_dev_ruid,ecryptfs_cipher=%s,ecryptfs_key_bytes=%d,ecryptfs_unlink_sigs%s%s%s%s", + KEY_CIPHER, + KEY_BYTES, +- sig ? ",ecryptfs_sig=" : "", +- sig ? sig : "", ++ sig_fekek ? ",ecryptfs_sig=" : "", ++ sig_fekek ? sig_fekek : "", + sig_fnek ? ",ecryptfs_fnek_sig=" : "", + sig_fnek ? sig_fnek : "" + ) < 0 +@@ -606,7 +622,7 @@ + fputs("Error incrementing mount counter\n", stderr); + } + /* Mounting, so exit if already mounted */ +- if (ecryptfs_private_is_mounted(src, dest, sig, mounting) == 1) { ++ if (ecryptfs_private_is_mounted(src, dest, sig_fekek, mounting) == 1) { + goto success; + } + /* We must maintain our real uid as the user who called this +@@ -655,8 +671,8 @@ + to prevent root from mounting without the user's key. + This is a best-effort basis, so we'll just print messages + on error. */ +- if (sig != NULL) { +- rc = ecryptfs_remove_auth_tok_from_keyring(sig); ++ if (sig_fekek != NULL) { ++ rc = ecryptfs_remove_auth_tok_from_keyring(sig_fekek); + if (rc != 0 && rc != ENOKEY) + fputs("Could not remove key from keyring, try 'ecryptfs-umount-private'\n", stderr); + } +@@ -666,7 +682,7 @@ + fputs("Could not remove key from keyring, try 'ecryptfs-umount-private'\n", stderr); + } + /* Unmounting, so exit if not mounted */ +- if (ecryptfs_private_is_mounted(src, dest, sig, mounting) == 0) { ++ if (ecryptfs_private_is_mounted(src, dest, sig_fekek, mounting) == 0) { + goto fail; + } + /* The key is not needed for unmounting, so we set res=0. diff -Nru ecryptfs-utils-96/debian/patches/series ecryptfs-utils-96/debian/patches/series --- ecryptfs-utils-96/debian/patches/series 2012-04-18 09:49:41.000000000 -0500 +++ ecryptfs-utils-96/debian/patches/series 2012-12-03 11:28:50.000000000 -0600 @@ -1,2 +1,3 @@ automount-fork-exit.patch setup-swap-skip-zram.patch +fix-private-mount-race.patch