1
1
/*
2
2
* Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2016-2017 Phusion Holding B.V.
3
+ * Copyright (c) 2016-2018 Phusion Holding B.V.
4
4
*
5
5
* "Passenger", "Phusion Passenger" and "Union Station" are registered
6
6
* trademarks of Phusion Holding B.V.
@@ -147,7 +147,8 @@ class HandshakePerform {
147
147
TRACE_POINT ();
148
148
try {
149
149
string path = session.responseDir + " /finish" ;
150
- int fd = syscalls::open (path.c_str (), O_RDONLY);
150
+ int fd = syscalls::openat (session.responseDirFd , " finish" ,
151
+ O_RDONLY | O_NOFOLLOW);
151
152
if (fd == -1 ) {
152
153
int e = errno;
153
154
throw FileSystemException (" Error opening FIFO " + path,
@@ -378,13 +379,21 @@ class HandshakePerform {
378
379
vector<string> errors;
379
380
380
381
// We already checked whether properties.json exists before invoking
381
- // this method, so if unsafeReadFile () fails then we can't be sure that
382
+ // this method, so if safeReadFile () fails then we can't be sure that
382
383
// it's an application problem. This is why we want the SystemException
383
384
// to propagate to higher layers so that there it can be turned into
384
385
// a generic filesystem-related or IO-related SpawnException, as opposed
385
386
// to one about this problem specifically.
386
387
387
- if (!reader.parse (unsafeReadFile (path), doc)) {
388
+ pair<string, bool > jsonContent = safeReadFile (session.responseDirFd , " properties.json" ,
389
+ SPAWNINGKIT_MAX_PROPERTIES_JSON_SIZE);
390
+ if (!jsonContent.second ) {
391
+ errors.push_back (" Error parsing " + path + " : file bigger than "
392
+ + toString (SPAWNINGKIT_MAX_PROPERTIES_JSON_SIZE) + " bytes" );
393
+ throwSpawnExceptionBecauseOfResultValidationErrors (vector<string>(),
394
+ errors);
395
+ }
396
+ if (!reader.parse (jsonContent.first , doc)) {
388
397
errors.push_back (" Error parsing " + path + " : " +
389
398
reader.getFormattedErrorMessages ());
390
399
throwSpawnExceptionBecauseOfResultValidationErrors (vector<string>(),
@@ -923,7 +932,8 @@ class HandshakePerform {
923
932
ErrorCategory inferErrorCategoryFromResponseDir (ErrorCategory defaultValue) const {
924
933
TRACE_POINT ();
925
934
if (fileExists (session.responseDir + " /error/category" )) {
926
- string value = strip (unsafeReadFile (session.responseDir + " /error/category" ));
935
+ string value = strip (safeReadFile (session.responseErrorDirFd ,
936
+ " category" , SPAWNINGKIT_MAX_ERROR_CATEGORY_SIZE).first );
927
937
ErrorCategory category = stringToErrorCategory (value);
928
938
929
939
if (category == UNKNOWN_ERROR_CATEGORY) {
@@ -1048,18 +1058,24 @@ class HandshakePerform {
1048
1058
continue ;
1049
1059
}
1050
1060
1061
+ map<JourneyStep, int >::const_iterator it = session.stepDirFds .find (step);
1062
+ if (it == session.stepDirFds .end ()) {
1063
+ P_BUG (" No fd opened for step " << stepString);
1064
+ }
1065
+
1051
1066
loadJourneyStateFromResponseDirForSpecificStep (
1052
- session, pid, stdoutAndErrCapturer, step, stepDir);
1067
+ session, pid, stdoutAndErrCapturer, step, stepDir, it-> second );
1053
1068
}
1054
1069
}
1055
1070
1056
1071
static void loadJourneyStateFromResponseDirForSpecificStep (HandshakeSession &session,
1057
1072
pid_t pid, const BackgroundIOCapturerPtr &stdoutAndErrCapturer,
1058
- JourneyStep step, const string &stepDir)
1073
+ JourneyStep step, const string &stepDir, int stepDirFd )
1059
1074
{
1060
1075
TRACE_POINT_WITH_DATA (journeyStepToString (step).data ());
1061
1076
string summary;
1062
- string value = strip (unsafeReadFile (stepDir + " /state" ));
1077
+ string value = strip (safeReadFile (stepDirFd, " state" ,
1078
+ SPAWNINGKIT_MAX_JOURNEY_STEP_FILE_SIZE).first );
1063
1079
JourneyStepState state = stringToJourneyStepState (value);
1064
1080
const Config *config = session.config ;
1065
1081
@@ -1275,13 +1291,15 @@ class HandshakePerform {
1275
1291
1276
1292
UPDATE_TRACE_POINT ();
1277
1293
if (fileExists (stepDir + " /begin_time_monotonic" )) {
1278
- value = unsafeReadFile (stepDir + " /begin_time_monotonic" );
1294
+ value = safeReadFile (stepDirFd, " begin_time_monotonic" ,
1295
+ SPAWNINGKIT_MAX_JOURNEY_STEP_FILE_SIZE).first ;
1279
1296
MonotonicTimeUsec beginTimeMonotonic = atof (value.c_str ()) * 1000000 ;
1280
1297
P_DEBUG (" [App " << pid << " journey] Step " << journeyStepToString (step)
1281
1298
<< " : monotonic begin time is \" " << cEscapeString (value) << " \" " );
1282
1299
session.journey .setStepBeginTime (step, beginTimeMonotonic);
1283
1300
} else if (fileExists (stepDir + " /begin_time" )) {
1284
- value = unsafeReadFile (stepDir + " /begin_time" );
1301
+ value = safeReadFile (stepDirFd, " begin_time" ,
1302
+ SPAWNINGKIT_MAX_JOURNEY_STEP_FILE_SIZE).first ;
1285
1303
unsigned long long beginTime = atof (value.c_str ()) * 1000000 ;
1286
1304
MonotonicTimeUsec beginTimeMonotonic = usecTimestampToMonoTime (beginTime);
1287
1305
P_DEBUG (" [App " << pid << " journey] Step " << journeyStepToString (step)
@@ -1295,13 +1313,15 @@ class HandshakePerform {
1295
1313
1296
1314
UPDATE_TRACE_POINT ();
1297
1315
if (fileExists (stepDir + " /end_time_monotonic" )) {
1298
- value = unsafeReadFile (stepDir + " /end_time_monotonic" );
1316
+ value = safeReadFile (stepDirFd, " end_time_monotonic" ,
1317
+ SPAWNINGKIT_MAX_JOURNEY_STEP_FILE_SIZE).first ;
1299
1318
MonotonicTimeUsec endTimeMonotonic = atof (value.c_str ()) * 1000000 ;
1300
1319
P_DEBUG (" [App " << pid << " journey] Step " << journeyStepToString (step)
1301
1320
<< " : monotonic end time is \" " << cEscapeString (value) << " \" " );
1302
1321
session.journey .setStepEndTime (step, endTimeMonotonic);
1303
1322
} else if (fileExists (stepDir + " /end_time" )) {
1304
- value = unsafeReadFile (stepDir + " /end_time" );
1323
+ value = safeReadFile (stepDirFd, " end_time" ,
1324
+ SPAWNINGKIT_MAX_JOURNEY_STEP_FILE_SIZE).first ;
1305
1325
unsigned long long endTime = atof (value.c_str ()) * 1000000 ;
1306
1326
MonotonicTimeUsec endTimeMonotonic = usecTimestampToMonoTime (endTime);
1307
1327
P_DEBUG (" [App " << pid << " journey] Step " << journeyStepToString (step)
@@ -1334,32 +1354,36 @@ class HandshakePerform {
1334
1354
const string &envDumpDir = session.envDumpDir ;
1335
1355
1336
1356
if (fileExists (responseDir + " /error/summary" )) {
1337
- e.setSummary (strip (unsafeReadFile (responseDir + " /error/summary" )));
1357
+ e.setSummary (strip (safeReadFile (session.responseErrorDirFd , " summary" ,
1358
+ SPAWNINGKIT_MAX_SUBPROCESS_ERROR_MESSAGE_SIZE).first ));
1338
1359
}
1339
1360
1340
1361
if (e.getAdvancedProblemDetails ().empty ()
1341
1362
&& fileExists (responseDir + " /error/advanced_problem_details" ))
1342
1363
{
1343
- e.setAdvancedProblemDetails (strip (unsafeReadFile (responseDir
1344
- + " /error/ advanced_problem_details" ) ));
1364
+ e.setAdvancedProblemDetails (strip (safeReadFile (session. responseErrorDirFd ,
1365
+ " advanced_problem_details" , SPAWNINGKIT_MAX_SUBPROCESS_ERROR_MESSAGE_SIZE). first ));
1345
1366
}
1346
1367
1347
1368
if (fileExists (responseDir + " /error/problem_description.html" )) {
1348
- e.setProblemDescriptionHTML (unsafeReadFile (responseDir + " /error/problem_description.html" ));
1369
+ e.setProblemDescriptionHTML (safeReadFile (session.responseErrorDirFd ,
1370
+ " problem_description.html" , SPAWNINGKIT_MAX_SUBPROCESS_ERROR_MESSAGE_SIZE).first );
1349
1371
} else if (fileExists (responseDir + " /error/problem_description.txt" )) {
1350
- e.setProblemDescriptionHTML (escapeHTML (strip (unsafeReadFile (
1351
- responseDir + " /error/ problem_description.txt" ) )));
1372
+ e.setProblemDescriptionHTML (escapeHTML (strip (safeReadFile (session. responseErrorDirFd ,
1373
+ " problem_description.txt" , SPAWNINGKIT_MAX_SUBPROCESS_ERROR_MESSAGE_SIZE). first )));
1352
1374
}
1353
1375
1354
1376
if (fileExists (responseDir + " /error/solution_description.html" )) {
1355
- e.setSolutionDescriptionHTML (unsafeReadFile (responseDir + " /error/solution_description.html" ));
1377
+ e.setSolutionDescriptionHTML (safeReadFile (session.responseErrorDirFd ,
1378
+ " solution_description.html" , SPAWNINGKIT_MAX_SUBPROCESS_ERROR_MESSAGE_SIZE).first );
1356
1379
} else if (fileExists (responseDir + " /error/solution_description.txt" )) {
1357
- e.setSolutionDescriptionHTML (escapeHTML (strip (unsafeReadFile (
1358
- responseDir + " /error/ solution_description.txt" ) )));
1380
+ e.setSolutionDescriptionHTML (escapeHTML (strip (safeReadFile (session. responseErrorDirFd ,
1381
+ " solution_description.txt" , SPAWNINGKIT_MAX_SUBPROCESS_ERROR_MESSAGE_SIZE). first )));
1359
1382
}
1360
1383
1361
1384
string envvars, userInfo, ulimits;
1362
- loadBasicInfoFromEnvDumpDir (envDumpDir, envvars, userInfo, ulimits);
1385
+ loadBasicInfoFromEnvDumpDir (envDumpDir, session.envDumpDirFd , envvars,
1386
+ userInfo, ulimits);
1363
1387
e.setSubprocessEnvvars (envvars);
1364
1388
e.setSubprocessUserInfo (userInfo);
1365
1389
e.setSubprocessUlimits (ulimits);
@@ -1388,7 +1412,9 @@ class HandshakePerform {
1388
1412
while ((ent = readdir (dir)) != NULL ) {
1389
1413
if (ent->d_name [0 ] != ' .' ) {
1390
1414
e.setAnnotation (ent->d_name , strip (
1391
- unsafeReadFile (path + " /" + ent->d_name )));
1415
+ safeReadFile (session.envDumpAnnotationsDirFd ,
1416
+ ent->d_name , SPAWNINGKIT_MAX_SUBPROCESS_ENVDUMP_SIZE).first
1417
+ ));
1392
1418
}
1393
1419
}
1394
1420
}
@@ -1630,16 +1656,19 @@ class HandshakePerform {
1630
1656
}
1631
1657
1632
1658
static void loadBasicInfoFromEnvDumpDir (const string &envDumpDir,
1633
- string &envvars, string &userInfo, string &ulimits)
1659
+ int envDumpDirFd, string &envvars, string &userInfo, string &ulimits)
1634
1660
{
1635
1661
if (fileExists (envDumpDir + " /envvars" )) {
1636
- envvars = unsafeReadFile (envDumpDir + " /envvars" );
1662
+ envvars = safeReadFile (envDumpDirFd, " envvars" ,
1663
+ SPAWNINGKIT_MAX_SUBPROCESS_ENVDUMP_SIZE).first ;
1637
1664
}
1638
1665
if (fileExists (envDumpDir + " /user_info" )) {
1639
- userInfo = unsafeReadFile (envDumpDir + " /user_info" );
1666
+ userInfo = safeReadFile (envDumpDirFd, " user_info" ,
1667
+ SPAWNINGKIT_MAX_SUBPROCESS_ENVDUMP_SIZE).first ;
1640
1668
}
1641
1669
if (fileExists (envDumpDir + " /ulimits" )) {
1642
- ulimits = unsafeReadFile (envDumpDir + " /ulimits" );
1670
+ ulimits = safeReadFile (envDumpDirFd, " ulimits" ,
1671
+ SPAWNINGKIT_MAX_SUBPROCESS_ENVDUMP_SIZE).first ;
1643
1672
}
1644
1673
}
1645
1674
};
0 commit comments