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 group_info-> blocks [0] = group_info-> small_block;
outro {
para (i = 0; 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 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 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 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
; /* nada */

stride / = 3;

while (stride) {

max = gidsetsize - stride;

para (base = 0; 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
sem assinatura int meados = esquerda + (direita - esquerda) / 2;

if (grp> GROUP_AT (group_info, mid))

esquerda = meio + 1;

else if (grp
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
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
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;

}

Categoria: IT & Programação
Subcategoria: Programação
Qual é o alcance do projeto?: Alteração média
Isso é um projeto ou uma posição de trabalho?: Um projeto
Tenho, atualmente: Eu tenho uma ideia geral
Disponibilidade requerida: Conforme necessário
Funções necessárias: Gerente de projetos, Analista de negócios, Outro
Integrações de API: Outros (Outras APIs)

Abierto

Presupuesto

1

Propuestas

1

Freelancers interesados

Publicado: Hace 5 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