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"); |