Reading /proc/sys/kernel/sched_domain/cpu*/domain0/flags mutliple times with small reads causes oopses with slub corruption issues because the kfree is free'ing an offset from a previous allocation. Fix this by adding in a new pointer 'buf' for the allocation and kfree and use the temporary pointer tmp to handle memory copies of the buf offsets.
Showing the changes to kernel (1 of 1 file). Show all
Unified · Split
| @@ -251,7 +251,7 @@ static int sd_ctl_doflags(struct ctl_table *table, int write, · 250 unmodified lines | ||
| 251 | 251 | unsigned long flags = *(unsigned long *)table->data; |
| 252 | 252 | size_t data_size = 0; |
| 253 | 253 | size_t len = 0; |
| 254 | − char *tmp; | |
| 254 | + char *tmp, *buf; | |
| 255 | 255 | int idx; |
| 256 | 256 | |
| 257 | 257 | if (write) |
| @@ -269,17 +269,17 @@ static int sd_ctl_doflags(struct ctl_table *table, int write, · 11 unmodified lines | ||
| 269 | 269 | return 0; |
| 270 | 270 | } |
| 271 | 271 | |
| 272 | − tmp = kcalloc(data_size + 1, sizeof(*tmp), GFP_KERNEL); | |
| 273 | − if (!tmp) | |
| 272 | + buf = kcalloc(data_size + 1, sizeof(*buf), GFP_KERNEL); | |
| 273 | + if (!buf) | |
| 274 | 274 | return -ENOMEM; |
| 275 | 275 | |
| 276 | 276 | for_each_set_bit(idx, &flags, __SD_FLAG_CNT) { |
| 277 | 277 | char *name = sd_flag_debug[idx].name; |
| 278 | 278 | |
| 279 | − len += snprintf(tmp + len, strlen(name) + 2, "%s ", name); | |
| 279 | + len += snprintf(buf + len, strlen(name) + 2, "%s ", name); | |
| 280 | 280 | } |
| 281 | 281 | |
| 282 | − tmp += *ppos; | |
| 282 | + tmp = buf + *ppos; | |
| 283 | 283 | len -= *ppos; |
| 284 | 284 | |
| 285 | 285 | if (len > *lenp) |
| @@ -294,7 +294,7 @@ static int sd_ctl_doflags(struct ctl_table *table, int write, · 8 unmodified lines | ||
| 294 | 294 | *lenp = len; |
| 295 | 295 | *ppos += len; |
| 296 | 296 | |
| 297 | − kfree(tmp); | |
| 297 | + kfree(buf); | |
| 298 | 298 | |
| 299 | 299 | return 0; |
| 300 | 300 | } |