liblog: check getgroups for AID_LOG for AID_LOG_SECURITY
Bug: 26792035
Change-Id: I634d3c8f9f3175956bd70e80daa479af40180f90
diff --git a/liblog/logd_write.c b/liblog/logd_write.c
index 55b965b..4946073 100644
--- a/liblog/logd_write.c
+++ b/liblog/logd_write.c
@@ -204,14 +204,36 @@
if (vec[0].iov_len < 4) {
return -EINVAL;
}
- if ((last_uid != AID_SYSTEM) && (last_uid != AID_ROOT)) {
+ /* Matches clientHasLogCredentials() in logd */
+ if ((last_uid != AID_SYSTEM) && (last_uid != AID_ROOT) && (last_uid != AID_LOG)) {
uid_t uid = geteuid();
- if ((uid != AID_SYSTEM) && (uid != AID_ROOT)) {
+ if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)) {
gid_t gid = getgid();
- if ((gid != AID_SYSTEM) && (gid != AID_ROOT)) {
+ if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
gid = getegid();
- if ((gid != AID_SYSTEM) && (gid != AID_ROOT)) {
- return -EPERM;
+ if ((gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
+ int num_groups;
+ gid_t *groups;
+
+ num_groups = getgroups(0, NULL);
+ if (num_groups <= 0) {
+ return -EPERM;
+ }
+ groups = calloc(num_groups, sizeof(gid_t));
+ if (!groups) {
+ return -ENOMEM;
+ }
+ num_groups = getgroups(num_groups, groups);
+ while (num_groups > 0) {
+ if (groups[num_groups - 1] == AID_LOG) {
+ break;
+ }
+ --num_groups;
+ }
+ free(groups);
+ if (num_groups <= 0) {
+ return -EPERM;
+ }
}
}
}