Changeset 91631 in vbox for trunk/src/VBox/Devices/Network
- Timestamp:
- Oct 7, 2021 10:00:09 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/slirp/tftp.c
r91627 r91631 75 75 TFPTPSESSIONOPTDESC OptionTimeout; 76 76 77 const char *pcszFilenameHost; 77 78 char szFilename[TFTP_FILENAME_MAX]; 78 79 } TFTPSESSION, *PTFTPSESSION, **PPTFTPSESSION; … … 135 136 136 137 /** 137 * This function evaluate file name. 138 * @param pu8Payload 139 * @param cbPayload 140 * @param cbFileName 141 * @return VINF_SUCCESS - 142 * VERR_INVALID_PARAMETER - 138 * This function resolves file name relative to tftp prefix. 139 * @param pData 140 * @param pTftpSession 143 141 */ 144 DECLINLINE(int) tftpSecurityFilenameCheck(PNATState pData, PCTFTPSESSION pcTftpSession) 145 { 146 int rc = VINF_SUCCESS; 147 AssertPtrReturn(pcTftpSession, VERR_INVALID_PARAMETER); 148 149 /* only allow exported prefixes */ 150 if (!tftp_prefix) 151 rc = VERR_INTERNAL_ERROR; 152 else 153 { 154 char *pszFullPathAbs = RTPathAbsExDup(tftp_prefix, pcTftpSession->szFilename, RTPATH_STR_F_STYLE_HOST); 155 156 if ( !pszFullPathAbs 157 || !RTPathStartsWith(pszFullPathAbs, tftp_prefix)) 158 rc = VERR_FILE_NOT_FOUND; 159 160 RTStrFree(pszFullPathAbs); 161 } 142 DECLINLINE(int) tftpSecurityFilenameCheck(PNATState pData, PTFTPSESSION pTftpSession) 143 { 144 int rc = VERR_FILE_NOT_FOUND; /* guilty until proved innocent */ 145 146 AssertPtrReturn(pTftpSession, VERR_INVALID_PARAMETER); 147 AssertReturn(pTftpSession->pcszFilenameHost == NULL, VERR_INVALID_PARAMETER); 148 149 /* prefix must be set to an absolute pathname. assert? */ 150 if (tftp_prefix == NULL || RTPathSkipRootSpec(tftp_prefix) == tftp_prefix) 151 goto done; 152 153 /* replace backslashes with forward slashes */ 154 char *s = pTftpSession->szFilename; 155 while ((s = strchr(s, '\\')) != NULL) 156 *s++ = '/'; 157 158 /* deny attempts to break out of tftp dir */ 159 if (RTStrStartsWith(pTftpSession->szFilename, "../")) 160 goto done; 161 162 const char *dotdot = RTStrStr(pTftpSession->szFilename, "/.."); 163 if (dotdot != NULL && (dotdot[3] == '/' || dotdot[3] == '\0')) 164 goto done; 165 166 char *pszPathHostAbs; 167 int cbLen = RTStrAPrintf(&pszPathHostAbs, "%s/%s", 168 tftp_prefix, pTftpSession->szFilename); 169 if (cbLen == -1) 170 goto done; 171 172 LogRel2(("NAT: TFTP: %s\n", pszPathHostAbs)); 173 pTftpSession->pcszFilenameHost = pszPathHostAbs; 174 rc = VINF_SUCCESS; 175 176 done: 162 177 LogFlowFuncLeaveRC(rc); 163 178 return rc; … … 254 269 DECLINLINE(void) tftpSessionTerminate(PTFTPSESSION pTftpSession) 255 270 { 271 if (pTftpSession->pcszFilenameHost != NULL) 272 { 273 RTStrFree((char *)pTftpSession->pcszFilenameHost); 274 pTftpSession->pcszFilenameHost = NULL; 275 } 276 256 277 pTftpSession->fInUse = 0; 257 278 } … … 378 399 379 400 found: 380 memset(pTftpSession, 0, sizeof(*pTftpSession)); 401 if (pTftpSession->pcszFilenameHost != NULL) 402 { 403 RTStrFree((char *)pTftpSession->pcszFilenameHost); 404 // pTftpSession->pcszFilenameHost = NULL; /* will be zeroed out below */ 405 } 406 RT_ZERO(*pTftpSession); 407 381 408 memcpy(&pTftpSession->IpClientAddress, &pcTftpIpHeader->IPv4Hdr.ip_src, sizeof(pTftpSession->IpClientAddress)); 382 409 pTftpSession->u16ClientPort = pcTftpIpHeader->UdpHdr.uh_sport; … … 437 464 } 438 465 439 DECLINLINE(int) pftpSessionOpenFile(PNATState pData, PTFTPSESSION pTftpSession, PRTFILE pSessionFile) 440 { 441 char szSessionFilename[TFTP_FILENAME_MAX]; 442 ssize_t cchSessionFilename; 466 DECLINLINE(int) pftpSessionOpenFile(PTFTPSESSION pTftpSession, PRTFILE pSessionFile) 467 { 443 468 int rc; 444 469 LogFlowFuncEnter(); 445 470 446 cchSessionFilename = RTStrPrintf2(szSessionFilename, TFTP_FILENAME_MAX, "%s/%s", tftp_prefix, pTftpSession->szFilename);447 if (cchSessionFilename > 0)448 {449 LogFunc(("szSessionFilename: %s\n", szSessionFilename));450 if (RTFileExists(szSessionFilename))451 452 rc = RTFileOpen(pSessionFile, szSessionFilename, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);453 }454 else471 if (pTftpSession->pcszFilenameHost == NULL) 472 { 473 rc = VERR_FILE_NOT_FOUND; 474 } 475 else 476 { 477 rc = RTFileOpen(pSessionFile, pTftpSession->pcszFilenameHost, 478 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE); 479 if (RT_FAILURE(rc)) 455 480 rc = VERR_FILE_NOT_FOUND; 456 481 } 457 else458 rc = VERR_FILENAME_TOO_LONG;459 482 460 483 LogFlowFuncLeaveRC(rc); … … 462 485 } 463 486 464 DECLINLINE(int) tftpSessionEvaluateOptions(P NATState pData, PTFTPSESSION pTftpSession)487 DECLINLINE(int) tftpSessionEvaluateOptions(PTFTPSESSION pTftpSession) 465 488 { 466 489 int rc; … … 470 493 LogFlowFunc(("pTftpSession:%p\n", pTftpSession)); 471 494 472 rc = pftpSessionOpenFile(p Data, pTftpSession, &hSessionFile);495 rc = pftpSessionOpenFile(pTftpSession, &hSessionFile); 473 496 if (RT_FAILURE(rc)) 474 497 { … … 569 592 570 593 u16BlkSize = (uint16_t)pcTftpSession->OptionBlkSize.u64Value; 571 rc = pftpSessionOpenFile(p Data, pcTftpSession, &hSessionFile);594 rc = pftpSessionOpenFile(pcTftpSession, &hSessionFile); 572 595 if (RT_FAILURE(rc)) 573 596 { … … 639 662 int rc; 640 663 641 rc = tftpSessionEvaluateOptions(p Data, pTftpSession);664 rc = tftpSessionEvaluateOptions(pTftpSession); 642 665 if (RT_FAILURE(rc)) 643 666 {
Note:
See TracChangeset
for help on using the changeset viewer.