Ejemplo n.º 1
0
/*
 * switchUser - Switches UID to radio, preserving CAP_NET_ADMIN capabilities.
 * Our group, cache, was set by init.
 */
void switchUser() {
    char debuggable[PROP_VALUE_MAX];

    prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
    setuid(AID_RADIO);

    struct __user_cap_header_struct header;
    memset(&header, 0, sizeof(header));
    header.version = _LINUX_CAPABILITY_VERSION_3;
    header.pid = 0;

    struct __user_cap_data_struct data[2];
    memset(&data, 0, sizeof(data));

    data[CAP_TO_INDEX(CAP_NET_ADMIN)].effective |= CAP_TO_MASK(CAP_NET_ADMIN);
    data[CAP_TO_INDEX(CAP_NET_ADMIN)].permitted |= CAP_TO_MASK(CAP_NET_ADMIN);

    data[CAP_TO_INDEX(CAP_NET_RAW)].effective |= CAP_TO_MASK(CAP_NET_RAW);
    data[CAP_TO_INDEX(CAP_NET_RAW)].permitted |= CAP_TO_MASK(CAP_NET_RAW);

    if (capset(&header, &data[0]) == -1) {
        RLOGE("capset failed: %s", strerror(errno));
        exit(EXIT_FAILURE);
    }

    /*
     * Debuggable build only:
     * Set DUMPABLE that was cleared by setuid() to have tombstone on RIL crash
     */
    property_get("ro.debuggable", debuggable, "0");
    if (strcmp(debuggable, "1") == 0) {
        prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
    }
}
Ejemplo n.º 2
0
Archivo: oor.c Proyecto: biels/oor
int
check_capabilities()
{
    struct __user_cap_header_struct cap_header;
    struct __user_cap_data_struct cap_data;

    cap_header.pid = getpid();
    cap_header.version = _LINUX_CAPABILITY_VERSION;

    /* Check if oor is already running: /var/run/oor.pid */

    if (capget(&cap_header, &cap_data) < 0)
    {
        OOR_LOG(LCRIT, "Could not retrieve capabilities");
        return BAD;
    }

    OOR_LOG(LWRN, "Rights: Effective [%u] Permitted  [%u]", cap_data.effective, cap_data.permitted);

    /* check for capabilities */
    if(  (cap_data.effective & CAP_TO_MASK(CAP_NET_ADMIN)) && (cap_data.effective & CAP_TO_MASK(CAP_NET_RAW))  )  {
    }
    else {
        OOR_LOG(LCRIT, "Insufficient rights, you need CAP_NET_ADMIN and CAP_NET_RAW. See README");
        return BAD;
    }

    return GOOD;
}
Ejemplo n.º 3
0
static void drop_capabilities_bounding_set_if_needed(struct minijail *j) {
    if (ALLOW_ADBD_ROOT || is_device_unlocked()) {
        if (__android_log_is_debuggable()) {
            return;
        }
    }
    minijail_capbset_drop(j, CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID));
}
Ejemplo n.º 4
0
static void lower_my_caps(void)
{
	struct __user_cap_header_struct caphdr = {
		.version = _LINUX_CAPABILITY_VERSION
	};
	cap_user_data_t capdata;
	ssize_t capstrlen = 0;
	cap_t my_cap;
	char *cap_text;
	int capsz;

	(void) capget(&caphdr, NULL);
	switch (caphdr.version) {
	case _LINUX_CAPABILITY_VERSION_1:
		capsz = _LINUX_CAPABILITY_U32S_1;
		break;
	case _LINUX_CAPABILITY_VERSION_2:
		capsz = _LINUX_CAPABILITY_U32S_2;
		break;
	default:
		abort(); /* can't happen */
	}

	capdata = gsh_calloc(capsz, sizeof(struct __user_cap_data_struct));
	caphdr.pid = getpid();

	if (capget(&caphdr, capdata) != 0)
		LogFatal(COMPONENT_INIT,
			 "Failed to query capabilities for process, errno=%u",
			 errno);

	/* Set the capability bitmask to remove CAP_SYS_RESOURCE */
	if (capdata->effective & CAP_TO_MASK(CAP_SYS_RESOURCE))
		capdata->effective &= ~CAP_TO_MASK(CAP_SYS_RESOURCE);

	if (capdata->permitted & CAP_TO_MASK(CAP_SYS_RESOURCE))
		capdata->permitted &= ~CAP_TO_MASK(CAP_SYS_RESOURCE);

	if (capdata->inheritable & CAP_TO_MASK(CAP_SYS_RESOURCE))
		capdata->inheritable &= ~CAP_TO_MASK(CAP_SYS_RESOURCE);

	if (capset(&caphdr, capdata) != 0)
		LogFatal(COMPONENT_INIT,
			 "Failed to set capabilities for process, errno=%u",
			 errno);
	else
		LogEvent(COMPONENT_INIT,
			 "CAP_SYS_RESOURCE was successfully removed for proper quota management in FSAL");

	/* Print newly set capabilities (same as what CLI "getpcaps" displays */
	my_cap = cap_get_proc();
	cap_text = cap_to_text(my_cap, &capstrlen);
	LogEvent(COMPONENT_INIT, "currenty set capabilities are: %s",
		 cap_text);
	cap_free(cap_text);
	cap_free(my_cap);
	gsh_free(capdata);
}
Ejemplo n.º 5
0
static int badness(struct task_struct *p)
{
	int points, cpu_time, run_time;

	if (!p->mm)
		return 0;

	if (p->flags & PF_MEMDIE)
		return 0;

	/*
	 * The memory size of the process is the basis for the badness.
	 */
	points = p->mm->total_vm;

	/*
	 * CPU time is in seconds and run time is in minutes. There is no
	 * particular reason for this other than that it turned out to work
	 * very well in practice. This is not safe against jiffie wraps
	 * but we don't care _that_ much...
	 */
	cpu_time = (p->times.tms_utime + p->times.tms_stime) >> (SHIFT_HZ + 3);
	run_time = (jiffies - p->start_time) >> (SHIFT_HZ + 10);

	points /= int_sqrt(cpu_time);
	points /= int_sqrt(int_sqrt(run_time));

	/*
	 * Niced processes are most likely less important, so double
	 * their badness points.
	 */
	if (p->nice > 0)
		points *= 2;

	/*
	 * Superuser processes are usually more important, so we make it
	 * less likely that we kill those.
	 */
	if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_ADMIN) ||
				p->uid == 0 || p->euid == 0)
		points /= 4;

	/*
	 * We don't want to kill a process with direct hardware access.
	 * Not only could that mess up the hardware, but usually users
	 * tend to only have this flag set on applications they think
	 * of as important.
	 */
	if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO))
		points /= 4;
#ifdef DEBUG
	printk(KERN_DEBUG "OOMkill: task %d (%s) got %d points\n",
	p->pid, p->comm, points);
#endif
	return points;
}
Ejemplo n.º 6
0
static void drop_capabilities_bounding_set_if_needed(struct minijail *j) {
#if defined(ALLOW_ADBD_ROOT)
    char value[PROPERTY_VALUE_MAX];
    property_get("ro.debuggable", value, "");
    if (strcmp(value, "1") == 0) {
        return;
    }
#endif
    minijail_capbset_drop(j, CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID));
}
Ejemplo n.º 7
0
static int drop_privs() {
    struct sched_param param;
    memset(&param, 0, sizeof(param));

    if (set_sched_policy(0, SP_BACKGROUND) < 0) {
        return -1;
    }

    if (sched_setscheduler((pid_t) 0, SCHED_BATCH, &param) < 0) {
        return -1;
    }

    if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) {
        return -1;
    }

    if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
        return -1;
    }

    gid_t groups[] = { AID_READPROC };

    if (setgroups(sizeof(groups) / sizeof(groups[0]), groups) == -1) {
        return -1;
    }

    if (setgid(AID_LOGD) != 0) {
        return -1;
    }

    if (setuid(AID_LOGD) != 0) {
        return -1;
    }

    struct __user_cap_header_struct capheader;
    struct __user_cap_data_struct capdata[2];
    memset(&capheader, 0, sizeof(capheader));
    memset(&capdata, 0, sizeof(capdata));
    capheader.version = _LINUX_CAPABILITY_VERSION_3;
    capheader.pid = 0;

    capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG);
    capdata[CAP_TO_INDEX(CAP_AUDIT_CONTROL)].permitted |= CAP_TO_MASK(CAP_AUDIT_CONTROL);

    capdata[0].effective = capdata[0].permitted;
    capdata[1].effective = capdata[1].permitted;
    capdata[0].inheritable = 0;
    capdata[1].inheritable = 0;

    if (capset(&capheader, &capdata[0]) < 0) {
        return -1;
    }

    return 0;
}
Ejemplo n.º 8
0
/*
 *  Check for superuser privileges
 */
int check_capabilities()
{
    struct __user_cap_header_struct cap_header;
    struct __user_cap_data_struct cap_data;

    cap_header.pid = getpid();
    cap_header.version = _LINUX_CAPABILITY_VERSION;
    if (capget(&cap_header, &cap_data) < 0)
    {
        lispd_log_msg(LISP_LOG_ERR, "Could not retrieve capabilities");
        return BAD;
    }

    lispd_log_msg(LISP_LOG_DEBUG_1, "Rights: Effective [%u] Permitted  [%u]", cap_data.effective, cap_data.permitted);

    /* check for capabilities */
    if(  (cap_data.effective & CAP_TO_MASK(CAP_NET_ADMIN)) && (cap_data.effective & CAP_TO_MASK(CAP_NET_RAW))  )  {
    }
    else {
        lispd_log_msg(LISP_LOG_CRIT, "Insufficient rights, you need CAP_NET_ADMIN and CAP_NET_RAW. See README");
        return BAD;
    }

    /* Clear all but the capability to bind to low ports */
    cap_data.effective = CAP_TO_MASK(CAP_NET_ADMIN) | CAP_TO_MASK(CAP_NET_RAW);
    cap_data.permitted = cap_data.effective ;
    cap_data.inheritable = 0;
    if (capset(&cap_header, &cap_data) < 0) {
        lispd_log_msg(LISP_LOG_WARNING, "Could not drop privileges");
        return BAD;
    }

    /* Tell kernel not clear permitted capabilities when dropping root */
    if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
        lispd_log_msg(LISP_LOG_WARNING, "Sprctl(PR_SET_KEEPCAPS) failed");
        return GOOD;
    }

    /* Now we can drop privilege, drop effective rights even with KEEPCAPS */
    if (setuid(getuid()) < 0) {
        lispd_log_msg(LISP_LOG_WARNING, "Could not drop privileges");
    }

    /* that's why we need to set effective rights equal to permitted rights */
    if (capset(&cap_header, &cap_data) < 0)
    {
        lispd_log_msg(LISP_LOG_CRIT, "Could not set effective rights to permitted ones");
        return (BAD);
    }

    lispd_log_msg(LISP_LOG_DEBUG_1, "Rights: Effective [%u] Permitted  [%u]", cap_data.effective, cap_data.permitted);

    return GOOD;
}
static bool set_capabilities(void)
{
#if defined(ANDROID)
	struct __user_cap_header_struct header;
	struct __user_cap_data_struct cap;

	header.version = _LINUX_CAPABILITY_VERSION;
	header.pid = 0;

	/*
	 * CAP_NET_ADMIN: Allow use of MGMT interface
	 * CAP_NET_BIND_SERVICE: Allow use of privileged PSM
	 * CAP_NET_RAW: Allow use of bnep ioctl calls
	 */
	cap.effective = cap.permitted =
		CAP_TO_MASK(CAP_NET_RAW) |
		CAP_TO_MASK(CAP_NET_ADMIN) |
		CAP_TO_MASK(CAP_NET_BIND_SERVICE);
	cap.inheritable = 0;

	/* don't clear capabilities when dropping root */
	if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
		error("%s: prctl(): %s", __func__, strerror(errno));
		return false;
	}

	/* Android bluetooth user UID=1002 */
	if (setuid(1002) < 0) {
		error("%s: setuid(): %s", __func__, strerror(errno));
		return false;
	}

	/* TODO: Move to cap_set_proc once bionic support it */
	if (capset(&header, &cap) < 0) {
		error("%s: capset(): %s", __func__, strerror(errno));
		return false;
	}

	/* TODO: Move to cap_get_proc once bionic support it */
	if (capget(&header, &cap) < 0) {
		error("%s: capget(): %s", __func__, strerror(errno));
		return false;
	}

	DBG("Caps: eff: 0x%x, perm: 0x%x, inh: 0x%x", cap.effective,
					cap.permitted, cap.inheritable);

#endif
	return true;
}
Ejemplo n.º 10
0
int SetPermission(int flag)
{
	int errno = 0;
	struct __user_cap_header_struct header;
	header.version = _LINUX_CAPABILITY_VERSION_3;
	header.pid = (int)ISyscall(__NR_gettid);

	printf("version: 0x%08x\n", header.version);

	unsigned int data[3];
	memset(data, 0, sizeof(data));
	if (ISyscall(__NR_capget, &header, &data)) {
		printf("capget failed!\n");
		return 0;
	}

	//memset(data, 0, sizeof(data));
	data[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag);
	if ((errno = ISyscall(__NR_capset, &header, &data))) {
		printf("capset failed! [%d]\n", errno);
		printf("version: 0x%08x\n", header.version);
		return 0;
	}

	printf("0x%08x\n", data[0]);
	printf("0x%08x\n", data[1]);
	printf("0x%08x\n", data[2]);
	return 1;
}
Ejemplo n.º 11
0
/* audit interface for capability */
void kse_cap_audit(struct task_struct *tsk,
			int cap, int result)
{
	int sclass, request;
	struct common_audit_data ad;

	if (kse_noyaudit == 1 && result == 0)
		return;

	COMMON_AUDIT_DATA_INIT(&ad, CAP);
	ad.tsk = tsk;
	ad.u.cap = cap;
	request = CAP_TO_MASK(cap);
	switch (CAP_TO_INDEX(cap)) {
	case 0:
		sclass = SECCLASS_CAPABILITY;
		break;
	case 1:
		sclass = SECCLASS_CAPABILITY2;
		break;
	default:
		printk(KERN_ERR
		       "KUXSE:  out of range capability %d\n", cap);
		BUG();
	}

	//kse_audit(task_cred_xxx(tsk, security), NULL, NULL, 0, sclass,
			//request, result, &ad);
	kse_audit(tsk->security, NULL, NULL, 0, sclass, request, result, &ad);
}
Ejemplo n.º 12
0
static int drop_privs() {
    struct sched_param param;
    memset(&param, 0, sizeof(param));

    if (sched_setscheduler((pid_t) 0, SCHED_BATCH, &param) < 0) {
        return -1;
    }

    if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
        return -1;
    }

    if (setgid(AID_LOGD) != 0) {
        return -1;
    }

    if (setuid(AID_LOGD) != 0) {
        return -1;
    }

    struct __user_cap_header_struct capheader;
    struct __user_cap_data_struct capdata[2];
    memset(&capheader, 0, sizeof(capheader));
    memset(&capdata, 0, sizeof(capdata));
    capheader.version = _LINUX_CAPABILITY_VERSION_3;
    capheader.pid = 0;

    capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG);
    capdata[CAP_TO_INDEX(CAP_AUDIT_CONTROL)].permitted |= CAP_TO_MASK(CAP_AUDIT_CONTROL);

    capdata[0].effective = capdata[0].permitted;
    capdata[1].effective = capdata[1].permitted;
    capdata[0].inheritable = 0;
    capdata[1].inheritable = 0;

    if (capset(&capheader, &capdata[0]) < 0) {
        return -1;
    }

    return 0;
}
Ejemplo n.º 13
0
static int drop_privs(void) {
    struct __user_cap_header_struct capheader;
    struct __user_cap_data_struct capdata[2];

    if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
        return -1;
    }

    /*
     * ensure we're running as the system user
     */
    if (setgid(AID_SYSTEM) != 0) {
        return -1;
    }

    if (setuid(AID_SYSTEM) != 0) {
        return -1;
    }

    /*
     * drop all capabilities except SYS_RAWIO
     */
    memset(&capheader, 0, sizeof(capheader));
    memset(&capdata, 0, sizeof(capdata));
    capheader.version = _LINUX_CAPABILITY_VERSION_3;
    capheader.pid = 0;

    capdata[CAP_TO_INDEX(CAP_SYS_RAWIO)].permitted = CAP_TO_MASK(CAP_SYS_RAWIO);
    capdata[CAP_TO_INDEX(CAP_SYS_RAWIO)].effective = CAP_TO_MASK(CAP_SYS_RAWIO);

    if (capset(&capheader, &capdata[0]) < 0) {
        return -1;
    }

    /* no-execute for user, no access for group and other */
    umask(S_IXUSR | S_IRWXG | S_IRWXO);

    return 0;
}
Ejemplo n.º 14
0
static void drop_privileges() {
    if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
        ALOGE("prctl(PR_SET_KEEPCAPS) failed: %s\n", strerror(errno));
        exit(1);
    }

    if (setgid(AID_INSTALL) < 0) {
        ALOGE("setgid() can't drop privileges; exiting.\n");
        exit(1);
    }

    if (setuid(AID_INSTALL) < 0) {
        ALOGE("setuid() can't drop privileges; exiting.\n");
        exit(1);
    }

    struct __user_cap_header_struct capheader;
    struct __user_cap_data_struct capdata[2];
    memset(&capheader, 0, sizeof(capheader));
    memset(&capdata, 0, sizeof(capdata));
    capheader.version = _LINUX_CAPABILITY_VERSION_3;
    capheader.pid = 0;

    capdata[CAP_TO_INDEX(CAP_DAC_OVERRIDE)].permitted |= CAP_TO_MASK(CAP_DAC_OVERRIDE);
    capdata[CAP_TO_INDEX(CAP_CHOWN)].permitted        |= CAP_TO_MASK(CAP_CHOWN);
    capdata[CAP_TO_INDEX(CAP_SETUID)].permitted       |= CAP_TO_MASK(CAP_SETUID);
    capdata[CAP_TO_INDEX(CAP_SETGID)].permitted       |= CAP_TO_MASK(CAP_SETGID);

    capdata[0].effective = capdata[0].permitted;
    capdata[1].effective = capdata[1].permitted;
    capdata[0].inheritable = 0;
    capdata[1].inheritable = 0;

    if (capset(&capheader, &capdata[0]) < 0) {
        ALOGE("capset failed: %s\n", strerror(errno));
        exit(1);
    }
}
Ejemplo n.º 15
0
/*
 * switchUser - Switches UID to radio, preserving CAP_NET_ADMIN capabilities.
 * Our group, cache, was set by init.
 */
void switchUser() {
    prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
    setuid(AID_RADIO);

    struct __user_cap_header_struct header;
    memset(&header, 0, sizeof(header));
    header.version = _LINUX_CAPABILITY_VERSION_3;
    header.pid = 0;

    struct __user_cap_data_struct data[2];
    memset(&data, 0, sizeof(data));

    data[CAP_TO_INDEX(CAP_NET_ADMIN)].effective |= CAP_TO_MASK(CAP_NET_ADMIN);
    data[CAP_TO_INDEX(CAP_NET_ADMIN)].permitted |= CAP_TO_MASK(CAP_NET_ADMIN);

    data[CAP_TO_INDEX(CAP_NET_RAW)].effective |= CAP_TO_MASK(CAP_NET_RAW);
    data[CAP_TO_INDEX(CAP_NET_RAW)].permitted |= CAP_TO_MASK(CAP_NET_RAW);

    if (capset(&header, &data[0]) == -1) {
        RLOGE("capset failed: %s", strerror(errno));
        exit(EXIT_FAILURE);
    }
}
Ejemplo n.º 16
0
static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
        size_t sz;

        assert(c);
        assert(capability >= 0);
        assert(c->capability);

        if ((unsigned) capability > cap_last_cap())
                return 0;

        sz = DIV_ROUND_UP(cap_last_cap(), 32U);

        return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability));
}
Ejemplo n.º 17
0
static void set_capabilities(void)
{
#if defined(ANDROID)
	struct __user_cap_header_struct header;
	struct __user_cap_data_struct cap;

	header.version = _LINUX_CAPABILITY_VERSION;
	header.pid = 0;

	/*
	 * CAP_NET_RAW: for snooping
	 * CAP_DAC_READ_SEARCH: override path search permissions
	 */
	cap.effective = cap.permitted =
		CAP_TO_MASK(CAP_NET_RAW) |
		CAP_TO_MASK(CAP_DAC_READ_SEARCH);
	cap.inheritable = 0;

	/* TODO: Move to cap_set_proc once bionic support it */
	if (capset(&header, &cap) < 0)
		exit(EXIT_FAILURE);
#endif
}
Ejemplo n.º 18
0
/*
 * Look at the environment for some special options.
 */
static void supR3GrabOptions(void)
{
    const char *pszOpt;

# ifdef RT_OS_LINUX
    g_uCaps = 0;

    /*
     * Do _not_ perform any capability-related system calls for root processes
     * (leaving g_uCaps at 0).
     * (Hint: getuid gets the real user id, not the effective.)
     */
    if (getuid() != 0)
    {
        /*
         * CAP_NET_RAW.
         * Default: enabled.
         * Can be disabled with 'export VBOX_HARD_CAP_NET_RAW=0'.
         */
        pszOpt = getenv("VBOX_HARD_CAP_NET_RAW");
        if (   !pszOpt
            || memcmp(pszOpt, "0", sizeof("0")) != 0)
            g_uCaps = CAP_TO_MASK(CAP_NET_RAW);

        /*
         * CAP_NET_BIND_SERVICE.
         * Default: disabled.
         * Can be enabled with 'export VBOX_HARD_CAP_NET_BIND_SERVICE=1'.
         */
        pszOpt = getenv("VBOX_HARD_CAP_NET_BIND_SERVICE");
        if (   pszOpt
            && memcmp(pszOpt, "0", sizeof("0")) != 0)
            g_uCaps |= CAP_TO_MASK(CAP_NET_BIND_SERVICE);
    }
# endif
}
Ejemplo n.º 19
0
/**
 * We must be careful though to never send SIGKILL a process with
 * CAP_SYS_RAW_IO set, send SIGTERM instead (but it's unlikely that
 * we select a process with CAP_SYS_RAW_IO set).
 */
void oom_kill_task(struct task_struct *p)
{
	printk(KERN_ERR "Out of Memory: Killed process %d (%s).\n", p->pid, p->comm);

	/*
	 * We give our sacrificial lamb high priority and access to
	 * all the memory it needs. That way it should be able to
	 * exit() and clear out its resources quickly...
	 */
	p->counter = 5 * HZ;

	/* This process has hardware access, be more careful. */
	if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO)) {
		force_sig(SIGTERM, p);
	} else {
		force_sig(SIGKILL, p);
	}
}
Ejemplo n.º 20
0
/** Drop all capabilities except for the mentioned ones */
void dropCapabilities(int8_t keep[]) {
    struct __user_cap_header_struct header;
    struct __user_cap_data_struct cap[2];
    memset(&header, 0, sizeof(header));
    memset(&cap, 0, sizeof(cap));
    header.version = _LINUX_CAPABILITY_VERSION_3;
    header.pid = 0;

    if (keep != NULL) {
      for (int i = 0; keep[i] >= 0; i++) {
        cap[CAP_TO_INDEX(keep[i])].permitted |= CAP_TO_MASK(keep[i]);
      }
      cap[0].effective = cap[0].inheritable = cap[0].permitted;
      cap[1].effective = cap[1].inheritable = cap[1].permitted;
    }

    capset(&header, &cap[0]);
}
Ejemplo n.º 21
0
void
linux_cap_change(int on, ...)
{
  struct __user_cap_header_struct x;
  struct __user_cap_data_struct s[3] = {};

  x.version = _LINUX_CAPABILITY_VERSION_3;
  x.pid = syscall(SYS_gettid);

  if(syscall(SYS_capget, &x, s)) {
    perror("capget");
    exit(1);
  }

  va_list ap;
  va_start(ap, on);

  int cap;
  while((cap = va_arg(ap, int)) != -1) {

    if(!cap_valid(cap)) {
      fprintf(stderr, "cap %d is not valid\n", cap);
      exit(1);
    }

    if(on) {
      s[CAP_TO_INDEX(cap)].effective |= CAP_TO_MASK(cap);
    } else {
      s[CAP_TO_INDEX(cap)].effective &= ~CAP_TO_MASK(cap);
    }
  }

  if(syscall(SYS_capset, &x, s)) {
    perror("capset");
    exit(1);
  }
}
Ejemplo n.º 22
0
int adb_main(int is_daemon, int server_port)
{
#if !ADB_HOST
    int port;
    char value[PROPERTY_VALUE_MAX];

    umask(000);
#endif

    atexit(adb_cleanup);
#ifdef HAVE_WIN32_PROC
    SetConsoleCtrlHandler( ctrlc_handler, TRUE );
#elif defined(HAVE_FORKEXEC)
    // No SIGCHLD. Let the service subproc handle its children.
    signal(SIGPIPE, SIG_IGN);
#endif

    init_transport_registration();

#if ADB_HOST
    HOST = 1;
    usb_vendors_init();
    usb_init();
    local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
    adb_auth_init();

    char local_name[30];
    build_local_name(local_name, sizeof(local_name), server_port);
    if(install_listener(local_name, "*smartsocket*", NULL, 0)) {
        exit(1);
    }
#else
    property_get("ro.adb.secure", value, "0");
    auth_enabled = !strcmp(value, "1");
    if (auth_enabled)
        adb_auth_init();

    // Our external storage path may be different than apps, since
    // we aren't able to bind mount after dropping root.
    const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE");
    if (NULL != adb_external_storage) {
        setenv("EXTERNAL_STORAGE", adb_external_storage, 1);
    } else {
        D("Warning: ADB_EXTERNAL_STORAGE is not set.  Leaving EXTERNAL_STORAGE"
          " unchanged.\n");
    }

    /* don't listen on a port (default 5037) if running in secure mode */
    /* don't run as root if we are running in secure mode */
    if (should_drop_privileges()) {
        struct __user_cap_header_struct header;
        struct __user_cap_data_struct cap[2];

        if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {
            exit(1);
        }

        /* add extra groups:
        ** AID_ADB to access the USB driver
        ** AID_LOG to read system logs (adb logcat)
        ** AID_INPUT to diagnose input issues (getevent)
        ** AID_INET to diagnose network issues (netcfg, ping)
        ** AID_GRAPHICS to access the frame buffer
        ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
        ** AID_SDCARD_R to allow reading from the SD card
        ** AID_SDCARD_RW to allow writing to the SD card
        ** AID_MOUNT to allow unmounting the SD card before rebooting
        ** AID_NET_BW_STATS to read out qtaguid statistics
        */
        gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,
                           AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW,
                           AID_MOUNT, AID_NET_BW_STATS };
        if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
            exit(1);
        }

        /* then switch user and group to "shell" */
        if (setgid(AID_SHELL) != 0) {
            exit(1);
        }
        if (setuid(AID_SHELL) != 0) {
            exit(1);
        }

        memset(&header, 0, sizeof(header));
        memset(cap, 0, sizeof(cap));

        /* set CAP_SYS_BOOT capability, so "adb reboot" will succeed */
        header.version = _LINUX_CAPABILITY_VERSION_3;
        header.pid = 0;
        cap[CAP_TO_INDEX(CAP_SYS_BOOT)].effective |= CAP_TO_MASK(CAP_SYS_BOOT);
        cap[CAP_TO_INDEX(CAP_SYS_BOOT)].permitted |= CAP_TO_MASK(CAP_SYS_BOOT);
        capset(&header, cap);

        D("Local port disabled\n");
    } else {
        char local_name[30];
        build_local_name(local_name, sizeof(local_name), server_port);
        if(install_listener(local_name, "*smartsocket*", NULL, 0)) {
            exit(1);
        }
    }

    int usb = 0;
    if (access(USB_ADB_PATH, F_OK) == 0 || access(USB_FFS_ADB_EP0, F_OK) == 0) {
        // listen on USB
        usb_init();
        usb = 1;
    }

    // If one of these properties is set, also listen on that port
    // If one of the properties isn't set and we couldn't listen on usb,
    // listen on the default port.
    property_get("service.adb.tcp.port", value, "");
    if (!value[0]) {
        property_get("persist.adb.tcp.port", value, "");
    }
    if (sscanf(value, "%d", &port) == 1 && port > 0) {
        printf("using port=%d\n", port);
        // listen on TCP port specified by service.adb.tcp.port property
        local_init(port);
    } else if (!usb) {
        // listen on default port
        local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT);
    }

    D("adb_main(): pre init_jdwp()\n");
    init_jdwp();
    D("adb_main(): post init_jdwp()\n");
#endif

    if (is_daemon)
    {
        // inform our parent that we are up and running.
#ifdef HAVE_WIN32_PROC
        DWORD  count;
        WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL );
#elif defined(HAVE_FORKEXEC)
        fprintf(stderr, "OK\n");
#endif
        start_logging();
    }
    D("Event loop starting\n");

    fdevent_loop();

    usb_cleanup();

    return 0;
}
Ejemplo n.º 23
0
int main (int argc, char *argv[])
{
    int    option;                                            // holds the option from getopt_long
    const char *const short_options = "hp:v:c:mis:g:w:r:lt:j:b:n";  // possible cmd line short options
    const struct option long_options[] = {                    // possible cmd line long options
        { "help",           0, NULL, 'h' },
        { "port",           1, NULL, 'p' },
        { "verbose",        1, NULL, 'v' },
        { "command",        1, NULL, 'c' },
        { "memdump",        0, NULL, 'm' },
        { "image",          0, NULL, 'i' },
        { "sahara",         1, NULL, 's' },
        { "prefix",         1, NULL, 'g' },
        { "where",          1, NULL, 'w' },
        { "ramdumpimage",   1, NULL, 'r' },
        { "efssyncloop",    0, NULL, 'l' },
        { "rxtimeout",      1, NULL, 't' },
        { "maxwrite",       1, NULL, 'j' },
        { "addsearchpath",  1, NULL, 'b' },
        { "noreset",        0, NULL, 'n' },
        { NULL,             0, NULL,  0  }
    };

    bool efs_sync = false;
    unsigned int i;
    bool   enable_sahara_transfer = false;

#ifndef WINDOWSPC
    unsigned long cap;
    int err;
    int rc;
    struct __user_cap_header_struct capheader;
    struct __user_cap_data_struct capdata[2];


    if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) != 0) {
        dbg(LOG_WARN, "set keepcaps failed!");
    }
    for (cap = 0; prctl(PR_CAPBSET_READ, cap, 0, 0, 0) >= 0; cap++) {
        if ((cap == CAP_SETUID) || (cap == CAP_SETGID) || (cap == CAP_BLOCK_SUSPEND)) {
            continue;
        }
        err = prctl(PR_CAPBSET_DROP, cap, 0, 0, 0);
        if ((err < 0) && (errno != EINVAL)) {
            dbg(LOG_WARN, "Drop capability %d failed\n", cap);
        }
    }

    if (setgid(AID_SYSTEM) != 0) {
      dbg(LOG_WARN, "setgid failed");
    }
    else {
      if (setuid(AID_SYSTEM) != 0) {
        dbg(LOG_WARN, "setuid failed");
      }
      else {
          memset(&capheader, 0, sizeof(capheader));
          memset(&capdata, 0, sizeof(capdata));
          capheader.version = _LINUX_CAPABILITY_VERSION_3;
          capheader.pid = 0;
          capdata[CAP_TO_INDEX(CAP_BLOCK_SUSPEND)].permitted |= CAP_TO_MASK(CAP_BLOCK_SUSPEND);
          capdata[CAP_TO_INDEX(CAP_BLOCK_SUSPEND)].effective |= CAP_TO_MASK(CAP_BLOCK_SUSPEND);

          if ((rc = capset(&capheader, capdata)) < 0) {
              dbg(LOG_WARN, "capset failed: %s, rc = %d\n", strerror(errno), rc);
          }
      }
    }
#endif

	if (false == init_search_path_list() || false == init_sahara_mapping_list()) {
		dbg(LOG_ERROR, "Could not initialize.");
		return EXIT_FAILURE;
	}

    /* parse command-line options */
    do {
        option = getopt_long (argc, argv, short_options, long_options, NULL);

        switch (option) {
        case -1:                /* no more option arguments */
            break;

        case 'h':               /* -h or --help */
            usage();
            return EXIT_SUCCESS;

        case 'p':               /* Get the port string name */
            com_port.port_name = optarg;
            dbg(LOG_INFO, "Port name '%s'", com_port.port_name);
            break;

        case 's':               /* -s or --sahara */
            /*add the input to <id,file_name> list*/
            if (false == add_input_to_sahara_mapping_list(optarg)) {
               dbg(LOG_ERROR, "Failed to add file to file list");
               return EXIT_FAILURE;
            }
            enable_sahara_transfer = true;
            break;

		case 'b':
            if (false == add_search_path(optarg)) {
               dbg(LOG_ERROR, "Failed to add to search path list");
               return EXIT_FAILURE;
            }
            break;

        case 'i':               /* -i or --image */
            sahara_data.mode = SAHARA_MODE_IMAGE_TX_PENDING;
			enable_sahara_transfer = true;
            break;

        case 'v':               /* -v or --verbose */
            kickstart_options.verbose = atoi(optarg);
            break;

        case 'm':               /* -m or --memdump */
            sahara_data.mode = SAHARA_MODE_MEMORY_DEBUG;
            enable_sahara_transfer = true;
            break;

        case 'r':               /* -r or --ramdumpimage */
            sahara_data.ram_dump_image = atoi(optarg);
			enable_sahara_transfer = true;
            break;

        case 'g':               /* -g or --prefix */
            kickstart_options.saved_file_prefix = optarg;
            break;

        case 'w':               /* -w or --where - path for memory dump */
            kickstart_options.path_to_save_files = optarg;
            break;

        case 'c':               /* -c or --command */
            sahara_data.mode = SAHARA_MODE_COMMAND;
			sahara_data.command = atoi(optarg);
			enable_sahara_transfer = true;
            break;

        case 'l':               /* -l or --loop */
            efs_sync = true;
			sahara_data.mode = SAHARA_MODE_MEMORY_DEBUG;
			com_port.rx_timeout = -1;
			enable_sahara_transfer = true;
            break;

        case 't':
            com_port.rx_timeout = atoi(optarg);
            break;

		case 'j':               /* -c or --command */
			com_port.MAX_TO_WRITE = atoi(optarg);
            break;

        case 'n':               /* -n or --noreset */
			sahara_data.allow_sahara_reset = false;
            break;

        default:                /* unknown option. */
            dbg(LOG_ERROR, "unrecognized option: '%c'", option);
            usage ();
            return EXIT_FAILURE;
        }
    } while (option != -1);

    #ifndef WINDOWSPC
    /* After parsing the command line args try to change the verbosity level of
       the logs if the system property was set. */
       kickstart_options.verbose = read_verbosity_property (kickstart_options.verbose);
    #endif

	if (true == enable_sahara_transfer) {
        if (NULL == com_port.port_name) {
            dbg(LOG_ERROR, "Port device name not specified; use -p option.");
            return EXIT_FAILURE;
        }

        for (i = 0; i < kickstart_options.port_connect_retries; i++) {
            if (true == port_connect(com_port.port_name)) {
                break;
            }
        }
        if (kickstart_options.port_connect_retries == i) {
            dbg(LOG_ERROR, "Could not connect to %s", com_port.port_name);
            return EXIT_FAILURE;
        }

        // This is a little hacky. Ideally the timeout values should be passed in
        // as an argument, but since they don't change too often, hardcoding them
        // here for now
        if (efs_sync) {
          com_port.rx_timeout_sec = 0;
          com_port.rx_timeout_usec = 500000;
          dbg(LOG_STATUS, "Setting timeout to 500ms");
        }
        else {
          com_port.rx_timeout_sec = 2;
          com_port.rx_timeout_usec = 0;
          dbg(LOG_STATUS, "Setting timeout to 2s");
        }

        if (false == sahara_main (efs_sync))
        {
           dbg(LOG_ERROR, "Uploading  Image using Sahara protocol failed");
           use_wakelock(WAKELOCK_RELEASE);
           port_disconnect();
           return EXIT_FAILURE;
        }
    }

    port_disconnect();
    return EXIT_SUCCESS;
}
Ejemplo n.º 24
0
int main(int argc, char *argv[]) {
    struct sigaction sigact;
    int do_add_date = 0;
    int do_compress = 0;
    int do_vibrate = 1;
    char* use_outfile = 0;
    char* begin_sound = 0;
    char* end_sound = 0;
    int use_socket = 0;
    int do_fb = 0;

    if (getuid() != 0) {
        // Old versions of the adb client would call the
        // dumpstate command directly. Newer clients
        // call /system/bin/bugreport instead. If we detect
        // we're being called incorrectly, then exec the
        // correct program.
        return execl("/system/bin/bugreport", "/system/bin/bugreport", NULL);
    }
    ALOGI("begin\n");

    memset(&sigact, 0, sizeof(sigact));
    sigact.sa_handler = sigpipe_handler;
    sigaction(SIGPIPE, &sigact, NULL);

    /* set as high priority, and protect from OOM killer */
    setpriority(PRIO_PROCESS, 0, -20);
    FILE *oom_adj = fopen("/proc/self/oom_adj", "w");
    if (oom_adj) {
        fputs("-17", oom_adj);
        fclose(oom_adj);
    }

    /* very first thing, collect stack traces from Dalvik and native processes (needs root) */
    dump_traces_path = dump_traces();

    int c;
    while ((c = getopt(argc, argv, "b:de:ho:svqzp")) != -1) {
        switch (c) {
            case 'b': begin_sound = optarg;  break;
            case 'd': do_add_date = 1;       break;
            case 'e': end_sound = optarg;    break;
            case 'o': use_outfile = optarg;  break;
            case 's': use_socket = 1;        break;
            case 'v': break;  // compatibility no-op
            case 'q': do_vibrate = 0;        break;
            case 'z': do_compress = 6;       break;
            case 'p': do_fb = 1;             break;
            case '?': printf("\n");
            case 'h':
                usage();
                exit(1);
        }
    }

    FILE *vibrator = 0;
    if (do_vibrate) {
        /* open the vibrator before dropping root */
        vibrator = fopen("/sys/class/timed_output/vibrator/enable", "w");
        if (vibrator) fcntl(fileno(vibrator), F_SETFD, FD_CLOEXEC);
    }

    /* read /proc/cmdline before dropping root */
    FILE *cmdline = fopen("/proc/cmdline", "r");
    if (cmdline != NULL) {
        fgets(cmdline_buf, sizeof(cmdline_buf), cmdline);
        fclose(cmdline);
    }

    if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
        ALOGE("prctl(PR_SET_KEEPCAPS) failed: %s\n", strerror(errno));
        return -1;
    }

    /* switch to non-root user and group */
    gid_t groups[] = { AID_LOG, AID_SDCARD_R, AID_SDCARD_RW,
            AID_MOUNT, AID_INET, AID_NET_BW_STATS };
    if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) {
        ALOGE("Unable to setgroups, aborting: %s\n", strerror(errno));
        return -1;
    }
    if (setgid(AID_SHELL) != 0) {
        ALOGE("Unable to setgid, aborting: %s\n", strerror(errno));
        return -1;
    }
    if (setuid(AID_SHELL) != 0) {
        ALOGE("Unable to setuid, aborting: %s\n", strerror(errno));
        return -1;
    }

    struct __user_cap_header_struct capheader;
    struct __user_cap_data_struct capdata[2];
    memset(&capheader, 0, sizeof(capheader));
    memset(&capdata, 0, sizeof(capdata));
    capheader.version = _LINUX_CAPABILITY_VERSION_3;
    capheader.pid = 0;

    capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG);
    capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG);
    capdata[0].inheritable = 0;
    capdata[1].inheritable = 0;

    if (capset(&capheader, &capdata[0]) < 0) {
        ALOGE("capset failed: %s\n", strerror(errno));
        return -1;
    }

    char path[PATH_MAX], tmp_path[PATH_MAX];
    pid_t gzip_pid = -1;

    if (use_socket) {
        redirect_to_socket(stdout, "dumpstate");
    } else if (use_outfile) {
        strlcpy(path, use_outfile, sizeof(path));
        if (do_add_date) {
            char date[80];
            time_t now = time(NULL);
            strftime(date, sizeof(date), "-%Y-%m-%d-%H-%M-%S", localtime(&now));
            strlcat(path, date, sizeof(path));
        }
        if (do_fb) {
            strlcpy(screenshot_path, path, sizeof(screenshot_path));
            strlcat(screenshot_path, ".png", sizeof(screenshot_path));
        }
        strlcat(path, ".txt", sizeof(path));
        if (do_compress) strlcat(path, ".gz", sizeof(path));
        strlcpy(tmp_path, path, sizeof(tmp_path));
        strlcat(tmp_path, ".tmp", sizeof(tmp_path));
        gzip_pid = redirect_to_file(stdout, tmp_path, do_compress);
    }

    if (begin_sound) {
        play_sound(begin_sound);
    } else if (vibrator) {
        fputs("150", vibrator);
        fflush(vibrator);
    }

    dumpstate();

    if (end_sound) {
        play_sound(end_sound);
    } else if (vibrator) {
        int i;
        for (i = 0; i < 3; i++) {
            fputs("75\n", vibrator);
            fflush(vibrator);
            usleep((75 + 50) * 1000);
        }
        fclose(vibrator);
    }

    /* wait for gzip to finish, otherwise it might get killed when we exit */
    if (gzip_pid > 0) {
        fclose(stdout);
        waitpid(gzip_pid, NULL, 0);
    }

    /* rename the (now complete) .tmp file to its final location */
    if (use_outfile && rename(tmp_path, path)) {
        fprintf(stderr, "rename(%s, %s): %s\n", tmp_path, path, strerror(errno));
    }

    ALOGI("done\n");

    return 0;
}
Ejemplo n.º 25
0
int main(int argc, char* argv[]) {
  // Check arguments.
  if (argc < 2) {
    error(1, 0, "usage: run-as <package-name> [--user <uid>] <command> [<args>]\n");
  }

  // This program runs with CAP_SETUID and CAP_SETGID capabilities on Android
  // production devices. Check user id of caller --- must be 'shell' or 'root'.
  if (getuid() != AID_SHELL && getuid() != AID_ROOT) {
    error(1, 0, "only 'shell' or 'root' users can run this program");
  }

  __user_cap_header_struct capheader;
  __user_cap_data_struct capdata[2];
  memset(&capheader, 0, sizeof(capheader));
  memset(&capdata, 0, sizeof(capdata));
  capheader.version = _LINUX_CAPABILITY_VERSION_3;
  capdata[CAP_TO_INDEX(CAP_SETUID)].effective |= CAP_TO_MASK(CAP_SETUID);
  capdata[CAP_TO_INDEX(CAP_SETGID)].effective |= CAP_TO_MASK(CAP_SETGID);
  capdata[CAP_TO_INDEX(CAP_SETUID)].permitted |= CAP_TO_MASK(CAP_SETUID);
  capdata[CAP_TO_INDEX(CAP_SETGID)].permitted |= CAP_TO_MASK(CAP_SETGID);
  if (capset(&capheader, &capdata[0]) == -1) {
    error(1, errno, "couldn't set capabilities");
  }

  char* pkgname = argv[1];
  int cmd_argv_offset = 2;

  // Get user_id from command line if provided.
  int userId = 0;
  if ((argc >= 4) && !strcmp(argv[2], "--user")) {
    userId = atoi(argv[3]);
    if (userId < 0) error(1, 0, "negative user id: %d", userId);
    cmd_argv_offset += 2;
  }

  // Retrieve package information from system, switching egid so we can read the file.
  gid_t old_egid = getegid();
  if (setegid(AID_PACKAGE_INFO) == -1) error(1, errno, "setegid(AID_PACKAGE_INFO) failed");
  pkg_info info;
  memset(&info, 0, sizeof(info));
  info.name = pkgname;
  if (!packagelist_parse(packagelist_parse_callback, &info)) {
    error(1, errno, "packagelist_parse failed");
  }
  if (info.uid == 0) {
    error(1, 0, "unknown package: %s", pkgname);
  }
  if (setegid(old_egid) == -1) error(1, errno, "couldn't restore egid");

  // Verify that user id is not too big.
  if ((UID_MAX - info.uid) / AID_USER < (uid_t)userId) {
    error(1, 0, "user id too big: %d", userId);
  }

  // Calculate user app ID.
  uid_t userAppId = (AID_USER * userId) + info.uid;

  // Reject system packages.
  if (userAppId < AID_APP) {
    error(1, 0, "package not an application: %s", pkgname);
  }

  // Reject any non-debuggable package.
  if (!info.debuggable) {
    error(1, 0, "package not debuggable: %s", pkgname);
  }

  // Check that the data directory path is valid.
  if (!check_data_path(info.data_dir, userAppId)) {
    error(1, 0, "package has corrupt installation: %s", pkgname);
  }

  // Ensure that we change all real/effective/saved IDs at the
  // same time to avoid nasty surprises.
  uid_t uid = userAppId;
  uid_t gid = userAppId;
  if (setresgid(gid, gid, gid) == -1) {
    error(1, errno, "setresgid failed");
  }
  if (setresuid(uid, uid, uid) == -1) {
    error(1, errno, "setresuid failed");
  }

  // Required if caller has uid and gid all non-zero.
  memset(&capdata, 0, sizeof(capdata));
  if (capset(&capheader, &capdata[0]) == -1) {
    error(1, errno, "couldn't clear all capabilities");
  }

  if (selinux_android_setcontext(uid, 0, info.seinfo, pkgname) < 0) {
    error(1, errno, "couldn't set SELinux security context");
  }

  // cd into the data directory, and set $HOME correspondingly.
  if (TEMP_FAILURE_RETRY(chdir(info.data_dir)) == -1) {
    error(1, errno, "couldn't chdir to package's data directory");
  }
  setenv("HOME", info.data_dir, 1);

  // Reset parts of the environment, like su would.
  setenv("PATH", _PATH_DEFPATH, 1);
  unsetenv("IFS");

  // Set the user-specific parts for this user.
  passwd* pw = getpwuid(uid);
  setenv("LOGNAME", pw->pw_name, 1);
  setenv("SHELL", pw->pw_shell, 1);
  setenv("USER", pw->pw_name, 1);

  // User specified command for exec.
  if ((argc >= cmd_argv_offset + 1) &&
      (execvp(argv[cmd_argv_offset], argv+cmd_argv_offset) == -1)) {
    error(1, errno, "exec failed for %s", argv[cmd_argv_offset]);
  }

  // Default exec shell.
  execlp(_PATH_BSHELL, "sh", NULL);
  error(1, errno, "exec failed");
}
int main(void)
{
    int retVal;
    pthread_attr_t attr;
    struct sched_param schedParam;
    pthread_t thread;


     struct __user_cap_header_struct cap_header_data;
     cap_user_header_t cap_header = &cap_header_data;

     struct __user_cap_data_struct cap_data_data;
     cap_user_data_t cap_data = &cap_data_data;
	 int ret;

    if (setresuid(0, 0, 0)) {
        fprintf(stderr, "Cannot switch to root: %s.\n", strerror(errno));
        return 1;
    }

     cap_header->pid = getpid();
     cap_header->version = _LINUX_CAPABILITY_VERSION;
 
     if (capget(cap_header, cap_data) < 0) {
         perror("Failed capget");
         exit(1);
     }
     printf("Cap data 0x%x, 0x%x, 0x%x\n", cap_data->effective,
         cap_data->permitted, cap_data->inheritable);

     /* Clear all but the capability to bind to low ports */
     cap_data->effective |= CAP_TO_MASK(CAP_SYS_ADMIN) | CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SYS_NICE);
     cap_data->permitted |= CAP_TO_MASK(CAP_SYS_ADMIN) | CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SYS_NICE);
     cap_data->inheritable |= CAP_TO_MASK(CAP_SYS_ADMIN) | CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SYS_NICE); 

	 if (capset(cap_header, cap_data) < 0)
		 printf("capset failed");

	 printf("Cap data 0x%x, 0x%x, 0x%x\n", cap_data->effective,
			 cap_data->permitted, cap_data->inheritable);

	ret = nice(-1);
	printf("nice: %d\n", ret);

	 /* Tell kernel not clear capabilities when dropping root */
	 if (prctl(PR_SET_KEEPCAPS, 1) < 0)
		 printf("prctl(PR_SET_KEEPCAPS) failed ");

	setresuid(1000,1000,1000);
	printf("setresuid\n");
	
	/* Clear all but the capability to bind to low ports */
     cap_data->effective |= CAP_TO_MASK(CAP_SYS_ADMIN) | CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SYS_NICE);
     cap_data->permitted |= CAP_TO_MASK(CAP_SYS_ADMIN) | CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SYS_NICE);
     cap_data->inheritable |= CAP_TO_MASK(CAP_SYS_ADMIN) | CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SYS_NICE); 

	 if (capset(cap_header, cap_data) < 0)
		 printf("capset failed");

	 printf("Cap data 0x%x, 0x%x, 0x%x\n", cap_data->effective,
			 cap_data->permitted, cap_data->inheritable);




    retVal = pthread_attr_init(&attr);
    if (retVal)
    {
        fprintf(stderr, "pthread_attr_init error %d\n", retVal);
        exit(1);
    }

    retVal = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
    if (retVal)
    {
        fprintf(stderr, "pthread_attr_setinheritsched error %d\n", retVal);
        exit(1);
    }

    retVal = pthread_attr_setschedpolicy(&attr, SCHED_RR);
    if (retVal)
    {
        fprintf(stderr, "pthread_attr_setschedpolicy error %d\n", retVal);
        exit(1);
    }

    schedParam.sched_priority = 99;
    retVal = pthread_attr_setschedparam(&attr, &schedParam);
    if (retVal)
    {
        fprintf(stderr, "pthread_attr_setschedparam error %d\n", retVal);
        exit(1);
    }

    retVal = pthread_create(&thread,
                            &attr,
                            _Thread,
                            NULL);
    if (retVal)
    {
        fprintf(stderr, "pthread_create error %d\n", retVal);
        exit(1);
    }

    retVal = pthread_join(thread, NULL);
    if (retVal)
    {
        fprintf(stderr, "pthread_join error %d\n", retVal);
        exit(1);
    }

    printf("main run successfully\n");
    return 0;
}
Ejemplo n.º 27
0
/*
 * The ruid refers to the caller's uid and is used to reset the effective uid
 * back to the callers real uid.
 * This clutch mainly exists for setuid-based new{g,u}idmap binaries that are
 * called in contexts where all capabilities other than the necessary
 * CAP_SET{G,U}ID capabilities are dropped. Since the kernel will require
 * assurance that the caller holds CAP_SYS_ADMIN over the target user namespace
 * the only way it can confirm is in this case is if the effective uid is
 * equivalent to the uid owning the target user namespace.
 * Note, we only support this when a) new{g,u}idmap is not called by root and
 * b) if the caller's uid and the uid retrieved via system appropriate means
 * (shadow file or other) are identical. Specifically, this does not support
 * when the root user calls the new{g,u}idmap binary for an unprivileged user.
 * If this is wanted: use file capabilities!
 */
void write_mapping(int proc_dir_fd, int ranges, struct map_range *mappings,
	const char *map_file, uid_t ruid)
{
	int idx;
	struct map_range *mapping;
	size_t bufsize;
	char *buf, *pos;
	int fd;

#if HAVE_SYS_CAPABILITY_H
	int cap;
	struct __user_cap_header_struct hdr = {_LINUX_CAPABILITY_VERSION_3, 0};
	struct __user_cap_data_struct data[2] = {{0}};

	if (strcmp(map_file, "uid_map") == 0) {
		cap = CAP_SETUID;
	} else if (strcmp(map_file, "gid_map") == 0) {
		cap = CAP_SETGID;
	} else {
		fprintf(stderr, _("%s: Invalid map file %s specified\n"), Prog, map_file);
		exit(EXIT_FAILURE);
	}

	/* Align setuid- and fscaps-based new{g,u}idmap behavior. */
	if (geteuid() == 0 && geteuid() != ruid) {
		if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) {
			fprintf(stderr, _("%s: Could not prctl(PR_SET_KEEPCAPS)\n"), Prog);
			exit(EXIT_FAILURE);
		}

		if (seteuid(ruid) < 0) {
			fprintf(stderr, _("%s: Could not seteuid to %d\n"), Prog, ruid);
			exit(EXIT_FAILURE);
		}
	}

	/* Lockdown new{g,u}idmap by dropping all unneeded capabilities. */
	memset(data, 0, sizeof(data));
	data[0].effective = CAP_TO_MASK(cap);
	data[0].permitted = data[0].effective;
	if (capset(&hdr, data) < 0) {
		fprintf(stderr, _("%s: Could not set caps\n"), Prog);
		exit(EXIT_FAILURE);
	}
#endif

	bufsize = ranges * ((ULONG_DIGITS  + 1) * 3);
	pos = buf = xmalloc(bufsize);

	/* Build the mapping command */
	mapping = mappings;
	for (idx = 0; idx < ranges; idx++, mapping++) {
		/* Append this range to the string that will be written */
		int written = snprintf(pos, bufsize - (pos - buf),
			"%lu %lu %lu\n",
			mapping->upper,
			mapping->lower,
			mapping->count);
		if ((written <= 0) || (written >= (bufsize - (pos - buf)))) {
			fprintf(stderr, _("%s: snprintf failed!\n"), Prog);
			exit(EXIT_FAILURE);
		}
		pos += written;
	}

	/* Write the mapping to the mapping file */
	fd = openat(proc_dir_fd, map_file, O_WRONLY);
	if (fd < 0) {
		fprintf(stderr, _("%s: open of %s failed: %s\n"),
			Prog, map_file, strerror(errno));
		exit(EXIT_FAILURE);
	}
	if (write(fd, buf, pos - buf) != (pos - buf)) {
		fprintf(stderr, _("%s: write to %s failed: %s\n"),
			Prog, map_file, strerror(errno));
		exit(EXIT_FAILURE);
	}
	close(fd);
}