title: Passing parameters to custom syscall in unix
body: <p>I am attempting to create a custom system call that inputs an (long) array and outputs some basic information about this array for a class assignment.</p>
  
  <p>I am having some trouble passing the appropriate arguments into the system call.</p>
  
  <p>Below is the test program I am using to debug this system call:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;sys/syscall.h&gt;
  #include "array_stats.h"
  
  #define _ARRAY_STATS_ 341 // for a 64 bit system
  
  int main () {
  
    struct array_stats * stats;
  
    long ary[3];
    ary[0] = 1;
    ary[1] = 2;
    ary[2] = 3;
  
    long s = 3;
  
    printf("\nDiving to kernel level\n\n");
  
    // Calling array_stats syscall
    int result = syscall(_ARRAY_STATS_, &amp;stats, ary, s);
  
    printf("\nRising to user level w/ result = %d\n\n", result);
  
    return 0;
  }
  </code></pre>
  
  <p>Here is the <code>array_stats</code> system call, I have inserted a bunch of <code>printk()</code> statements for debugging purposes:</p>
  
  <pre><code>#include &lt;linux/kernel.h&gt;
  #include &lt;asm/errno.h&gt;
  #include &lt;linux/uaccess.h&gt;
  #include "array_stats.h"
  
  asmlinkage long sys_array_stats (struct array_stats *stats, long data[], long size) {
    printk("1. %s\n", "System call started");
  
    long loc_max;
    long loc_min;
    long loc_sum;
    long local_data[size];
    int i = 1;
    int result = 0;
  
    printk("2. %s\n", "Variables created");
    printk("Size %lu\n", size);
    printk("data[0] = %lu\n", data[0]);
    printk("data[1] = %lu\n", data[1]);
    printk("data[2] = %lu\n", data[2]);
  
    if (size &lt;= 0) return -EINVAL;
  
    printk("3. %s\n", "Size validated");
  
    result = copy_from_user (local_data, data, size * sizeof * data);
  
    if (!result) return EFAULT;
  
    loc_max = local_data[0];
    loc_min = local_data[0];
    loc_sum = local_data[0];
  
    for (; i &lt; loc_sum; i++) {
      loc_sum += local_data[i];
      if (local_data[i] &lt; loc_min) loc_min = local_data[i];
      if (local_data[i] &gt; loc_max) loc_max = local_data[i];
    }
  
    stats -&gt; min = loc_min;
    stats -&gt; max = loc_max;
    stats -&gt; sum = loc_sum;
  
    printk("Min: %lu\n", loc_min);
    printk("Max: %lu\n", loc_max);
    printk("Sum: %lu\n", loc_sum);
  
    return result;
  }
  </code></pre>
  
  <p>The running of the test program results in the following:</p>
  
  <pre><code>root@debian-amd64:~# ./array_stats_test 
  
  Diving to kernel level
  
  [   92.735994] 1. System call started
  [   92.737851] 2. Variables created
  [   92.738037] Size 0
  [   92.738155] data[0] = 0
  [   92.738417] data[1] = 6955032
  [   92.738565] data[2] = 0
  
  Rising to user level w/ result = -1
  
  root@debian-amd64:~# 
  </code></pre>
  
  <p>As you can see, the arguments aren't being passed in properly. What am I doing wrong?</p>
  
  <p>Thanks in advance!</p>