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 | unsigned long flags = *(unsigned long *)table->data; | 251 | unsigned long flags = *(unsigned long *)table->data; |
| 252 | size_t data_size = 0; | 252 | size_t data_size = 0; |
| 253 | size_t len = 0; | 253 | size_t len = 0; |
| 254 | char *tmp; | 254 | char *tmp, *buf; |
| 255 | int idx; | 255 | int idx; |
| 256 | 256 | ||
| 257 | if (write) | 257 | if (write) |
| @@ -269,17 +269,17 @@ static int sd_ctl_doflags(struct ctl_table *table, int write, · 11 unmodified lines | |||
| 269 | return 0; | 269 | return 0; |
| 270 | } | 270 | } |
| 271 | 271 | ||
| 272 | tmp = kcalloc(data_size + 1, sizeof(*tmp), GFP_KERNEL); | 272 | buf = kcalloc(data_size + 1, sizeof(*buf), GFP_KERNEL); |
| 273 | if (!tmp) | 273 | if (!buf) |
| 274 | return -ENOMEM; | 274 | return -ENOMEM; |
| 275 | 275 | ||
| 276 | for_each_set_bit(idx, &flags, __SD_FLAG_CNT) { | 276 | for_each_set_bit(idx, &flags, __SD_FLAG_CNT) { |
| 277 | char *name = sd_flag_debug[idx].name; | 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 | len -= *ppos; | 283 | len -= *ppos; |
| 284 | 284 | ||
| 285 | if (len > *lenp) | 285 | if (len > *lenp) |
| @@ -294,7 +294,7 @@ static int sd_ctl_doflags(struct ctl_table *table, int write, · 8 unmodified lines | |||
| 294 | *lenp = len; | 294 | *lenp = len; |
| 295 | *ppos += len; | 295 | *ppos += len; |
| 296 | 296 | ||
| 297 | kfree(tmp); | 297 | kfree(buf); |
| 298 | 298 | ||
| 299 | return 0; | 299 | return 0; |
| 300 | } | 300 | } |