ueventd.cpp revision c0c1ffea588c7d3c565b79d4f8bf3d4a8f75abc9
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 17f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross#include <poll.h> 1844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include <fcntl.h> 1944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include <string.h> 2044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include <stdlib.h> 2144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include <stdio.h> 2244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include <ctype.h> 238d48c8e45724c7103f0ace7885d339e49399908bBrian Swetland#include <signal.h> 248d48c8e45724c7103f0ace7885d339e49399908bBrian Swetland 2544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include <private/android_filesystem_config.h> 26f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 27f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross#include "ueventd.h" 28f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross#include "log.h" 29f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross#include "util.h" 30f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross#include "devices.h" 3144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross#include "ueventd_parser.h" 3244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 3344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Crossstatic char hardware[32]; 3444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Crossstatic unsigned revision = 0; 35f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 362b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkinestatic void import_kernel_nv(char *name, int in_qemu) 372b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine{ 382b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine if (*name != '\0') { 392b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine char *value = strchr(name, '='); 402b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine if (value != NULL) { 412b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine *value++ = 0; 422b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine if (!strcmp(name,"androidboot.hardware")) 432b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine { 442b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine strlcpy(hardware, value, sizeof(hardware)); 452b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine } 462b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine } 472b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine } 482b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine} 492b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine 50f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Crossint ueventd_main(int argc, char **argv) 51f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross{ 52f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross struct pollfd ufd; 53f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross int nr; 5444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross char tmp[32]; 55f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 566ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich /* 576ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich * init sets the umask to 077 for forked processes. We need to 586ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich * create files with exact permissions, without modification by 596ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich * the umask. 606ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich */ 616ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich umask(000); 626ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich 636ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich /* Prevent fire-and-forget children from becoming zombies. 646ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich * If we should need to wait() for some children in the future 656ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich * (as opposed to none right now), double-forking here instead 666ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich * of ignoring SIGCHLD may be the better solution. 676ebf12fe1bc2de7af4522349973e8bfcc71d6126Nick Kralevich */ 688d48c8e45724c7103f0ace7885d339e49399908bBrian Swetland signal(SIGCHLD, SIG_IGN); 698d48c8e45724c7103f0ace7885d339e49399908bBrian Swetland 70f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross open_devnull_stdio(); 718f91282ebe1963b9d27f8779ad1342302b293bd2Dima Zavin klog_init(); 7218ccc1b8ee8f74ec9dde20782948c78e8ba2667fAlex Ray#if LOG_UEVENTS 7318ccc1b8ee8f74ec9dde20782948c78e8ba2667fAlex Ray /* Ensure we're at a logging level that will show the events */ 74eb6ffc765b4a2919bbabd3132bf2bd68a4966415Alex Ray if (klog_get_level() < KLOG_INFO_LEVEL) { 75eb6ffc765b4a2919bbabd3132bf2bd68a4966415Alex Ray klog_set_level(KLOG_INFO_LEVEL); 7618ccc1b8ee8f74ec9dde20782948c78e8ba2667fAlex Ray } 7718ccc1b8ee8f74ec9dde20782948c78e8ba2667fAlex Ray#endif 78f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 79f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross INFO("starting ueventd\n"); 80f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 812b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine /* Respect hardware passed in through the kernel cmd line. Here we will look 822b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine * for androidboot.hardware param in kernel cmdline, and save its value in 832b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine * hardware[]. */ 842b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine import_kernel_cmdline(0, import_kernel_nv); 852b99543cef1b8b0aa8cca39544939910035117b0Vladimir Chtchetkine 8644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross get_hardware_name(hardware, &revision); 8744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 8844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross ueventd_parse_config_file("/ueventd.rc"); 8944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 9044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross snprintf(tmp, sizeof(tmp), "/ueventd.%s.rc", hardware); 9144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross ueventd_parse_config_file(tmp); 9244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 93f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross device_init(); 94f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 95f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross ufd.events = POLLIN; 96f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross ufd.fd = get_device_fd(); 97f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross 98f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross while(1) { 99f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross ufd.revents = 0; 100f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross nr = poll(&ufd, 1, -1); 101f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross if (nr <= 0) 102f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross continue; 1031d4e86c44589b3a97ca0113493c2e569c3aabcc6Amir Goldstein if (ufd.revents & POLLIN) 104f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross handle_device_fd(); 105f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross } 106f83d0b9af5cbe4440cc41ceaa8a7806a13c86282Colin Cross} 10744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 10844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Crossstatic int get_android_id(const char *id) 10944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross{ 11044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross unsigned int i; 11144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross for (i = 0; i < ARRAY_SIZE(android_ids); i++) 11244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (!strcmp(id, android_ids[i].name)) 11344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross return android_ids[i].aid; 1144f97fd91e361c8fc2f5fbcab0fa34e2bd68d3218Veeren Mandalia return -1; 11544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross} 11644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 11744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Crossvoid set_device_permission(int nargs, char **args) 11844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross{ 11944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross char *name; 120bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland char *attr = 0; 12144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross mode_t perm; 12244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross uid_t uid; 12344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross gid_t gid; 12444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross int prefix = 0; 125c0c1ffea588c7d3c565b79d4f8bf3d4a8f75abc9Daniel Leung int wildcard = 0; 12644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross char *endptr; 12744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross int ret; 12844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross char *tmp = 0; 12944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 13044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (nargs == 0) 13144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross return; 13244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 13344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (args[0][0] == '#') 13444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross return; 13544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 136bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland name = args[0]; 137bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland 138bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland if (!strncmp(name,"/sys/", 5) && (nargs == 5)) { 139bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland INFO("/sys/ rule %s %s\n",args[0],args[1]); 140bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland attr = args[1]; 141bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland args++; 142bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland nargs--; 143bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland } 144bc57d4ce925a62f14c28c55e0ff28af1114f12beBrian Swetland 14544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (nargs != 4) { 14644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross ERROR("invalid line ueventd.rc line for '%s'\n", args[0]); 14744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross return; 14844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } 14944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 15044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross /* If path starts with mtd@ lookup the mount number. */ 15144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (!strncmp(name, "mtd@", 4)) { 15244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross int n = mtd_name_to_number(name + 4); 15344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (n >= 0) 15444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross asprintf(&tmp, "/dev/mtd/mtd%d", n); 15544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross name = tmp; 15644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } else { 15744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross int len = strlen(name); 158c0c1ffea588c7d3c565b79d4f8bf3d4a8f75abc9Daniel Leung char *wildcard_chr = strchr(name, '*'); 159c0c1ffea588c7d3c565b79d4f8bf3d4a8f75abc9Daniel Leung if ((name[len - 1] == '*') && 160c0c1ffea588c7d3c565b79d4f8bf3d4a8f75abc9Daniel Leung (wildcard_chr == (name + len - 1))) { 16144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross prefix = 1; 16244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross name[len - 1] = '\0'; 163c0c1ffea588c7d3c565b79d4f8bf3d4a8f75abc9Daniel Leung } else if (wildcard_chr) { 164c0c1ffea588c7d3c565b79d4f8bf3d4a8f75abc9Daniel Leung wildcard = 1; 16544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } 16644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } 16744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 16844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross perm = strtol(args[1], &endptr, 8); 16944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (!endptr || *endptr != '\0') { 17044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross ERROR("invalid mode '%s'\n", args[1]); 17144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross free(tmp); 17244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross return; 17344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } 17444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 17544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross ret = get_android_id(args[2]); 17644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (ret < 0) { 17744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross ERROR("invalid uid '%s'\n", args[2]); 17844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross free(tmp); 17944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross return; 18044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } 18144b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross uid = ret; 18244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 18344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross ret = get_android_id(args[3]); 18444b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross if (ret < 0) { 18544b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross ERROR("invalid gid '%s'\n", args[3]); 18644b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross free(tmp); 18744b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross return; 18844b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross } 18944b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross gid = ret; 19044b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross 191c0c1ffea588c7d3c565b79d4f8bf3d4a8f75abc9Daniel Leung add_dev_perms(name, attr, perm, uid, gid, prefix, wildcard); 19244b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross free(tmp); 19344b65d047cc39baf30e21bfd8dd438f6bc1f77f5Colin Cross} 194