Loading services/core/java/com/android/server/am/NativeCrashListener.java +13 −14 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.app.ApplicationErrorReport.CrashInfo; import android.system.ErrnoException; import android.system.Os; import android.system.StructTimeval; import android.system.StructUcred; import android.system.UnixSocketAddress; import android.util.Slog; Loading Loading @@ -105,9 +104,9 @@ final class NativeCrashListener extends Thread { if (DEBUG) Slog.i(TAG, "Starting up"); // The file system entity for this socket is created with 0700 perms, owned // by system:system. debuggerd runs as root, so is capable of connecting to // it, but 3rd party apps cannot. // The file system entity for this socket is created with 0777 perms, owned // by system:system. selinux restricts things so that only crash_dump can // access it. { File socketFile = new File(DEBUGGERD_SOCKET_PATH); if (socketFile.exists()) { Loading @@ -121,6 +120,7 @@ final class NativeCrashListener extends Thread { DEBUGGERD_SOCKET_PATH); Os.bind(serverFd, sockAddr); Os.listen(serverFd, 1); Os.chmod(DEBUGGERD_SOCKET_PATH, 0777); while (true) { FileDescriptor peerFd = null; Loading @@ -129,19 +129,14 @@ final class NativeCrashListener extends Thread { peerFd = Os.accept(serverFd, null /* peerAddress */); if (MORE_DEBUG) Slog.v(TAG, "Got debuggerd socket " + peerFd); if (peerFd != null) { // Only the superuser is allowed to talk to us over this socket StructUcred credentials = Os.getsockoptUcred(peerFd, SOL_SOCKET, SO_PEERCRED); if (credentials.uid == 0) { // the reporting thread may take responsibility for // acking the debugger; make sure we play along. consumeNativeCrashData(peerFd); } } } catch (Exception e) { Slog.w(TAG, "Error handling connection", e); } finally { // Always ack debuggerd's connection to us. The actual // Always ack crash_dump's connection to us. The actual // byte written is irrelevant. if (peerFd != null) { try { Loading Loading @@ -194,7 +189,7 @@ final class NativeCrashListener extends Thread { return totalRead; } // Read the crash report from the debuggerd connection // Read a crash report from the connection void consumeNativeCrashData(FileDescriptor fd) { if (MORE_DEBUG) Slog.i(TAG, "debuggerd connected"); final byte[] buf = new byte[4096]; Loading @@ -205,6 +200,10 @@ final class NativeCrashListener extends Thread { Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, timeout); Os.setsockoptTimeval(fd, SOL_SOCKET, SO_SNDTIMEO, timeout); // The socket is guarded by an selinux neverallow rule that only // permits crash_dump to connect to it. This allows us to trust the // received values. // first, the pid and signal number int headerBytes = readExactly(fd, buf, 0, 8); if (headerBytes != 8) { Loading Loading
services/core/java/com/android/server/am/NativeCrashListener.java +13 −14 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.app.ApplicationErrorReport.CrashInfo; import android.system.ErrnoException; import android.system.Os; import android.system.StructTimeval; import android.system.StructUcred; import android.system.UnixSocketAddress; import android.util.Slog; Loading Loading @@ -105,9 +104,9 @@ final class NativeCrashListener extends Thread { if (DEBUG) Slog.i(TAG, "Starting up"); // The file system entity for this socket is created with 0700 perms, owned // by system:system. debuggerd runs as root, so is capable of connecting to // it, but 3rd party apps cannot. // The file system entity for this socket is created with 0777 perms, owned // by system:system. selinux restricts things so that only crash_dump can // access it. { File socketFile = new File(DEBUGGERD_SOCKET_PATH); if (socketFile.exists()) { Loading @@ -121,6 +120,7 @@ final class NativeCrashListener extends Thread { DEBUGGERD_SOCKET_PATH); Os.bind(serverFd, sockAddr); Os.listen(serverFd, 1); Os.chmod(DEBUGGERD_SOCKET_PATH, 0777); while (true) { FileDescriptor peerFd = null; Loading @@ -129,19 +129,14 @@ final class NativeCrashListener extends Thread { peerFd = Os.accept(serverFd, null /* peerAddress */); if (MORE_DEBUG) Slog.v(TAG, "Got debuggerd socket " + peerFd); if (peerFd != null) { // Only the superuser is allowed to talk to us over this socket StructUcred credentials = Os.getsockoptUcred(peerFd, SOL_SOCKET, SO_PEERCRED); if (credentials.uid == 0) { // the reporting thread may take responsibility for // acking the debugger; make sure we play along. consumeNativeCrashData(peerFd); } } } catch (Exception e) { Slog.w(TAG, "Error handling connection", e); } finally { // Always ack debuggerd's connection to us. The actual // Always ack crash_dump's connection to us. The actual // byte written is irrelevant. if (peerFd != null) { try { Loading Loading @@ -194,7 +189,7 @@ final class NativeCrashListener extends Thread { return totalRead; } // Read the crash report from the debuggerd connection // Read a crash report from the connection void consumeNativeCrashData(FileDescriptor fd) { if (MORE_DEBUG) Slog.i(TAG, "debuggerd connected"); final byte[] buf = new byte[4096]; Loading @@ -205,6 +200,10 @@ final class NativeCrashListener extends Thread { Os.setsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO, timeout); Os.setsockoptTimeval(fd, SOL_SOCKET, SO_SNDTIMEO, timeout); // The socket is guarded by an selinux neverallow rule that only // permits crash_dump to connect to it. This allows us to trust the // received values. // first, the pid and signal number int headerBytes = readExactly(fd, buf, 0, 8); if (headerBytes != 8) { Loading