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 012cba0d6d96..b072648dc3f6 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) | |||
115 | struct agp_memory *new; | 115 | struct agp_memory *new; |
116 | unsigned long alloc_size = num_agp_pages*sizeof(struct page *); | 116 | unsigned long alloc_size = num_agp_pages*sizeof(struct page *); |
117 | 117 | ||
118 | if (INT_MAX/sizeof(struct page *) < num_agp_pages) | ||
119 | return NULL; | ||
120 | |||
118 | new = kzalloc(sizeof(struct agp_memory), GFP_KERNEL); | 121 | new = kzalloc(sizeof(struct agp_memory), GFP_KERNEL); |
119 | if (new == NULL) | 122 | if (new == NULL) |
120 | return NULL; | 123 | return NULL; |
@@ -234,11 +237,14 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge, | |||
234 | int scratch_pages; | 237 | int scratch_pages; |
235 | struct agp_memory *new; | 238 | struct agp_memory *new; |
236 | size_t i; | 239 | size_t i; |
240 | int cur_memory; | ||
237 | 241 | ||
238 | if (!bridge) | 242 | if (!bridge) |
239 | return NULL; | 243 | return NULL; |
240 | 244 | ||
241 | if ((atomic_read(&bridge->current_memory_agp) + page_count) > bridge->max_memory_agp) | 245 | cur_memory = atomic_read(&bridge->current_memory_agp); |
246 | if ((cur_memory + page_count > bridge->max_memory_agp) || | ||
247 | (cur_memory + page_count < page_count)) | ||
242 | return NULL; | 248 | return NULL; |
243 | 249 | ||
244 | if (type >= AGP_USER_TYPES) { | 250 | if (type >= AGP_USER_TYPES) { |
@@ -1089,8 +1095,8 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type) | |||
1089 | return -EINVAL; | 1095 | return -EINVAL; |
1090 | } | 1096 | } |
1091 | 1097 | ||
1092 | /* AK: could wrap */ | 1098 | if (((pg_start + mem->page_count) > num_entries) || |
1093 | if ((pg_start + mem->page_count) > num_entries) | 1099 | ((pg_start + mem->page_count) < pg_start)) |
1094 | return -EINVAL; | 1100 | return -EINVAL; |
1095 | 1101 | ||
1096 | j = pg_start; | 1102 | j = pg_start; |
@@ -1124,7 +1130,7 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
1124 | { | 1130 | { |
1125 | size_t i; | 1131 | size_t i; |
1126 | struct agp_bridge_data *bridge; | 1132 | struct agp_bridge_data *bridge; |
1127 | int mask_type; | 1133 | int mask_type, num_entries; |
1128 | 1134 | ||
1129 | bridge = mem->bridge; | 1135 | bridge = mem->bridge; |
1130 | if (!bridge) | 1136 | if (!bridge) |
@@ -1136,6 +1142,11 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
1136 | if (type != mem->type) | 1142 | if (type != mem->type) |
1137 | return -EINVAL; | 1143 | return -EINVAL; |
1138 | 1144 | ||
1145 | num_entries = agp_num_entries(); | ||
1146 | if (((pg_start + mem->page_count) > num_entries) || | ||
1147 | ((pg_start + mem->page_count) < pg_start)) | ||
1148 | return -EINVAL; | ||
1149 | |||
1139 | mask_type = bridge->driver->agp_type_to_mask_type(bridge, type); | 1150 | mask_type = bridge->driver->agp_type_to_mask_type(bridge, type); |
1140 | if (mask_type != 0) { | 1151 | if (mask_type != 0) { |
1141 | /* The generic routines know nothing of memory types */ | 1152 | /* The generic routines know nothing of memory types */ |