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

Ruslan Kuprieiev kupruser at gmail.com
Thu Oct 23 09:56:22 PDT 2014


On 23.10.2014 19:43, Pavel Emelyanov wrote:
> 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.

I totally agree.

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

struct is only used to transfer length of strings.
Lengths are packed with struct to take into account
that src and dst might have different byte-order.
(even though i'm not sure that we can migrate
process from little-endinan to big-endian or vise-versa.)
strings are .encode()-d and .decode()-d to take into
account different encodings on src and dst.

>> 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