From 352b28117de7e523ea09fd2b6a5066d8ffd1156b Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Thu, 4 Oct 2018 15:24:13 +0200 Subject: [socket-nif] Add owner validation when setopt controlling_process Before allowing setopt(Sock, opt, controlling_process, NewPid), verify that the caller is actually the current controlling_process. OTP-14831 --- erts/emulator/nifs/common/socket_int.h | 11 +++++++++++ erts/emulator/nifs/common/socket_nif.c | 14 +++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/erts/emulator/nifs/common/socket_int.h b/erts/emulator/nifs/common/socket_int.h index c3595e495d..f9246856fa 100644 --- a/erts/emulator/nifs/common/socket_int.h +++ b/erts/emulator/nifs/common/socket_int.h @@ -103,8 +103,10 @@ typedef unsigned int BOOLEAN_T; /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * "Global" atoms */ +extern ERL_NIF_TERM esock_atom_accept; extern ERL_NIF_TERM esock_atom_addr; extern ERL_NIF_TERM esock_atom_any; +extern ERL_NIF_TERM esock_atom_connect; extern ERL_NIF_TERM esock_atom_credentials; extern ERL_NIF_TERM esock_atom_ctrl; extern ERL_NIF_TERM esock_atom_ctrunc; @@ -129,6 +131,8 @@ extern ERL_NIF_TERM esock_atom_local; extern ERL_NIF_TERM esock_atom_loopback; extern ERL_NIF_TERM esock_atom_lowdelay; extern ERL_NIF_TERM esock_atom_mincost; +extern ERL_NIF_TERM esock_atom_not_found; +extern ERL_NIF_TERM esock_atom_not_owner; extern ERL_NIF_TERM esock_atom_ok; extern ERL_NIF_TERM esock_atom_oob; extern ERL_NIF_TERM esock_atom_origdstaddr; @@ -138,11 +142,18 @@ extern ERL_NIF_TERM esock_atom_port; extern ERL_NIF_TERM esock_atom_protocol; extern ERL_NIF_TERM esock_atom_raw; extern ERL_NIF_TERM esock_atom_rdm; +extern ERL_NIF_TERM esock_atom_recv; +extern ERL_NIF_TERM esock_atom_recvfrom; +extern ERL_NIF_TERM esock_atom_recvmsg; extern ERL_NIF_TERM esock_atom_reliability; extern ERL_NIF_TERM esock_atom_rights; extern ERL_NIF_TERM esock_atom_scope_id; extern ERL_NIF_TERM esock_atom_sctp; extern ERL_NIF_TERM esock_atom_sec; +extern ERL_NIF_TERM esock_atom_select_sent; +extern ERL_NIF_TERM esock_atom_send; +extern ERL_NIF_TERM esock_atom_sendmsg; +extern ERL_NIF_TERM esock_atom_sendto; extern ERL_NIF_TERM esock_atom_seqpacket; extern ERL_NIF_TERM esock_atom_socket; extern ERL_NIF_TERM esock_atom_spec_dst; diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c index 876bed3135..a762742cd7 100644 --- a/erts/emulator/nifs/common/socket_nif.c +++ b/erts/emulator/nifs/common/socket_nif.c @@ -2391,6 +2391,7 @@ ERL_NIF_TERM esock_atom_loopback; ERL_NIF_TERM esock_atom_lowdelay; ERL_NIF_TERM esock_atom_mincost; ERL_NIF_TERM esock_atom_not_found; +ERL_NIF_TERM esock_atom_not_owner; ERL_NIF_TERM esock_atom_ok; ERL_NIF_TERM esock_atom_oob; ERL_NIF_TERM esock_atom_origdstaddr; @@ -5074,7 +5075,7 @@ ERL_NIF_TERM nsetopt_otp_ctrl_proc(ErlNifEnv* env, SocketDescriptor* descP, ERL_NIF_TERM eVal) { - ErlNifPid newCtrlPid; + ErlNifPid caller, newCtrlPid; ErlNifMonitor newCtrlMon; int xres; @@ -5083,6 +5084,16 @@ ERL_NIF_TERM nsetopt_otp_ctrl_proc(ErlNifEnv* env, "\r\n eVal: %T" "\r\n", eVal) ); + /* Before we begin, ensure that caller is (current) controlling-process */ + if (enif_self(env, &caller) == NULL) + return esock_make_error(env, atom_exself); + + if (!compare_pids(env, &descP->ctrlPid, &caller)) { + SSDBG( descP, ("SOCKET", "nsetopt_otp_ctrl_proc -> not owner (%T)\r\n", + descP->ctrlPid) ); + return esock_make_error(env, esock_atom_not_owner); + } + if (!GET_LPID(env, eVal, &newCtrlPid)) { esock_warning_msg("Failed get pid of new controlling process\r\n"); return esock_make_error(env, esock_atom_einval); @@ -15413,6 +15424,7 @@ int on_load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) esock_atom_lowdelay = MKA(env, "lowdelay"); esock_atom_mincost = MKA(env, "mincost"); esock_atom_not_found = MKA(env, "not_found"); + esock_atom_not_owner = MKA(env, "not_owner"); esock_atom_ok = MKA(env, "ok"); esock_atom_oob = MKA(env, "oob"); esock_atom_origdstaddr = MKA(env, "origdstaddr"); -- cgit v1.2.3