Beispiel #1
0
int 
setegid(gid_t egid) {
  struct Capability cap;

  OSCALLENTER(OSCALL_setegid);

  if (__current->egid == egid)
    return 0;

  /* Layout the desired capability */
  cap.c_perm = CL_DUP | CL_W;
  cap.c_valid = 1;
  cap.c_isptr = 0;
  cap.c_len = egid ? 3 : 1;
  cap.c_name[0] = 2;
  cap.c_name[1] = egid >> 8;
  cap.c_name[2] = egid & 0xFF;

  /* Try to forge the new gid capability with CAP_GID */
  if (sys_self_forge(CAP_GID, CAP_EGID, &cap) < 0) {
    errno = EPERM;
    OSCALLEXIT(OSCALL_setegid);
    return -1;
  }

  __current->egid = egid;
  OSCALLEXIT(OSCALL_setegid);
  return 0;
}
Beispiel #2
0
int 
setuid(uid_t uid) {
  struct Capability cap;

  OSCALLENTER(OSCALL_setuid);

  /* Layout the desired capability */
  cap.c_perm = CL_ALL;
  cap.c_valid = 1;
  cap.c_isptr = 0;
  cap.c_len = uid ? 3 : 1;
  cap.c_name[0] = 1;
  cap.c_name[1] = uid >> 8;
  cap.c_name[2] = uid & 0xFF;

  /* Try to forge the new uid capability with CAP_EUID */
  if (sys_self_forge(CAP_EUID, CAP_SCRATCH, &cap) < 0) {
    /* Couldn't forge, are we just blowing away the euid? */
    if (uid == __current->uid) {
      sys_self_forge(CAP_UID, CAP_EUID, &__curenv->env_clist[CAP_UID]);
      __current->euid = uid;
      __current->fsuid = uid;
      OSCALLEXIT(OSCALL_setuid);
      return 0;
    } else {
      errno = EPERM;
      OSCALLEXIT(OSCALL_setuid);
      return -1;
    }
  }

  /* CAP_SCRATCH is now a token for `cap', move this into euid and uid */
  /* These can't fail since we just forged `cap' into CAP_SCRATCH */
  sys_self_forge(CAP_SCRATCH, CAP_UID, &cap);
  sys_self_forge(CAP_SCRATCH, CAP_EUID, &cap);
  __current->uid = uid;
  __current->euid = uid;
  __current->fsuid = uid;
  OSCALLEXIT(OSCALL_setuid);
  return 0;
}
Beispiel #3
0
int 
setgid(gid_t gid) {
  struct Capability cap;

  OSCALLENTER(OSCALL_setgid);

  /* Layout the desired capability */
  cap.c_perm = CL_DUP | CL_W;
  cap.c_valid = 1;
  cap.c_isptr = 0;
  cap.c_len = gid ? 3 : 1;
  cap.c_name[0] = 2;
  cap.c_name[1] = gid >> 8;
  cap.c_name[2] = gid & 0xFF;

  /* Try to forge the new gid capability with CAP_EGID and CAP_EUID */
  if (sys_self_forge(CAP_EGID, CAP_SCRATCH, &cap) < 0  &&
      sys_self_forge(CAP_EUID, CAP_SCRATCH, &cap) < 0) {
    /* Couldn't forge, Use CAP_GID only if we are setting egid back to gid */
    if (gid == __current->gid) {
      sys_self_forge(CAP_GID, CAP_EGID, &__curenv->env_clist[CAP_GID]);
      __current->egid = gid;
      OSCALLEXIT(OSCALL_setgid);
      return 0;
    } else {
      errno = EPERM;
      OSCALLEXIT(OSCALL_setgid);
      return -1;
    }
  }

  /* CAP_SCRATCH is now a token for `cap', move this into euid and uid */
  /* These can't fail since we know CAP_SCRATCH dominates/equals `cap' */
  sys_self_forge(CAP_SCRATCH, CAP_GID, &cap);
  sys_self_forge(CAP_SCRATCH, CAP_EGID, &cap);
  __current->gid = gid;
  __current->egid = gid;
  OSCALLEXIT(OSCALL_setgid);
  return 0;
}
Beispiel #4
0
void
InitCaps() {
  struct Capability cap;
  int r;

  /* clear cname */
  bzero (cap.c_name, sizeof (cap.c_name));

  /* JJJ Keep root capability here until we handle caps better. */
  sys_self_forge(CAP_ENV, CAP_ROOT, &__curenv->env_clist[CAP_ENV]);

  cap.c_valid = 1;
  cap.c_isptr = 0;


  cap.c_len = 1;
  
  cap.c_perm = CL_ALL;
  cap.c_name[0] = CAP_NM_UID;
  sys_self_forge(CAP_ROOT, CAP_UID, &cap);
  sys_self_forge(CAP_ROOT, CAP_EUID, &cap);
  
  cap.c_perm = CL_DUP | CL_W;
  cap.c_name[0] = CAP_NM_GID;
  sys_self_forge(CAP_ROOT, CAP_GID, &cap);
  sys_self_forge(CAP_ROOT, CAP_EGID, &cap);


  cap.c_len = 3;
  cap.c_name[1] = 0;
  cap.c_name[2] = 0;
  sys_self_forge(CAP_ROOT, CAP_WORLD, &cap);


  sys_pgacl_setsize(CAP_ROOT, sys_read_pte(UADDR, CAP_ROOT, __envid, &r),
		    2);
  sys_pgacl_mod(CAP_ROOT, sys_read_pte(UADDR, CAP_ROOT, __envid, &r),
		2, &cap);
}