Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c4e4823b authored by Mark Salyzyn's avatar Mark Salyzyn
Browse files

logd: validate and fill in socket credentials

- android::pidToUid() additional checking.  Make sure if we have to
  convert a PID to an UID that the parse of /proc/<pid>/status
  requires a trailing space after the number
- android::tidToPid() added, in the same vein as android::pidToUid().
- stats.tidToPid() added
- If no credentials, set PID to 0 and UID to DEFAULT_OVERFLOWUID
- If credentialed PID is 0, use stats.tidToPid()
- If credentialed UID is DEFAULT_OVERFLOWUID, use stats.pidToUid()

Test: remove +passcred from logd.rc for daemon and confirm very few
      UID=65534 or PID=0 cases actually show up
Bug: 37985222
Change-Id: I7d20506e70e67beb3043d1537cf9450ab58dc278
parent 46bb1ffa
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -159,9 +159,12 @@ class LogBuffer : public LogBufferInterface {
    const char* pidToName(pid_t pid) {
        return stats.pidToName(pid);
    }
    uid_t pidToUid(pid_t pid) {
    virtual uid_t pidToUid(pid_t pid) override {
        return stats.pidToUid(pid);
    }
    virtual pid_t tidToPid(pid_t tid) override {
        return stats.tidToPid(tid);
    }
    const char* uidToName(uid_t uid) {
        return stats.uidToName(uid);
    }
+8 −1
Original line number Diff line number Diff line
@@ -15,8 +15,15 @@
 */

#include "LogBufferInterface.h"
#include "LogUtils.h"

LogBufferInterface::LogBufferInterface() {
}
LogBufferInterface::~LogBufferInterface() {
}
uid_t LogBufferInterface::pidToUid(pid_t pid) {
    return android::pidToUid(pid);
}
pid_t LogBufferInterface::tidToPid(pid_t tid) {
    return android::tidToPid(tid);
}
+3 −0
Original line number Diff line number Diff line
@@ -33,6 +33,9 @@ class LogBufferInterface {
    virtual int log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
                    pid_t tid, const char* msg, unsigned short len) = 0;

    virtual uid_t pidToUid(pid_t pid);
    virtual pid_t tidToPid(pid_t tid);

   private:
    DISALLOW_COPY_AND_ASSIGN(LogBufferInterface);
};
+27 −1
Original line number Diff line number Diff line
@@ -14,7 +14,9 @@
 * limitations under the License.
 */

#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <sys/cdefs.h>
#include <sys/prctl.h>
#include <sys/socket.h>
@@ -72,8 +74,11 @@ bool LogListener::onDataAvailable(SocketClient* cli) {
        cmsg = CMSG_NXTHDR(&hdr, cmsg);
    }

    struct ucred fake_cred;
    if (cred == NULL) {
        return false;
        cred = &fake_cred;
        cred->pid = 0;
        cred->uid = DEFAULT_OVERFLOWUID;
    }

    if (cred->uid == AID_LOGD) {
@@ -96,6 +101,27 @@ bool LogListener::onDataAvailable(SocketClient* cli) {
        return false;
    }

    // Check credential validity, acquire corrected details if not supplied.
    if (cred->pid == 0) {
        cred->pid = logbuf ? logbuf->tidToPid(header->tid)
                           : android::tidToPid(header->tid);
        if (cred->pid == getpid()) {
            // We expect that /proc/<tid>/ is accessible to self even without
            // readproc group, so that we will always drop messages that come
            // from any of our logd threads and their library calls.
            return false;  // ignore self
        }
    }
    if (cred->uid == DEFAULT_OVERFLOWUID) {
        uid_t uid =
            logbuf ? logbuf->pidToUid(cred->pid) : android::pidToUid(cred->pid);
        if (uid == AID_LOGD) {
            uid = logbuf ? logbuf->pidToUid(header->tid)
                         : android::pidToUid(cred->pid);
        }
        if (uid != AID_LOGD) cred->uid = uid;
    }

    char* msg = ((char*)buffer) + sizeof(android_log_header_t);
    n -= sizeof(android_log_header_t);

+10 −0
Original line number Diff line number Diff line
@@ -20,6 +20,16 @@
#include <sysutils/SocketListener.h>
#include "LogReader.h"

// DEFAULT_OVERFLOWUID is defined in linux/highuid.h, which is not part of
// the uapi headers for userspace to use.  This value is filled in on the
// out-of-band socket credentials if the OS fails to find one available.
// One of the causes of this is if SO_PASSCRED is set, all the packets before
// that point will have this value.  We also use it in a fake credential if
// no socket credentials are supplied.
#ifndef DEFAULT_OVERFLOWUID
#define DEFAULT_OVERFLOWUID 65534
#endif

class LogListener : public SocketListener {
    LogBufferInterface* logbuf;
    LogReader* reader;
Loading