From df0638e021eb18a4271a02fdae08aa1779867209 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 13 Dec 2018 21:52:38 +0100 Subject: erts: Fix warning and potential big-endian-bug in prim_file for set_permission and set_owner. --- erts/emulator/nifs/common/prim_file_nif.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erts/emulator/nifs/common/prim_file_nif.c b/erts/emulator/nifs/common/prim_file_nif.c index b34bf11205..5fff55b467 100644 --- a/erts/emulator/nifs/common/prim_file_nif.c +++ b/erts/emulator/nifs/common/prim_file_nif.c @@ -933,7 +933,7 @@ static ERL_NIF_TERM set_permissions_nif(ErlNifEnv *env, int argc, const ERL_NIF_ posix_errno_t posix_errno; efile_path_t path; - Uint permissions; + unsigned int permissions; if(argc != 2 || !enif_get_uint(env, argv[1], &permissions)) { return enif_make_badarg(env); @@ -952,7 +952,7 @@ static ERL_NIF_TERM set_owner_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM a posix_errno_t posix_errno; efile_path_t path; - Sint uid, gid; + int uid, gid; if(argc != 3 || !enif_get_int(env, argv[1], &uid) || !enif_get_int(env, argv[2], &gid)) { -- cgit v1.2.3 From 1e6ab2fdac21c7847b7fda32fed1ea35883a535e Mon Sep 17 00:00:00 2001 From: Tomas Abrahamsson Date: Thu, 13 Dec 2018 22:36:03 +0100 Subject: erts: Fix possible heap corruption getting atomics Due to comparison as a signed integer, when getting an unsigned atomic in the range 2^63-1..2^64-1 (when the most significant bit was set), the heap could get corrupted when the integer was retrieved: hsz would get set to zero, but the code proceeded to build a bignum. Steps to reproduce (at least on x86_64): $ erl 1> A = atomics:new(1,[{signed,false}]). 2> atomics:put(A,1,18446744073709551615). 3> atomics:get(A,1). At the last step, the shell would print some garbage and hang. --- erts/emulator/beam/erl_bif_atomics.c | 2 +- erts/emulator/test/atomics_SUITE.erl | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/erts/emulator/beam/erl_bif_atomics.c b/erts/emulator/beam/erl_bif_atomics.c index 092dbb3bd3..029831bd95 100644 --- a/erts/emulator/beam/erl_bif_atomics.c +++ b/erts/emulator/beam/erl_bif_atomics.c @@ -133,7 +133,7 @@ static ERTS_INLINE Eterm bld_atomic(Process* proc, AtomicsRef* p, if ((Uint64)val <= MAX_SMALL) return make_small((Sint) val); else { - Uint hsz = ERTS_UINT64_HEAP_SIZE(val); + Uint hsz = ERTS_UINT64_HEAP_SIZE((Uint64)val); Eterm* hp = HAlloc(proc, hsz); return erts_uint64_to_big(val, &hp); } diff --git a/erts/emulator/test/atomics_SUITE.erl b/erts/emulator/test/atomics_SUITE.erl index 8c42354770..a5407c42ee 100644 --- a/erts/emulator/test/atomics_SUITE.erl +++ b/erts/emulator/test/atomics_SUITE.erl @@ -126,6 +126,9 @@ unsigned_limits(Config) when is_list(Config) -> Min = atomics:add_get(Ref, 1, 1), Max = atomics:sub_get(Ref, 1, 1), + atomics:put(Ref, 1, Max), + io:format("Max=~p~n", [atomics:get(Ref, 1)]), + {'EXIT',{badarg,_}} = (catch atomics:add(Ref, 1, Max+1)), IncrMin = -(1 bsl (Bits-1)), ok = atomics:put(Ref, 1, -IncrMin), -- cgit v1.2.3 From c8d3bff46adbff3205eaf76de8a634557cbd4af4 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Mon, 17 Dec 2018 16:03:36 +0100 Subject: erts: Fix bug in 'band' of two negative numbers, one big Similar bug as for bxor fixed by abc4fd372d476821448dfb9 Ex: 1> io:format("~.16B\n", [-16#1110000000000000000 band (-1)]). -1120000000000000000 Wrong result for (-X bsl WS) band -Y. where X is any positive integer WS is erlang:system_info(wordsize)*8*N where N is 1 or larger Y is any positive integer smaller than (1 bsl WS) Fix: The subtraction of 1 (for 2-complement conversion) must be carried along all the way to the last words. --- erts/emulator/beam/big.c | 7 +++++-- erts/emulator/test/big_SUITE.erl | 39 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c index 323cd6c518..6497089419 100644 --- a/erts/emulator/beam/big.c +++ b/erts/emulator/beam/big.c @@ -1139,8 +1139,11 @@ static dsize_t I_band(ErtsDigit* x, dsize_t xl, short xsgn, *r++ = ~c1 & ~c2; x++; y++; } - while(xl--) - *r++ = ~*x++; + while(xl--) { + DSUBb(*x,0,b1,c1); + *r++ = ~c1; + x++; + } } } return I_btrail(r0, r, sign); diff --git a/erts/emulator/test/big_SUITE.erl b/erts/emulator/test/big_SUITE.erl index c5bb228bc3..4b11c4905f 100644 --- a/erts/emulator/test/big_SUITE.erl +++ b/erts/emulator/test/big_SUITE.erl @@ -23,7 +23,7 @@ init_per_group/2,end_per_group/2]). -export([t_div/1, eq_28/1, eq_32/1, eq_big/1, eq_math/1, big_literals/1, borders/1, negative/1, big_float_1/1, big_float_2/1, - bxor_2pow/1, + bxor_2pow/1, band_2pow/1, shift_limit_1/1, powmod/1, system_limit/1, toobig/1, otp_6692/1]). %% Internal exports. @@ -41,7 +41,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [t_div, eq_28, eq_32, eq_big, eq_math, big_literals, borders, negative, {group, big_float}, shift_limit_1, - bxor_2pow, + bxor_2pow, band_2pow, powmod, system_limit, toobig, otp_6692]. groups() -> @@ -476,3 +476,38 @@ my_bxor(A, B, N, Acc0) -> false -> Acc0 bor (1 bsl N) end, my_bxor(A bsr 1, B bsr 1, N+1, Acc1). + + +%% ERL-804 +band_2pow(_Config) -> + IL = lists:seq(8*3, 8*16, 4), + JL = lists:seq(0, 64), + [band_2pow_1((1 bsl I), (1 bsl J)) + || I <- IL, J <- JL], + ok. + +band_2pow_1(A, B) -> + for(-1,1, fun(Ad) -> + for(-1,1, fun(Bd) -> + band_2pow_2(A+Ad, B+Bd), + band_2pow_2(-A+Ad, B+Bd), + band_2pow_2(A+Ad, -B+Bd), + band_2pow_2(-A+Ad, -B+Bd) + end) + end). + +band_2pow_2(A, B) -> + Correct = my_band(A, B), + case A band B of + Correct -> ok; + Wrong -> + io:format("~.16# band ~.16#\n", [A,B]), + io:format("Expected ~.16#\n", [Correct]), + io:format("Got ~.16#\n", [Wrong]), + ct:fail({failed, 'band'}) + + end. + +%% Implement band without band +my_band(A, B) -> + bnot ((bnot A) bor (bnot B)). -- cgit v1.2.3