1ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes// Copyright (C) 2016 The Android Open Source Project 2ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes// 3ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes// Licensed under the Apache License, Version 2.0 (the "License"); 4ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes// you may not use this file except in compliance with the License. 5ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes// You may obtain a copy of the License at 6ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes// 7ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes// http://www.apache.org/licenses/LICENSE-2.0 8ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes// 9ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes// Unless required by applicable law or agreed to in writing, software 10ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes// distributed under the License is distributed on an "AS IS" BASIS, 11ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes// See the License for the specific language governing permissions and 13ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes// limitations under the License. 14ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes 15ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes#include <sys/capability.h> 16c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes#include <sys/types.h> 17ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes#include <unistd.h> 18ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes 19ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes#include <libminijail.h> 20ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes 21ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes#include <android-base/logging.h> 22404d2bb02680f9f433dbe9c71f87bf1f003bf495Mike Frysinger#include <android-base/macros.h> 23ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes 24ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obesconst uid_t kSystemUid = 1000U; 25ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes 26c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obesgid_t groups[] = {kSystemUid + 1, kSystemUid + 2}; 27c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes 28c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obessize_t getgroups_with_alloc(gid_t** plist) { 29c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes *plist = NULL; 30c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes 31c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes int nsupp_groups = getgroups(0, NULL); 32c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes if (nsupp_groups < 0) { 33c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes PLOG(ERROR) << "getgroups(0)"; 34c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes return 0; 35c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes } 36c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes if (nsupp_groups == 0) { 37c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes LOG(INFO) << "No supplementary groups."; 38c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes return 0; 39c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes } 40c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes 41c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes *plist = (gid_t*)calloc((size_t)nsupp_groups, sizeof(gid_t)); 42c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes nsupp_groups = getgroups(nsupp_groups, *plist); 43c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes if (nsupp_groups < 0) { 44c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes PLOG(ERROR) << "getgroups(nsupp_groups)"; 45c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes free(*plist); 46c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes return 0; 47c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes } 48c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes return nsupp_groups; 49ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes} 50ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes 51ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obesbool check_ugid(uid_t expected_id) { 52c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes bool success = true; 53c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes 54c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes uid_t ruid = getuid(); 55c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes if (ruid != expected_id) { 56c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes LOG(ERROR) << "rUID " << ruid << " is not " << expected_id; 57c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes success = false; 58c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes } 59c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes gid_t rgid = getgid(); 60c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes if (rgid != expected_id) { 61c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes LOG(ERROR) << "rGID " << ruid << " is not " << expected_id; 62c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes success = false; 63c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes } 64c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes return success; 65ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes} 66ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes 67c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obesbool check_groups(size_t expected_size, gid_t* expected_list) { 68c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes bool success = true; 69c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes 70c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes gid_t* actual_list; 71c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes size_t actual_size = getgroups_with_alloc(&actual_list); 72c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes 73c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes if (expected_size != actual_size) { 74c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes LOG(ERROR) << "Mismatched supplementary group list size: expected " 75c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes << expected_size << ", actual " << actual_size; 76c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes success = false; 77c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes } 78c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes 79c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes for (size_t i = 0; i < expected_size; i++) { 80c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes bool found = false; 81c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes for (size_t j = 0; j < actual_size; j++) { 82c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes if (expected_list[i] == actual_list[j]) { 83c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes // Test next expected GID. 84c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes found = true; 85c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes break; 86c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes } 870e3fe532a9fdf42bed41e371939134af38dd53b5Jorge Lucangeli Obes } 88c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes if (!found) { 89c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes LOG(ERROR) << "Expected GID " << expected_list[i] << " not found."; 90c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes success = false; 910e3fe532a9fdf42bed41e371939134af38dd53b5Jorge Lucangeli Obes } 92c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes } 93c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes free(actual_list); 94c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes return success; 950e3fe532a9fdf42bed41e371939134af38dd53b5Jorge Lucangeli Obes} 960e3fe532a9fdf42bed41e371939134af38dd53b5Jorge Lucangeli Obes 97ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obesvoid log_resugid() { 98c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes uid_t ruid, euid, suid; 99c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes gid_t rgid, egid, sgid; 100c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes getresuid(&ruid, &euid, &suid); 101c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes getresgid(&rgid, &egid, &sgid); 102c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes 103c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes LOG(INFO) << "ruid " << ruid << " euid " << euid << " suid " << suid; 104c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes LOG(INFO) << "rgid " << rgid << " egid " << egid << " sgid " << sgid; 105c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes 106c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes gid_t* list; 107c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes size_t nsupp_groups = getgroups_with_alloc(&list); 108c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes for (size_t i = 0; i < (size_t)nsupp_groups; i++) { 109c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes LOG(INFO) << "supp gid " << i + 1 << " " << list[i]; 110c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes } 111c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes free(list); 112ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes} 113ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes 114ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obesint main(void) { 115c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes minijail* j = minijail_new(); 116c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes minijail_change_user(j, "system"); 117c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes minijail_change_group(j, "system"); 118404d2bb02680f9f433dbe9c71f87bf1f003bf495Mike Frysinger size_t num_groups = arraysize(groups); 119c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes minijail_set_supplementary_gids(j, num_groups, groups); 120c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes minijail_use_caps(j, CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID)); 121c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes minijail_enter(j); 122c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes 123c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes bool success = check_ugid(kSystemUid); 124c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes success = success && check_groups(num_groups, groups); 125c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes 126c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes minijail_destroy(j); 127c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes minijail* j2 = minijail_new(); 128c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes minijail_change_uid(j2, 5 * kSystemUid); 129c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes minijail_change_gid(j2, 5 * kSystemUid); 130c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes minijail_enter(j2); 131c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes 132c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes success = success && check_ugid(5 * kSystemUid); 133c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes 134c8b606a21be909cd74713ecce5432a924dfdaed0Jorge Lucangeli Obes return success ? 0 : 1; 135ac9e342ef745e9057edc4e1b02a52d8943ea608aJorge Lucangeli Obes} 136