コード例 #1
0
ファイル: sys.c プロジェクト: maraz/linux-2.6
int in_egroup_p(gid_t grp)
{
	int retval = 1;
	if (grp != current->egid)
		retval = groups_search(current->group_info, grp);
	return retval;
}
コード例 #2
0
ファイル: authlist.c プロジェクト: oboguev/dprio
static bool in_egroup(const struct cred *cred, kgid_t kgid)
{
	if (gid_eq(cred->egid, kgid))
		return true;

	return groups_search(cred->group_info, kgid);
}
コード例 #3
0
ファイル: sys.c プロジェクト: FatSunHYS/OSCourseDesign
/*
 * Check whether we're fsgid/egid or in the supplemental group..
 */
int in_group_p(gid_t grp)
{
	int retval = 1;
	if (grp != current->fsgid) {
		retval = groups_search(current->group_info, grp);
	}
	return retval;
}
コード例 #4
0
ファイル: restore.c プロジェクト: virthub/virthub
int ckpt_restore_cred(ckpt_desc_t desc)
{
    int ret = 0;
    ckpt_cred_t cred;
    gid_t *groups = NULL;
    const struct cred *curr_cred = current->cred;

    log_restore_cred("restoring cred ...");
    if (ckpt_read(desc, &cred, sizeof(ckpt_cred_t)) != sizeof(ckpt_cred_t)) {
        log_err("failed to get cred");
        return -EIO;
    }

    if (cred.ngroups > NGROUPS_MAX) {
        log_err("ngroups (%d) > NGROUPS_MAX", cred.ngroups);
        return -EINVAL;
    }

    if (cred.ngroups > 0) {
        int i;
        size_t size = cred.ngroups * sizeof(gid_t);
        struct group_info *gi = curr_cred->group_info;

        groups = vmalloc(size);
        if (!groups) {
            log_err("no memory");
            return -ENOMEM;
        }

        if (ckpt_read(desc, groups, size) != size) {
            log_err("failed to get groups");
            ret = -EIO;
            goto out;
        }

        for (i = 0; i < cred.ngroups; i++) {
            if (!groups_search(gi, groups[i])) {
                mm_segment_t fs = get_fs();
                set_fs(KERNEL_DS);
                ret = sys_setgroups(cred.ngroups, groups);
                set_fs(fs);
                if (ret < 0) {
                    log_err("failed to set groups");
                    goto out;
                }
                break;
            }
        }
    }

    current->gpid = cred.gpid;
    ret = sys_setresgid(cred.gid, cred.egid, cred.sgid);
    if (ret < 0) {
        log_err("failed to restore gid");
        goto out;
    }

    ret = sys_setresuid(cred.uid, cred.euid, cred.suid);
    if (ret < 0) {
        log_err("failed to restore uid");
        goto out;
    }

    if ((curr_cred->euid == curr_cred->uid) && (curr_cred->egid == curr_cred->gid))
        set_dumpable(current->mm, 1);
    else
        set_dumpable(current->mm, *compat_suid_dumpable);
    log_restore_pos(desc);
out:
    if (groups)
        vfree(groups);
    return ret;
}
コード例 #5
0
ファイル: cr_creds.c プロジェクト: AvengerMoJo/apc-8750
int cr_load_creds(cr_rstrt_proc_req_t *proc_req)
{
    cr_errbuf_t *eb = proc_req->req->errbuf;
    struct cr_context_creds cf_creds;
    int retval;
    gid_t *groups = NULL;

    CR_KTRACE_HIGH_LVL("%d: Restoring credentials", current->pid);

    retval = cr_kread(eb, proc_req->file, &cf_creds, sizeof(cf_creds));
    if (retval < sizeof(cf_creds)) {
	CR_ERR_PROC_REQ(proc_req, "credentials: read returned %d", retval);
        goto out;
    }
     
    if (cf_creds.ngroups > CR_NGROUPS_MAX) {
	CR_ERR_PROC_REQ(proc_req, "Invalid supplemental group count (%d)", (int)cf_creds.ngroups);
	retval = -EINVAL;
	goto out;
    } else if (cf_creds.ngroups) {
	size_t sizeof_groups = cf_creds.ngroups*sizeof(gid_t);
	groups = vmalloc(sizeof_groups);
	retval = -ENOMEM;
	if (groups == NULL) {
	    goto out;
	}

	retval = cr_kread(eb, proc_req->file, groups, sizeof_groups);
	if (retval < sizeof_groups) {
	    CR_ERR_PROC_REQ(proc_req, "groups: read returned %d", retval);
            goto out_vfree;
        }
    }

#if CR_RESTORE_IDS
    if (cf_creds.ngroups) {
      #if CR_HAVE_GROUP_INFO || defined(CR_KCODE_groups_search) || !defined(CR_KCODE_supplemental_group_member)
	cr_group_info_t gi = cr_current_groups();
      #endif
	int i;
	/* Search for any required "expansion" of the group set */
	for (i = 0; i < cf_creds.ngroups; ++i) {
	    gid_t g = groups[i];
	    int gid_ok = 0; /* Assume no match for this gid */

    #if defined(CR_KCODE_groups_search)
	    gid_ok = groups_search((struct group_info *)gi, g); // search is const, but not declared as such
    #elif defined(CR_KCODE_supplemental_group_member)
	    gid_ok = supplemental_group_member(g);
    #else
	    /* Just in case groups_search() or supplemental_group_member()
	     * is not found (each was static in some kernels) */
	    int j;
	    for (j = 0; j < gi->ngroups; ++j) {
                if (g == CR_GROUP_AT(gi, j)) {
		    gid_ok = 1; /* OK, g is in the existing set */
		    break;
		}
	    }
    #endif

	    if (!gid_ok) {
	        /* If we reach here then we've seen a supplemental group in the
	         * saved context, which is not present in the current list.
		 * The set_groups() call checks permissions for us.  If we fail,
		 * then we must not have enough credentials.
		 */
		mm_segment_t oldfs = get_fs();
		set_fs(KERNEL_DS);
		retval = sys_setgroups(cf_creds.ngroups, groups);
		set_fs(oldfs);
		if (retval < 0) {
		    CR_ERR_PROC_REQ(proc_req, "Failed to restore supplemental group(s).");
		    goto out_vfree;
		}
		CR_KTRACE_LOW_LVL("Restored %d supplemental group(s)", cf_creds.ngroups);
		break; /* no need to continue the i loop */
	    }
	}
  #if CR_HAVE_GROUP_INFO
	(void)cr_insert_object(proc_req->req->map, (void *)cf_creds.group_info, (void *)gi, GFP_KERNEL);
  #endif
    }
  #if CR_HAVE_GROUP_INFO
    else {
	// NOTE: requires restore order match save order
	struct group_info *found_group_info = NULL;

	if (!cr_find_object(proc_req->req->map, (void *)cf_creds.group_info, (void **)&found_group_info)) {
	   // Nothing to do
	} else if (found_group_info != cr_current_groups()) {
	    // validation and sort were done previously, but are not worth avoiding
	    set_current_groups(found_group_info);
	    CR_KTRACE_LOW_LVL("Reuse cached group_info %p", found_group_info);
	} else {
	    CR_KTRACE_LOW_LVL("Cached group_info == current");
	}
    }
  #endif

    {
	cr_cred_t my_cred = cr_current_cred();

	/* The set_setresgid() call checks permissions for us, always OK if no change . */
	retval = sys_setresgid(cf_creds.gid, cf_creds.egid, cf_creds.sgid);
	if (retval < 0) {
	    CR_ERR_PROC_REQ(proc_req, "Failed to restore real/effective/saved gids.");
	    goto out_vfree;
	}
	CR_KTRACE_LOW_LVL("Restored gids");

	/* The set_setresuid() call checks permissions for us, always OK if no change . */
	retval = sys_setresuid(cf_creds.uid, cf_creds.euid, cf_creds.suid);
	if (retval < 0) {
	    CR_ERR_PROC_REQ(proc_req, "Failed to restore real/effective/saved uids.");
	    goto out_vfree;
	}
	CR_KTRACE_LOW_LVL("Restored uids");

        /* 
	 * sys_setresuid sets current->mm->dumpable to suid_dumpable if the
	 * call was successful.  This can have some weird side-effects on
	 * restarted jobs, like /proc/self/fd will not be accessable.  
         *
	 * We should probably save this flag and restore it if we ever
	 * support real setuid checkpoints from the user, but for now we'll
	 * just set the flag to 1 if the user had permission to restore their
	 * credentials in the first place.  This should mimic the behavior
         * of exec.
         *
         * Set the dumpable flag for the process, taken from 2.6.22 fs/exec.c
         */
        if (my_cred->euid == my_cred->uid && my_cred->egid == my_cred->gid) {
            cr_set_dumpable(current->mm, 1);
        } else {
            cr_set_dumpable(current->mm, cr_suid_dumpable);
        }
    }
#endif	 /* CR_RESTORE_IDS */

out_vfree:
    vfree(groups);

out:
    return retval;
}