From b438d5a6b0cb90a79cb3d4630a95e8331975217a Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Wed, 21 Jun 2017 15:22:11 +0800 Subject: [PATCH 1/8] remove typedef --- skynet-src/malloc_hook.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/skynet-src/malloc_hook.c b/skynet-src/malloc_hook.c index da8a536b..92834252 100644 --- a/skynet-src/malloc_hook.c +++ b/skynet-src/malloc_hook.c @@ -11,15 +11,16 @@ 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; +}; #define SLOT_SIZE 0x10000 #define PREFIX_SIZE sizeof(uint32_t) -static mem_data mem_stats[SLOT_SIZE]; +static struct mem_data mem_stats[SLOT_SIZE]; #ifndef NOUSE_JEMALLOC @@ -33,7 +34,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) { @@ -209,7 +210,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 +242,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 +256,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; } From b3c60d1de27cf24b9eec385a40b8652eebc22d38 Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Wed, 21 Jun 2017 15:41:46 +0800 Subject: [PATCH 2/8] add MEMORY_CHECK macro to check double free --- skynet-src/malloc_hook.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/skynet-src/malloc_hook.c b/skynet-src/malloc_hook.c index 92834252..344b9fb6 100644 --- a/skynet-src/malloc_hook.c +++ b/skynet-src/malloc_hook.c @@ -9,6 +9,12 @@ #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; @@ -17,8 +23,15 @@ struct mem_data { ssize_t allocated; }; +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 struct mem_data mem_stats[SLOT_SIZE]; @@ -76,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; } @@ -86,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; } From 78ea3d4091cc520226ef6b9b9039c03e37144ff6 Mon Sep 17 00:00:00 2001 From: Jexocn Date: Wed, 21 Jun 2017 17:16:16 +0800 Subject: [PATCH 3/8] hook memalign --- skynet-src/malloc_hook.c | 7 +++++++ skynet-src/skynet_malloc.h | 1 + 2 files changed, 8 insertions(+) diff --git a/skynet-src/malloc_hook.c b/skynet-src/malloc_hook.c index 344b9fb6..25c3491b 100644 --- a/skynet-src/malloc_hook.c +++ b/skynet-src/malloc_hook.c @@ -195,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 diff --git a/skynet-src/skynet_malloc.h b/skynet-src/skynet_malloc.h index 7bafa406..e67f475c 100644 --- a/skynet-src/skynet_malloc.h +++ b/skynet-src/skynet_malloc.h @@ -14,5 +14,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 From a9122a9fe12f345c70d5eb30787ea930f46fe3c8 Mon Sep 17 00:00:00 2001 From: Jexocn Date: Wed, 21 Jun 2017 17:16:16 +0800 Subject: [PATCH 4/8] hook memalign --- skynet-src/malloc_hook.c | 7 +++++++ skynet-src/skynet_malloc.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/skynet-src/malloc_hook.c b/skynet-src/malloc_hook.c index 344b9fb6..25c3491b 100644 --- a/skynet-src/malloc_hook.c +++ b/skynet-src/malloc_hook.c @@ -195,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 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 From 933f6730b22bd64d9a70746bf7f298fe0becbef1 Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Wed, 21 Jun 2017 17:33:27 +0800 Subject: [PATCH 5/8] add comment to hmac64 --- lualib-src/lua-crypt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lualib-src/lua-crypt.c b/lualib-src/lua-crypt.c index 888fe544..14ab5edd 100644 --- a/lualib-src/lua-crypt.c +++ b/lualib-src/lua-crypt.c @@ -545,7 +545,8 @@ const uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22 // leftrotate function definition #define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c)))) - + +// 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]; From 7dd78ec89d90c8063de7e2f98c2ac65b808bfdda Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Wed, 21 Jun 2017 19:05:03 +0800 Subject: [PATCH 6/8] add crypt.hmac64_md5 --- lualib-src/lua-crypt.c | 76 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 63 insertions(+), 13 deletions(-) diff --git a/lualib-src/lua-crypt.c b/lualib-src/lua-crypt.c index 14ab5edd..e7e3561c 100644 --- a/lualib-src/lua-crypt.c +++ b/lualib-src/lua-crypt.c @@ -546,10 +546,8 @@ const uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22 // leftrotate function definition #define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c)))) -// 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]; +digest_md5(uint32_t w[16], uint32_t result[4]) { uint32_t a, b, c, d, f, g, temp; int i; @@ -558,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); @@ -585,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 @@ -634,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 @@ -921,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 }, From 72b60393287b907b70d3f6d3ce74e198d71b71fe Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Thu, 22 Jun 2017 09:51:07 +0800 Subject: [PATCH 7/8] static const --- lualib-src/lua-crypt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lualib-src/lua-crypt.c b/lualib-src/lua-crypt.c index e7e3561c..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,7 +538,7 @@ 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}; From eb2bc91e3fbf273e97e5f8f63f3d4154dd269e05 Mon Sep 17 00:00:00 2001 From: Cloud Wu Date: Mon, 26 Jun 2017 16:32:43 +0800 Subject: [PATCH 8/8] negative decimal number --- lualib-src/sproto/README.md | 2 +- lualib-src/sproto/lsproto.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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;