|
From: Shivaram U. <shi...@qu...> - 2013-02-18 17:00:35
|
Hi, There is a possibility of a double free during session reinstatement. The scenario is as follows 1. The initiator closes a connection and the kernel module notifies ietd. At this point the session in the user level code has a conn_cnt of 1 2. The notification is yet to be processed by ietd, when a new connection for the old session is received. At this point the new conn->session = oldsession . This is done in iscsid.c:login_finish. Note that however the session->conn_cnt is still 1 corresponding to the old conn 3. Now event_loop processes the notification from the kernel module and since conn_cnt is 1 the session is freed. However the new connection has still a reference to the freed session 4. During the first write for the connection, conn_take_fd will fail with -ENOENT since the session for the new conn is longer in the kernel. Also the session in the user land is no longer valid and later in the event loop this session is freed again. Attached is a patch which attempts to fix this issue. Basically every time a conn is assigned a session pointer, the session's conn_cnt is incremented. If conn_take_fd() fails the conn_cnt for the session is decremented and if conn_cnt == 0 the session will be freed by event_loop() Also the patch fixes the possibility of session->initiator being a NULL pointer. Cheers, Shivaram -- QUADStor Storage Virtualization : Thin Provisioning, Data Deduplication, VAAI, High Availability http://www.quadstor.com |