diff options
Diffstat (limited to 'drivers/char/agp/generic.c')
| -rw-r--r-- | drivers/char/agp/generic.c | 19 | 
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 012cba0d6d9..b072648dc3f 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -115,6 +115,9 @@ static struct agp_memory *agp_create_user_memory(unsigned long num_agp_pages)  	struct agp_memory *new;  	unsigned long alloc_size = num_agp_pages*sizeof(struct page *); +	if (INT_MAX/sizeof(struct page *) < num_agp_pages) +		return NULL; +  	new = kzalloc(sizeof(struct agp_memory), GFP_KERNEL);  	if (new == NULL)  		return NULL; @@ -234,11 +237,14 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge,  	int scratch_pages;  	struct agp_memory *new;  	size_t i; +	int cur_memory;  	if (!bridge)  		return NULL; -	if ((atomic_read(&bridge->current_memory_agp) + page_count) > bridge->max_memory_agp) +	cur_memory = atomic_read(&bridge->current_memory_agp); +	if ((cur_memory + page_count > bridge->max_memory_agp) || +	    (cur_memory + page_count < page_count))  		return NULL;  	if (type >= AGP_USER_TYPES) { @@ -1089,8 +1095,8 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)  		return -EINVAL;  	} -	/* AK: could wrap */ -	if ((pg_start + mem->page_count) > num_entries) +	if (((pg_start + mem->page_count) > num_entries) || +	    ((pg_start + mem->page_count) < pg_start))  		return -EINVAL;  	j = pg_start; @@ -1124,7 +1130,7 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type)  {  	size_t i;  	struct agp_bridge_data *bridge; -	int mask_type; +	int mask_type, num_entries;  	bridge = mem->bridge;  	if (!bridge) @@ -1136,6 +1142,11 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type)  	if (type != mem->type)  		return -EINVAL; +	num_entries = agp_num_entries(); +	if (((pg_start + mem->page_count) > num_entries) || +	    ((pg_start + mem->page_count) < pg_start)) +		return -EINVAL; +  	mask_type = bridge->driver->agp_type_to_mask_type(bridge, type);  	if (mask_type != 0) {  		/* The generic routines know nothing of memory types */  |