aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/flexible-arrays.txt4
-rw-r--r--include/linux/flex_array.h2
-rw-r--r--lib/flex_array.c13
-rw-r--r--security/selinux/ss/policydb.c6
4 files changed, 14 insertions, 11 deletions
diff --git a/Documentation/flexible-arrays.txt b/Documentation/flexible-arrays.txt
index cb8a3a00cc92..df904aec9904 100644
--- a/Documentation/flexible-arrays.txt
+++ b/Documentation/flexible-arrays.txt
@@ -66,10 +66,10 @@ trick is to ensure that any needed memory allocations are done before
66entering atomic context, using: 66entering atomic context, using:
67 67
68 int flex_array_prealloc(struct flex_array *array, unsigned int start, 68 int flex_array_prealloc(struct flex_array *array, unsigned int start,
69 unsigned int end, gfp_t flags); 69 unsigned int nr_elements, gfp_t flags);
70 70
71This function will ensure that memory for the elements indexed in the range 71This function will ensure that memory for the elements indexed in the range
72defined by start and end has been allocated. Thereafter, a 72defined by start and nr_elements has been allocated. Thereafter, a
73flex_array_put() call on an element in that range is guaranteed not to 73flex_array_put() call on an element in that range is guaranteed not to
74block. 74block.
75 75
diff --git a/include/linux/flex_array.h b/include/linux/flex_array.h
index 70e4efabe0fb..ebeb2f3ad068 100644
--- a/include/linux/flex_array.h
+++ b/include/linux/flex_array.h
@@ -61,7 +61,7 @@ struct flex_array {
61struct flex_array *flex_array_alloc(int element_size, unsigned int total, 61struct flex_array *flex_array_alloc(int element_size, unsigned int total,
62 gfp_t flags); 62 gfp_t flags);
63int flex_array_prealloc(struct flex_array *fa, unsigned int start, 63int flex_array_prealloc(struct flex_array *fa, unsigned int start,
64 unsigned int end, gfp_t flags); 64 unsigned int nr_elements, gfp_t flags);
65void flex_array_free(struct flex_array *fa); 65void flex_array_free(struct flex_array *fa);
66void flex_array_free_parts(struct flex_array *fa); 66void flex_array_free_parts(struct flex_array *fa);
67int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src, 67int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src,
diff --git a/lib/flex_array.c b/lib/flex_array.c
index c0ea40ba2082..0c33b24498ba 100644
--- a/lib/flex_array.c
+++ b/lib/flex_array.c
@@ -232,10 +232,10 @@ EXPORT_SYMBOL(flex_array_clear);
232 232
233/** 233/**
234 * flex_array_prealloc - guarantee that array space exists 234 * flex_array_prealloc - guarantee that array space exists
235 * @fa: the flex array for which to preallocate parts 235 * @fa: the flex array for which to preallocate parts
236 * @start: index of first array element for which space is allocated 236 * @start: index of first array element for which space is allocated
237 * @end: index of last (inclusive) element for which space is allocated 237 * @nr_elements: number of elements for which space is allocated
238 * @flags: page allocation flags 238 * @flags: page allocation flags
239 * 239 *
240 * This will guarantee that no future calls to flex_array_put() 240 * This will guarantee that no future calls to flex_array_put()
241 * will allocate memory. It can be used if you are expecting to 241 * will allocate memory. It can be used if you are expecting to
@@ -245,13 +245,16 @@ EXPORT_SYMBOL(flex_array_clear);
245 * Locking must be provided by the caller. 245 * Locking must be provided by the caller.
246 */ 246 */
247int flex_array_prealloc(struct flex_array *fa, unsigned int start, 247int flex_array_prealloc(struct flex_array *fa, unsigned int start,
248 unsigned int end, gfp_t flags) 248 unsigned int nr_elements, gfp_t flags)
249{ 249{
250 int start_part; 250 int start_part;
251 int end_part; 251 int end_part;
252 int part_nr; 252 int part_nr;
253 unsigned int end;
253 struct flex_array_part *part; 254 struct flex_array_part *part;
254 255
256 end = start + nr_elements - 1;
257
255 if (start >= fa->total_nr_elements || end >= fa->total_nr_elements) 258 if (start >= fa->total_nr_elements || end >= fa->total_nr_elements)
256 return -ENOSPC; 259 return -ENOSPC;
257 if (elements_fit_in_base(fa)) 260 if (elements_fit_in_base(fa))
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index e7b850ad57ee..e6e7ce0d3d55 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -502,7 +502,7 @@ static int policydb_index(struct policydb *p)
502 goto out; 502 goto out;
503 503
504 rc = flex_array_prealloc(p->type_val_to_struct_array, 0, 504 rc = flex_array_prealloc(p->type_val_to_struct_array, 0,
505 p->p_types.nprim - 1, GFP_KERNEL | __GFP_ZERO); 505 p->p_types.nprim, GFP_KERNEL | __GFP_ZERO);
506 if (rc) 506 if (rc)
507 goto out; 507 goto out;
508 508
@@ -519,7 +519,7 @@ static int policydb_index(struct policydb *p)
519 goto out; 519 goto out;
520 520
521 rc = flex_array_prealloc(p->sym_val_to_name[i], 521 rc = flex_array_prealloc(p->sym_val_to_name[i],
522 0, p->symtab[i].nprim - 1, 522 0, p->symtab[i].nprim,
523 GFP_KERNEL | __GFP_ZERO); 523 GFP_KERNEL | __GFP_ZERO);
524 if (rc) 524 if (rc)
525 goto out; 525 goto out;
@@ -2375,7 +2375,7 @@ int policydb_read(struct policydb *p, void *fp)
2375 goto bad; 2375 goto bad;
2376 2376
2377 /* preallocate so we don't have to worry about the put ever failing */ 2377 /* preallocate so we don't have to worry about the put ever failing */
2378 rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim - 1, 2378 rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim,
2379 GFP_KERNEL | __GFP_ZERO); 2379 GFP_KERNEL | __GFP_ZERO);
2380 if (rc) 2380 if (rc)
2381 goto bad; 2381 goto bad;