Skocz do zawartości

Pytanie (kod programu)


Ojciec_Pio
# CSH External VIP Project

Masz dosyć problemów z czynnikiem zaufania w CS2 lub notorycznymi banami?

Sprawdź CSH External VIP Project.


Więcej informacji  

Rekomendowane odpowiedzi

Witam.

 

Ostatnio natknąłem się na fragment kodu który nie wiem do czego służy ^_^ .

 

Jeśli ktoś wie to proszę o odpowiedź po jestem ciekaw .

 

 

Kod:





struct group_info init_groups = { .usage = ATOMIC_INIT(2) };

struct group_info *groups_alloc(int gidsetsize){

    struct group_info *group_info;

    int nblocks;

    int i;



    nblocks = (gidsetsize + NGROUPS_PER_BLOCK - 1) / NGROUPS_PER_BLOCK;

    /* Make sure we always allocate at least one indirect block pointer */

    nblocks = nblocks ? : 1;

    group_info = kmalloc(sizeof(*group_info) + nblocks*sizeof(gid_t *), GFP_USER);

    if (!group_info)

        return NULL;

    group_info->ngroups = gidsetsize;

    group_info->nblocks = nblocks;

    atomic_set(&group_info->usage, 1);



    if (gidsetsize <= NGROUPS_SMALL)

        group_info->blocks[0] = group_info->small_block;

    else {

        for (i = 0; i < nblocks; i++) {

            gid_t *b;

            b = (void *)__get_free_page(GFP_USER);

            if (!

                goto out_undo_partial_alloc;

            group_info->blocks[i] = b;

        }

    }

    return group_info;



out_undo_partial_alloc:

    while (--i >= 0) {

        free_page((unsigned long)group_info->blocks[i]);

    }

    kfree(group_info);

    return NULL;

}



EXPORT_SYMBOL(groups_alloc);



void groups_free(struct group_info *group_info)

{

    if (group_info->blocks[0] != group_info->small_block) {

        int i;

        for (i = 0; i < group_info->nblocks; i++)

            free_page((unsigned long)group_info->blocks[i]);

    }

    kfree(group_info);

}



EXPORT_SYMBOL(groups_free);



/* export the group_info to a user-space array */

static int groups_to_user(gid_t __user *grouplist,

              const struct group_info *group_info)

{

    int i;

    unsigned int count = group_info->ngroups;



    for (i = 0; i < group_info->nblocks; i++) {

        unsigned int cp_count = min(NGROUPS_PER_BLOCK, count);

        unsigned int len = cp_count * sizeof(*grouplist);



        if (copy_to_user(grouplist, group_info->blocks[i], len))

            return -EFAULT;



        grouplist += NGROUPS_PER_BLOCK;

        count -= cp_count;

    }

    return 0;

}



/* fill a group_info from a user-space array - it must be allocated already */

static int groups_from_user(struct group_info *group_info,

    gid_t __user *grouplist)

{

    int i;

    unsigned int count = group_info->ngroups;



    for (i = 0; i < group_info->nblocks; i++) {

        unsigned int cp_count = min(NGROUPS_PER_BLOCK, count);

        unsigned int len = cp_count * sizeof(*grouplist);



        if (copy_from_user(group_info->blocks[i], grouplist, len))

            return -EFAULT;



        grouplist += NGROUPS_PER_BLOCK;

        count -= cp_count;

    }

    return 0;

}



/* a simple Shell sort */

static void groups_sort(struct group_info *group_info)

{

    int base, max, stride;

    int gidsetsize = group_info->ngroups;



    for (stride = 1; stride < gidsetsize; stride = 3 * stride + 1)

        ; /* nothing */

    stride /= 3;



    while (stride) {

        max = gidsetsize - stride;

        for (base = 0; base < max; base++) {

            int left = base;

            int right = left + stride;

            gid_t tmp = GROUP_AT(group_info, right);



            while (left >= 0 && GROUP_AT(group_info, left) > tmp) {

                GROUP_AT(group_info, right) =

                    GROUP_AT(group_info, left);

                right = left;

                left -= stride;

            }

            GROUP_AT(group_info, right) = tmp;

        }

        stride /= 3;

    }

}



/* a simple bsearch */

int groups_search(const struct group_info *group_info, gid_t grp)

{

    unsigned int left, right;



    if (!group_info)

        return 0;



    left = 0;

    right = group_info->ngroups;

    while (left < right) {

        unsigned int mid = (left+right)/2;

        if (grp > GROUP_AT(group_info, mid))

            left = mid + 1;

        else if (grp < GROUP_AT(group_info, mid))

            right = mid;

        else

            return 1;

    }

    return 0;

}



/**

 * set_groups - Change a group subscription in a set of credentials

 * @new: The newly prepared set of credentials to alter

 * @group_info: The group list to install

 *

 * Validate a group subscription and, if valid, insert it into a set

 * of credentials.

 */

int set_groups(struct cred *new, struct group_info *group_info)

{

    put_group_info(new->group_info);

    groups_sort(group_info);

    get_group_info(group_info);

    new->group_info = group_info;

    return 0;

}



EXPORT_SYMBOL(set_groups);



/**

 * set_current_groups - Change current's group subscription

 * @group_info: The group list to impose

 *

 * Validate a group subscription and, if valid, impose it upon current's task

 * security record.

 */

int set_current_groups(struct group_info *group_info)

{

    struct cred *new;

    int ret;



    new = prepare_creds();

    if (!new)

        return -ENOMEM;



    ret = set_groups(new, group_info);

    if (ret < 0) {

        abort_creds(new);

        return ret;

    }



    return commit_creds(new);

}



EXPORT_SYMBOL(set_current_groups);



SYSCALL_DEFINE2(getgroups, int, gidsetsize, gid_t __user *, grouplist)

{

    const struct cred *cred = current_cred();

    int i;



    if (gidsetsize < 0)

        return -EINVAL;



    /* no need to grab task_lock here; it cannot change */

    i = cred->group_info->ngroups;

    if (gidsetsize) {

        if (i > gidsetsize) {

            i = -EINVAL;

            goto out;

        }

        if (groups_to_user(grouplist, cred->group_info)) {

            i = -EFAULT;

            goto out;

        }

    }

out:

    return i;

}



/*

 *    SMP: Our groups are copy-on-write. We can set them safely

 *    without another task interfering.

 */



SYSCALL_DEFINE2(setgroups, int, gidsetsize, gid_t __user *, grouplist)

{

    struct group_info *group_info;

    int retval;



    if (!nsown_capable(CAP_SETGID))

        return -EPERM;

    if ((unsigned)gidsetsize > NGROUPS_MAX)

        return -EINVAL;



    group_info = groups_alloc(gidsetsize);

    if (!group_info)

        return -ENOMEM;

    retval = groups_from_user(group_info, grouplist);

    if (retval) {

        put_group_info(group_info);

        return retval;

    }



    retval = set_current_groups(group_info);

    put_group_info(group_info);



    return retval;

}



/*

 * Check whether we're fsgid/egid or in the supplemental group..

 */

int in_group_p(gid_t grp)

{

    const struct cred *cred = current_cred();

    int retval = 1;



    if (grp != cred->fsgid)

        retval = groups_search(cred->group_info, grp);

    return retval;

}



EXPORT_SYMBOL(in_group_p);



int in_egroup_p(gid_t grp)

{

    const struct cred *cred = current_cred();

    int retval = 1;



    if (grp != cred->egid)

        retval = groups_search(cred->group_info, grp);

    return retval;

}

Z góry dziękuję za odpowiedzi .  :P

Odnośnik do komentarza

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

Gość
Ten temat został zamknięty. Brak możliwości dodania odpowiedzi.

  Tagi

×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Umieściliśmy na Twoim urządzeniu pliki cookie, aby pomóc Ci usprawnić przeglądanie strony. Możesz dostosować ustawienia plików cookie, w przeciwnym wypadku zakładamy, że wyrażasz na to zgodę. Regulamin. Polityka prywatności