|
@@ -672,6 +672,7 @@ static int tftp_rx_oack ( struct tftp_request *tftp, void *buf, size_t len ) {
|
672
|
672
|
char *end = buf + len;
|
673
|
673
|
char *name;
|
674
|
674
|
char *value;
|
|
675
|
+ char *next;
|
675
|
676
|
int rc = 0;
|
676
|
677
|
|
677
|
678
|
/* Sanity check */
|
|
@@ -681,26 +682,41 @@ static int tftp_rx_oack ( struct tftp_request *tftp, void *buf, size_t len ) {
|
681
|
682
|
rc = -EINVAL;
|
682
|
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
|
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
|
703
|
if ( value == end ) {
|
696
|
704
|
DBGC ( tftp, "TFTP %p received OACK missing value "
|
697
|
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
|
718
|
if ( ( rc = tftp_process_option ( tftp, name, value ) ) != 0 )
|
702
|
719
|
goto done;
|
703
|
|
- name = ( value + strlen ( value ) + 1 );
|
704
|
720
|
}
|
705
|
721
|
|
706
|
722
|
/* Process tsize information, if available */
|