Merge "Remove permitted path for non-isolated namespace"
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 06e4c50..a5b2f7b 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -1134,7 +1134,9 @@
std::string host;
int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
std::string error;
- if (!android::base::ParseNetAddress(address, &host, &port, &serial, &error)) {
+ if (address.starts_with("vsock:")) {
+ serial = address;
+ } else if (!android::base::ParseNetAddress(address, &host, &port, &serial, &error)) {
SendFail(reply_fd, android::base::StringPrintf("couldn't parse '%s': %s",
address.c_str(), error.c_str()));
return true;
diff --git a/adb/daemon/transport_qemu.cpp b/adb/daemon/transport_qemu.cpp
index 8ad2572..e996c17 100644
--- a/adb/daemon/transport_qemu.cpp
+++ b/adb/daemon/transport_qemu.cpp
@@ -78,7 +78,7 @@
/* This could be an older version of the emulator, that doesn't
* implement adb QEMUD service. Fall back to the old TCP way. */
D("adb service is not available. Falling back to TCP socket.");
- std::thread(server_socket_thread, port).detach();
+ std::thread(server_socket_thread, android::base::StringPrintf("tcp:%d", port)).detach();
return;
}
diff --git a/adb/socket_spec.cpp b/adb/socket_spec.cpp
index cc67b6b..de4fff9 100644
--- a/adb/socket_spec.cpp
+++ b/adb/socket_spec.cpp
@@ -46,6 +46,11 @@
#define ADB_WINDOWS 0
#endif
+#if ADB_LINUX
+#include <sys/socket.h>
+#include "sysdeps/vm_sockets.h"
+#endif
+
// Not static because it is used in commandline.c.
int gListenAll = 0;
@@ -174,6 +179,62 @@
return true;
}
return false;
+ } else if (address.starts_with("vsock:")) {
+#if ADB_LINUX
+ std::string spec_str(address);
+ std::vector<std::string> fragments = android::base::Split(spec_str, ":");
+ unsigned int port_value = port ? *port : 0;
+ if (fragments.size() != 2 && fragments.size() != 3) {
+ *error = android::base::StringPrintf("expected vsock:cid or vsock:port:cid in '%s'",
+ spec_str.c_str());
+ errno = EINVAL;
+ return false;
+ }
+ unsigned int cid = 0;
+ if (!android::base::ParseUint(fragments[1], &cid)) {
+ *error = android::base::StringPrintf("could not parse vsock cid in '%s'",
+ spec_str.c_str());
+ errno = EINVAL;
+ return false;
+ }
+ if (fragments.size() == 3 && !android::base::ParseUint(fragments[2], &port_value)) {
+ *error = android::base::StringPrintf("could not parse vsock port in '%s'",
+ spec_str.c_str());
+ errno = EINVAL;
+ return false;
+ }
+ if (port_value == 0) {
+ *error = android::base::StringPrintf("vsock port was not provided.");
+ errno = EINVAL;
+ return false;
+ }
+ fd->reset(socket(AF_VSOCK, SOCK_STREAM, 0));
+ if (fd->get() == -1) {
+ *error = "could not open vsock socket";
+ return false;
+ }
+ sockaddr_vm addr{};
+ addr.svm_family = AF_VSOCK;
+ addr.svm_port = port_value;
+ addr.svm_cid = cid;
+ if (serial) {
+ *serial = android::base::StringPrintf("vsock:%u:%d", cid, port_value);
+ }
+ if (connect(fd->get(), reinterpret_cast<sockaddr*>(&addr), sizeof(addr))) {
+ int error_num = errno;
+ *error = android::base::StringPrintf("could not connect to vsock address '%s'",
+ spec_str.c_str());
+ errno = error_num;
+ return false;
+ }
+ if (port) {
+ *port = port_value;
+ }
+ return true;
+#else // ADB_LINUX
+ *error = "vsock is only supported on linux";
+ return false;
+#endif // ADB_LINUX
}
for (const auto& it : kLocalSocketTypes) {
@@ -187,6 +248,9 @@
fd->reset(network_local_client(&address[prefix.length()], it.second.socket_namespace,
SOCK_STREAM, error));
+ if (serial) {
+ *serial = address;
+ }
return true;
}
}
@@ -196,7 +260,7 @@
return false;
}
-int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_tcp_port) {
+int socket_spec_listen(std::string_view spec, std::string* error, int* resolved_port) {
if (spec.starts_with("tcp:")) {
std::string hostname;
int port;
@@ -215,10 +279,59 @@
return -1;
}
- if (result >= 0 && port == 0 && resolved_tcp_port) {
- *resolved_tcp_port = adb_socket_get_local_port(result);
+ if (result >= 0 && resolved_port) {
+ *resolved_port = adb_socket_get_local_port(result);
}
return result;
+ } else if (spec.starts_with("vsock:")) {
+#if ADB_LINUX
+ std::string spec_str(spec);
+ std::vector<std::string> fragments = android::base::Split(spec_str, ":");
+ if (fragments.size() != 2) {
+ *error = "given vsock server socket string was invalid";
+ return -1;
+ }
+ int port;
+ if (!android::base::ParseInt(fragments[1], &port)) {
+ *error = "could not parse vsock port";
+ errno = EINVAL;
+ return -1;
+ } else if (port < 0) {
+ *error = "vsock port was negative.";
+ errno = EINVAL;
+ return -1;
+ }
+ unique_fd serverfd(socket(AF_VSOCK, SOCK_STREAM, 0));
+ if (serverfd == -1) {
+ int error_num = errno;
+ *error = android::base::StringPrintf("could not create vsock server: '%s'",
+ strerror(error_num));
+ errno = error_num;
+ return -1;
+ }
+ sockaddr_vm addr{};
+ addr.svm_family = AF_VSOCK;
+ addr.svm_port = port == 0 ? VMADDR_PORT_ANY : port;
+ addr.svm_cid = VMADDR_CID_ANY;
+ socklen_t addr_len = sizeof(addr);
+ if (bind(serverfd, reinterpret_cast<struct sockaddr*>(&addr), addr_len)) {
+ return -1;
+ }
+ if (listen(serverfd, 4)) {
+ return -1;
+ }
+ if (serverfd >= 0 && resolved_port) {
+ if (getsockname(serverfd, reinterpret_cast<sockaddr*>(&addr), &addr_len) == 0) {
+ *resolved_port = addr.svm_port;
+ } else {
+ return -1;
+ }
+ }
+ return serverfd.release();
+#else // ADB_LINUX
+ *error = "vsock is only supported on linux";
+ return -1;
+#endif // ADB_LINUX
}
for (const auto& it : kLocalSocketTypes) {
diff --git a/adb/sockets.cpp b/adb/sockets.cpp
index 28da975..5b4c51e 100644
--- a/adb/sockets.cpp
+++ b/adb/sockets.cpp
@@ -609,6 +609,14 @@
return false;
}
}
+ if (command.starts_with("vsock:")) {
+ // vsock serials are vsock:cid:port, which have an extra colon compared to tcp.
+ size_t next_colon = command.find(':');
+ if (next_colon == std::string::npos) {
+ return false;
+ }
+ consume(next_colon + 1);
+ }
bool found_address = false;
if (command[0] == '[') {
diff --git a/adb/sysdeps/vm_sockets.h b/adb/sysdeps/vm_sockets.h
new file mode 100644
index 0000000..75c5f44
--- /dev/null
+++ b/adb/sysdeps/vm_sockets.h
@@ -0,0 +1,49 @@
+#if __BIONIC__
+#include <linux/vm_sockets.h>
+#else
+/****************************************************************************
+ ****************************************************************************
+ ***
+ *** This header was automatically generated from a Linux kernel header
+ *** of the same name, to make information necessary for userspace to
+ *** call into the kernel available to libc. It contains only constants,
+ *** structures, and macros generated from the original header, and thus,
+ *** contains no copyrightable information.
+ ***
+ *** Copied and modified from bionic/libc/kernel/uapi/linux/vm_sockets.h
+ ***
+ ****************************************************************************
+ ****************************************************************************/
+#ifndef _UAPI_VM_SOCKETS_H
+#define _UAPI_VM_SOCKETS_H
+#include <linux/socket.h>
+#define SO_VM_SOCKETS_BUFFER_SIZE 0
+#define SO_VM_SOCKETS_BUFFER_MIN_SIZE 1
+#define SO_VM_SOCKETS_BUFFER_MAX_SIZE 2
+#define SO_VM_SOCKETS_PEER_HOST_VM_ID 3
+#define SO_VM_SOCKETS_TRUSTED 5
+#define SO_VM_SOCKETS_CONNECT_TIMEOUT 6
+#define SO_VM_SOCKETS_NONBLOCK_TXRX 7
+#define VMADDR_CID_ANY -1U
+#define VMADDR_PORT_ANY -1U
+#define VMADDR_CID_HYPERVISOR 0
+#define VMADDR_CID_RESERVED 1
+#define VMADDR_CID_HOST 2
+#define VM_SOCKETS_INVALID_VERSION -1U
+#define VM_SOCKETS_VERSION_EPOCH(_v) (((_v)&0xFF000000) >> 24)
+#define VM_SOCKETS_VERSION_MAJOR(_v) (((_v)&0x00FF0000) >> 16)
+#define VM_SOCKETS_VERSION_MINOR(_v) (((_v)&0x0000FFFF))
+struct sockaddr_vm {
+ __kernel_sa_family_t svm_family;
+ unsigned short svm_reserved1;
+ unsigned int svm_port;
+ unsigned int svm_cid;
+ unsigned char svm_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) - sizeof(unsigned short) -
+ sizeof(unsigned int) - sizeof(unsigned int)];
+};
+#define IOCTL_VM_SOCKETS_GET_LOCAL_CID _IO(7, 0xb9)
+#ifndef AF_VSOCK
+#define AF_VSOCK 40
+#endif
+#endif
+#endif
diff --git a/adb/transport.h b/adb/transport.h
index 3baeb1c..71e4857 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -28,6 +28,7 @@
#include <memory>
#include <mutex>
#include <string>
+#include <string_view>
#include <thread>
#include <unordered_set>
@@ -400,7 +401,7 @@
asocket* create_device_tracker(bool long_output);
#if !ADB_HOST
-void server_socket_thread(int port);
+void server_socket_thread(std::string_view spec);
#if defined(__ANDROID__)
void qemu_socket_thread(int port);
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index 8885db4..c254d1d 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -26,6 +26,7 @@
#include <sys/types.h>
#include <condition_variable>
+#include <functional>
#include <memory>
#include <mutex>
#include <thread>
@@ -74,14 +75,15 @@
unique_fd fd;
int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
std::string serial;
- if (socket_spec_connect(&fd, "tcp:" + address, &port, &serial, response)) {
+ std::string prefix_addr = address.starts_with("vsock:") ? address : "tcp:" + address;
+ if (socket_spec_connect(&fd, prefix_addr, &port, &serial, response)) {
close_on_exec(fd);
if (!set_tcp_keepalive(fd, 1)) {
D("warning: failed to configure TCP keepalives (%s)", strerror(errno));
}
return std::make_tuple(std::move(fd), port, serial);
}
- return std::make_tuple(unique_fd(), 0, "");
+ return std::make_tuple(unique_fd(), 0, serial);
}
void connect_device(const std::string& address, std::string* response) {
@@ -95,6 +97,9 @@
int port;
std::string serial;
std::tie(fd, port, serial) = tcp_connect(address, response);
+ if (fd.get() == -1) {
+ return;
+ }
auto reconnect = [address](atransport* t) {
std::string response;
unique_fd fd;
@@ -231,16 +236,20 @@
#else // !ADB_HOST
-void server_socket_thread(int port) {
+void server_socket_thread(std::string_view spec) {
unique_fd serverfd;
adb_thread_setname("server socket");
D("transport: server_socket_thread() starting");
+ int port;
while (serverfd == -1) {
- std::string spec = android::base::StringPrintf("tcp:%d", port);
std::string error;
- serverfd.reset(socket_spec_listen(spec, &error));
- if (serverfd < 0) {
+ errno = 0;
+ serverfd.reset(socket_spec_listen(spec, &error, &port));
+ if (errno == EAFNOSUPPORT || errno == EINVAL || errno == EPROTONOSUPPORT) {
+ D("unrecoverable error: '%s'", error.c_str());
+ return;
+ } else if (serverfd < 0) {
D("server: cannot bind socket yet: %s", error.c_str());
std::this_thread::sleep_for(1s);
continue;
@@ -249,7 +258,8 @@
}
while (true) {
- D("server: trying to get new connection from %d", port);
+ std::string spec_str{spec};
+ D("server: trying to get new connection from %s", spec_str.c_str());
unique_fd fd(adb_socket_accept(serverfd, nullptr, nullptr));
if (fd >= 0) {
D("server: new connection on fd %d", fd.get());
@@ -266,25 +276,25 @@
#endif
void local_init(int port) {
- void (*func)(int);
- const char* debug_name = "";
-
#if ADB_HOST
- func = client_socket_thread;
- debug_name = "client";
+ D("transport: local client init");
+ std::thread(client_socket_thread, port).detach();
#elif !defined(__ANDROID__)
// Host adbd.
- func = server_socket_thread;
- debug_name = "server";
+ D("transport: local server init");
+ std::thread(server_socket_thread, android::base::StringPrintf("tcp:%d", port)).detach();
+ std::thread(server_socket_thread, android::base::StringPrintf("vsock:%d", port)).detach();
#else
+ D("transport: local server init");
// For the adbd daemon in the system image we need to distinguish
// between the device, and the emulator.
- func = use_qemu_goldfish() ? qemu_socket_thread : server_socket_thread;
- debug_name = "server";
+ if (use_qemu_goldfish()) {
+ std::thread(qemu_socket_thread, port).detach();
+ } else {
+ std::thread(server_socket_thread, android::base::StringPrintf("tcp:%d", port)).detach();
+ }
+ std::thread(server_socket_thread, android::base::StringPrintf("vsock:%d", port)).detach();
#endif // !ADB_HOST
-
- D("transport: local %s init", debug_name);
- std::thread(func, port).detach();
}
#if ADB_HOST
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 8076909..aeab893 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -720,10 +720,10 @@
}
// Returns fstab entries parsed from the device tree if they exist
-bool ReadFstabFromDt(Fstab* fstab) {
+bool ReadFstabFromDt(Fstab* fstab, bool log) {
std::string fstab_buf = read_fstab_from_dt();
if (fstab_buf.empty()) {
- LINFO << __FUNCTION__ << "(): failed to read fstab from dt";
+ if (log) LINFO << __FUNCTION__ << "(): failed to read fstab from dt";
return false;
}
@@ -731,13 +731,15 @@
fmemopen(static_cast<void*>(const_cast<char*>(fstab_buf.c_str())),
fstab_buf.length(), "r"), fclose);
if (!fstab_file) {
- PERROR << __FUNCTION__ << "(): failed to create a file stream for fstab dt";
+ if (log) PERROR << __FUNCTION__ << "(): failed to create a file stream for fstab dt";
return false;
}
if (!fs_mgr_read_fstab_file(fstab_file.get(), false, fstab)) {
- LERROR << __FUNCTION__ << "(): failed to load fstab from kernel:"
- << std::endl << fstab_buf;
+ if (log) {
+ LERROR << __FUNCTION__ << "(): failed to load fstab from kernel:" << std::endl
+ << fstab_buf;
+ }
return false;
}
@@ -779,7 +781,7 @@
// Loads the fstab file and combines with fstab entries passed in from device tree.
bool ReadDefaultFstab(Fstab* fstab) {
Fstab dt_fstab;
- ReadFstabFromDt(&dt_fstab);
+ ReadFstabFromDt(&dt_fstab, false);
*fstab = std::move(dt_fstab);
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
index 38f96c0..9c4d2da 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -192,7 +192,7 @@
using Fstab = std::vector<FstabEntry>;
bool ReadFstabFromFile(const std::string& path, Fstab* fstab);
-bool ReadFstabFromDt(Fstab* fstab);
+bool ReadFstabFromDt(Fstab* fstab, bool log = true);
bool ReadDefaultFstab(Fstab* fstab);
// Temporary conversion functions.
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 537bf86..d081666 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -47,7 +47,7 @@
# Mix device-specific information into the entropy pool
copy /proc/cmdline /dev/urandom
- copy /default.prop /dev/urandom
+ copy /system/etc/prop.default /dev/urandom
symlink /proc/self/fd/0 /dev/stdin
symlink /proc/self/fd/1 /dev/stdout