Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 23bdecb0 authored by Eric Paris's avatar Eric Paris
Browse files

selinux: convert type_val_to_struct to flex_array



In rawhide type_val_to_struct will allocate 26848 bytes, an order 3
allocations.  While this hasn't been seen to fail it isn't outside the
realm of possibiliy on systems with severe memory fragmentation.  Convert
to flex_array so no allocation will ever be bigger than PAGE_SIZE.

Signed-off-by: default avatarEric Paris <eparis@redhat.com>
parent c41ab6a1
Loading
Loading
Loading
Loading
+21 −7
Original line number Diff line number Diff line
@@ -307,7 +307,11 @@ static int type_index(void *key, void *datum, void *datap)
		    || typdatum->bounds > p->p_types.nprim)
			return -EINVAL;
		p->p_type_val_to_name[typdatum->value - 1] = key;
		p->type_val_to_struct[typdatum->value - 1] = typdatum;
		/* this flex array was all preallocated, this cannot fail */
		if (flex_array_put_ptr(p->type_val_to_struct_array,
				       typdatum->value - 1, typdatum,
				       GFP_KERNEL | __GFP_ZERO))
			BUG();
	}

	return 0;
@@ -484,11 +488,17 @@ static int policydb_index_others(struct policydb *p)
	if (!p->user_val_to_struct)
		goto out;

	/* Yes, I want the sizeof the pointer, not the structure */
	rc = -ENOMEM;
	p->type_val_to_struct =
		kmalloc(p->p_types.nprim * sizeof(*(p->type_val_to_struct)),
			GFP_KERNEL);
	if (!p->type_val_to_struct)
	p->type_val_to_struct_array = flex_array_alloc(sizeof(struct type_datum *),
						       p->p_types.nprim,
						       GFP_KERNEL | __GFP_ZERO);
	if (!p->type_val_to_struct_array)
		goto out;

	rc = flex_array_prealloc(p->type_val_to_struct_array, 0,
				 p->p_types.nprim - 1, GFP_KERNEL | __GFP_ZERO);
	if (rc)
		goto out;

	rc = -ENOMEM;
@@ -699,7 +709,8 @@ void policydb_destroy(struct policydb *p)
	kfree(p->class_val_to_struct);
	kfree(p->role_val_to_struct);
	kfree(p->user_val_to_struct);
	kfree(p->type_val_to_struct);
	if (p->type_val_to_struct_array)
		flex_array_free(p->type_val_to_struct_array);

	avtab_destroy(&p->te_avtab);

@@ -1618,7 +1629,10 @@ static int type_bounds_sanity_check(void *key, void *datum, void *datap)
			return -EINVAL;
		}

		upper = p->type_val_to_struct[upper->bounds - 1];
		upper = flex_array_get_ptr(p->type_val_to_struct_array,
					   upper->bounds - 1);
		BUG_ON(!upper);

		if (upper->attribute) {
			printk(KERN_ERR "SELinux: type %s: "
			       "bounded by attribute %s",
+1 −1
Original line number Diff line number Diff line
@@ -217,7 +217,7 @@ struct policydb {
	struct class_datum **class_val_to_struct;
	struct role_datum **role_val_to_struct;
	struct user_datum **user_val_to_struct;
	struct type_datum **type_val_to_struct;
	struct flex_array *type_val_to_struct_array;

	/* type enforcement access vectors and transitions */
	struct avtab te_avtab;
+12 −5
Original line number Diff line number Diff line
@@ -530,12 +530,18 @@ static void type_attribute_bounds_av(struct context *scontext,
	struct context lo_scontext;
	struct context lo_tcontext;
	struct av_decision lo_avd;
	struct type_datum *source
		= policydb.type_val_to_struct[scontext->type - 1];
	struct type_datum *target
		= policydb.type_val_to_struct[tcontext->type - 1];
	struct type_datum *source;
	struct type_datum *target;
	u32 masked = 0;

	source = flex_array_get_ptr(policydb.type_val_to_struct_array,
				    scontext->type - 1);
	BUG_ON(!source);

	target = flex_array_get_ptr(policydb.type_val_to_struct_array,
				    tcontext->type - 1);
	BUG_ON(!target);

	if (source->bounds) {
		memset(&lo_avd, 0, sizeof(lo_avd));

@@ -828,7 +834,8 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)

	index = new_context->type;
	while (true) {
		type = policydb.type_val_to_struct[index - 1];
		type = flex_array_get_ptr(policydb.type_val_to_struct_array,
					  index - 1);
		BUG_ON(!type);

		/* not bounded anymore */