[CRIU] [PATCH 1/2] p.haul: do not use getsockname() as a hash_name

Pavel Emelyanov xemul at parallels.com
Thu Oct 23 09:43:33 PDT 2014


On 10/22/2014 11:41 PM, Ruslan Kuprieiev wrote:
> Currently xem_rpc is not proxy-resistant.
> It means that if there is a proxy somewhere in
> between client and server, p.haul will fail,
> because getsockname() on client != getpeername()
> on server. Lets use strings as hash names for
> sockets. Lets send socket name(e.g. datask or rpc)
> right after calling connect().

Different clients may pick the same name. The better
solution to me seems like this:

1. On main rpc socket after init_rpc() the server
   reports back the name by which it sees the client
   socket.

2. After calling connect() on data socket the client
   should mix the name from step 1 to the data socket
   name to distinguish his data socket from those
   created by other clients.

BTW, what's the point in packing the name into structs?
Why not use plain python strings?

> Signed-off-by: Ruslan Kuprieiev <kupruser at gmail.com>
> ---
>  xem_rpc.py | 24 +++++++++++++++---------
>  1 file changed, 15 insertions(+), 9 deletions(-)
> 
> diff --git a/xem_rpc.py b/xem_rpc.py
> index 9718eef..6a79b63 100644
> --- a/xem_rpc.py
> +++ b/xem_rpc.py
> @@ -3,6 +3,7 @@ import select
>  import threading
>  import traceback
>  import util
> +import struct
>  
>  rpc_port = 12345
>  rpc_sk_buf = 256
> @@ -41,22 +42,24 @@ class _rpc_proxy_caller:
>  class rpc_proxy:
>  	def __init__(self, conn, *args):
>  		self._srv = conn
> -		self._rpc_sk = self._make_sk()
> +		self._rpc_sk = self._make_sk("rpc")
>  		util.set_cloexec(self._rpc_sk)
>  		_rpc_proxy_caller(self._rpc_sk, RPC_CMD, "init_rpc")(args)
>  
>  	def __getattr__(self, attr):
>  		return _rpc_proxy_caller(self._rpc_sk, RPC_CALL, attr)
>  
> -	def _make_sk(self):
> +	def _make_sk(self, uname):
>  		sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>  		sk.connect((self._srv, rpc_port))
> +		sk.send(struct.pack("!i", len(uname)))
> +		sk.send(uname.encode())
>  		return sk
>  
>  	def open_socket(self, uname):
> -		sk = self._make_sk()
> +		sk = self._make_sk(uname)
>  		c = _rpc_proxy_caller(self._rpc_sk, RPC_CMD, "pick_channel")
> -		c(sk.getsockname(), uname)
> +		c(uname)
>  		return sk
>  
>  
> @@ -66,15 +69,16 @@ class rpc_proxy:
>  #
>  
>  class _rpc_server_sk:
> -	def __init__(self, sk):
> +	def __init__(self, sk, uname):
>  		self._sk = sk
>  		self._master = None
> +		self._uname = uname
>  
>  	def fileno(self):
>  		return self._sk.fileno()
>  
>  	def hash_name(self):
> -		return self._sk.getpeername()
> +		return self._uname
>  
>  	def work(self, mgr):
>  		raw_data = self._sk.recv(rpc_sk_buf)
> @@ -110,8 +114,8 @@ class _rpc_server_sk:
>  		self._master = mgr.make_master()
>  		self._master.on_connect(*args)
>  
> -	def pick_channel(self, mgr, hash_name, uname):
> -		sk = mgr.pick_sk(hash_name)
> +	def pick_channel(self, mgr, uname):
> +		sk = mgr.pick_sk(uname)
>  		if sk:
>  			self._master.on_socket_open(sk._sk, uname)
>  
> @@ -128,7 +132,9 @@ class _rpc_server_ask:
>  
>  	def work(self, mgr):
>  		sk, addr = self._sk.accept()
> -		mgr.add(_rpc_server_sk(sk))
> +		size, = struct.unpack("!i", sk.recv(4))
> +		uname = sk.recv(size).decode()
> +		mgr.add(_rpc_server_sk(sk, uname))
>  
>  class _rpc_stop_fd:
>  	def __init__(self, fd):
> 



More information about the CRIU mailing list