소스 검색

[pxe] Check for a valid PXE network device when applicable

Very nasty things can happen if a NULL network device is used.  Check
that pxe_netdev is non-NULL at the applicable entry points, so that
this type of problem gets reported to the caller rather than being
allowed to crash the system.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 년 전
부모
커밋
faf50e8fa3
2개의 변경된 파일213개의 추가작업 그리고 11개의 파일을 삭제
  1. 8
    0
      src/arch/i386/interface/pxe/pxe_preboot.c
  2. 205
    11
      src/arch/i386/interface/pxe/pxe_undi.c

+ 8
- 0
src/arch/i386/interface/pxe/pxe_preboot.c 파일 보기

@@ -155,6 +155,14 @@ PXENV_EXIT_t pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO
155 155
 	       get_cached_info->Buffer.segment,
156 156
 	       get_cached_info->Buffer.offset, get_cached_info->BufferSize );
157 157
 
158
+	/* Sanity check */
159
+	if ( ! pxe_netdev ) {
160
+		DBGC ( &pxe_netdev, "PXENV_GET_CACHED_INFO called with no "
161
+		       "network device\n" );
162
+		get_cached_info->Status = PXENV_STATUS_UNDI_INVALID_STATE;
163
+		return PXENV_EXIT_FAILURE;
164
+	}
165
+
158 166
 	/* Sanity check */
159 167
         idx = ( get_cached_info->PacketType - 1 );
160 168
 	if ( idx >= NUM_CACHED_INFOS ) {

+ 205
- 11
src/arch/i386/interface/pxe/pxe_undi.c 파일 보기

@@ -58,11 +58,14 @@ struct net_device *pxe_netdev = NULL;
58 58
  * @v netdev		Network device, or NULL
59 59
  */
60 60
 void pxe_set_netdev ( struct net_device *netdev ) {
61
+
61 62
 	if ( pxe_netdev ) {
62 63
 		netdev_rx_unfreeze ( pxe_netdev );
63 64
 		netdev_put ( pxe_netdev );
64 65
 	}
66
+
65 67
 	pxe_netdev = NULL;
68
+
66 69
 	if ( netdev )
67 70
 		pxe_netdev = netdev_get ( netdev );
68 71
 }
@@ -75,11 +78,14 @@ void pxe_set_netdev ( struct net_device *netdev ) {
75 78
 static int pxe_netdev_open ( void ) {
76 79
 	int rc;
77 80
 
81
+	assert ( pxe_netdev != NULL );
82
+
78 83
 	if ( ( rc = netdev_open ( pxe_netdev ) ) != 0 )
79 84
 		return rc;
80 85
 
81 86
 	netdev_rx_freeze ( pxe_netdev );
82 87
 	netdev_irq ( pxe_netdev, 1 );
88
+
83 89
 	return 0;
84 90
 }
85 91
 
@@ -88,6 +94,8 @@ static int pxe_netdev_open ( void ) {
88 94
  *
89 95
  */
90 96
 static void pxe_netdev_close ( void ) {
97
+
98
+	assert ( pxe_netdev != NULL );
91 99
 	netdev_rx_unfreeze ( pxe_netdev );
92 100
 	netdev_irq ( pxe_netdev, 0 );
93 101
 	netdev_close ( pxe_netdev );
@@ -116,6 +124,14 @@ static void pxe_dump_mcast_list ( struct s_PXENV_UNDI_MCAST_ADDRESS *mcast ) {
116 124
 PXENV_EXIT_t pxenv_undi_startup ( struct s_PXENV_UNDI_STARTUP *undi_startup ) {
117 125
 	DBGC ( &pxe_netdev, "PXENV_UNDI_STARTUP\n" );
118 126
 
127
+	/* Sanity check */
128
+	if ( ! pxe_netdev ) {
129
+		DBGC ( &pxe_netdev, "PXENV_UNDI_STARTUP called with no "
130
+		       "network device\n" );
131
+		undi_startup->Status = PXENV_STATUS_UNDI_INVALID_STATE;
132
+		return PXENV_EXIT_FAILURE;
133
+	}
134
+
119 135
 	undi_startup->Status = PXENV_STATUS_SUCCESS;
120 136
 	return PXENV_EXIT_SUCCESS;
121 137
 }
@@ -127,6 +143,15 @@ PXENV_EXIT_t pxenv_undi_startup ( struct s_PXENV_UNDI_STARTUP *undi_startup ) {
127 143
 PXENV_EXIT_t pxenv_undi_cleanup ( struct s_PXENV_UNDI_CLEANUP *undi_cleanup ) {
128 144
 	DBGC ( &pxe_netdev, "PXENV_UNDI_CLEANUP\n" );
129 145
 
146
+	/* Sanity check */
147
+	if ( ! pxe_netdev ) {
148
+		DBGC ( &pxe_netdev, "PXENV_UNDI_CLEANUP called with no "
149
+		       "network device\n" );
150
+		undi_cleanup->Status = PXENV_STATUS_UNDI_INVALID_STATE;
151
+		return PXENV_EXIT_FAILURE;
152
+	}
153
+
154
+	/* Close network device */
130 155
 	pxe_netdev_close();
131 156
 
132 157
 	undi_cleanup->Status = PXENV_STATUS_SUCCESS;
@@ -142,6 +167,14 @@ PXENV_EXIT_t pxenv_undi_initialize ( struct s_PXENV_UNDI_INITIALIZE
142 167
 	DBGC ( &pxe_netdev, "PXENV_UNDI_INITIALIZE protocolini %08x\n",
143 168
 	       undi_initialize->ProtocolIni );
144 169
 
170
+	/* Sanity check */
171
+	if ( ! pxe_netdev ) {
172
+		DBGC ( &pxe_netdev, "PXENV_UNDI_INITIALIZE called with no "
173
+		       "network device\n" );
174
+		undi_initialize->Status = PXENV_STATUS_UNDI_INVALID_STATE;
175
+		return PXENV_EXIT_FAILURE;
176
+	}
177
+
145 178
 	undi_initialize->Status = PXENV_STATUS_SUCCESS;
146 179
 	return PXENV_EXIT_SUCCESS;
147 180
 }
@@ -158,6 +191,15 @@ PXENV_EXIT_t pxenv_undi_reset_adapter ( struct s_PXENV_UNDI_RESET
158 191
 	pxe_dump_mcast_list ( &undi_reset_adapter->R_Mcast_Buf );
159 192
 	DBGC ( &pxe_netdev, "\n" );
160 193
 
194
+	/* Sanity check */
195
+	if ( ! pxe_netdev ) {
196
+		DBGC ( &pxe_netdev, "PXENV_UNDI_RESET_ADAPTER called with no "
197
+		       "network device\n" );
198
+		undi_reset_adapter->Status = PXENV_STATUS_UNDI_INVALID_STATE;
199
+		return PXENV_EXIT_FAILURE;
200
+	}
201
+
202
+	/* Close and reopen network device */
161 203
 	pxe_netdev_close();
162 204
 	if ( ( rc = pxe_netdev_open() ) != 0 ) {
163 205
 		DBGC ( &pxe_netdev, "PXENV_UNDI_RESET_ADAPTER could not "
@@ -178,6 +220,15 @@ PXENV_EXIT_t pxenv_undi_shutdown ( struct s_PXENV_UNDI_SHUTDOWN
178 220
 				   *undi_shutdown ) {
179 221
 	DBGC ( &pxe_netdev, "PXENV_UNDI_SHUTDOWN\n" );
180 222
 
223
+	/* Sanity check */
224
+	if ( ! pxe_netdev ) {
225
+		DBGC ( &pxe_netdev, "PXENV_UNDI_SHUTDOWN called with no "
226
+		       "network device\n" );
227
+		undi_shutdown->Status = PXENV_STATUS_UNDI_INVALID_STATE;
228
+		return PXENV_EXIT_FAILURE;
229
+	}
230
+
231
+	/* Close network device */
181 232
 	pxe_netdev_close();
182 233
 
183 234
 	undi_shutdown->Status = PXENV_STATUS_SUCCESS;
@@ -196,6 +247,15 @@ PXENV_EXIT_t pxenv_undi_open ( struct s_PXENV_UNDI_OPEN *undi_open ) {
196 247
 	pxe_dump_mcast_list ( &undi_open->R_Mcast_Buf );
197 248
 	DBGC ( &pxe_netdev, "\n" );
198 249
 
250
+	/* Sanity check */
251
+	if ( ! pxe_netdev ) {
252
+		DBGC ( &pxe_netdev, "PXENV_UNDI_OPEN called with no "
253
+		       "network device\n" );
254
+		undi_open->Status = PXENV_STATUS_UNDI_INVALID_STATE;
255
+		return PXENV_EXIT_FAILURE;
256
+	}
257
+
258
+	/* Open network device */
199 259
 	if ( ( rc = pxe_netdev_open() ) != 0 ) {
200 260
 		DBGC ( &pxe_netdev, "PXENV_UNDI_OPEN could not open %s: %s\n",
201 261
 		       pxe_netdev->name, strerror ( rc ) );
@@ -214,6 +274,15 @@ PXENV_EXIT_t pxenv_undi_open ( struct s_PXENV_UNDI_OPEN *undi_open ) {
214 274
 PXENV_EXIT_t pxenv_undi_close ( struct s_PXENV_UNDI_CLOSE *undi_close ) {
215 275
 	DBGC ( &pxe_netdev, "PXENV_UNDI_CLOSE\n" );
216 276
 
277
+	/* Sanity check */
278
+	if ( ! pxe_netdev ) {
279
+		DBGC ( &pxe_netdev, "PXENV_UNDI_CLOSE called with no "
280
+		       "network device\n" );
281
+		undi_close->Status = PXENV_STATUS_UNDI_INVALID_STATE;
282
+		return PXENV_EXIT_FAILURE;
283
+	}
284
+
285
+	/* Close network device */
217 286
 	pxe_netdev_close();
218 287
 
219 288
 	undi_close->Status = PXENV_STATUS_SUCCESS;
@@ -230,7 +299,7 @@ PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT
230 299
 	struct DataBlk *datablk;
231 300
 	struct io_buffer *iobuf;
232 301
 	struct net_protocol *net_protocol;
233
-	struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
302
+	struct ll_protocol *ll_protocol;
234 303
 	char destaddr[MAX_LL_ADDR_LEN];
235 304
 	const void *ll_dest;
236 305
 	size_t len;
@@ -239,6 +308,14 @@ PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT
239 308
 
240 309
 	DBGC2 ( &pxe_netdev, "PXENV_UNDI_TRANSMIT" );
241 310
 
311
+	/* Sanity check */
312
+	if ( ! pxe_netdev ) {
313
+		DBGC ( &pxe_netdev, "PXENV_UNDI_TRANSMIT called with no "
314
+		       "network device\n" );
315
+		undi_transmit->Status = PXENV_STATUS_UNDI_INVALID_STATE;
316
+		return PXENV_EXIT_FAILURE;
317
+	}
318
+
242 319
 	/* Forcibly enable interrupts and freeze receive queue
243 320
 	 * processing at this point, to work around callers that never
244 321
 	 * call PXENV_UNDI_OPEN before attempting to use the UNDI API.
@@ -299,6 +376,7 @@ PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT
299 376
 	if ( net_protocol != NULL ) {
300 377
 
301 378
 		/* Calculate destination address */
379
+		ll_protocol = pxe_netdev->ll_protocol;
302 380
 		if ( undi_transmit->XmitFlag == XMT_DESTADDR ) {
303 381
 			copy_from_real ( destaddr,
304 382
 					 undi_transmit->DestAddr.segment,
@@ -355,6 +433,15 @@ pxenv_undi_set_mcast_address ( struct s_PXENV_UNDI_SET_MCAST_ADDRESS
355 433
 	pxe_dump_mcast_list ( &undi_set_mcast_address->R_Mcast_Buf );
356 434
 	DBGC ( &pxe_netdev, "\n" );
357 435
 
436
+	/* Sanity check */
437
+	if ( ! pxe_netdev ) {
438
+		DBGC ( &pxe_netdev, "PXENV_UNDI_SET_MCAST_ADDRESS called with "
439
+		       "no network device\n" );
440
+		undi_set_mcast_address->Status =
441
+			PXENV_STATUS_UNDI_INVALID_STATE;
442
+		return PXENV_EXIT_FAILURE;
443
+	}
444
+
358 445
 	undi_set_mcast_address->Status = PXENV_STATUS_SUCCESS;
359 446
 	return PXENV_EXIT_SUCCESS;
360 447
 }
@@ -366,8 +453,18 @@ pxenv_undi_set_mcast_address ( struct s_PXENV_UNDI_SET_MCAST_ADDRESS
366 453
 PXENV_EXIT_t 
367 454
 pxenv_undi_set_station_address ( struct s_PXENV_UNDI_SET_STATION_ADDRESS
368 455
 				 *undi_set_station_address ) {
369
-	struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
456
+	struct ll_protocol *ll_protocol;
457
+
458
+	/* Sanity check */
459
+	if ( ! pxe_netdev ) {
460
+		DBGC ( &pxe_netdev, "PXENV_UNDI_SET_STATION_ADDRESS called "
461
+		       "with no network device\n" );
462
+		undi_set_station_address->Status =
463
+			PXENV_STATUS_UNDI_INVALID_STATE;
464
+		return PXENV_EXIT_FAILURE;
465
+	}
370 466
 
467
+	ll_protocol = pxe_netdev->ll_protocol;
371 468
 	DBGC ( &pxe_netdev, "PXENV_UNDI_SET_STATION_ADDRESS %s",
372 469
 	       ll_protocol->ntoa ( undi_set_station_address->StationAddress ) );
373 470
 
@@ -403,6 +500,15 @@ pxenv_undi_set_packet_filter ( struct s_PXENV_UNDI_SET_PACKET_FILTER
403 500
 	DBGC ( &pxe_netdev, "PXENV_UNDI_SET_PACKET_FILTER %02x\n",
404 501
 	       undi_set_packet_filter->filter );
405 502
 
503
+	/* Sanity check */
504
+	if ( ! pxe_netdev ) {
505
+		DBGC ( &pxe_netdev, "PXENV_UNDI_SET_PACKET_FILTER called with "
506
+		       "no network device\n" );
507
+		undi_set_packet_filter->Status =
508
+			PXENV_STATUS_UNDI_INVALID_STATE;
509
+		return PXENV_EXIT_FAILURE;
510
+	}
511
+
406 512
 	/* Pretend that we succeeded, otherwise the 3Com DOS UNDI
407 513
 	 * driver refuses to load.  (We ignore the filter value in the
408 514
 	 * PXENV_UNDI_OPEN call anyway.)
@@ -418,20 +524,30 @@ pxenv_undi_set_packet_filter ( struct s_PXENV_UNDI_SET_PACKET_FILTER
418 524
  */
419 525
 PXENV_EXIT_t pxenv_undi_get_information ( struct s_PXENV_UNDI_GET_INFORMATION
420 526
 					  *undi_get_information ) {
421
-	struct device *dev = pxe_netdev->dev;
422
-	struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
423
-	size_t ll_addr_len = ll_protocol->ll_addr_len;
527
+	struct device *dev;
528
+	struct ll_protocol *ll_protocol;
424 529
 
425 530
 	DBGC ( &pxe_netdev, "PXENV_UNDI_GET_INFORMATION" );
426 531
 
532
+	/* Sanity check */
533
+	if ( ! pxe_netdev ) {
534
+		DBGC ( &pxe_netdev, "PXENV_UNDI_GET_INFORMATION called with no "
535
+		       "network device\n" );
536
+		undi_get_information->Status = PXENV_STATUS_UNDI_INVALID_STATE;
537
+		return PXENV_EXIT_FAILURE;
538
+	}
539
+
540
+	/* Fill in information */
541
+	dev = pxe_netdev->dev;
542
+	ll_protocol = pxe_netdev->ll_protocol;
427 543
 	undi_get_information->BaseIo = dev->desc.ioaddr;
428 544
 	undi_get_information->IntNumber =
429 545
 		( netdev_irq_supported ( pxe_netdev ) ? dev->desc.irq : 0 );
430 546
 	/* Cheat: assume all cards can cope with this */
431 547
 	undi_get_information->MaxTranUnit = ETH_MAX_MTU;
432 548
 	undi_get_information->HwType = ntohs ( ll_protocol->ll_proto );
433
-	undi_get_information->HwAddrLen = ll_addr_len;
434
-	assert ( ll_addr_len <=
549
+	undi_get_information->HwAddrLen = ll_protocol->ll_addr_len;
550
+	assert ( ll_protocol->ll_addr_len <=
435 551
 		 sizeof ( undi_get_information->CurrentNodeAddress ) );
436 552
 	memcpy ( &undi_get_information->CurrentNodeAddress,
437 553
 		 pxe_netdev->ll_addr,
@@ -462,16 +578,25 @@ PXENV_EXIT_t pxenv_undi_get_statistics ( struct s_PXENV_UNDI_GET_STATISTICS
462 578
 					 *undi_get_statistics ) {
463 579
 	DBGC ( &pxe_netdev, "PXENV_UNDI_GET_STATISTICS" );
464 580
 
581
+	/* Sanity check */
582
+	if ( ! pxe_netdev ) {
583
+		DBGC ( &pxe_netdev, "PXENV_UNDI_GET_STATISTICS called with no "
584
+		       "network device\n" );
585
+		undi_get_statistics->Status = PXENV_STATUS_UNDI_INVALID_STATE;
586
+		return PXENV_EXIT_FAILURE;
587
+	}
588
+
589
+	/* Report statistics */
465 590
 	undi_get_statistics->XmtGoodFrames = pxe_netdev->tx_stats.good;
466 591
 	undi_get_statistics->RcvGoodFrames = pxe_netdev->rx_stats.good;
467 592
 	undi_get_statistics->RcvCRCErrors = pxe_netdev->rx_stats.bad;
468 593
 	undi_get_statistics->RcvResourceErrors = pxe_netdev->rx_stats.bad;
469
-
470 594
 	DBGC ( &pxe_netdev, " txok %d rxok %d rxcrc %d rxrsrc %d\n",
471 595
 	       undi_get_statistics->XmtGoodFrames,
472 596
 	       undi_get_statistics->RcvGoodFrames,
473 597
 	       undi_get_statistics->RcvCRCErrors,
474 598
 	       undi_get_statistics->RcvResourceErrors );
599
+
475 600
 	undi_get_statistics->Status = PXENV_STATUS_SUCCESS;
476 601
 	return PXENV_EXIT_SUCCESS;
477 602
 }
@@ -484,6 +609,15 @@ PXENV_EXIT_t pxenv_undi_clear_statistics ( struct s_PXENV_UNDI_CLEAR_STATISTICS
484 609
 					   *undi_clear_statistics ) {
485 610
 	DBGC ( &pxe_netdev, "PXENV_UNDI_CLEAR_STATISTICS\n" );
486 611
 
612
+	/* Sanity check */
613
+	if ( ! pxe_netdev ) {
614
+		DBGC ( &pxe_netdev, "PXENV_UNDI_CLEAR_STATISTICS called with "
615
+		       "no network device\n" );
616
+		undi_clear_statistics->Status = PXENV_STATUS_UNDI_INVALID_STATE;
617
+		return PXENV_EXIT_FAILURE;
618
+	}
619
+
620
+	/* Clear statistics */
487 621
 	memset ( &pxe_netdev->tx_stats, 0, sizeof ( pxe_netdev->tx_stats ) );
488 622
 	memset ( &pxe_netdev->rx_stats, 0, sizeof ( pxe_netdev->rx_stats ) );
489 623
 
@@ -500,6 +634,14 @@ PXENV_EXIT_t pxenv_undi_initiate_diags ( struct s_PXENV_UNDI_INITIATE_DIAGS
500 634
 					 *undi_initiate_diags ) {
501 635
 	DBGC ( &pxe_netdev, "PXENV_UNDI_INITIATE_DIAGS failed: unsupported\n" );
502 636
 
637
+	/* Sanity check */
638
+	if ( ! pxe_netdev ) {
639
+		DBGC ( &pxe_netdev, "PXENV_UNDI_INITIATE_DIAGS called with no "
640
+		       "network device\n" );
641
+		undi_initiate_diags->Status = PXENV_STATUS_UNDI_INVALID_STATE;
642
+		return PXENV_EXIT_FAILURE;
643
+	}
644
+
503 645
 	undi_initiate_diags->Status = PXENV_STATUS_UNSUPPORTED;
504 646
 	return PXENV_EXIT_FAILURE;
505 647
 }
@@ -514,6 +656,14 @@ PXENV_EXIT_t pxenv_undi_force_interrupt ( struct s_PXENV_UNDI_FORCE_INTERRUPT
514 656
 	DBGC ( &pxe_netdev,
515 657
 	       "PXENV_UNDI_FORCE_INTERRUPT failed: unsupported\n" );
516 658
 
659
+	/* Sanity check */
660
+	if ( ! pxe_netdev ) {
661
+		DBGC ( &pxe_netdev, "PXENV_UNDI_FORCE_INTERRUPT called with no "
662
+		       "network device\n" );
663
+		undi_force_interrupt->Status = PXENV_STATUS_UNDI_INVALID_STATE;
664
+		return PXENV_EXIT_FAILURE;
665
+	}
666
+
517 667
 	undi_force_interrupt->Status = PXENV_STATUS_UNSUPPORTED;
518 668
 	return PXENV_EXIT_FAILURE;
519 669
 }
@@ -525,13 +675,24 @@ PXENV_EXIT_t pxenv_undi_force_interrupt ( struct s_PXENV_UNDI_FORCE_INTERRUPT
525 675
 PXENV_EXIT_t
526 676
 pxenv_undi_get_mcast_address ( struct s_PXENV_UNDI_GET_MCAST_ADDRESS
527 677
 			       *undi_get_mcast_address ) {
528
-	struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
678
+	struct ll_protocol *ll_protocol;
529 679
 	struct in_addr ip = { .s_addr = undi_get_mcast_address->InetAddr };
530 680
 	int rc;
531 681
 
532 682
 	DBGC ( &pxe_netdev, "PXENV_UNDI_GET_MCAST_ADDRESS %s",
533 683
 	       inet_ntoa ( ip ) );
534 684
 
685
+	/* Sanity check */
686
+	if ( ! pxe_netdev ) {
687
+		DBGC ( &pxe_netdev, "PXENV_UNDI_GET_MCAST_ADDRESS called with "
688
+		       "no network device\n" );
689
+		undi_get_mcast_address->Status =
690
+			PXENV_STATUS_UNDI_INVALID_STATE;
691
+		return PXENV_EXIT_FAILURE;
692
+	}
693
+
694
+	/* Hash address using the network device's link-layer protocol */
695
+	ll_protocol = pxe_netdev->ll_protocol;
535 696
 	if ( ( rc = ll_protocol->mc_hash ( AF_INET, &ip,
536 697
 				      undi_get_mcast_address->MediaAddr ))!=0){
537 698
 		DBGC ( &pxe_netdev, " failed: %s\n", strerror ( rc ) );
@@ -551,13 +712,22 @@ pxenv_undi_get_mcast_address ( struct s_PXENV_UNDI_GET_MCAST_ADDRESS
551 712
  */
552 713
 PXENV_EXIT_t pxenv_undi_get_nic_type ( struct s_PXENV_UNDI_GET_NIC_TYPE
553 714
 				       *undi_get_nic_type ) {
554
-	struct device *dev = pxe_netdev->dev;
715
+	struct device *dev;
555 716
 
556 717
 	DBGC ( &pxe_netdev, "PXENV_UNDI_GET_NIC_TYPE" );
557 718
 
719
+	/* Sanity check */
720
+	if ( ! pxe_netdev ) {
721
+		DBGC ( &pxe_netdev, "PXENV_UNDI_GET_NIC_TYPE called with "
722
+		       "no network device\n" );
723
+		undi_get_nic_type->Status = PXENV_STATUS_UNDI_INVALID_STATE;
724
+		return PXENV_EXIT_FAILURE;
725
+	}
726
+
727
+	/* Fill in information */
558 728
 	memset ( &undi_get_nic_type->info, 0,
559 729
 		 sizeof ( undi_get_nic_type->info ) );
560
-
730
+	dev = pxe_netdev->dev;
561 731
 	switch ( dev->desc.bus_type ) {
562 732
 	case BUS_TYPE_PCI: {
563 733
 		struct pci_nic_info *info = &undi_get_nic_type->info.pci;
@@ -615,6 +785,14 @@ PXENV_EXIT_t pxenv_undi_get_iface_info ( struct s_PXENV_UNDI_GET_IFACE_INFO
615 785
 					 *undi_get_iface_info ) {
616 786
 	DBGC ( &pxe_netdev, "PXENV_UNDI_GET_IFACE_INFO" );
617 787
 
788
+	/* Sanity check */
789
+	if ( ! pxe_netdev ) {
790
+		DBGC ( &pxe_netdev, "PXENV_UNDI_GET_IFACE_INFO called with "
791
+		       "no network device\n" );
792
+		undi_get_iface_info->Status = PXENV_STATUS_UNDI_INVALID_STATE;
793
+		return PXENV_EXIT_FAILURE;
794
+	}
795
+
618 796
 	/* Just hand back some info, doesn't really matter what it is.
619 797
 	 * Most PXE stacks seem to take this approach.
620 798
 	 */
@@ -645,6 +823,14 @@ PXENV_EXIT_t pxenv_undi_get_state ( struct s_PXENV_UNDI_GET_STATE
645 823
 				    *undi_get_state ) {
646 824
 	DBGC ( &pxe_netdev, "PXENV_UNDI_GET_STATE failed: unsupported\n" );
647 825
 
826
+	/* Sanity check */
827
+	if ( ! pxe_netdev ) {
828
+		DBGC ( &pxe_netdev, "PXENV_UNDI_GET_STATE called with "
829
+		       "no network device\n" );
830
+		undi_get_state->Status = PXENV_STATUS_UNDI_INVALID_STATE;
831
+		return PXENV_EXIT_FAILURE;
832
+	}
833
+
648 834
 	undi_get_state->Status = PXENV_STATUS_UNSUPPORTED;
649 835
 	return PXENV_EXIT_FAILURE;
650 836
 };
@@ -671,6 +857,14 @@ PXENV_EXIT_t pxenv_undi_isr ( struct s_PXENV_UNDI_ISR *undi_isr ) {
671 857
 	 */
672 858
 	DBGC2 ( &pxenv_undi_isr, "PXENV_UNDI_ISR" );
673 859
 
860
+	/* Sanity check */
861
+	if ( ! pxe_netdev ) {
862
+		DBGC ( &pxe_netdev, "PXENV_UNDI_ISR called with "
863
+		       "no network device\n" );
864
+		undi_isr->Status = PXENV_STATUS_UNDI_INVALID_STATE;
865
+		return PXENV_EXIT_FAILURE;
866
+	}
867
+
674 868
 	/* Just in case some idiot actually looks at these fields when
675 869
 	 * we weren't meant to fill them in...
676 870
 	 */

Loading…
취소
저장