FANDOM


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 (!b)
               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;

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.