diff --git a/lualib-src/lua-crypt.c b/lualib-src/lua-crypt.c index 888fe544..6959f171 100644 --- a/lualib-src/lua-crypt.c +++ b/lualib-src/lua-crypt.c @@ -519,7 +519,7 @@ lfromhex(lua_State *L) { } // Constants are the integer part of the sines of integers (in radians) * 2^32. -const uint32_t k[64] = { +static const uint32_t k[64] = { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee , 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 , 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be , @@ -538,17 +538,16 @@ const uint32_t k[64] = { 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }; // r specifies the per-round shift amounts -const uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, +static const uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}; // leftrotate function definition #define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c)))) - + static void -hmac(uint32_t x[2], uint32_t y[2], uint32_t result[2]) { - uint32_t w[16]; +digest_md5(uint32_t w[16], uint32_t result[4]) { uint32_t a, b, c, d, f, g, temp; int i; @@ -557,13 +556,6 @@ hmac(uint32_t x[2], uint32_t y[2], uint32_t result[2]) { c = 0x98badcfeu; d = 0x10325476u; - for (i=0;i<16;i+=4) { - w[i] = x[1]; - w[i+1] = x[0]; - w[i+2] = y[1]; - w[i+3] = y[0]; - } - for(i = 0; i<64; i++) { if (i < 16) { f = (b & c) | ((~b) & d); @@ -584,11 +576,54 @@ hmac(uint32_t x[2], uint32_t y[2], uint32_t result[2]) { c = b; b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]); a = temp; - } - result[0] = c^d; - result[1] = a^b; + result[0] = a; + result[1] = b; + result[2] = c; + result[3] = d; +} + +// hmac64 use md5 algorithm without padding, and the result is (c^d .. a^b) +static void +hmac(uint32_t x[2], uint32_t y[2], uint32_t result[2]) { + uint32_t w[16]; + uint32_t r[4]; + int i; + for (i=0;i<16;i+=4) { + w[i] = x[1]; + w[i+1] = x[0]; + w[i+2] = y[1]; + w[i+3] = y[0]; + } + + digest_md5(w,r); + + result[0] = r[2]^r[3]; + result[1] = r[0]^r[1]; +} + +static void +hmac_md5(uint32_t x[2], uint32_t y[2], uint32_t result[2]) { + uint32_t w[16]; + uint32_t r[4]; + int i; + for (i=0;i<12;i+=4) { + w[i] = x[0]; + w[i+1] = x[1]; + w[i+2] = y[0]; + w[i+3] = y[1]; + } + + w[12] = 0x80; + w[13] = 0; + w[14] = 384; + w[15] = 0; + + digest_md5(w,r); + + result[0] = (r[0] + 0x67452301u) ^ (r[2] + 0x98badcfeu); + result[1] = (r[1] + 0xefcdab89u) ^ (r[3] + 0x10325476u); } static void @@ -633,6 +668,21 @@ lhmac64(lua_State *L) { return pushqword(L, result); } +/* + h1 = crypt.hmac64_md5(a,b) + m = md5.sum((a..b):rep(3)) + h2 = crypt.xor_str(m:sub(1,8), m:sub(9,16)) + assert(h1 == h2) + */ +static int +lhmac64_md5(lua_State *L) { + uint32_t x[2], y[2]; + read64(L, x, y); + uint32_t result[2]; + hmac_md5(x,y,result); + return pushqword(L, result); +} + /* 8bytes key string text @@ -920,6 +970,7 @@ luaopen_skynet_crypt(lua_State *L) { { "hexencode", ltohex }, { "hexdecode", lfromhex }, { "hmac64", lhmac64 }, + { "hmac64_md5", lhmac64_md5 }, { "dhexchange", ldhexchange }, { "dhsecret", ldhsecret }, { "base64encode", lb64encode }, diff --git a/lualib-src/sproto/README.md b/lualib-src/sproto/README.md index 9fd4c3ff..237e4b5c 100644 --- a/lualib-src/sproto/README.md +++ b/lualib-src/sproto/README.md @@ -252,7 +252,7 @@ If n is odd, that means the tags is not continuous, and we should add current ta Arrays are always encode in data part, 4 bytes header for the size, and the following bytes is the contents. See the example 2 for the struct array; example 3/4 for the integer array ; example 5 for the boolean array. -Fot integer array, an additional byte (4 or 8) to indicate the value is 32bit or 64bit. +For integer array, an additional byte (4 or 8) to indicate the value is 32bit or 64bit. Read the examples below to see more details. diff --git a/lualib-src/sproto/lsproto.c b/lualib-src/sproto/lsproto.c index d7160a62..9cb61a4a 100644 --- a/lualib-src/sproto/lsproto.c +++ b/lualib-src/sproto/lsproto.c @@ -344,12 +344,12 @@ decode(const struct sproto_arg *args) { // notice: in lua 5.2, 52bit integer support (not 64) if (args->extra) { // lua_Integer is 32bit in small lua. - uint64_t v = *(uint64_t*)args->value; + int64_t v = *(int64_t*)args->value; lua_Number vn = (lua_Number)v; vn /= args->extra; lua_pushnumber(L, vn); } else { - lua_Integer v = *(uint64_t*)args->value; + lua_Integer v = *(int64_t*)args->value; lua_pushinteger(L, v); } break; diff --git a/skynet-src/malloc_hook.c b/skynet-src/malloc_hook.c index da8a536b..25c3491b 100644 --- a/skynet-src/malloc_hook.c +++ b/skynet-src/malloc_hook.c @@ -9,17 +9,31 @@ #include "skynet.h" #include "atomic.h" +// turn on MEMORY_CHECK can do more memory check, such as double free +// #define MEMORY_CHECK + +#define MEMORY_ALLOCTAG 0x20140605 +#define MEMORY_FREETAG 0x0badf00d + static size_t _used_memory = 0; static size_t _memory_block = 0; -typedef struct _mem_data { + +struct mem_data { uint32_t handle; ssize_t allocated; -} mem_data; +}; + +struct mem_cookie { + uint32_t handle; +#ifdef MEMORY_CHECK + uint32_t dogtag; +#endif +}; #define SLOT_SIZE 0x10000 -#define PREFIX_SIZE sizeof(uint32_t) +#define PREFIX_SIZE sizeof(struct mem_cookie) -static mem_data mem_stats[SLOT_SIZE]; +static struct mem_data mem_stats[SLOT_SIZE]; #ifndef NOUSE_JEMALLOC @@ -33,7 +47,7 @@ static mem_data mem_stats[SLOT_SIZE]; static ssize_t* get_allocated_field(uint32_t handle) { int h = (int)(handle & (SLOT_SIZE - 1)); - mem_data *data = &mem_stats[h]; + struct mem_data *data = &mem_stats[h]; uint32_t old_handle = data->handle; ssize_t old_alloc = data->allocated; if(old_handle == 0 || old_alloc <= 0) { @@ -75,9 +89,12 @@ inline static void* fill_prefix(char* ptr) { uint32_t handle = skynet_current_handle(); size_t size = je_malloc_usable_size(ptr); - uint32_t *p = (uint32_t *)(ptr + size - sizeof(uint32_t)); - memcpy(p, &handle, sizeof(handle)); - + struct mem_cookie *p = (struct mem_cookie *)(ptr + size - sizeof(struct mem_cookie)); + memcpy(&p->handle, &handle, sizeof(handle)); +#ifdef MEMORY_CHECK + uint32_t dogtag = MEMORY_ALLOCTAG; + memcpy(&p->dogtag, &dogtag, sizeof(dogtag)); +#endif update_xmalloc_stat_alloc(handle, size); return ptr; } @@ -85,9 +102,19 @@ fill_prefix(char* ptr) { inline static void* clean_prefix(char* ptr) { size_t size = je_malloc_usable_size(ptr); - uint32_t *p = (uint32_t *)(ptr + size - sizeof(uint32_t)); + struct mem_cookie *p = (struct mem_cookie *)(ptr + size - sizeof(struct mem_cookie)); uint32_t handle; - memcpy(&handle, p, sizeof(handle)); + memcpy(&handle, &p->handle, sizeof(handle)); +#ifdef MEMORY_CHECK + uint32_t dogtag; + memcpy(&dogtag, &p->dogtag, sizeof(dogtag)); + if (dogtag == MEMORY_FREETAG) { + fprintf(stderr, "xmalloc: double free in :%08x\n", handle); + } + assert(dogtag == MEMORY_ALLOCTAG); // memory out of bounds + dogtag = MEMORY_FREETAG; + memcpy(&p->dogtag, &dogtag, sizeof(dogtag)); +#endif update_xmalloc_stat_free(handle, size); return ptr; } @@ -168,6 +195,13 @@ skynet_calloc(size_t nmemb,size_t size) { return fill_prefix(ptr); } +void * +skynet_memalign(size_t alignment, size_t size) { + void* ptr = je_memalign(alignment, size + PREFIX_SIZE); + if(!ptr) malloc_oom(size); + return fill_prefix(ptr); +} + #else // for skynet_lalloc use @@ -209,7 +243,7 @@ dump_c_mem() { size_t total = 0; skynet_error(NULL, "dump all service mem:"); for(i=0; ihandle != 0 && data->allocated != 0) { total += data->allocated; skynet_error(NULL, "0x%x -> %zdkb", data->handle, data->allocated >> 10); @@ -241,7 +275,7 @@ dump_mem_lua(lua_State *L) { int i; lua_newtable(L); for(i=0; ihandle != 0 && data->allocated != 0) { lua_pushinteger(L, data->allocated); lua_rawseti(L, -2, (lua_Integer)data->handle); @@ -255,7 +289,7 @@ malloc_current_memory(void) { uint32_t handle = skynet_current_handle(); int i; for(i=0; ihandle == (uint32_t)handle && data->allocated != 0) { return (size_t) data->allocated; } diff --git a/skynet-src/skynet_malloc.h b/skynet-src/skynet_malloc.h index 7bafa406..e2f0aa8d 100644 --- a/skynet-src/skynet_malloc.h +++ b/skynet-src/skynet_malloc.h @@ -7,6 +7,7 @@ #define skynet_calloc calloc #define skynet_realloc realloc #define skynet_free free +#define skynet_memalign memalign void * skynet_malloc(size_t sz); void * skynet_calloc(size_t nmemb,size_t size); @@ -14,5 +15,6 @@ void * skynet_realloc(void *ptr, size_t size); void skynet_free(void *ptr); char * skynet_strdup(const char *str); void * skynet_lalloc(void *ptr, size_t osize, size_t nsize); // use for lua +void * skynet_memalign(size_t alignment, size_t size); #endif