Line data Source code
1 : #include <unistd.h> 2 : 3 : #include "memory-util.h" 4 : 5 93704 : size_t page_size(void) { 6 : static thread_local size_t pgsz = 0; 7 : long r; 8 : 9 93704 : if (_likely_(pgsz > 0)) 10 93528 : return pgsz; 11 : 12 176 : r = sysconf(_SC_PAGESIZE); 13 176 : assert(r > 0); 14 : 15 176 : pgsz = (size_t) r; 16 176 : return pgsz; 17 : } 18 : 19 4 : bool memeqzero(const void *data, size_t length) { 20 : /* Does the buffer consist entirely of NULs? 21 : * Copied from https://github.com/systemd/casync/, copied in turn from 22 : * https://github.com/rustyrussell/ccan/blob/master/ccan/mem/mem.c#L92, 23 : * which is licensed CC-0. 24 : */ 25 : 26 4 : const uint8_t *p = data; 27 : size_t i; 28 : 29 : /* Check first 16 bytes manually */ 30 36 : for (i = 0; i < 16; i++, length--) { 31 35 : if (length == 0) 32 1 : return true; 33 34 : if (p[i]) 34 2 : return false; 35 : } 36 : 37 : /* Now we know first 16 bytes are NUL, memcmp with self. */ 38 1 : return memcmp(data, p + i, length) == 0; 39 : } 40 : 41 : #if !HAVE_EXPLICIT_BZERO 42 : /* 43 : * The pointer to memset() is volatile so that compiler must de-reference the pointer and can't assume that 44 : * it points to any function in particular (such as memset(), which it then might further "optimize"). This 45 : * approach is inspired by openssl's crypto/mem_clr.c. 46 : */ 47 : typedef void *(*memset_t)(void *,int,size_t); 48 : 49 : static volatile memset_t memset_func = memset; 50 : 51 : void* explicit_bzero_safe(void *p, size_t l) { 52 : if (l > 0) 53 : memset_func(p, '\0', l); 54 : 55 : return p; 56 : } 57 : #endif