1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <gtest/gtest_prod.h>
19 #include <sysutils/SocketListener.h>
20 #include <utils/RefBase.h>
21 
22 #include "LogEventFilter.h"
23 #include "logd/LogEventQueue.h"
24 
25 // DEFAULT_OVERFLOWUID is defined in linux/highuid.h, which is not part of
26 // the uapi headers for userspace to use.  This value is filled in on the
27 // out-of-band socket credentials if the OS fails to find one available.
28 // One of the causes of this is if SO_PASSCRED is set, all the packets before
29 // that point will have this value.  We also use it in a fake credential if
30 // no socket credentials are supplied.
31 #ifndef DEFAULT_OVERFLOWUID
32 #define DEFAULT_OVERFLOWUID 65534
33 #endif
34 
35 namespace android {
36 namespace os {
37 namespace statsd {
38 
39 class StatsSocketListener : public SocketListener, public virtual RefBase {
40 public:
41     explicit StatsSocketListener(const std::shared_ptr<LogEventQueue>& queue,
42                                  const std::shared_ptr<LogEventFilter>& logEventFilter);
43 
44     virtual ~StatsSocketListener() = default;
45 
46 protected:
47     bool onDataAvailable(SocketClient* cli) override;
48 
49 private:
50     static int getLogSocket();
51 
52     /**
53      * @brief Helper API to parse raw socket data buffer, make the LogEvent & submit it into the
54      * queue. Performs preliminary data validation.
55      * Created as a separate API to be easily tested without StatsSocketListener instance
56      *
57      * @param buffer buffer to parse
58      * @param len size of buffer in bytes
59      * @param uid arguments for LogEvent constructor
60      * @param pid arguments for LogEvent constructor
61      * @param queue queue to submit the event
62      * @param filter to be used for event evaluation
63      * @return tuple of <atom id, elapsed time>
64      */
65     static std::tuple<int32_t, int64_t> processSocketMessage(const char* buffer, uint32_t len,
66                                                              uint32_t uid, uint32_t pid,
67                                                              LogEventQueue& queue,
68                                                              const LogEventFilter& filter);
69 
70     /**
71      * @brief Helper API to parse buffer, make the LogEvent & submit it into the queue
72      * Created as a separate API to be easily tested without StatsSocketListener instance
73      *
74      * @param msg buffer to parse
75      * @param len size of buffer in bytes
76      * @param uid arguments for LogEvent constructor
77      * @param pid arguments for LogEvent constructor
78      * @param queue queue to submit the event
79      * @param filter to be used for event evaluation
80      * @return tuple of <atom id, elapsed time>
81      */
82     static std::tuple<int32_t, int64_t> processStatsEventBuffer(const uint8_t* msg, uint32_t len,
83                                                                 uint32_t uid, uint32_t pid,
84                                                                 LogEventQueue& queue,
85                                                                 const LogEventFilter& filter);
86 
87     /**
88      * Who is going to get the events when they're read.
89      */
90     std::shared_ptr<LogEventQueue> mQueue;
91 
92     std::shared_ptr<LogEventFilter> mLogEventFilter;
93 
94     int64_t mLastSocketReadTimeNs;
95 
96     // Tracks the atom counts per read. Member variable to avoid churn.
97     std::unordered_map<int32_t, int32_t> mAtomCounts;
98 
99     friend void fuzzSocket(const uint8_t* data, size_t size);
100 
101     friend class SocketParseMessageTest;
102     friend void generateAtomLogging(LogEventQueue& queue, const LogEventFilter& filter,
103                                     int eventCount, int startAtomId);
104 
105     FRIEND_TEST(SocketParseMessageTest, TestProcessMessage);
106     FRIEND_TEST(SocketParseMessageTest, TestProcessMessageEmptySetExplicitSet);
107     FRIEND_TEST(SocketParseMessageTest, TestProcessMessageFilterCompleteSet);
108     FRIEND_TEST(SocketParseMessageTest, TestProcessMessageFilterPartialSet);
109     FRIEND_TEST(SocketParseMessageTest, TestProcessMessageFilterToggle);
110     FRIEND_TEST(LogEventQueue_test, TestQueueMaxSize);
111 };
112 
113 }  // namespace statsd
114 }  // namespace os
115 }  // namespace android
116