Skip to content

Commit

Permalink
Version 2.3.2
Browse files Browse the repository at this point in the history
* Cherry-pick 3972f73 to stable
  • Loading branch information
sortie committed Jun 11, 2019
2 parents 3f2d646 + 43da31d commit 7a9c3ef
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 21 deletions.
35 changes: 35 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
## 2.3.2

* Cherry-pick 3972f738ca4e91104e2d6dad9bb1f36147879e98 to stable

## 2.3.2 - 2019-06-11

This is a patch version release with a security improvement.

### Security vulnerability

* **Security improvement:** On Linux and Android, starting a process with
`Process.run`, `Process.runSync`, or `Process.start` would first search the
current directory before searching `PATH` (Issue [37101][]). This behavior
effectively put the current working directory in the front of `PATH`, even if
it wasn't in the `PATH`. This release changes that behavior to only searching
the directories in the `PATH` environment variable. Operating systems other
than Linux and Android didn't have this behavior and aren't affected by this
vulnerability.

This vulnerability could result in execution of untrusted code if a command
without a slash in its name was run inside an untrusted directory containing
an executable file with that name:

```dart
Process.run("ls", workingDirectory: "/untrusted/directory")
```

This would attempt to run `/untrusted/directory/ls` if it existed, even
though it is not in the `PATH`. It was always safe to instead use an absolute
path or a path containing a slash.

This vulnerability was introduced in Dart 2.0.0.

[37101]: https://github.com/dart-lang/sdk/issues/37101

## 2.3.1 - 2019-05-21

This is a patch version release with bug fixes.
Expand Down
20 changes: 10 additions & 10 deletions runtime/bin/process_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -436,24 +436,24 @@ class ProcessStarter {
}
}

// Tries to find path_ relative to the current namespace.
// Tries to find path_ relative to the current namespace unless it should be
// searched in the PATH.
// The path that should be passed to exec is returned in realpath.
// Returns true on success, and false if there was an error that should
// be reported to the parent.
bool FindPathInNamespace(char* realpath, intptr_t realpath_size) {
// Perform a PATH search if there's no slash in the path.
if (strchr(path_, '/') == NULL) {
// TODO(zra): If there is a non-default namespace, the entries in PATH
// should be treated as relative to the namespace.
strncpy(realpath, path_, realpath_size);
realpath[realpath_size - 1] = '\0';
return true;
}
NamespaceScope ns(namespc_, path_);
const int fd =
TEMP_FAILURE_RETRY(openat(ns.fd(), ns.path(), O_RDONLY | O_CLOEXEC));
if (fd == -1) {
if ((errno == ENOENT) && (strchr(path_, '/') == NULL)) {
// path_ was not found relative to the namespace, but since it didn't
// contain a '/', we can pass it directly to execvp, which will do a
// lookup in PATH.
// TODO(zra): If there is a non-default namespace, the entries in PATH
// should be treated as relative to the namespace.
strncpy(realpath, path_, realpath_size);
return true;
}
return false;
}
char procpath[PATH_MAX];
Expand Down
20 changes: 10 additions & 10 deletions runtime/bin/process_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -436,24 +436,24 @@ class ProcessStarter {
}
}

// Tries to find path_ relative to the current namespace.
// Tries to find path_ relative to the current namespace unless it should be
// searched in the PATH.
// The path that should be passed to exec is returned in realpath.
// Returns true on success, and false if there was an error that should
// be reported to the parent.
bool FindPathInNamespace(char* realpath, intptr_t realpath_size) {
// Perform a PATH search if there's no slash in the path.
if (strchr(path_, '/') == NULL) {
// TODO(zra): If there is a non-default namespace, the entries in PATH
// should be treated as relative to the namespace.
strncpy(realpath, path_, realpath_size);
realpath[realpath_size - 1] = '\0';
return true;
}
NamespaceScope ns(namespc_, path_);
const int fd =
TEMP_FAILURE_RETRY(openat64(ns.fd(), ns.path(), O_RDONLY | O_CLOEXEC));
if (fd == -1) {
if ((errno == ENOENT) && (strchr(path_, '/') == NULL)) {
// path_ was not found relative to the namespace, but since it didn't
// contain a '/', we can pass it directly to execvp, which will do a
// lookup in PATH.
// TODO(zra): If there is a non-default namespace, the entries in PATH
// should be treated as relative to the namespace.
strncpy(realpath, path_, realpath_size);
return true;
}
return false;
}
char procpath[PATH_MAX];
Expand Down
2 changes: 1 addition & 1 deletion tools/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
CHANNEL stable
MAJOR 2
MINOR 3
PATCH 1
PATCH 2
PRERELEASE 0
PRERELEASE_PATCH 0
ABI_VERSION 4
Expand Down

0 comments on commit 7a9c3ef

Please sign in to comment.