From 227d3f3ff078426ae79b7f2313bc8be915c5e252 Mon Sep 17 00:00:00 2001 From: Michael Santos Date: Fri, 23 Jul 2010 11:28:46 -0400 Subject: inet: fix ifr_name buffer overflow The byte holding the length of the interface name for the ifget/2 functions is used in a signed context and can become negative, causing the ifreq.ifr_name buffer to be overrun. Test case: inet:ifget(lists:duplicate(128, "x"), [addr]). --- lib/kernel/test/inet_SUITE.erl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl index eb8f918491..d475ec74b6 100644 --- a/lib/kernel/test/inet_SUITE.erl +++ b/lib/kernel/test/inet_SUITE.erl @@ -26,7 +26,8 @@ t_gethostbyaddr_v6/1, t_getaddr_v6/1, t_gethostbyname_v6/1, ipv4_to_ipv6/1, host_and_addr/1, parse/1, t_gethostnative/1, gethostnative_parallell/1, cname_loop/1, - gethostnative_soft_restart/1,gethostnative_debug_level/1,getif/1]). + gethostnative_soft_restart/1,gethostnative_debug_level/1,getif/1, + getif_ifr_name_overflow/1]). -export([get_hosts/1, get_ipv6_hosts/1, parse_hosts/1, parse_address/1, kill_gethost/0, parallell_gethost/0]). @@ -39,7 +40,7 @@ all(suite) -> ipv4_to_ipv6, host_and_addr, parse,t_gethostnative, gethostnative_parallell, cname_loop, gethostnative_debug_level,gethostnative_soft_restart, - getif]. + getif,getif_ifr_name_overflow]. init_per_testcase(_Func, Config) -> Dog = test_server:timetrap(test_server:seconds(60)), @@ -891,6 +892,13 @@ getif(Config) when is_list(Config) -> ?line true = ip_member(Loopback, Addresses), ?line ok. +getif_ifr_name_overflow(doc) -> + "Test long interface names do not overrun buffer"; +getif_ifr_name_overflow(Config) when is_list(Config) -> + %% emulator should not crash + ?line {ok,[]} = inet:ifget(lists:duplicate(128, "x"), [addr]), + ok. + %% Works just like lists:member/2, except that any {127,_,_,_} tuple %% matches any other {127,_,_,_}. We do this to handle Linux systems %% that use (for instance) 127.0.1.1 as the IP address for the hostname. -- cgit v1.2.3 From d61d41e235bc464a15925e6fd1b7e9138477d3b3 Mon Sep 17 00:00:00 2001 From: Michael Santos Date: Fri, 23 Jul 2010 11:29:20 -0400 Subject: inet: fix getservbyname buffer overflow The byte holding the length of the interface name for the getservbyname/2 function is used in a signed context and can become negative, causing the buffer to be overrun. Make the same change for getservbyport/2. Test case: inet:getservbyname(list_to_atom(lists:flatten(lists:duplicate(128, "x"))), tcp). --- lib/kernel/test/inet_SUITE.erl | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl index d475ec74b6..86c2a0cbca 100644 --- a/lib/kernel/test/inet_SUITE.erl +++ b/lib/kernel/test/inet_SUITE.erl @@ -27,7 +27,7 @@ ipv4_to_ipv6/1, host_and_addr/1, parse/1, t_gethostnative/1, gethostnative_parallell/1, cname_loop/1, gethostnative_soft_restart/1,gethostnative_debug_level/1,getif/1, - getif_ifr_name_overflow/1]). + getif_ifr_name_overflow/1,getservbyname_overflow/1]). -export([get_hosts/1, get_ipv6_hosts/1, parse_hosts/1, parse_address/1, kill_gethost/0, parallell_gethost/0]). @@ -40,7 +40,7 @@ all(suite) -> ipv4_to_ipv6, host_and_addr, parse,t_gethostnative, gethostnative_parallell, cname_loop, gethostnative_debug_level,gethostnative_soft_restart, - getif,getif_ifr_name_overflow]. + getif,getif_ifr_name_overflow,getservbyname_overflow]. init_per_testcase(_Func, Config) -> Dog = test_server:timetrap(test_server:seconds(60)), @@ -899,6 +899,13 @@ getif_ifr_name_overflow(Config) when is_list(Config) -> ?line {ok,[]} = inet:ifget(lists:duplicate(128, "x"), [addr]), ok. +getservbyname_overflow(doc) -> + "Test long service names do not overrun buffer"; +getservbyname_overflow(Config) when is_list(Config) -> + %% emulator should not crash + ?line {error,einval} = inet:getservbyname(list_to_atom(lists:flatten(lists:duplicate(128, "x"))), tcp), + ok. + %% Works just like lists:member/2, except that any {127,_,_,_} tuple %% matches any other {127,_,_,_}. We do this to handle Linux systems %% that use (for instance) 127.0.1.1 as the IP address for the hostname. -- cgit v1.2.3 From 8393c5d5b682f8acbdc0ecf5b0e6f87589a314cb Mon Sep 17 00:00:00 2001 From: Michael Santos Date: Wed, 21 Jul 2010 14:50:58 -0400 Subject: inet: support retrieving MAC address on BSD On systems supporting getaddrinfo(), support looking up the MAC address from inet:ifget/2. The results have the same quirks as with Linux: if the MAC address is longer than 6 bytes (e.g., fw0 under Mac OS X), the address is truncated; if the interface does not have a MAC address (e.g., lo0), an address consisting of 0's is returned. --- lib/kernel/test/inet_SUITE.erl | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'lib') diff --git a/lib/kernel/test/inet_SUITE.erl b/lib/kernel/test/inet_SUITE.erl index 86c2a0cbca..f4f27933a5 100644 --- a/lib/kernel/test/inet_SUITE.erl +++ b/lib/kernel/test/inet_SUITE.erl @@ -877,6 +877,17 @@ getif(Config) when is_list(Config) -> ?line {ok,Address} = inet:getaddr(Hostname, inet), ?line {ok,Loopback} = inet:getaddr("localhost", inet), ?line {ok,Interfaces} = inet:getiflist(), + ?line HWAs = + lists:sort( + lists:foldl( + fun (I, Acc) -> + case inet:ifget(I, [hwaddr]) of + {ok,[{hwaddr,A}]} -> [A|Acc]; + {ok,[]} -> Acc + end + end, [], Interfaces)), + ?line io:format("HWAs = ~p~n", [HWAs]), + ?line length(HWAs) > 0 orelse ?t:fail(no_HWAs), ?line Addresses = lists:sort( lists:foldl( -- cgit v1.2.3