diff options
| -rw-r--r-- | net/core/filter.c | 112 |
1 files changed, 80 insertions, 32 deletions
diff --git a/net/core/filter.c b/net/core/filter.c index 3a10e0bc90e8..8964d3445588 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | * 2 of the License, or (at your option) any later version. | 13 | * 2 of the License, or (at your option) any later version. |
| 14 | * | 14 | * |
| 15 | * Andi Kleen - Fix a few bad bugs and races. | 15 | * Andi Kleen - Fix a few bad bugs and races. |
| 16 | * Kris Katterjohn - Added many additional checks in sk_chk_filter() | ||
| 16 | */ | 17 | */ |
| 17 | 18 | ||
| 18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| @@ -250,7 +251,7 @@ load_b: | |||
| 250 | mem[fentry->k] = X; | 251 | mem[fentry->k] = X; |
| 251 | continue; | 252 | continue; |
| 252 | default: | 253 | default: |
| 253 | /* Invalid instruction counts as RET */ | 254 | WARN_ON(1); |
| 254 | return 0; | 255 | return 0; |
| 255 | } | 256 | } |
| 256 | 257 | ||
| @@ -283,8 +284,8 @@ load_b: | |||
| 283 | * | 284 | * |
| 284 | * Check the user's filter code. If we let some ugly | 285 | * Check the user's filter code. If we let some ugly |
| 285 | * filter code slip through kaboom! The filter must contain | 286 | * filter code slip through kaboom! The filter must contain |
| 286 | * no references or jumps that are out of range, no illegal instructions | 287 | * no references or jumps that are out of range, no illegal |
| 287 | * and no backward jumps. It must end with a RET instruction | 288 | * instructions, and must end with a RET instruction. |
| 288 | * | 289 | * |
| 289 | * Returns 0 if the rule set is legal or a negative errno code if not. | 290 | * Returns 0 if the rule set is legal or a negative errno code if not. |
| 290 | */ | 291 | */ |
| @@ -300,38 +301,85 @@ int sk_chk_filter(struct sock_filter *filter, int flen) | |||
| 300 | for (pc = 0; pc < flen; pc++) { | 301 | for (pc = 0; pc < flen; pc++) { |
| 301 | /* all jumps are forward as they are not signed */ | 302 | /* all jumps are forward as they are not signed */ |
| 302 | ftest = &filter[pc]; | 303 | ftest = &filter[pc]; |
| 303 | if (BPF_CLASS(ftest->code) == BPF_JMP) { | ||
| 304 | /* but they mustn't jump off the end */ | ||
| 305 | if (BPF_OP(ftest->code) == BPF_JA) { | ||
| 306 | /* | ||
| 307 | * Note, the large ftest->k might cause loops. | ||
| 308 | * Compare this with conditional jumps below, | ||
| 309 | * where offsets are limited. --ANK (981016) | ||
| 310 | */ | ||
| 311 | if (ftest->k >= (unsigned)(flen-pc-1)) | ||
| 312 | return -EINVAL; | ||
| 313 | } else { | ||
| 314 | /* for conditionals both must be safe */ | ||
| 315 | if (pc + ftest->jt +1 >= flen || | ||
| 316 | pc + ftest->jf +1 >= flen) | ||
| 317 | return -EINVAL; | ||
| 318 | } | ||
| 319 | } | ||
| 320 | 304 | ||
| 321 | /* check for division by zero -Kris Katterjohn 2005-10-30 */ | 305 | /* Only allow valid instructions */ |
| 322 | if (ftest->code == (BPF_ALU|BPF_DIV|BPF_K) && ftest->k == 0) | 306 | switch (ftest->code) { |
| 323 | return -EINVAL; | 307 | case BPF_ALU|BPF_ADD|BPF_K: |
| 308 | case BPF_ALU|BPF_ADD|BPF_X: | ||
| 309 | case BPF_ALU|BPF_SUB|BPF_K: | ||
| 310 | case BPF_ALU|BPF_SUB|BPF_X: | ||
| 311 | case BPF_ALU|BPF_MUL|BPF_K: | ||
| 312 | case BPF_ALU|BPF_MUL|BPF_X: | ||
| 313 | case BPF_ALU|BPF_DIV|BPF_X: | ||
| 314 | case BPF_ALU|BPF_AND|BPF_K: | ||
| 315 | case BPF_ALU|BPF_AND|BPF_X: | ||
| 316 | case BPF_ALU|BPF_OR|BPF_K: | ||
| 317 | case BPF_ALU|BPF_OR|BPF_X: | ||
| 318 | case BPF_ALU|BPF_LSH|BPF_K: | ||
| 319 | case BPF_ALU|BPF_LSH|BPF_X: | ||
| 320 | case BPF_ALU|BPF_RSH|BPF_K: | ||
| 321 | case BPF_ALU|BPF_RSH|BPF_X: | ||
| 322 | case BPF_ALU|BPF_NEG: | ||
| 323 | case BPF_LD|BPF_W|BPF_ABS: | ||
| 324 | case BPF_LD|BPF_H|BPF_ABS: | ||
| 325 | case BPF_LD|BPF_B|BPF_ABS: | ||
| 326 | case BPF_LD|BPF_W|BPF_LEN: | ||
| 327 | case BPF_LD|BPF_W|BPF_IND: | ||
| 328 | case BPF_LD|BPF_H|BPF_IND: | ||
| 329 | case BPF_LD|BPF_B|BPF_IND: | ||
| 330 | case BPF_LD|BPF_IMM: | ||
| 331 | case BPF_LDX|BPF_W|BPF_LEN: | ||
| 332 | case BPF_LDX|BPF_B|BPF_MSH: | ||
| 333 | case BPF_LDX|BPF_IMM: | ||
| 334 | case BPF_MISC|BPF_TAX: | ||
| 335 | case BPF_MISC|BPF_TXA: | ||
| 336 | case BPF_RET|BPF_K: | ||
| 337 | case BPF_RET|BPF_A: | ||
| 338 | break; | ||
| 339 | |||
| 340 | /* Some instructions need special checks */ | ||
| 324 | 341 | ||
| 325 | /* check that memory operations use valid addresses. */ | 342 | case BPF_ALU|BPF_DIV|BPF_K: |
| 326 | if (ftest->k >= BPF_MEMWORDS) { | 343 | /* check for division by zero */ |
| 327 | /* but it might not be a memory operation... */ | 344 | if (ftest->k == 0) |
| 328 | switch (ftest->code) { | ||
| 329 | case BPF_ST: | ||
| 330 | case BPF_STX: | ||
| 331 | case BPF_LD|BPF_MEM: | ||
| 332 | case BPF_LDX|BPF_MEM: | ||
| 333 | return -EINVAL; | 345 | return -EINVAL; |
| 334 | } | 346 | break; |
| 347 | |||
| 348 | case BPF_LD|BPF_MEM: | ||
| 349 | case BPF_LDX|BPF_MEM: | ||
| 350 | case BPF_ST: | ||
| 351 | case BPF_STX: | ||
| 352 | /* check for invalid memory addresses */ | ||
| 353 | if (ftest->k >= BPF_MEMWORDS) | ||
| 354 | return -EINVAL; | ||
| 355 | break; | ||
| 356 | |||
| 357 | case BPF_JMP|BPF_JA: | ||
| 358 | /* | ||
| 359 | * Note, the large ftest->k might cause loops. | ||
| 360 | * Compare this with conditional jumps below, | ||
| 361 | * where offsets are limited. --ANK (981016) | ||
| 362 | */ | ||
| 363 | if (ftest->k >= (unsigned)(flen-pc-1)) | ||
| 364 | return -EINVAL; | ||
| 365 | break; | ||
| 366 | |||
| 367 | case BPF_JMP|BPF_JEQ|BPF_K: | ||
| 368 | case BPF_JMP|BPF_JEQ|BPF_X: | ||
| 369 | case BPF_JMP|BPF_JGE|BPF_K: | ||
| 370 | case BPF_JMP|BPF_JGE|BPF_X: | ||
| 371 | case BPF_JMP|BPF_JGT|BPF_K: | ||
| 372 | case BPF_JMP|BPF_JGT|BPF_X: | ||
| 373 | case BPF_JMP|BPF_JSET|BPF_K: | ||
| 374 | case BPF_JMP|BPF_JSET|BPF_X: | ||
| 375 | /* for conditionals both must be safe */ | ||
| 376 | if (pc + ftest->jt + 1 >= flen || | ||
| 377 | pc + ftest->jf + 1 >= flen) | ||
| 378 | return -EINVAL; | ||
| 379 | break; | ||
| 380 | |||
| 381 | default: | ||
| 382 | return -EINVAL; | ||
| 335 | } | 383 | } |
| 336 | } | 384 | } |
| 337 | 385 | ||
