diff options
| -rw-r--r-- | Documentation/assoc_array.txt | 6 | ||||
| -rw-r--r-- | include/linux/assoc_array.h | 6 | ||||
| -rw-r--r-- | include/linux/shmem_fs.h | 2 | ||||
| -rw-r--r-- | kernel/.gitignore | 1 | ||||
| -rw-r--r-- | kernel/system_certificates.S | 14 | ||||
| -rw-r--r-- | kernel/system_keyring.c | 4 | ||||
| -rw-r--r-- | lib/assoc_array.c | 4 | ||||
| -rw-r--r-- | mm/shmem.c | 36 | ||||
| -rw-r--r-- | security/keys/big_key.c | 2 | ||||
| -rw-r--r-- | security/keys/key.c | 8 | ||||
| -rw-r--r-- | security/keys/keyring.c | 17 |
11 files changed, 64 insertions, 36 deletions
diff --git a/Documentation/assoc_array.txt b/Documentation/assoc_array.txt index f4faec0f66e4..2f2c6cdd73c0 100644 --- a/Documentation/assoc_array.txt +++ b/Documentation/assoc_array.txt | |||
| @@ -164,10 +164,10 @@ This points to a number of methods, all of which need to be provided: | |||
| 164 | 164 | ||
| 165 | (4) Diff the index keys of two objects. | 165 | (4) Diff the index keys of two objects. |
| 166 | 166 | ||
| 167 | int (*diff_objects)(const void *a, const void *b); | 167 | int (*diff_objects)(const void *object, const void *index_key); |
| 168 | 168 | ||
| 169 | Return the bit position at which the index keys of two objects differ or | 169 | Return the bit position at which the index key of the specified object |
| 170 | -1 if they are the same. | 170 | differs from the given index key or -1 if they are the same. |
| 171 | 171 | ||
| 172 | 172 | ||
| 173 | (5) Free an object. | 173 | (5) Free an object. |
diff --git a/include/linux/assoc_array.h b/include/linux/assoc_array.h index 9a193b84238a..a89df3be1686 100644 --- a/include/linux/assoc_array.h +++ b/include/linux/assoc_array.h | |||
| @@ -41,10 +41,10 @@ struct assoc_array_ops { | |||
| 41 | /* Is this the object we're looking for? */ | 41 | /* Is this the object we're looking for? */ |
| 42 | bool (*compare_object)(const void *object, const void *index_key); | 42 | bool (*compare_object)(const void *object, const void *index_key); |
| 43 | 43 | ||
| 44 | /* How different are two objects, to a bit position in their keys? (or | 44 | /* How different is an object from an index key, to a bit position in |
| 45 | * -1 if they're the same) | 45 | * their keys? (or -1 if they're the same) |
| 46 | */ | 46 | */ |
| 47 | int (*diff_objects)(const void *a, const void *b); | 47 | int (*diff_objects)(const void *object, const void *index_key); |
| 48 | 48 | ||
| 49 | /* Method to free an object. */ | 49 | /* Method to free an object. */ |
| 50 | void (*free_object)(void *object); | 50 | void (*free_object)(void *object); |
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index 30aa0dc60d75..9d55438bc4ad 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h | |||
| @@ -47,6 +47,8 @@ extern int shmem_init(void); | |||
| 47 | extern int shmem_fill_super(struct super_block *sb, void *data, int silent); | 47 | extern int shmem_fill_super(struct super_block *sb, void *data, int silent); |
| 48 | extern struct file *shmem_file_setup(const char *name, | 48 | extern struct file *shmem_file_setup(const char *name, |
| 49 | loff_t size, unsigned long flags); | 49 | loff_t size, unsigned long flags); |
| 50 | extern struct file *shmem_kernel_file_setup(const char *name, loff_t size, | ||
| 51 | unsigned long flags); | ||
| 50 | extern int shmem_zero_setup(struct vm_area_struct *); | 52 | extern int shmem_zero_setup(struct vm_area_struct *); |
| 51 | extern int shmem_lock(struct file *file, int lock, struct user_struct *user); | 53 | extern int shmem_lock(struct file *file, int lock, struct user_struct *user); |
| 52 | extern void shmem_unlock_mapping(struct address_space *mapping); | 54 | extern void shmem_unlock_mapping(struct address_space *mapping); |
diff --git a/kernel/.gitignore b/kernel/.gitignore index b3097bde4e9c..790d83c7d160 100644 --- a/kernel/.gitignore +++ b/kernel/.gitignore | |||
| @@ -5,3 +5,4 @@ config_data.h | |||
| 5 | config_data.gz | 5 | config_data.gz |
| 6 | timeconst.h | 6 | timeconst.h |
| 7 | hz.bc | 7 | hz.bc |
| 8 | x509_certificate_list | ||
diff --git a/kernel/system_certificates.S b/kernel/system_certificates.S index 4aef390671cb..3e9868d47535 100644 --- a/kernel/system_certificates.S +++ b/kernel/system_certificates.S | |||
| @@ -3,8 +3,18 @@ | |||
| 3 | 3 | ||
| 4 | __INITRODATA | 4 | __INITRODATA |
| 5 | 5 | ||
| 6 | .align 8 | ||
| 6 | .globl VMLINUX_SYMBOL(system_certificate_list) | 7 | .globl VMLINUX_SYMBOL(system_certificate_list) |
| 7 | VMLINUX_SYMBOL(system_certificate_list): | 8 | VMLINUX_SYMBOL(system_certificate_list): |
| 9 | __cert_list_start: | ||
| 8 | .incbin "kernel/x509_certificate_list" | 10 | .incbin "kernel/x509_certificate_list" |
| 9 | .globl VMLINUX_SYMBOL(system_certificate_list_end) | 11 | __cert_list_end: |
| 10 | VMLINUX_SYMBOL(system_certificate_list_end): | 12 | |
| 13 | .align 8 | ||
| 14 | .globl VMLINUX_SYMBOL(system_certificate_list_size) | ||
| 15 | VMLINUX_SYMBOL(system_certificate_list_size): | ||
| 16 | #ifdef CONFIG_64BIT | ||
| 17 | .quad __cert_list_end - __cert_list_start | ||
| 18 | #else | ||
| 19 | .long __cert_list_end - __cert_list_start | ||
| 20 | #endif | ||
diff --git a/kernel/system_keyring.c b/kernel/system_keyring.c index 564dd93430a2..52ebc70263f4 100644 --- a/kernel/system_keyring.c +++ b/kernel/system_keyring.c | |||
| @@ -22,7 +22,7 @@ struct key *system_trusted_keyring; | |||
| 22 | EXPORT_SYMBOL_GPL(system_trusted_keyring); | 22 | EXPORT_SYMBOL_GPL(system_trusted_keyring); |
| 23 | 23 | ||
| 24 | extern __initconst const u8 system_certificate_list[]; | 24 | extern __initconst const u8 system_certificate_list[]; |
| 25 | extern __initconst const u8 system_certificate_list_end[]; | 25 | extern __initconst const unsigned long system_certificate_list_size; |
| 26 | 26 | ||
| 27 | /* | 27 | /* |
| 28 | * Load the compiled-in keys | 28 | * Load the compiled-in keys |
| @@ -60,8 +60,8 @@ static __init int load_system_certificate_list(void) | |||
| 60 | 60 | ||
| 61 | pr_notice("Loading compiled-in X.509 certificates\n"); | 61 | pr_notice("Loading compiled-in X.509 certificates\n"); |
| 62 | 62 | ||
| 63 | end = system_certificate_list_end; | ||
| 64 | p = system_certificate_list; | 63 | p = system_certificate_list; |
| 64 | end = p + system_certificate_list_size; | ||
| 65 | while (p < end) { | 65 | while (p < end) { |
| 66 | /* Each cert begins with an ASN.1 SEQUENCE tag and must be more | 66 | /* Each cert begins with an ASN.1 SEQUENCE tag and must be more |
| 67 | * than 256 bytes in size. | 67 | * than 256 bytes in size. |
diff --git a/lib/assoc_array.c b/lib/assoc_array.c index 17edeaf19180..1b6a44f1ec3e 100644 --- a/lib/assoc_array.c +++ b/lib/assoc_array.c | |||
| @@ -759,8 +759,8 @@ all_leaves_cluster_together: | |||
| 759 | pr_devel("all leaves cluster together\n"); | 759 | pr_devel("all leaves cluster together\n"); |
| 760 | diff = INT_MAX; | 760 | diff = INT_MAX; |
| 761 | for (i = 0; i < ASSOC_ARRAY_FAN_OUT; i++) { | 761 | for (i = 0; i < ASSOC_ARRAY_FAN_OUT; i++) { |
| 762 | int x = ops->diff_objects(assoc_array_ptr_to_leaf(edit->leaf), | 762 | int x = ops->diff_objects(assoc_array_ptr_to_leaf(node->slots[i]), |
| 763 | assoc_array_ptr_to_leaf(node->slots[i])); | 763 | index_key); |
| 764 | if (x < diff) { | 764 | if (x < diff) { |
| 765 | BUG_ON(x < 0); | 765 | BUG_ON(x < 0); |
| 766 | diff = x; | 766 | diff = x; |
diff --git a/mm/shmem.c b/mm/shmem.c index 8297623fcaed..902a14842b74 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
| @@ -2918,13 +2918,8 @@ static struct dentry_operations anon_ops = { | |||
| 2918 | .d_dname = simple_dname | 2918 | .d_dname = simple_dname |
| 2919 | }; | 2919 | }; |
| 2920 | 2920 | ||
| 2921 | /** | 2921 | static struct file *__shmem_file_setup(const char *name, loff_t size, |
| 2922 | * shmem_file_setup - get an unlinked file living in tmpfs | 2922 | unsigned long flags, unsigned int i_flags) |
| 2923 | * @name: name for dentry (to be seen in /proc/<pid>/maps | ||
| 2924 | * @size: size to be set for the file | ||
| 2925 | * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size | ||
| 2926 | */ | ||
| 2927 | struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags) | ||
| 2928 | { | 2923 | { |
| 2929 | struct file *res; | 2924 | struct file *res; |
| 2930 | struct inode *inode; | 2925 | struct inode *inode; |
| @@ -2957,6 +2952,7 @@ struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags | |||
| 2957 | if (!inode) | 2952 | if (!inode) |
| 2958 | goto put_dentry; | 2953 | goto put_dentry; |
| 2959 | 2954 | ||
| 2955 | inode->i_flags |= i_flags; | ||
| 2960 | d_instantiate(path.dentry, inode); | 2956 | d_instantiate(path.dentry, inode); |
| 2961 | inode->i_size = size; | 2957 | inode->i_size = size; |
| 2962 | clear_nlink(inode); /* It is unlinked */ | 2958 | clear_nlink(inode); /* It is unlinked */ |
| @@ -2977,6 +2973,32 @@ put_memory: | |||
| 2977 | shmem_unacct_size(flags, size); | 2973 | shmem_unacct_size(flags, size); |
| 2978 | return res; | 2974 | return res; |
| 2979 | } | 2975 | } |
| 2976 | |||
| 2977 | /** | ||
| 2978 | * shmem_kernel_file_setup - get an unlinked file living in tmpfs which must be | ||
| 2979 | * kernel internal. There will be NO LSM permission checks against the | ||
| 2980 | * underlying inode. So users of this interface must do LSM checks at a | ||
| 2981 | * higher layer. The one user is the big_key implementation. LSM checks | ||
| 2982 | * are provided at the key level rather than the inode level. | ||
| 2983 | * @name: name for dentry (to be seen in /proc/<pid>/maps | ||
| 2984 | * @size: size to be set for the file | ||
| 2985 | * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size | ||
| 2986 | */ | ||
| 2987 | struct file *shmem_kernel_file_setup(const char *name, loff_t size, unsigned long flags) | ||
| 2988 | { | ||
| 2989 | return __shmem_file_setup(name, size, flags, S_PRIVATE); | ||
| 2990 | } | ||
| 2991 | |||
| 2992 | /** | ||
| 2993 | * shmem_file_setup - get an unlinked file living in tmpfs | ||
| 2994 | * @name: name for dentry (to be seen in /proc/<pid>/maps | ||
| 2995 | * @size: size to be set for the file | ||
| 2996 | * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size | ||
| 2997 | */ | ||
| 2998 | struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags) | ||
| 2999 | { | ||
| 3000 | return __shmem_file_setup(name, size, flags, 0); | ||
| 3001 | } | ||
| 2980 | EXPORT_SYMBOL_GPL(shmem_file_setup); | 3002 | EXPORT_SYMBOL_GPL(shmem_file_setup); |
| 2981 | 3003 | ||
| 2982 | /** | 3004 | /** |
diff --git a/security/keys/big_key.c b/security/keys/big_key.c index 7f44c3207a9b..8137b27d641d 100644 --- a/security/keys/big_key.c +++ b/security/keys/big_key.c | |||
| @@ -70,7 +70,7 @@ int big_key_instantiate(struct key *key, struct key_preparsed_payload *prep) | |||
| 70 | * | 70 | * |
| 71 | * TODO: Encrypt the stored data with a temporary key. | 71 | * TODO: Encrypt the stored data with a temporary key. |
| 72 | */ | 72 | */ |
| 73 | file = shmem_file_setup("", datalen, 0); | 73 | file = shmem_kernel_file_setup("", datalen, 0); |
| 74 | if (IS_ERR(file)) { | 74 | if (IS_ERR(file)) { |
| 75 | ret = PTR_ERR(file); | 75 | ret = PTR_ERR(file); |
| 76 | goto err_quota; | 76 | goto err_quota; |
diff --git a/security/keys/key.c b/security/keys/key.c index 55d110f0aced..6e21c11e48bc 100644 --- a/security/keys/key.c +++ b/security/keys/key.c | |||
| @@ -272,7 +272,7 @@ struct key *key_alloc(struct key_type *type, const char *desc, | |||
| 272 | } | 272 | } |
| 273 | 273 | ||
| 274 | /* allocate and initialise the key and its description */ | 274 | /* allocate and initialise the key and its description */ |
| 275 | key = kmem_cache_alloc(key_jar, GFP_KERNEL); | 275 | key = kmem_cache_zalloc(key_jar, GFP_KERNEL); |
| 276 | if (!key) | 276 | if (!key) |
| 277 | goto no_memory_2; | 277 | goto no_memory_2; |
| 278 | 278 | ||
| @@ -293,18 +293,12 @@ struct key *key_alloc(struct key_type *type, const char *desc, | |||
| 293 | key->uid = uid; | 293 | key->uid = uid; |
| 294 | key->gid = gid; | 294 | key->gid = gid; |
| 295 | key->perm = perm; | 295 | key->perm = perm; |
| 296 | key->flags = 0; | ||
| 297 | key->expiry = 0; | ||
| 298 | key->payload.data = NULL; | ||
| 299 | key->security = NULL; | ||
| 300 | 296 | ||
| 301 | if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) | 297 | if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) |
| 302 | key->flags |= 1 << KEY_FLAG_IN_QUOTA; | 298 | key->flags |= 1 << KEY_FLAG_IN_QUOTA; |
| 303 | if (flags & KEY_ALLOC_TRUSTED) | 299 | if (flags & KEY_ALLOC_TRUSTED) |
| 304 | key->flags |= 1 << KEY_FLAG_TRUSTED; | 300 | key->flags |= 1 << KEY_FLAG_TRUSTED; |
| 305 | 301 | ||
| 306 | memset(&key->type_data, 0, sizeof(key->type_data)); | ||
| 307 | |||
| 308 | #ifdef KEY_DEBUGGING | 302 | #ifdef KEY_DEBUGGING |
| 309 | key->magic = KEY_DEBUG_MAGIC; | 303 | key->magic = KEY_DEBUG_MAGIC; |
| 310 | #endif | 304 | #endif |
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 69f0cb7bab7e..d46cbc5e335e 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
| @@ -160,7 +160,7 @@ static u64 mult_64x32_and_fold(u64 x, u32 y) | |||
| 160 | static unsigned long hash_key_type_and_desc(const struct keyring_index_key *index_key) | 160 | static unsigned long hash_key_type_and_desc(const struct keyring_index_key *index_key) |
| 161 | { | 161 | { |
| 162 | const unsigned level_shift = ASSOC_ARRAY_LEVEL_STEP; | 162 | const unsigned level_shift = ASSOC_ARRAY_LEVEL_STEP; |
| 163 | const unsigned long level_mask = ASSOC_ARRAY_LEVEL_STEP_MASK; | 163 | const unsigned long fan_mask = ASSOC_ARRAY_FAN_MASK; |
| 164 | const char *description = index_key->description; | 164 | const char *description = index_key->description; |
| 165 | unsigned long hash, type; | 165 | unsigned long hash, type; |
| 166 | u32 piece; | 166 | u32 piece; |
| @@ -194,10 +194,10 @@ static unsigned long hash_key_type_and_desc(const struct keyring_index_key *inde | |||
| 194 | * ordinary keys by making sure the lowest level segment in the hash is | 194 | * ordinary keys by making sure the lowest level segment in the hash is |
| 195 | * zero for keyrings and non-zero otherwise. | 195 | * zero for keyrings and non-zero otherwise. |
| 196 | */ | 196 | */ |
| 197 | if (index_key->type != &key_type_keyring && (hash & level_mask) == 0) | 197 | if (index_key->type != &key_type_keyring && (hash & fan_mask) == 0) |
| 198 | return hash | (hash >> (ASSOC_ARRAY_KEY_CHUNK_SIZE - level_shift)) | 1; | 198 | return hash | (hash >> (ASSOC_ARRAY_KEY_CHUNK_SIZE - level_shift)) | 1; |
| 199 | if (index_key->type == &key_type_keyring && (hash & level_mask) != 0) | 199 | if (index_key->type == &key_type_keyring && (hash & fan_mask) != 0) |
| 200 | return (hash + (hash << level_shift)) & ~level_mask; | 200 | return (hash + (hash << level_shift)) & ~fan_mask; |
| 201 | return hash; | 201 | return hash; |
| 202 | } | 202 | } |
| 203 | 203 | ||
| @@ -279,12 +279,11 @@ static bool keyring_compare_object(const void *object, const void *data) | |||
| 279 | * Compare the index keys of a pair of objects and determine the bit position | 279 | * Compare the index keys of a pair of objects and determine the bit position |
| 280 | * at which they differ - if they differ. | 280 | * at which they differ - if they differ. |
| 281 | */ | 281 | */ |
| 282 | static int keyring_diff_objects(const void *_a, const void *_b) | 282 | static int keyring_diff_objects(const void *object, const void *data) |
| 283 | { | 283 | { |
| 284 | const struct key *key_a = keyring_ptr_to_key(_a); | 284 | const struct key *key_a = keyring_ptr_to_key(object); |
| 285 | const struct key *key_b = keyring_ptr_to_key(_b); | ||
| 286 | const struct keyring_index_key *a = &key_a->index_key; | 285 | const struct keyring_index_key *a = &key_a->index_key; |
| 287 | const struct keyring_index_key *b = &key_b->index_key; | 286 | const struct keyring_index_key *b = data; |
| 288 | unsigned long seg_a, seg_b; | 287 | unsigned long seg_a, seg_b; |
| 289 | int level, i; | 288 | int level, i; |
| 290 | 289 | ||
| @@ -691,8 +690,8 @@ descend_to_node: | |||
| 691 | smp_read_barrier_depends(); | 690 | smp_read_barrier_depends(); |
| 692 | ptr = ACCESS_ONCE(shortcut->next_node); | 691 | ptr = ACCESS_ONCE(shortcut->next_node); |
| 693 | BUG_ON(!assoc_array_ptr_is_node(ptr)); | 692 | BUG_ON(!assoc_array_ptr_is_node(ptr)); |
| 694 | node = assoc_array_ptr_to_node(ptr); | ||
| 695 | } | 693 | } |
| 694 | node = assoc_array_ptr_to_node(ptr); | ||
| 696 | 695 | ||
| 697 | begin_node: | 696 | begin_node: |
| 698 | kdebug("begin_node"); | 697 | kdebug("begin_node"); |
