Browse Source

[iscsi] Eliminate variable-length stack allocations in CHAP handlers

Signed-off-by: Michael Brown <mcb30@ipxe.org>
master
Michael Brown 4 years ago
parent
commit
e2e29e7ae3
1 changed files with 41 additions and 11 deletions
  1. 41
    11
      src/net/tcp/iscsi.c

+ 41
- 11
src/net/tcp/iscsi.c View File

@@ -980,18 +980,26 @@ static int iscsi_handle_chap_i_value ( struct iscsi_session *iscsi,
980 980
  */
981 981
 static int iscsi_handle_chap_c_value ( struct iscsi_session *iscsi,
982 982
 				       const char *value ) {
983
-	uint8_t buf[ strlen ( value ) ]; /* Decoding never expands data */
983
+	uint8_t *buf;
984 984
 	unsigned int i;
985 985
 	int len;
986 986
 	int rc;
987 987
 
988
+	/* Allocate decoding buffer */
989
+	len = strlen ( value ); /* Decoding never expands data */
990
+	buf = malloc ( len );
991
+	if ( ! buf ) {
992
+		rc = -ENOMEM;
993
+		goto err_alloc;
994
+	}
995
+
988 996
 	/* Process challenge */
989
-	len = iscsi_large_binary_decode ( value, buf, sizeof ( buf ) );
997
+	len = iscsi_large_binary_decode ( value, buf, len );
990 998
 	if ( len < 0 ) {
991 999
 		rc = len;
992 1000
 		DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
993 1001
 		       iscsi, value, strerror ( rc ) );
994
-		return rc;
1002
+		goto err_decode;
995 1003
 	}
996 1004
 	chap_update ( &iscsi->chap, buf, len );
997 1005
 
@@ -1009,7 +1017,13 @@ static int iscsi_handle_chap_c_value ( struct iscsi_session *iscsi,
1009 1017
 		}
1010 1018
 	}
1011 1019
 
1012
-	return 0;
1020
+	/* Success */
1021
+	rc = 0;
1022
+
1023
+ err_decode:
1024
+	free ( buf );
1025
+ err_alloc:
1026
+	return rc;
1013 1027
 }
1014 1028
 
1015 1029
 /**
@@ -1050,7 +1064,7 @@ static int iscsi_handle_chap_n_value ( struct iscsi_session *iscsi,
1050 1064
  */
1051 1065
 static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
1052 1066
 				       const char *value ) {
1053
-	uint8_t buf[ strlen ( value ) ]; /* Decoding never expands data */
1067
+	uint8_t *buf;
1054 1068
 	int len;
1055 1069
 	int rc;
1056 1070
 
@@ -1059,7 +1073,7 @@ static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
1059 1073
 	if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
1060 1074
 		DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
1061 1075
 		       iscsi, strerror ( rc ) );
1062
-		return rc;
1076
+		goto err_chap_init;
1063 1077
 	}
1064 1078
 	chap_set_identifier ( &iscsi->chap, iscsi->chap_challenge[0] );
1065 1079
 	if ( iscsi->target_password ) {
@@ -1070,31 +1084,47 @@ static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
1070 1084
 		      ( sizeof ( iscsi->chap_challenge ) - 1 ) );
1071 1085
 	chap_respond ( &iscsi->chap );
1072 1086
 
1087
+	/* Allocate decoding buffer */
1088
+	len = strlen ( value ); /* Decoding never expands data */
1089
+	buf = malloc ( len );
1090
+	if ( ! buf ) {
1091
+		rc = -ENOMEM;
1092
+		goto err_alloc;
1093
+	}
1094
+
1073 1095
 	/* Process response */
1074
-	len = iscsi_large_binary_decode ( value, buf, sizeof ( buf ) );
1096
+	len = iscsi_large_binary_decode ( value, buf, len );
1075 1097
 	if ( len < 0 ) {
1076 1098
 		rc = len;
1077 1099
 		DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
1078 1100
 		       iscsi, value, strerror ( rc ) );
1079
-		return rc;
1101
+		goto err_decode;
1080 1102
 	}
1081 1103
 
1082 1104
 	/* Check CHAP response */
1083 1105
 	if ( len != ( int ) iscsi->chap.response_len ) {
1084 1106
 		DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n",
1085 1107
 		       iscsi );
1086
-		return -EPROTO_INVALID_CHAP_RESPONSE;
1108
+		rc = -EPROTO_INVALID_CHAP_RESPONSE;
1109
+		goto err_response_len;
1087 1110
 	}
1088 1111
 	if ( memcmp ( buf, iscsi->chap.response, len ) != 0 ) {
1089 1112
 		DBGC ( iscsi, "iSCSI %p incorrect CHAP response \"%s\"\n",
1090 1113
 		       iscsi, value );
1091
-		return -EACCES_INCORRECT_TARGET_PASSWORD;
1114
+		rc = -EACCES_INCORRECT_TARGET_PASSWORD;
1115
+		goto err_response;
1092 1116
 	}
1093 1117
 
1094 1118
 	/* Mark session as authenticated */
1095 1119
 	iscsi->status |= ISCSI_STATUS_AUTH_REVERSE_OK;
1096 1120
 
1097
-	return 0;
1121
+ err_response:
1122
+ err_response_len:
1123
+ err_decode:
1124
+	free ( buf );
1125
+ err_alloc:
1126
+ err_chap_init:
1127
+	return rc;
1098 1128
 }
1099 1129
 
1100 1130
 /** An iSCSI text string that we want to handle */

Loading…
Cancel
Save