Передача параметров в пользовательский системный вызов в Unix - PullRequest
0 голосов
/ 03 июня 2018

Я пытаюсь создать собственный системный вызов, который вводит (длинный) массив и выводит некоторую базовую информацию об этом массиве для назначения класса.

У меня возникают некоторые проблемы при передаче соответствующих аргументов в системуcall.

Ниже приведена тестовая программа, которую я использую для отладки этого системного вызова:

#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#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_, &stats, ary, s);

  printf("\nRising to user level w/ result = %d\n\n", result);

  return 0;
}

Вот системный вызов array_stats, я вставил несколько операторов printk()для целей отладки:

#include <linux/kernel.h>
#include <asm/errno.h>
#include <linux/uaccess.h>
#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 <= 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 < loc_sum; i++) {
    loc_sum += local_data[i];
    if (local_data[i] < loc_min) loc_min = local_data[i];
    if (local_data[i] > loc_max) loc_max = local_data[i];
  }

  stats -> min = loc_min;
  stats -> max = loc_max;
  stats -> sum = loc_sum;

  printk("Min: %lu\n", loc_min);
  printk("Max: %lu\n", loc_max);
  printk("Sum: %lu\n", loc_sum);

  return result;
}

Запуск тестовой программы приводит к следующему:

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:~# 

Как видите, аргументы не передаются должным образом.Что я делаю не так?

Заранее спасибо!

...