Progamador nivel maximo


Evaluando propuestas
Descripción:
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;
    / * Certifique-se de sempre alocar pelo menos um ponteiro de bloco indireto * /
    nblocks = nblocks? : 1;
    group_info = kmalloc (sizeof (* group_info) + nblocos * 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;
    outro {
        para (i = 0; i <nblocks; i ++) {
            gid_t * b;
            b = (void *) __ get_free_page (GFP_USER);
            if (! b)
                goto out_undo_partial_alloc;
            group_info-> blocos [i] = b;
        }
    }
    return group_info;


out_undo_partial_alloc:

    while (--i> = 0) {

        free_page ((unsigned long) group_info-> blocos [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;

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

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

    }

    kfree (group_info);

}



EXPORT_SYMBOL (groups_free);



/ * exportar o group_info para uma matriz de espaço do usuário * /

estático int groups_to_user (gid_t __user * grouplist,

              const struct group_info * group_info)

{

    int i;

    Unsigned int count = group_info-> ngroups;



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

        unsigned int cp_count = min (NGROUPS_PER_BLOCK, count);

        int sem assinatura len = cp_count * sizeof (* grouplist);



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

            return -EFAULT;



        grouplist + = NGROUPS_PER_BLOCK;

        count - = cp_count;

    }

    return 0;

}



/ * preenche um group_info de uma matriz de espaço do usuário - ele deve ser alocado já * /

estático int groups_from_user (struct group_info * group_info,

    gid_t __user * grouplist)

{

    int i;

    Unsigned int count = group_info-> ngroups;



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

        unsigned int cp_count = min (NGROUPS_PER_BLOCK, count);

        int sem assinatura len = cp_count * sizeof (* grouplist);



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

            return -EFAULT;



        grouplist + = NGROUPS_PER_BLOCK;

        count - = cp_count;

    }

    return 0;

}



/ * um simples tipo de shell * /

static void groups_sort (struct group_info * group_info)

{

    int base, max, stride;

    int gidsetsize = group_info-> ngroups;



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

        ; /* nada */

    stride / = 3;



    while (stride) {

        max = gidsetsize - stride;

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

            int esquerda = base;

            int direita = esquerda + passada;

            gid_t tmp = GROUP_AT (group_info, right);



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

                GROUP_AT (group_info, right) =

                    GROUP_AT (group_info, à esquerda);

                direita = esquerda;

                esquerda - = passada;

            }

            GROUP_AT (group_info, right) = tmp;

        }

        stride / = 3;

    }

}



/ * um simples bsearch * /

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

{

    Unsigned int esquerda, direita;



    if (! group_info)

        return 0;



    esquerda = 0;

    right = group_info-> ngroups;

    while (esquerda <direita) {

        sem assinatura int meados = esquerda + (direita - esquerda) / 2;

        if (grp> GROUP_AT (group_info, mid))

            esquerda = meio + 1;

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

            direita = meio;

        outro

            return 1;

    }

    return 0;

}



/ **

* set_groups - Altera uma assinatura de grupo em um conjunto de credenciais

* @new: O recém-preparado conjunto de credenciais para alterar

* @group_info: A lista de grupos a instalar

*

* Valide uma assinatura de grupo e, se for válido, insira-a em um conjunto

* de credenciais.

* /

Int set_groups (struct cred * novo, 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 - Altera a assinatura do grupo atual

* @group_info: A lista de grupos para impor

*

* Valide uma assinatura de grupo e, se for válido, imponha-a na tarefa atual

* registro de segurança.

* /

Int set_current_groups (struct group_info * group_info)

{

    struct cred * novo;

    int ret;



    novo = prepare_creds ();

    if (! novo)

        retorno -ENOMEM;



    ret = set_groups (novo, group_info);

    if (ret <0) {

        abort_creds (novo);

        retorno ret;

    }



    return commit_creds (novo);

}



EXPORT_SYMBOL (set_current_groups);



Syscall_define2 (getgroups, int, gidsetsize, gid_t __usuário *, grouplist)

{

    const struct cred * cred = current_cred ();

    int i;



    if (gidsetsize <0)

        return -einval;



    / * não há necessidade de pegar task_lock aqui; não pode mudar * /

    i = cred-> group_info-> ngroups;

    if (gidsetsize) {

        if (i> gidsetsize) {

            i = -inval;

            ir embora;

        }

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

            i = -efault;

            ir embora;

        }

    }

fora:

    return i;

}



/ *

* smp: nossos grupos são copy-on-write. Nós podemos configurá-los com segurança

* sem outra tarefa interferindo.

* /



SYSCALL_DEFINE2 (setgroups, int, gidsetsize, gid_t __utilizador *, 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)

        retorno -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;

}



/ *

* verifique se estamos fsgid / egid ou no grupo suplementar ..

* /

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;

}

Category: Programación y Tecnología
Subcategory: Programación Web
What is the scope of the project?: Medium-sized change
Is this a project or a position?: Project
I currently have: I have an idea
Required availability: As needed
API Integrations: Other (Other APIs)
Roles needed: Project manager, Business analyst, Other

Abierto

Presupuesto

1

Propuestas

1

Freelancers interesados

Publicado: Hace 8 meses

Plazo: No definido

Crea tu propio proyecto

¿Buscas un freelancer para realizar un proyecto similar? Crea tu propio proyecto y recibirás ofertas de los mejores freelancers.


Freelancers que ya aplicaron para este trabajo