1f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross/* 2f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross * Copyright (C) 2010 The Android Open Source Project 3f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross * 4f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross * Licensed under the Apache License, Version 2.0 (the "License"); 5f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross * you may not use this file except in compliance with the License. 6f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross * You may obtain a copy of the License at 7f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross * 8f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross * http://www.apache.org/licenses/LICENSE-2.0 9f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross * 10f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross * Unless required by applicable law or agreed to in writing, software 11f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross * distributed under the License is distributed on an "AS IS" BASIS, 12f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross * See the License for the specific language governing permissions and 14f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross * limitations under the License. 15f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross */ 16f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 1744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include <ctype.h> 18da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes#include <fcntl.h> 19da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes#include <poll.h> 208d48c8e45724c7103f0ace7885d339e49399908bBrian Swetland#include <signal.h> 21da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes#include <stdio.h> 22da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes#include <stdlib.h> 23da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes#include <string.h> 248d48c8e45724c7103f0ace7885d339e49399908bBrian Swetland 254f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/stringprintf.h> 2644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include <private/android_filesystem_config.h> 27da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes#include <selinux/selinux.h> 28f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 29f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross#include "ueventd.h" 30f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross#include "log.h" 31f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross#include "util.h" 32f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross#include "devices.h" 3344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include "ueventd_parser.h" 3474b34f3cb79aa8f2c5ba6a9dcc46d0dd84cdac86Rom Lemarchand#include "property_service.h" 352b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine 36f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Crossint ueventd_main(int argc, char **argv) 37f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross{ 386ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich /* 396ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich * init sets the umask to 077 for forked processes. We need to 406ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich * create files with exact permissions, without modification by 416ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich * the umask. 426ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich */ 436ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich umask(000); 446ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich 456ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich /* Prevent fire-and-forget children from becoming zombies. 466ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich * If we should need to wait() for some children in the future 476ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich * (as opposed to none right now), double-forking here instead 486ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich * of ignoring SIGCHLD may be the better solution. 496ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich */ 508d48c8e45724c7103f0ace7885d339e49399908bBrian Swetland signal(SIGCHLD, SIG_IGN); 518d48c8e45724c7103f0ace7885d339e49399908bBrian Swetland 52f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross open_devnull_stdio(); 538f91282ebe1963b9d27f8779ad1342302b293bd2Dima Zavin klog_init(); 54da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes klog_set_level(KLOG_NOTICE_LEVEL); 55f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 56da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes NOTICE("ueventd started!\n"); 57439224e27530353351c7df504fb29fad9ac776a0Stephen Smalley 58da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes selinux_callback cb; 59da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes cb.func_log = selinux_klog_callback; 60da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes selinux_set_callback(SELINUX_CB_LOG, cb); 61f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 6274edcea90e31a3795e58aa1b2bbe96032f0bcd61Yabin Cui std::string hardware = property_get("ro.hardware"); 6344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 6444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross ueventd_parse_config_file("/ueventd.rc"); 6574edcea90e31a3795e58aa1b2bbe96032f0bcd61Yabin Cui ueventd_parse_config_file(android::base::StringPrintf("/ueventd.%s.rc", hardware.c_str()).c_str()); 6644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 67f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross device_init(); 68f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 69da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes pollfd ufd; 70f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross ufd.events = POLLIN; 71f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross ufd.fd = get_device_fd(); 72f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 73da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes while (true) { 74f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross ufd.revents = 0; 75da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes int nr = poll(&ufd, 1, -1); 76da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes if (nr <= 0) { 77f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross continue; 78da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes } 79da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes if (ufd.revents & POLLIN) { 80da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes handle_device_fd(); 81da40c00137f75543a69972f1be506e2d14a41845Elliott Hughes } 82f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross } 832145779c871d4a9f632a8afbfc2adc5bea185a45Elliott Hughes 842145779c871d4a9f632a8afbfc2adc5bea185a45Elliott Hughes return 0; 85f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross} 8644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 8744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Crossstatic int get_android_id(const char *id) 8844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross{ 8944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross unsigned int i; 9044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross for (i = 0; i < ARRAY_SIZE(android_ids); i++) 9144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (!strcmp(id, android_ids[i].name)) 9244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross return android_ids[i].aid; 934f97fd91e361c8fc2f5fbcab0fa34e2bd68d3218Veeren Mandalia return -1; 9444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross} 9544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 9644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Crossvoid set_device_permission(int nargs, char **args) 9744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross{ 9844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross char *name; 99bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland char *attr = 0; 10044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross mode_t perm; 10144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross uid_t uid; 10244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross gid_t gid; 10344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross int prefix = 0; 104c0c1ffea588c7d3c565b79d4f8bf3d4a8f75abc9Daniel Leung int wildcard = 0; 10544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross char *endptr; 10644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross int ret; 10744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross char *tmp = 0; 10844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 10944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (nargs == 0) 11044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross return; 11144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 11244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (args[0][0] == '#') 11344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross return; 11444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 115bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland name = args[0]; 116bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland 117bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland if (!strncmp(name,"/sys/", 5) && (nargs == 5)) { 118bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland INFO("/sys/ rule %s %s\n",args[0],args[1]); 119bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland attr = args[1]; 120bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland args++; 121bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland nargs--; 122bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland } 123bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland 12444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (nargs != 4) { 12544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross ERROR("invalid line ueventd.rc line for '%s'\n", args[0]); 12644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross return; 12744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } 12844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 12944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross /* If path starts with mtd@ lookup the mount number. */ 13044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (!strncmp(name, "mtd@", 4)) { 13144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross int n = mtd_name_to_number(name + 4); 13244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (n >= 0) 13344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross asprintf(&tmp, "/dev/mtd/mtd%d", n); 13444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross name = tmp; 13544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } else { 13644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross int len = strlen(name); 137c0c1ffea588c7d3c565b79d4f8bf3d4a8f75abc9Daniel Leung char *wildcard_chr = strchr(name, '*'); 138c0c1ffea588c7d3c565b79d4f8bf3d4a8f75abc9Daniel Leung if ((name[len - 1] == '*') && 139c0c1ffea588c7d3c565b79d4f8bf3d4a8f75abc9Daniel Leung (wildcard_chr == (name + len - 1))) { 14044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross prefix = 1; 14144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross name[len - 1] = '\0'; 142c0c1ffea588c7d3c565b79d4f8bf3d4a8f75abc9Daniel Leung } else if (wildcard_chr) { 143c0c1ffea588c7d3c565b79d4f8bf3d4a8f75abc9Daniel Leung wildcard = 1; 14444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } 14544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } 14644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 14744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross perm = strtol(args[1], &endptr, 8); 14844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (!endptr || *endptr != '\0') { 14944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross ERROR("invalid mode '%s'\n", args[1]); 15044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross free(tmp); 15144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross return; 15244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } 15344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 15444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross ret = get_android_id(args[2]); 15544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (ret < 0) { 15644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross ERROR("invalid uid '%s'\n", args[2]); 15744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross free(tmp); 15844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross return; 15944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } 16044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross uid = ret; 16144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 16244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross ret = get_android_id(args[3]); 16344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (ret < 0) { 16444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross ERROR("invalid gid '%s'\n", args[3]); 16544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross free(tmp); 16644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross return; 16744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } 16844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross gid = ret; 16944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 170c0c1ffea588c7d3c565b79d4f8bf3d4a8f75abc9Daniel Leung add_dev_perms(name, attr, perm, uid, gid, prefix, wildcard); 17144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross free(tmp); 17244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross} 173