3

HugeTLB - Large Page Support in the Linux Kernel

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdlib.h>

#define MB_1 (1024*1024)
#define MB_8 (8*MB_1)

char  *a;
int shmid1;

void init_hugetlb_seg()
{
  shmid1 = shmget(2, MB_8, SHM_HUGETLB
         | IPC_CREAT | SHM_R
         | SHM_W);
  if ( shmid1 < 0 ) {
    perror("shmget");
    exit(1);
  }
  printf("HugeTLB shmid: 0x%x\n", shmid1);
  a = shmat(shmid1, 0, 0);
  if (a == (char *)-1) {
    perror("Shared memory attach failure");
    shmctl(shmid1, IPC_RMID, NULL);
    exit(2);
  }
}

void wr_to_array()
{
  int i;
  for( i=0 ; i<MB_8 ; i++) {
    a[i] = 'A';
  }
}

void rd_from_array()
{
  int i, count = 0;
  for( i=0 ; i<MB_8 ; i++)
    if (a[i] == 'A') count++;
  if (count==i)
    printf("HugeTLB read success :-)\n");
  else
    printf("HugeTLB read failed :-(\n");
}

int main(int argc, char *argv[])
{
  init_hugetlb_seg();
  printf("HugeTLB memory segment initialized !\n");
  printf("Press any key to write to memory area\n");
  getchar();
  wr_to_array();
  printf("Press any key to rd from memory area\n");
  getchar();
  rd_from_array();
  shmctl(shmid1, IPC_RMID, NULL);
  return 0;
}

Question> I don't have root permission to run this code. What should I do to fix the permission issue?

$ gcc hugetlb-array.c -o hugetlb-array -Wall
$ ./hugetlb-array
shmget: Operation not permitted

Without using SHM_HUGETLB, the code runs well without problem.

$ ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status
0x00000002 32768      myid         600        2097152    1
q0987
  • 34,938
  • 69
  • 242
  • 387

1 Answers1

4

You need the CAP_IPC_LOCK capability. You can add this to an executable using setcap(8).

Specifically, run:

root@yourmachine$ setcap cap_ipc_lock=ep your_executable

This has to be redone every time your executable is modified (recompiled/reinstalled) - otherwise there would be a gaping security hole.

If you only need to do this at startup, you should also consider dropping privileges as soon as possible, but this is not essential (if anyone really cares, you'll probably get a patch).

See also Using setcap in linux

o11c
  • 15,265
  • 4
  • 50
  • 75
  • May you give further detail here? I read the link and still have no idea for the issue. – q0987 Aug 28 '17 at 02:06
  • do you mean I have to get the root permission first in order to run my code? Unfortunately, I am not able to obtain the root permission. – q0987 Aug 28 '17 at 02:16
  • Yes, you still need root permission once (but not for every run). Hm, except possibly if you enter a new IPC namespace (which requires entering a new UID namespace)? See `unshare(1)` - I haven't tried it for this kind of thing though, only as a permissionless-chroot/mount substitute. – o11c Aug 28 '17 at 02:21