Skip to content

Commit bfb9351

Browse files
committed
ForkExecNode: check that the file is executable according to Truffle FS
1 parent de611e8 commit bfb9351

File tree

1 file changed

+33
-16
lines changed

1 file changed

+33
-16
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixSubprocessModuleBuiltins.java

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@
7777
import com.oracle.graal.python.runtime.PythonOptions;
7878
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
7979
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
80+
import com.oracle.truffle.api.TruffleFile;
81+
import com.oracle.truffle.api.TruffleLanguage.Env;
8082
import com.oracle.truffle.api.TruffleLogger;
8183
import com.oracle.truffle.api.dsl.Cached;
8284
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
@@ -141,14 +143,11 @@ private synchronized int forkExec(PList args, PList execList, @SuppressWarnings(
141143
}
142144

143145
File cwdFile;
144-
try {
145-
if (getContext().getEnv().getPublicTruffleFile(cwd).exists()) {
146-
cwdFile = new File(cwd);
147-
} else {
148-
throw raise(PythonBuiltinClassType.OSError, ErrorMessages.WORK_DIR_NOT_ACCESSIBLE, cwd);
149-
}
150-
} catch (SecurityException e) {
151-
throw raise(PythonBuiltinClassType.OSError, e);
146+
Env truffleEnv = context.getEnv();
147+
if (getSafeTruffleFile(truffleEnv, cwd).exists()) {
148+
cwdFile = new File(cwd);
149+
} else {
150+
throw raise(PythonBuiltinClassType.OSError, ErrorMessages.WORK_DIR_NOT_ACCESSIBLE, cwd);
152151
}
153152

154153
SequenceStorage envStorage = env.getSequenceStorage();
@@ -209,18 +208,22 @@ private synchronized int forkExec(PList args, PList execList, @SuppressWarnings(
209208
} else {
210209
argStrings.set(0, path);
211210
}
212-
try {
213-
return exec(argStrings, cwdFile, envMap, p2cwrite, p2cread, c2pwrite, c2pread, errwrite, errpipe_write, resources, errread);
214-
} catch (IOException ex) {
215-
if (firstError == null) {
216-
firstError = ex;
211+
TruffleFile executableFile = getSafeTruffleFile(truffleEnv, argStrings.get(0));
212+
if (executableFile.isExecutable()) {
213+
try {
214+
return exec(argStrings, cwdFile, envMap, p2cwrite, p2cread, c2pwrite, c2pread, errwrite, errpipe_write, resources, errread);
215+
} catch (IOException ex) {
216+
if (firstError == null) {
217+
firstError = ex;
218+
}
217219
}
220+
} else {
221+
LOGGER.finest(() -> "_posixsubprocess.fork_exec not executable: " + executableFile);
218222
}
219223
for (int j = 1; j < executableListLen; j++) {
220224
argStrings.remove(1);
221225
}
222226
}
223-
assert firstError != null;
224227
if (errpipe_write != -1) {
225228
handleIOError(errpipe_write, resources, firstError);
226229
}
@@ -285,6 +288,14 @@ private int exec(ArrayList<String> argStrings, File cwd, Map<String, String> env
285288
return resources.registerChild(process);
286289
}
287290

291+
private TruffleFile getSafeTruffleFile(Env env, String path) {
292+
try {
293+
return env.getPublicTruffleFile(path);
294+
} catch (SecurityException e) {
295+
throw raise(PythonBuiltinClassType.OSError, e);
296+
}
297+
}
298+
288299
private String checkNullBytesAndEncode(PythonObjectLibrary pyLib, PBytes bytesObj) {
289300
byte[] bytes;
290301
try {
@@ -307,12 +318,18 @@ private String checkNullBytesAndEncode(PythonObjectLibrary pyLib, PBytes bytesOb
307318
@TruffleBoundary(allowInlining = true)
308319
private void handleIOError(int errpipe_write, PosixResources resources, IOException e) {
309320
// write exec error information here. Data format: "exception name:hex
310-
// errno:description"
321+
// errno:description". The exception can be null if we did not find any file in the
322+
// execList that could be executed
311323
Channel err = resources.getFileChannel(errpipe_write);
312324
if (!(err instanceof WritableByteChannel)) {
313325
throw raise(PythonBuiltinClassType.OSError, ErrorMessages.ERROR_WRITING_FORKEXEC);
314326
} else {
315-
ErrorAndMessagePair pair = OSErrorEnum.fromException(e);
327+
ErrorAndMessagePair pair;
328+
if (e == null) {
329+
pair = new ErrorAndMessagePair(OSErrorEnum.ENOENT, OSErrorEnum.ENOENT.getMessage());
330+
} else {
331+
pair = OSErrorEnum.fromException(e);
332+
}
316333
try {
317334
((WritableByteChannel) err).write(ByteBuffer.wrap(("OSError:" + Long.toHexString(pair.oserror.getNumber()) + ":" + pair.message).getBytes()));
318335
} catch (IOException e1) {

0 commit comments

Comments
 (0)