• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012-2013 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 
17 #include <dirent.h>
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <poll.h>
21 #include <sched.h>
22 #include <semaphore.h>
23 #include <signal.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/capability.h>
28 #include <sys/klog.h>
29 #include <sys/prctl.h>
30 #include <sys/resource.h>
31 #include <sys/stat.h>
32 #include <sys/types.h>
33 #include <syslog.h>
34 #include <unistd.h>
35 
36 #include <cstdbool>
37 #include <memory>
38 
39 #include <android-base/macros.h>
40 #include <cutils/android_get_control_file.h>
41 #include <cutils/properties.h>
42 #include <cutils/sched_policy.h>
43 #include <cutils/sockets.h>
44 #include <log/event_tag_map.h>
45 #include <packagelistparser/packagelistparser.h>
46 #include <private/android_filesystem_config.h>
47 #include <private/android_logger.h>
48 #include <utils/threads.h>
49 
50 #include "CommandListener.h"
51 #include "LogAudit.h"
52 #include "LogBuffer.h"
53 #include "LogKlog.h"
54 #include "LogListener.h"
55 #include "LogUtils.h"
56 
57 #define KMSG_PRIORITY(PRI)                                 \
58     '<', '0' + LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(PRI)) / 10, \
59         '0' + LOG_MAKEPRI(LOG_DAEMON, LOG_PRI(PRI)) % 10, '>'
60 
61 //
62 // The service is designed to be run by init, it does not respond well
63 // to starting up manually. When starting up manually the sockets will
64 // fail to open typically for one of the following reasons:
65 //     EADDRINUSE if logger is running.
66 //     EACCESS if started without precautions (below)
67 //
68 // Here is a cookbook procedure for starting up logd manually assuming
69 // init is out of the way, pedantically all permissions and SELinux
70 // security is put back in place:
71 //
72 //    setenforce 0
73 //    rm /dev/socket/logd*
74 //    chmod 777 /dev/socket
75 //        # here is where you would attach the debugger or valgrind for example
76 //    runcon u:r:logd:s0 /system/bin/logd </dev/null >/dev/null 2>&1 &
77 //    sleep 1
78 //    chmod 755 /dev/socket
79 //    chown logd.logd /dev/socket/logd*
80 //    restorecon /dev/socket/logd*
81 //    setenforce 1
82 //
83 // If minimalism prevails, typical for debugging and security is not a concern:
84 //
85 //    setenforce 0
86 //    chmod 777 /dev/socket
87 //    logd
88 //
89 
drop_privs(bool klogd,bool auditd)90 static int drop_privs(bool klogd, bool auditd) {
91     // Tricky, if ro.build.type is "eng" then this is true because of the
92     // side effect that ro.debuggable == 1 as well, else it is false.
93     bool eng =
94         __android_logger_property_get_bool("ro.build.type", BOOL_DEFAULT_FALSE);
95 
96     struct sched_param param;
97     memset(&param, 0, sizeof(param));
98 
99     if (set_sched_policy(0, SP_BACKGROUND) < 0) {
100         android::prdebug("failed to set background scheduling policy");
101         if (!eng) return -1;
102     }
103 
104     if (sched_setscheduler((pid_t)0, SCHED_BATCH, &param) < 0) {
105         android::prdebug("failed to set batch scheduler");
106         if (!eng) return -1;
107     }
108 
109     if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) {
110         android::prdebug("failed to set background cgroup");
111         if (!eng) return -1;
112     }
113 
114     if (!eng && (prctl(PR_SET_DUMPABLE, 0) < 0)) {
115         android::prdebug("failed to clear PR_SET_DUMPABLE");
116         return -1;
117     }
118 
119     if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
120         android::prdebug("failed to set PR_SET_KEEPCAPS");
121         if (!eng) return -1;
122     }
123 
124     std::unique_ptr<struct _cap_struct, int (*)(void*)> caps(cap_init(),
125                                                              cap_free);
126     if (cap_clear(caps.get()) < 0) return -1;
127     cap_value_t cap_value[] = { CAP_SETGID,  // must be first for below
128                                 klogd ? CAP_SYSLOG : CAP_SETGID,
129                                 auditd ? CAP_AUDIT_CONTROL : CAP_SETGID };
130     if (cap_set_flag(caps.get(), CAP_PERMITTED, arraysize(cap_value), cap_value,
131                      CAP_SET) < 0) {
132         return -1;
133     }
134     if (cap_set_flag(caps.get(), CAP_EFFECTIVE, arraysize(cap_value), cap_value,
135                      CAP_SET) < 0) {
136         return -1;
137     }
138     if (cap_set_proc(caps.get()) < 0) {
139         android::prdebug(
140             "failed to set CAP_SETGID, CAP_SYSLOG or CAP_AUDIT_CONTROL (%d)",
141             errno);
142         if (!eng) return -1;
143     }
144 
145     gid_t groups[] = { AID_READPROC };
146 
147     if (setgroups(arraysize(groups), groups) == -1) {
148         android::prdebug("failed to set AID_READPROC groups");
149         if (!eng) return -1;
150     }
151 
152     if (setgid(AID_LOGD) != 0) {
153         android::prdebug("failed to set AID_LOGD gid");
154         if (!eng) return -1;
155     }
156 
157     if (setuid(AID_LOGD) != 0) {
158         android::prdebug("failed to set AID_LOGD uid");
159         if (!eng) return -1;
160     }
161 
162     if (cap_set_flag(caps.get(), CAP_PERMITTED, 1, cap_value, CAP_CLEAR) < 0) {
163         return -1;
164     }
165     if (cap_set_flag(caps.get(), CAP_EFFECTIVE, 1, cap_value, CAP_CLEAR) < 0) {
166         return -1;
167     }
168     if (cap_set_proc(caps.get()) < 0) {
169         android::prdebug("failed to clear CAP_SETGID (%d)", errno);
170         if (!eng) return -1;
171     }
172 
173     return 0;
174 }
175 
176 // Property helper
check_flag(const char * prop,const char * flag)177 static bool check_flag(const char* prop, const char* flag) {
178     const char* cp = strcasestr(prop, flag);
179     if (!cp) {
180         return false;
181     }
182     // We only will document comma (,)
183     static const char sep[] = ",:;|+ \t\f";
184     if ((cp != prop) && !strchr(sep, cp[-1])) {
185         return false;
186     }
187     cp += strlen(flag);
188     return !*cp || !!strchr(sep, *cp);
189 }
190 
191 static int fdDmesg = -1;
prdebug(const char * fmt,...)192 void android::prdebug(const char* fmt, ...) {
193     if (fdDmesg < 0) {
194         return;
195     }
196 
197     static const char message[] = {
198         KMSG_PRIORITY(LOG_DEBUG), 'l', 'o', 'g', 'd', ':', ' '
199     };
200     char buffer[256];
201     memcpy(buffer, message, sizeof(message));
202 
203     va_list ap;
204     va_start(ap, fmt);
205     int n = vsnprintf(buffer + sizeof(message),
206                       sizeof(buffer) - sizeof(message), fmt, ap);
207     va_end(ap);
208     if (n > 0) {
209         buffer[sizeof(buffer) - 1] = '\0';
210         if (!strchr(buffer, '\n')) {
211             buffer[sizeof(buffer) - 2] = '\0';
212             strlcat(buffer, "\n", sizeof(buffer));
213         }
214         write(fdDmesg, buffer, strlen(buffer));
215     }
216 }
217 
218 static sem_t uidName;
219 static uid_t uid;
220 static char* name;
221 
222 static sem_t reinit;
223 static bool reinit_running = false;
224 static LogBuffer* logBuf = nullptr;
225 
package_list_parser_cb(pkg_info * info,void *)226 static bool package_list_parser_cb(pkg_info* info, void* /* userdata */) {
227     bool rc = true;
228     if (info->uid == uid) {
229         name = strdup(info->name);
230         // false to stop processing
231         rc = false;
232     }
233 
234     packagelist_free(info);
235     return rc;
236 }
237 
reinit_thread_start(void *)238 static void* reinit_thread_start(void* /*obj*/) {
239     prctl(PR_SET_NAME, "logd.daemon");
240     set_sched_policy(0, SP_BACKGROUND);
241     setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND);
242 
243     cap_t caps = cap_init();
244     (void)cap_clear(caps);
245     (void)cap_set_proc(caps);
246     (void)cap_free(caps);
247 
248     // If we are AID_ROOT, we should drop to AID_LOGD+AID_SYSTEM, if we are
249     // anything else, we have even lesser privileges and accept our fate. Not
250     // worth checking for error returns setting this thread's privileges.
251     (void)setgid(AID_SYSTEM);  // readonly access to /data/system/packages.list
252     (void)setuid(AID_LOGD);    // access to everything logd, eg /data/misc/logd
253 
254     while (reinit_running && !sem_wait(&reinit) && reinit_running) {
255         // uidToName Privileged Worker
256         if (uid) {
257             name = nullptr;
258 
259             packagelist_parse(package_list_parser_cb, nullptr);
260 
261             uid = 0;
262             sem_post(&uidName);
263             continue;
264         }
265 
266         if (fdDmesg >= 0) {
267             static const char reinit_message[] = { KMSG_PRIORITY(LOG_INFO),
268                                                    'l',
269                                                    'o',
270                                                    'g',
271                                                    'd',
272                                                    '.',
273                                                    'd',
274                                                    'a',
275                                                    'e',
276                                                    'm',
277                                                    'o',
278                                                    'n',
279                                                    ':',
280                                                    ' ',
281                                                    'r',
282                                                    'e',
283                                                    'i',
284                                                    'n',
285                                                    'i',
286                                                    't',
287                                                    '\n' };
288             write(fdDmesg, reinit_message, sizeof(reinit_message));
289         }
290 
291         // Anything that reads persist.<property>
292         if (logBuf) {
293             logBuf->init();
294             logBuf->initPrune(nullptr);
295         }
296         android::ReReadEventLogTags();
297     }
298 
299     return nullptr;
300 }
301 
302 static sem_t sem_name;
303 
uidToName(uid_t u)304 char* android::uidToName(uid_t u) {
305     if (!u || !reinit_running) {
306         return nullptr;
307     }
308 
309     sem_wait(&sem_name);
310 
311     // Not multi-thread safe, we use sem_name to protect
312     uid = u;
313 
314     name = nullptr;
315     sem_post(&reinit);
316     sem_wait(&uidName);
317     char* ret = name;
318 
319     sem_post(&sem_name);
320 
321     return ret;
322 }
323 
324 // Serves as a global method to trigger reinitialization
325 // and as a function that can be provided to signal().
reinit_signal_handler(int)326 void reinit_signal_handler(int /*signal*/) {
327     sem_post(&reinit);
328 }
329 
readDmesg(LogAudit * al,LogKlog * kl)330 static void readDmesg(LogAudit* al, LogKlog* kl) {
331     if (!al && !kl) {
332         return;
333     }
334 
335     int rc = klogctl(KLOG_SIZE_BUFFER, nullptr, 0);
336     if (rc <= 0) {
337         return;
338     }
339 
340     // Margin for additional input race or trailing nul
341     ssize_t len = rc + 1024;
342     std::unique_ptr<char[]> buf(new char[len]);
343 
344     rc = klogctl(KLOG_READ_ALL, buf.get(), len);
345     if (rc <= 0) {
346         return;
347     }
348 
349     if (rc < len) {
350         len = rc + 1;
351     }
352     buf[--len] = '\0';
353 
354     if (kl && kl->isMonotonic()) {
355         kl->synchronize(buf.get(), len);
356     }
357 
358     ssize_t sublen;
359     for (char *ptr = nullptr, *tok = buf.get();
360          (rc >= 0) && !!(tok = android::log_strntok_r(tok, len, ptr, sublen));
361          tok = nullptr) {
362         if ((sublen <= 0) || !*tok) continue;
363         if (al) {
364             rc = al->log(tok, sublen);
365         }
366         if (kl) {
367             rc = kl->log(tok, sublen);
368         }
369     }
370 }
371 
issueReinit()372 static int issueReinit() {
373     cap_t caps = cap_init();
374     (void)cap_clear(caps);
375     (void)cap_set_proc(caps);
376     (void)cap_free(caps);
377 
378     int sock = TEMP_FAILURE_RETRY(socket_local_client(
379         "logd", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM));
380     if (sock < 0) return -errno;
381 
382     static const char reinitStr[] = "reinit";
383     ssize_t ret = TEMP_FAILURE_RETRY(write(sock, reinitStr, sizeof(reinitStr)));
384     if (ret < 0) return -errno;
385 
386     struct pollfd p;
387     memset(&p, 0, sizeof(p));
388     p.fd = sock;
389     p.events = POLLIN;
390     ret = TEMP_FAILURE_RETRY(poll(&p, 1, 1000));
391     if (ret < 0) return -errno;
392     if ((ret == 0) || !(p.revents & POLLIN)) return -ETIME;
393 
394     static const char success[] = "success";
395     char buffer[sizeof(success) - 1];
396     memset(buffer, 0, sizeof(buffer));
397     ret = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer)));
398     if (ret < 0) return -errno;
399 
400     return strncmp(buffer, success, sizeof(success) - 1) != 0;
401 }
402 
403 // Foreground waits for exit of the main persistent threads
404 // that are started here. The threads are created to manage
405 // UNIX domain client sockets for writing, reading and
406 // controlling the user space logger, and for any additional
407 // logging plugins like auditd and restart control. Additional
408 // transitory per-client threads are created for each reader.
main(int argc,char * argv[])409 int main(int argc, char* argv[]) {
410     // issue reinit command. KISS argument parsing.
411     if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) {
412         return issueReinit();
413     }
414 
415     static const char dev_kmsg[] = "/dev/kmsg";
416     fdDmesg = android_get_control_file(dev_kmsg);
417     if (fdDmesg < 0) {
418         fdDmesg = TEMP_FAILURE_RETRY(open(dev_kmsg, O_WRONLY | O_CLOEXEC));
419     }
420 
421     int fdPmesg = -1;
422     bool klogd = __android_logger_property_get_bool(
423         "logd.kernel", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST |
424                            BOOL_DEFAULT_FLAG_ENG | BOOL_DEFAULT_FLAG_SVELTE);
425     if (klogd) {
426         static const char proc_kmsg[] = "/proc/kmsg";
427         fdPmesg = android_get_control_file(proc_kmsg);
428         if (fdPmesg < 0) {
429             fdPmesg = TEMP_FAILURE_RETRY(
430                 open(proc_kmsg, O_RDONLY | O_NDELAY | O_CLOEXEC));
431         }
432         if (fdPmesg < 0) android::prdebug("Failed to open %s\n", proc_kmsg);
433     }
434 
435     // Reinit Thread
436     sem_init(&reinit, 0, 0);
437     sem_init(&uidName, 0, 0);
438     sem_init(&sem_name, 0, 1);
439     pthread_attr_t attr;
440     if (!pthread_attr_init(&attr)) {
441         struct sched_param param;
442 
443         memset(&param, 0, sizeof(param));
444         pthread_attr_setschedparam(&attr, &param);
445         pthread_attr_setschedpolicy(&attr, SCHED_BATCH);
446         if (!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) {
447             pthread_t thread;
448             reinit_running = true;
449             if (pthread_create(&thread, &attr, reinit_thread_start, nullptr)) {
450                 reinit_running = false;
451             }
452         }
453         pthread_attr_destroy(&attr);
454     }
455 
456     bool auditd =
457         __android_logger_property_get_bool("ro.logd.auditd", BOOL_DEFAULT_TRUE);
458     if (drop_privs(klogd, auditd) != 0) {
459         return -1;
460     }
461 
462     // Serves the purpose of managing the last logs times read on a
463     // socket connection, and as a reader lock on a range of log
464     // entries.
465 
466     LastLogTimes* times = new LastLogTimes();
467 
468     // LogBuffer is the object which is responsible for holding all
469     // log entries.
470 
471     logBuf = new LogBuffer(times);
472 
473     signal(SIGHUP, reinit_signal_handler);
474 
475     if (__android_logger_property_get_bool(
476             "logd.statistics", BOOL_DEFAULT_TRUE | BOOL_DEFAULT_FLAG_PERSIST |
477                                    BOOL_DEFAULT_FLAG_ENG |
478                                    BOOL_DEFAULT_FLAG_SVELTE)) {
479         logBuf->enableStatistics();
480     }
481 
482     // LogReader listens on /dev/socket/logdr. When a client
483     // connects, log entries in the LogBuffer are written to the client.
484 
485     LogReader* reader = new LogReader(logBuf);
486     if (reader->startListener()) {
487         exit(1);
488     }
489 
490     // LogListener listens on /dev/socket/logdw for client
491     // initiated log messages. New log entries are added to LogBuffer
492     // and LogReader is notified to send updates to connected clients.
493 
494     LogListener* swl = new LogListener(logBuf, reader);
495     // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value
496     if (swl->startListener(600)) {
497         exit(1);
498     }
499 
500     // Command listener listens on /dev/socket/logd for incoming logd
501     // administrative commands.
502 
503     CommandListener* cl = new CommandListener(logBuf, reader, swl);
504     if (cl->startListener()) {
505         exit(1);
506     }
507 
508     // LogAudit listens on NETLINK_AUDIT socket for selinux
509     // initiated log messages. New log entries are added to LogBuffer
510     // and LogReader is notified to send updates to connected clients.
511 
512     LogAudit* al = nullptr;
513     if (auditd) {
514         al = new LogAudit(logBuf, reader,
515                           __android_logger_property_get_bool(
516                               "ro.logd.auditd.dmesg", BOOL_DEFAULT_TRUE)
517                               ? fdDmesg
518                               : -1);
519     }
520 
521     LogKlog* kl = nullptr;
522     if (klogd) {
523         kl = new LogKlog(logBuf, reader, fdDmesg, fdPmesg, al != nullptr);
524     }
525 
526     readDmesg(al, kl);
527 
528     // failure is an option ... messages are in dmesg (required by standard)
529 
530     if (kl && kl->startListener()) {
531         delete kl;
532     }
533 
534     if (al && al->startListener()) {
535         delete al;
536     }
537 
538     TEMP_FAILURE_RETRY(pause());
539 
540     exit(0);
541 }
542