Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44b65d04 authored by Colin Cross's avatar Colin Cross
Browse files

init: Add ueventd.rc parsing to ueventd

Change-Id: Iea53050d6c10e8cabf563e5d80e84eaf78873695
parent f83d0b9a
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -14,7 +14,8 @@ LOCAL_SRC_FILES:= \
	keychords.c \
	keychords.c \
	signal_handler.c \
	signal_handler.c \
	init_parser.c \
	init_parser.c \
	ueventd.c
	ueventd.c \
	ueventd_parser.c


ifeq ($(strip $(INIT_BOOTCHART)),true)
ifeq ($(strip $(INIT_BOOTCHART)),true)
LOCAL_SRC_FILES += bootchart.c
LOCAL_SRC_FILES += bootchart.c
+29 −159
Original line number Original line Diff line number Diff line
@@ -37,10 +37,8 @@
#include "log.h"
#include "log.h"
#include "list.h"
#include "list.h"


#define CMDLINE_PREFIX  "/dev"
#define SYSFS_PREFIX    "/sys"
#define SYSFS_PREFIX    "/sys"
#define FIRMWARE_DIR    "/etc/firmware"
#define FIRMWARE_DIR    "/etc/firmware"
#define MAX_QEMU_PERM 6


static int device_fd = -1;
static int device_fd = -1;


@@ -87,102 +85,21 @@ struct perms_ {
    unsigned int gid;
    unsigned int gid;
    unsigned short prefix;
    unsigned short prefix;
};
};
static struct perms_ devperms[] = {
    { "/dev/null",          0666,   AID_ROOT,       AID_ROOT,       0 },
    { "/dev/zero",          0666,   AID_ROOT,       AID_ROOT,       0 },
    { "/dev/full",          0666,   AID_ROOT,       AID_ROOT,       0 },
    { "/dev/ptmx",          0666,   AID_ROOT,       AID_ROOT,       0 },
    { "/dev/tty",           0666,   AID_ROOT,       AID_ROOT,       0 },
    { "/dev/random",        0666,   AID_ROOT,       AID_ROOT,       0 },
    { "/dev/urandom",       0666,   AID_ROOT,       AID_ROOT,       0 },
    { "/dev/ashmem",        0666,   AID_ROOT,       AID_ROOT,       0 },
    { "/dev/binder",        0666,   AID_ROOT,       AID_ROOT,       0 },

	    /* logger should be world writable (for logging) but not readable */
    { "/dev/log/",          0662,   AID_ROOT,       AID_LOG,        1 },

    /* the msm hw3d client device node is world writable/readable. */
    { "/dev/msm_hw3dc",     0666,   AID_ROOT,       AID_ROOT,       0 },

    /* gpu driver for adreno200 is globally accessible */
    { "/dev/kgsl",          0666,   AID_ROOT,       AID_ROOT,       0 },

        /* these should not be world writable */
    { "/dev/diag",          0660,   AID_RADIO,      AID_RADIO,        0 },
    { "/dev/diag_arm9",     0660,   AID_RADIO,      AID_RADIO,        0 },
    { "/dev/android_adb",   0660,   AID_ADB,        AID_ADB,        0 },
    { "/dev/android_adb_enable",   0660,   AID_ADB,        AID_ADB,        0 },
    { "/dev/ttyMSM0",       0600,   AID_BLUETOOTH,  AID_BLUETOOTH,  0 },
    { "/dev/ttyHS0",        0600,   AID_BLUETOOTH,  AID_BLUETOOTH,  0 },
    { "/dev/uinput",        0660,   AID_SYSTEM,     AID_BLUETOOTH,  0 },
    { "/dev/alarm",         0664,   AID_SYSTEM,     AID_RADIO,      0 },
    { "/dev/tty0",          0660,   AID_ROOT,       AID_SYSTEM,     0 },
    { "/dev/graphics/",     0660,   AID_ROOT,       AID_GRAPHICS,   1 },
    { "/dev/msm_hw3dm",     0660,   AID_SYSTEM,     AID_GRAPHICS,   0 },
    { "/dev/input/",        0660,   AID_ROOT,       AID_INPUT,      1 },
    { "/dev/eac",           0660,   AID_ROOT,       AID_AUDIO,      0 },
    { "/dev/cam",           0660,   AID_ROOT,       AID_CAMERA,     0 },
    { "/dev/pmem",          0660,   AID_SYSTEM,     AID_GRAPHICS,   0 },
    { "/dev/pmem_adsp",     0660,   AID_SYSTEM,     AID_AUDIO,      1 },
    { "/dev/pmem_camera",   0660,   AID_SYSTEM,     AID_CAMERA,     1 },
    { "/dev/oncrpc/",       0660,   AID_ROOT,       AID_SYSTEM,     1 },
    { "/dev/adsp/",         0660,   AID_SYSTEM,     AID_AUDIO,      1 },
    { "/dev/snd/",          0660,   AID_SYSTEM,     AID_AUDIO,      1 },
    { "/dev/mt9t013",       0660,   AID_SYSTEM,     AID_SYSTEM,     0 },
    { "/dev/msm_camera/",   0660,   AID_SYSTEM,     AID_SYSTEM,     1 },
    { "/dev/akm8976_daemon",0640,   AID_COMPASS,    AID_SYSTEM,     0 },
    { "/dev/akm8976_aot",   0640,   AID_COMPASS,    AID_SYSTEM,     0 },
    { "/dev/akm8973_daemon",0640,   AID_COMPASS,    AID_SYSTEM,     0 },
    { "/dev/akm8973_aot",   0640,   AID_COMPASS,    AID_SYSTEM,     0 },
    { "/dev/bma150",        0640,   AID_COMPASS,    AID_SYSTEM,     0 },
    { "/dev/cm3602",        0640,   AID_COMPASS,    AID_SYSTEM,     0 },
    { "/dev/akm8976_pffd",  0640,   AID_COMPASS,    AID_SYSTEM,     0 },
    { "/dev/lightsensor",   0640,   AID_SYSTEM,     AID_SYSTEM,     0 },
    { "/dev/msm_pcm_out",   0660,   AID_SYSTEM,     AID_AUDIO,      1 },
    { "/dev/msm_pcm_in",    0660,   AID_SYSTEM,     AID_AUDIO,      1 },
    { "/dev/msm_pcm_ctl",   0660,   AID_SYSTEM,     AID_AUDIO,      1 },
    { "/dev/msm_snd",       0660,   AID_SYSTEM,     AID_AUDIO,      1 },
    { "/dev/msm_mp3",       0660,   AID_SYSTEM,     AID_AUDIO,      1 },
    { "/dev/audience_a1026", 0660,   AID_SYSTEM,     AID_AUDIO,      1 },
    { "/dev/tpa2018d1",     0660,   AID_SYSTEM,     AID_AUDIO,      1 },
    { "/dev/msm_audpre",    0660,   AID_SYSTEM,     AID_AUDIO,      0 },
    { "/dev/msm_audio_ctl", 0660,   AID_SYSTEM,     AID_AUDIO,      0 },
    { "/dev/htc-acoustic",  0660,   AID_SYSTEM,     AID_AUDIO,      0 },
    { "/dev/vdec",          0660,   AID_SYSTEM,     AID_AUDIO,      0 },
    { "/dev/q6venc",        0660,   AID_SYSTEM,     AID_AUDIO,      0 },
    { "/dev/snd/dsp",       0660,   AID_SYSTEM,     AID_AUDIO,      0 },
    { "/dev/snd/dsp1",      0660,   AID_SYSTEM,     AID_AUDIO,      0 },
    { "/dev/snd/mixer",     0660,   AID_SYSTEM,     AID_AUDIO,      0 },
    { "/dev/smd0",          0640,   AID_RADIO,      AID_RADIO,      0 },
    { "/dev/qemu_trace",    0666,   AID_SYSTEM,     AID_SYSTEM,     0 },
    { "/dev/qmi",           0640,   AID_RADIO,      AID_RADIO,      0 },
    { "/dev/qmi0",          0640,   AID_RADIO,      AID_RADIO,      0 },
    { "/dev/qmi1",          0640,   AID_RADIO,      AID_RADIO,      0 },
    { "/dev/qmi2",          0640,   AID_RADIO,      AID_RADIO,      0 },
        /* CDMA radio interface MUX */
    { "/dev/ts0710mux",     0640,   AID_RADIO,      AID_RADIO,      1 },
    { "/dev/ppp",           0660,   AID_RADIO,      AID_VPN,        0 },
    { "/dev/tun",           0640,   AID_VPN,        AID_VPN,        0 },
    { NULL, 0, 0, 0, 0 },
};


/* devperms_partners list and perm_node are for hardware specific /dev entries */
struct perm_node {
struct perm_node {
    struct perms_ dp;
    struct perms_ dp;
    struct listnode plist;
    struct listnode plist;
};
};
list_declare(devperms_partners);
static list_declare(dev_perms);


/*
/*
 * Permission override when in emulator mode, must be parsed before
 * Permission override when in emulator mode, must be parsed before
 * system properties is initalized.
 * system properties is initalized.
 */
 */
static int qemu_perm_count;
int add_dev_perms(const char *name, mode_t perm, unsigned int uid,
static struct perms_ qemu_perms[MAX_QEMU_PERM + 1];

int add_devperms_partners(const char *name, mode_t perm, unsigned int uid,
                  unsigned int gid, unsigned short prefix) {
                  unsigned int gid, unsigned short prefix) {
    int size;
    int size;
    char *tmp = 0;
    struct perm_node *node = malloc(sizeof (struct perm_node));
    struct perm_node *node = malloc(sizeof (struct perm_node));
    if (!node)
    if (!node)
        return -ENOMEM;
        return -ENOMEM;
@@ -197,51 +114,10 @@ int add_devperms_partners(const char *name, mode_t perm, unsigned int uid,
    node->dp.gid = gid;
    node->dp.gid = gid;
    node->dp.prefix = prefix;
    node->dp.prefix = prefix;


    list_add_tail(&devperms_partners, &node->plist);
    list_add_tail(&dev_perms, &node->plist);
    return 0;
    return 0;
}
}


void qemu_init(void) {
    qemu_perm_count = 0;
    memset(&qemu_perms, 0, sizeof(qemu_perms));
}

static int qemu_perm(const char* name, mode_t perm, unsigned int uid,
                         unsigned int gid, unsigned short prefix)
{
    char *buf;
    if (qemu_perm_count == MAX_QEMU_PERM)
        return -ENOSPC;

    buf = malloc(strlen(name) + 1);
    if (!buf)
        return -errno;

    strlcpy(buf, name, strlen(name) + 1);
    qemu_perms[qemu_perm_count].name = buf;
    qemu_perms[qemu_perm_count].perm = perm;
    qemu_perms[qemu_perm_count].uid = uid;
    qemu_perms[qemu_perm_count].gid = gid;
    qemu_perms[qemu_perm_count].prefix = prefix;

    qemu_perm_count++;
    return 0;
}

/* Permission overrides for emulator that are parsed from /proc/cmdline. */
void qemu_cmdline(const char* name, const char *value)
{
    char *buf;
    if (!strcmp(name, "android.ril")) {
        /* cmd line params currently assume /dev/ prefix */
        if (asprintf(&buf, CMDLINE_PREFIX"/%s", value) == -1) {
            return;
        }
        INFO("nani- buf:: %s\n", buf);
        qemu_perm(buf, 0660, AID_RADIO, AID_ROOT, 0);
    }
}

static int get_device_perm_inner(struct perms_ *perms, const char *path,
static int get_device_perm_inner(struct perms_ *perms, const char *path,
                                    unsigned *uid, unsigned *gid, mode_t *perm)
                                    unsigned *uid, unsigned *gid, mode_t *perm)
{
{
@@ -267,18 +143,14 @@ static int get_device_perm_inner(struct perms_ *perms, const char *path,
static mode_t get_device_perm(const char *path, unsigned *uid, unsigned *gid)
static mode_t get_device_perm(const char *path, unsigned *uid, unsigned *gid)
{
{
    mode_t perm;
    mode_t perm;

    if (get_device_perm_inner(qemu_perms, path, uid, gid, &perm) == 0) {
        return perm;
    } else if (get_device_perm_inner(devperms, path, uid, gid, &perm) == 0) {
        return perm;
    } else {
    struct listnode *node;
    struct listnode *node;
    struct perm_node *perm_node;
    struct perm_node *perm_node;
    struct perms_ *dp;
    struct perms_ *dp;


        /* Check partners list. */
    /* search the perms list in reverse so that ueventd.$hardware can
        list_for_each(node, &devperms_partners) {
     * override ueventd.rc
     */
    list_for_each_reverse(node, &dev_perms) {
        perm_node = node_to_item(node, struct perm_node, plist);
        perm_node = node_to_item(node, struct perm_node, plist);
        dp = &perm_node->dp;
        dp = &perm_node->dp;


@@ -289,7 +161,6 @@ static mode_t get_device_perm(const char *path, unsigned *uid, unsigned *gid)
            if (strcmp(path, dp->name))
            if (strcmp(path, dp->name))
                continue;
                continue;
        }
        }
            /* Found perm in partner list. */
        *uid = dp->uid;
        *uid = dp->uid;
        *gid = dp->gid;
        *gid = dp->gid;
        return dp->perm;
        return dp->perm;
@@ -299,7 +170,6 @@ static mode_t get_device_perm(const char *path, unsigned *uid, unsigned *gid)
    *gid = 0;
    *gid = 0;
    return 0600;
    return 0600;
}
}
}


static void make_device(const char *path, int block, int major, int minor)
static void make_device(const char *path, int block, int major, int minor)
{
{
+3 −0
Original line number Original line Diff line number Diff line
@@ -35,6 +35,9 @@ struct listnode
#define list_for_each(node, list) \
#define list_for_each(node, list) \
    for (node = (list)->next; node != (list); node = node->next)
    for (node = (list)->next; node != (list); node = node->next)


#define list_for_each_reverse(node, list) \
    for (node = (list)->prev; node != (list); node = node->prev)

void list_init(struct listnode *list);
void list_init(struct listnode *list);
void list_add_tail(struct listnode *list, struct listnode *item);
void list_add_tail(struct listnode *list, struct listnode *item);
void list_remove(struct listnode *item);
void list_remove(struct listnode *item);
+91 −0
Original line number Original line Diff line number Diff line
@@ -15,22 +15,40 @@
 */
 */


#include <poll.h>
#include <poll.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <private/android_filesystem_config.h>


#include "ueventd.h"
#include "ueventd.h"
#include "log.h"
#include "log.h"
#include "util.h"
#include "util.h"
#include "devices.h"
#include "devices.h"
#include "ueventd_parser.h"

static char hardware[32];
static unsigned revision = 0;


int ueventd_main(int argc, char **argv)
int ueventd_main(int argc, char **argv)
{
{
    struct pollfd ufd;
    struct pollfd ufd;
    int nr;
    int nr;
    char tmp[32];


    open_devnull_stdio();
    open_devnull_stdio();
    log_init();
    log_init();


    INFO("starting ueventd\n");
    INFO("starting ueventd\n");


    get_hardware_name(hardware, &revision);

    ueventd_parse_config_file("/ueventd.rc");

    snprintf(tmp, sizeof(tmp), "/ueventd.%s.rc", hardware);
    ueventd_parse_config_file(tmp);

    device_init();
    device_init();


    ufd.events = POLLIN;
    ufd.events = POLLIN;
@@ -45,3 +63,76 @@ int ueventd_main(int argc, char **argv)
               handle_device_fd();
               handle_device_fd();
    }
    }
}
}

static int get_android_id(const char *id)
{
    unsigned int i;
    for (i = 0; i < ARRAY_SIZE(android_ids); i++)
        if (!strcmp(id, android_ids[i].name))
            return android_ids[i].aid;
    return 0;
}

void set_device_permission(int nargs, char **args)
{
    char *name;
    mode_t perm;
    uid_t uid;
    gid_t gid;
    int prefix = 0;
    char *endptr;
    int ret;
    char *tmp = 0;

    if (nargs == 0)
        return;

    if (args[0][0] == '#')
        return;

    if (nargs != 4) {
        ERROR("invalid line ueventd.rc line for '%s'\n", args[0]);
        return;
    }

    name = args[0];
    /* If path starts with mtd@ lookup the mount number. */
    if (!strncmp(name, "mtd@", 4)) {
        int n = mtd_name_to_number(name + 4);
        if (n >= 0)
            asprintf(&tmp, "/dev/mtd/mtd%d", n);
        name = tmp;
    } else {
        int len = strlen(name);
        if (name[len - 1] == '*') {
            prefix = 1;
            name[len - 1] = '\0';
        }
    }

    perm = strtol(args[1], &endptr, 8);
    if (!endptr || *endptr != '\0') {
        ERROR("invalid mode '%s'\n", args[1]);
        free(tmp);
        return;
    }

    ret = get_android_id(args[2]);
    if (ret < 0) {
        ERROR("invalid uid '%s'\n", args[2]);
        free(tmp);
        return;
    }
    uid = ret;

    ret = get_android_id(args[3]);
    if (ret < 0) {
        ERROR("invalid gid '%s'\n", args[3]);
        free(tmp);
        return;
    }
    gid = ret;

    add_dev_perms(name, perm, uid, gid, prefix);
    free(tmp);
}

init/ueventd_parser.c

0 → 100644
+76 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <string.h>

#include "ueventd_parser.h"
#include "parser.h"
#include "log.h"
#include "list.h"
#include "util.h"

static void parse_line_device(struct parse_state *state, int nargs, char **args);

static void parse_config(const char *fn, char *s)
{
    struct parse_state state;
    char *args[UEVENTD_PARSER_MAXARGS];
    int nargs;
    nargs = 0;
    state.filename = fn;
    state.line = 1;
    state.ptr = s;
    state.nexttoken = 0;
    state.parse_line = parse_line_device;
    for (;;) {
        int token = next_token(&state);
        switch (token) {
        case T_EOF:
            state.parse_line(&state, 0, 0);
            return;
        case T_NEWLINE:
            if (nargs) {
                state.parse_line(&state, nargs, args);
                nargs = 0;
            }
            break;
        case T_TEXT:
            if (nargs < UEVENTD_PARSER_MAXARGS) {
                args[nargs++] = state.text;
            }
            break;
        }
    }
}

int ueventd_parse_config_file(const char *fn)
{
    char *data;
    data = read_file(fn, 0);
    if (!data) return -1;

    parse_config(fn, data);
    DUMP();
    return 0;
}

static void parse_line_device(struct parse_state* state, int nargs, char **args)
{
    set_device_permission(nargs, args);
}
Loading