]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/ecryptfs/crypto.c
Merge branch 'devel' of git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa...
[linux-2.6-omap-h63xx.git] / fs / ecryptfs / crypto.c
index c01e043670e21300808dcd5d58e77f19bfccd076..8b65f289ee00802a54f3ed2e3d9718de5a9a0d65 100644 (file)
@@ -946,6 +946,8 @@ static int ecryptfs_copy_mount_wide_sigs_to_inode_sigs(
        list_for_each_entry(global_auth_tok,
                            &mount_crypt_stat->global_auth_tok_list,
                            mount_crypt_stat_list) {
+               if (global_auth_tok->flags & ECRYPTFS_AUTH_TOK_FNEK)
+                       continue;
                rc = ecryptfs_add_keysig(crypt_stat, global_auth_tok->sig);
                if (rc) {
                        printk(KERN_ERR "Error adding keysig; rc = [%d]\n", rc);
@@ -1322,14 +1324,13 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t max,
 }
 
 static int
-ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat,
-                                   struct dentry *ecryptfs_dentry,
-                                   char *virt)
+ecryptfs_write_metadata_to_contents(struct dentry *ecryptfs_dentry,
+                                   char *virt, size_t virt_len)
 {
        int rc;
 
        rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, virt,
-                                 0, crypt_stat->num_header_bytes_at_front);
+                                 0, virt_len);
        if (rc)
                printk(KERN_ERR "%s: Error attempting to write header "
                       "information to lower file; rc = [%d]\n", __func__,
@@ -1339,7 +1340,6 @@ ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat,
 
 static int
 ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
-                                struct ecryptfs_crypt_stat *crypt_stat,
                                 char *page_virt, size_t size)
 {
        int rc;
@@ -1349,6 +1349,17 @@ ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
        return rc;
 }
 
+static unsigned long ecryptfs_get_zeroed_pages(gfp_t gfp_mask,
+                                              unsigned int order)
+{
+       struct page *page;
+
+       page = alloc_pages(gfp_mask | __GFP_ZERO, order);
+       if (page)
+               return (unsigned long) page_address(page);
+       return 0;
+}
+
 /**
  * ecryptfs_write_metadata
  * @ecryptfs_dentry: The eCryptfs dentry
@@ -1365,7 +1376,9 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
 {
        struct ecryptfs_crypt_stat *crypt_stat =
                &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
+       unsigned int order;
        char *virt;
+       size_t virt_len;
        size_t size = 0;
        int rc = 0;
 
@@ -1381,33 +1394,35 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
                rc = -EINVAL;
                goto out;
        }
+       virt_len = crypt_stat->num_header_bytes_at_front;
+       order = get_order(virt_len);
        /* Released in this function */
-       virt = (char *)get_zeroed_page(GFP_KERNEL);
+       virt = (char *)ecryptfs_get_zeroed_pages(GFP_KERNEL, order);
        if (!virt) {
                printk(KERN_ERR "%s: Out of memory\n", __func__);
                rc = -ENOMEM;
                goto out;
        }
-       rc = ecryptfs_write_headers_virt(virt, PAGE_CACHE_SIZE, &size,
-                                        crypt_stat, ecryptfs_dentry);
+       rc = ecryptfs_write_headers_virt(virt, virt_len, &size, crypt_stat,
+                                        ecryptfs_dentry);
        if (unlikely(rc)) {
                printk(KERN_ERR "%s: Error whilst writing headers; rc = [%d]\n",
                       __func__, rc);
                goto out_free;
        }
        if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
-               rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry,
-                                                     crypt_stat, virt, size);
+               rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, virt,
+                                                     size);
        else
-               rc = ecryptfs_write_metadata_to_contents(crypt_stat,
-                                                        ecryptfs_dentry, virt);
+               rc = ecryptfs_write_metadata_to_contents(ecryptfs_dentry, virt,
+                                                        virt_len);
        if (rc) {
                printk(KERN_ERR "%s: Error writing metadata out to lower file; "
                       "rc = [%d]\n", __func__, rc);
                goto out_free;
        }
 out_free:
-       free_page((unsigned long)virt);
+       free_pages((unsigned long)virt, order);
 out:
        return rc;
 }
@@ -1716,7 +1731,7 @@ static int ecryptfs_copy_filename(char **copied_name, size_t *copied_name_size,
 {
        int rc = 0;
 
-       (*copied_name) = kmalloc((name_size + 2), GFP_KERNEL);
+       (*copied_name) = kmalloc((name_size + 1), GFP_KERNEL);
        if (!(*copied_name)) {
                rc = -ENOMEM;
                goto out;
@@ -1726,7 +1741,7 @@ static int ecryptfs_copy_filename(char **copied_name, size_t *copied_name_size,
                                                 * in printing out the
                                                 * string in debug
                                                 * messages */
-       (*copied_name_size) = (name_size + 1);
+       (*copied_name_size) = name_size;
 out:
        return rc;
 }
@@ -2206,17 +2221,19 @@ int ecryptfs_decode_and_decrypt_filename(char **plaintext_name,
                                         struct dentry *ecryptfs_dir_dentry,
                                         const char *name, size_t name_size)
 {
+       struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
+               &ecryptfs_superblock_to_private(
+                       ecryptfs_dir_dentry->d_sb)->mount_crypt_stat;
        char *decoded_name;
        size_t decoded_name_size;
        size_t packet_size;
        int rc = 0;
 
-       if ((name_size > ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE)
+       if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)
+           && !(mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED)
+           && (name_size > ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE)
            && (strncmp(name, ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX,
                        ECRYPTFS_FNEK_ENCRYPTED_FILENAME_PREFIX_SIZE) == 0)) {
-               struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
-                       &ecryptfs_superblock_to_private(
-                               ecryptfs_dir_dentry->d_sb)->mount_crypt_stat;
                const char *orig_name = name;
                size_t orig_name_size = name_size;