Browse Source

[tftp] Process OACKs even if malformed

IBM Tivoli PXE Server 5.1.0.3 is reported to send trailing garbage
bytes at the end of the OACK packet, which causes gPXE to reject the
packet and abort the TFTP transfer.

Work around the problem by processing as much as possible of the OACK,
and treating name/value parsing errors as non-fatal.

Reported-by: Shao Miller <Shao.Miller@yrdsb.edu.on.ca>
tags/v0.9.8
Michael Brown 15 years ago
parent
commit
1958974d0a
1 changed files with 28 additions and 12 deletions
  1. 28
    12
      src/net/udp/tftp.c

+ 28
- 12
src/net/udp/tftp.c View File

672
 	char *end = buf + len;
672
 	char *end = buf + len;
673
 	char *name;
673
 	char *name;
674
 	char *value;
674
 	char *value;
675
+	char *next;
675
 	int rc = 0;
676
 	int rc = 0;
676
 
677
 
677
 	/* Sanity check */
678
 	/* Sanity check */
681
 		rc = -EINVAL;
682
 		rc = -EINVAL;
682
 		goto done;
683
 		goto done;
683
 	}
684
 	}
684
-	if ( end[-1] != '\0' ) {
685
-		DBGC ( tftp, "TFTP %p received OACK missing final NUL\n",
686
-		       tftp );
687
-		rc = -EINVAL;
688
-		goto done;
689
-	}
690
 
685
 
691
 	/* Process each option in turn */
686
 	/* Process each option in turn */
692
-	name = oack->data;
693
-	while ( name < end ) {
694
-		value = ( name + strlen ( name ) + 1 );
687
+	for ( name = oack->data ; name < end ; name = next ) {
688
+
689
+		/* Parse option name and value
690
+		 *
691
+		 * We treat parsing errors as non-fatal, because there
692
+		 * exists at least one TFTP server (IBM Tivoli PXE
693
+		 * Server 5.1.0.3) that has been observed to send
694
+		 * malformed OACKs containing trailing garbage bytes.
695
+		 */
696
+		value = ( name + strnlen ( name, ( end - name ) ) + 1 );
697
+		if ( value > end ) {
698
+			DBGC ( tftp, "TFTP %p received OACK with malformed "
699
+			       "option name:\n", tftp );
700
+			DBGC_HD ( tftp, oack, len );
701
+			break;
702
+		}
695
 		if ( value == end ) {
703
 		if ( value == end ) {
696
 			DBGC ( tftp, "TFTP %p received OACK missing value "
704
 			DBGC ( tftp, "TFTP %p received OACK missing value "
697
 			       "for option \"%s\"\n", tftp, name );
705
 			       "for option \"%s\"\n", tftp, name );
698
-			rc = -EINVAL;
699
-			goto done;
706
+			DBGC_HD ( tftp, oack, len );
707
+			break;
700
 		}
708
 		}
709
+		next = ( value + strnlen ( value, ( end - value ) ) + 1 );
710
+		if ( next > end ) {
711
+			DBGC ( tftp, "TFTP %p received OACK with malformed "
712
+			       "value for option \"%s\":\n", tftp, name );
713
+			DBGC_HD ( tftp, oack, len );
714
+			break;
715
+		}
716
+
717
+		/* Process option */
701
 		if ( ( rc = tftp_process_option ( tftp, name, value ) ) != 0 )
718
 		if ( ( rc = tftp_process_option ( tftp, name, value ) ) != 0 )
702
 			goto done;
719
 			goto done;
703
-		name = ( value + strlen ( value ) + 1 );
704
 	}
720
 	}
705
 
721
 
706
 	/* Process tsize information, if available */
722
 	/* Process tsize information, if available */

Loading…
Cancel
Save