Index: subr_poison.c =================================================================== RCS file: /cvs/src/sys/kern/subr_poison.c,v retrieving revision 1.13 diff -u -p -r1.13 subr_poison.c --- subr_poison.c 14 Mar 2015 03:38:50 -0000 1.13 +++ subr_poison.c 19 Apr 2015 04:41:41 -0000 @@ -20,6 +20,8 @@ #include +#include + /* * The POISON is used as known text to copy into free objects so * that modifications after frees can be detected. @@ -34,7 +36,6 @@ #else #define POISON1 ((unsigned) 0xdeafbead) #endif -#define POISON_SIZE 64 uint32_t poison_value(void *v) @@ -57,40 +58,54 @@ poison_value(void *v) } void -poison_mem(void *v, size_t len) +poison_stream(chacha_ctx *ctx) { - uint32_t *ip = v; - size_t i; - uint32_t poison; + static chacha_ctx template; + static int poison_init; - poison = poison_value(v); + if (__predict_false(poison_init == 0)) { + u_int8_t key[32]; + arc4random_buf(key, sizeof(key)); + chacha_keysetup(&template, key, sizeof(key) * 8, 0); + poison_init = 1; + } - if (len > POISON_SIZE) - len = POISON_SIZE; - len = len / sizeof(*ip); - for (i = 0; i < len; i++) - ip[i] = poison; + memcpy(ctx, &template, sizeof(*ctx)); +} + +void +poison_mem(void *v, size_t len) +{ + chacha_ctx stream; + u_int64_t iv = (vaddr_t)v; + + poison_stream(&stream); + chacha_ivsetup(&stream, (u_int8_t *)&iv); + memset(v, 0, len); + chacha_encrypt_bytes(&stream, v, v, len); } int poison_check(void *v, size_t len, size_t *pidx, uint32_t *pval) { + chacha_ctx stream; + u_int64_t iv = (vaddr_t)v; uint32_t *ip = v; size_t i; - uint32_t poison; - poison = poison_value(v); + poison_stream(&stream); + chacha_ivsetup(&stream, (u_int8_t *)&iv); + chacha_encrypt_bytes(&stream, v, v, len); - if (len > POISON_SIZE) - len = POISON_SIZE; len = len / sizeof(*ip); for (i = 0; i < len; i++) { - if (ip[i] != poison) { + if (ip[i] != 0) { *pidx = i; - *pval = poison; + *pval = ip[i]; return 1; } } + return 0; }