Kaynağa Gözat

Proper limits checking for message sizes to allow ~1mb max message sizes for corosync.

git-svn-id: http://svn.fedorahosted.org/svn/corosync/trunk@2388 fd59a12c-fef9-0310-b244-a6a79926bd2f
Steven Dake 16 yıl önce
ebeveyn
işleme
f558917703
4 değiştirilmiş dosya ile 43 ekleme ve 6 silme
  1. 12 0
      exec/coroipcs.c
  2. 6 0
      exec/main.c
  3. 21 6
      exec/totempg.c
  4. 4 0
      lib/coroipcc.c

+ 12 - 0
exec/coroipcs.c

@@ -625,6 +625,18 @@ retry_semop:
 			header,
 			header,
 			conn_info->sending_allowed_private_data);
 			conn_info->sending_allowed_private_data);
 
 
+		/*
+		 * This happens when the message contains some kind of invalid
+		 * parameter, such as an invalid size
+		 */
+		if (send_ok == -1) {
+			coroipc_response_header.size = sizeof (coroipc_response_header_t);
+			coroipc_response_header.id = 0;
+			coroipc_response_header.error = CS_ERR_INVALID_PARAM;
+			coroipcs_response_send (conn_info,
+				&coroipc_response_header,
+				sizeof (coroipc_response_header_t));
+		} else 
 		if (send_ok) {
 		if (send_ok) {
 			api->serialize_lock();
 			api->serialize_lock();
 			api->handler_fn_get (conn_info->service, header->id) (conn_info, header);
 			api->handler_fn_get (conn_info->service, header->id) (conn_info, header);

+ 6 - 0
exec/main.c

@@ -573,6 +573,9 @@ static int corosync_sending_allowed (
 	pd->reserved_msgs = totempg_groups_joined_reserve (
 	pd->reserved_msgs = totempg_groups_joined_reserve (
 		corosync_group_handle,
 		corosync_group_handle,
 		&reserve_iovec, 1);
 		&reserve_iovec, 1);
+	if (pd->reserved_msgs == -1) {
+		return (-1);
+	}
 
 
 	sending_allowed =
 	sending_allowed =
 		(corosync_quorum_is_quorate() == 1 ||
 		(corosync_quorum_is_quorate() == 1 ||
@@ -590,6 +593,9 @@ static void corosync_sending_allowed_release (void *sending_allowed_private_data
 	struct sending_allowed_private_data_struct *pd =
 	struct sending_allowed_private_data_struct *pd =
 		(struct sending_allowed_private_data_struct *)sending_allowed_private_data;
 		(struct sending_allowed_private_data_struct *)sending_allowed_private_data;
 
 
+	if (pd->reserved_msgs == -1) {
+		return;
+	}
 	totempg_groups_joined_release (pd->reserved_msgs);
 	totempg_groups_joined_release (pd->reserved_msgs);
 }
 }
 
 

+ 21 - 6
exec/totempg.c

@@ -155,6 +155,8 @@ static int mcast_packed_msg_count = 0;
 
 
 static int totempg_reserved = 0;
 static int totempg_reserved = 0;
 
 
+static unsigned int totempg_size_limit;
+
 /*
 /*
  * Function and data used to log messages
  * Function and data used to log messages
  */
  */
@@ -719,6 +721,8 @@ int totempg_initialize (
 		return (-1);
 		return (-1);
 	}
 	}
 
 
+	totemsrp_net_mtu_adjust (totem_config);
+
 	res = totemmrp_initialize (
 	res = totemmrp_initialize (
 		poll_handle,
 		poll_handle,
 		totem_config,
 		totem_config,
@@ -732,7 +736,9 @@ int totempg_initialize (
 		callback_token_received_fn,
 		callback_token_received_fn,
 		0);
 		0);
 
 
-	totemsrp_net_mtu_adjust (totem_config);
+	totempg_size_limit = (totemmrp_avail() - 1) *
+		(totempg_totem_config->net_mtu -
+		sizeof (struct totempg_mcast) - 16);
 
 
 	return (res);
 	return (res);
 }
 }
@@ -791,7 +797,7 @@ static int mcast_msg (
 	}
 	}
 
 
 	if (byte_count_send_ok (total_size + sizeof(unsigned short) *
 	if (byte_count_send_ok (total_size + sizeof(unsigned short) *
-		(mcast_packed_msg_count+1)) == 0) {
+		(mcast_packed_msg_count)) == 0) {
 
 
 		pthread_mutex_unlock (&mcast_msg_mutex);
 		pthread_mutex_unlock (&mcast_msg_mutex);
 		return(-1);
 		return(-1);
@@ -872,6 +878,9 @@ static int mcast_msg (
 			iovecs[2].iov_len = max_packet_size;
 			iovecs[2].iov_len = max_packet_size;
 			assert (totemmrp_avail() > 0);
 			assert (totemmrp_avail() > 0);
 			res = totemmrp_mcast (iovecs, 3, guarantee);
 			res = totemmrp_mcast (iovecs, 3, guarantee);
+			if (res == -1) {
+				goto error_exit;
+			}
 
 
 			/*
 			/*
 			 * Recalculate counts and indexes for the next.
 			 * Recalculate counts and indexes for the next.
@@ -907,6 +916,7 @@ static int mcast_msg (
 			mcast_packed_msg_count++;
 			mcast_packed_msg_count++;
 	}
 	}
 
 
+error_exit:
 	pthread_mutex_unlock (&mcast_msg_mutex);
 	pthread_mutex_unlock (&mcast_msg_mutex);
 	return (res);
 	return (res);
 }
 }
@@ -919,7 +929,7 @@ static int msg_count_send_ok (
 {
 {
 	int avail = 0;
 	int avail = 0;
 
 
-	avail = totemmrp_avail () - totempg_reserved - 1;
+	avail = totemmrp_avail ();
 
 
 	return (avail > msg_count);
 	return (avail > msg_count);
 }
 }
@@ -930,9 +940,9 @@ static int byte_count_send_ok (
 	unsigned int msg_count = 0;
 	unsigned int msg_count = 0;
 	int avail = 0;
 	int avail = 0;
 
 
-	avail = totemmrp_avail () - 1;
+	avail = totemmrp_avail ();
 
 
-	msg_count = (byte_count / (totempg_totem_config->net_mtu - 25)) + 1;
+	msg_count = (byte_count / (totempg_totem_config->net_mtu - sizeof (struct totempg_mcast) - 16));
 
 
 	return (avail > msg_count);
 	return (avail > msg_count);
 }
 }
@@ -942,7 +952,7 @@ static int send_reserve (
 {
 {
 	unsigned int msg_count = 0;
 	unsigned int msg_count = 0;
 
 
-	msg_count = (msg_size / (totempg_totem_config->net_mtu - 25)) + 1;
+	msg_count = (msg_size / (totempg_totem_config->net_mtu - sizeof (struct totempg_mcast) - 16)) + 1;
 	totempg_reserved += msg_count;
 	totempg_reserved += msg_count;
 
 
 	return (msg_count);
 	return (msg_count);
@@ -1163,6 +1173,10 @@ int totempg_groups_joined_reserve (
 	for (i = 0; i < iov_len; i++) {
 	for (i = 0; i < iov_len; i++) {
 		size += iovec[i].iov_len;
 		size += iovec[i].iov_len;
 	}
 	}
+	if (size >= totempg_size_limit) {
+		reserved = -1;
+		goto error_put;
+	}
 
 
 	reserved = send_reserve (size);
 	reserved = send_reserve (size);
 	if (msg_count_send_ok (reserved) == 0) {
 	if (msg_count_send_ok (reserved) == 0) {
@@ -1170,6 +1184,7 @@ int totempg_groups_joined_reserve (
 		reserved = 0;
 		reserved = 0;
 	}
 	}
 
 
+error_put:
 	hdb_handle_put (&totempg_groups_instance_database, handle);
 	hdb_handle_put (&totempg_groups_instance_database, handle);
 
 
 error_exit:
 error_exit:

+ 4 - 0
lib/coroipcc.c

@@ -408,6 +408,10 @@ msg_send (
 	int req_buffer_idx = 0;
 	int req_buffer_idx = 0;
 
 
 	for (i = 0; i < iov_len; i++) {
 	for (i = 0; i < iov_len; i++) {
+		if ((req_buffer_idx + iov[i].iov_len) > 
+			ipc_instance->request_size) {
+			return (CS_ERR_INVALID_PARAM);
+		}
 		memcpy (&ipc_instance->request_buffer[req_buffer_idx],
 		memcpy (&ipc_instance->request_buffer[req_buffer_idx],
 			iov[i].iov_base,
 			iov[i].iov_base,
 			iov[i].iov_len);
 			iov[i].iov_len);