0

I have a structure I am declaring/defining in the linux kernel (3.2), and I am currently trying to allocate one of these structures inside a syscall, and return a pointer to it for the process calling the syscall.

  1. How can I #include this file in a program outside the kernel (the question might be which file should I include)? Currently, I am declaring the structure in include/linux/syscalls.h and defining it in a file I created myself in kernel/mysystemcall.c. If I try and use the structure in a program, I get error: dereferencing pointer to incomplete type.

  2. How can I actually read from this memory, given that if I dereference it, I get a segmentation fault? Currently, I am using kmalloc to allocate the memory; is there a flag I need to turn on to access the memory, or should I be using something else to allocate this memory?

Thanks for any help provided!

Current syscall implementation:

#include <linux/linkage.h>
#include <linux/sched.h>
#include <linux/slab.h>

struct threadinfo_struct {
    int pid;
    int nthreads;
    int *tid;
};

asmlinkage struct threadinfo_struct *sys_threadinfo(void) {
    struct threadinfo_struct *info = kmalloc(sizeof(struct threadinfo_struct), GFP_KERNEL);
    info->pid = current->pid;
    info->nthreads = -1;
    info->tid = NULL;
    return info;
}

Current test code (outsider kernel):

#include <stdio.h>
#include <linux/unistd.h>
#include <sys/syscall.h>
#define sys_threadinfo 349

int main(void) {
    int *ti = (int*) syscall(sys_threadinfo);
    printf("Thread id: %d\n", *ti); // Causes a segfault
    return 0;
}

EDIT: I realize I can have my syscall take a pointer to already allocated memory, and just to fill in the values for the user, but it is preferred (teacher preference) to do it this way for the assignment.

Mat
  • 202,337
  • 40
  • 393
  • 406
Casey Kuball
  • 7,717
  • 5
  • 38
  • 70
  • Look at the implementation of the system calls whose purpose is to allocate memory for a user-space process: `brk` and `mmap`. (`mmap` does other things as well, but it should be clear which code path is which.) Both are defined in `mm/mmap.c`. – zwol Oct 20 '12 at 01:57
  • @Zack is this the `SYSCALL_DEFINE1(brk, unsigned long, brk)` and `SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg)` definitions that you are referring to? I can see the mmap uses `copy_from_user` (not much is clear here - new to linux kernel), is there a way I can give the memory to the user without using something like `copy_to_user`? – Casey Kuball Oct 20 '12 at 04:16
  • Those are not the *implementations* of the system calls; those are effectively only interface declarations (despite the DEFINE in the name). The *implementations* are in `mm/mmap.c`, as I said. Look for functions named `sys_brk`, `sys_mmap`, `do_brk`, and `do_mmap`. – zwol Oct 20 '12 at 14:05
  • @Zack Ah, I will look at those functions then. (Those SYSCALL_DEFINE1 parts were both in mm/mmap.c) – Casey Kuball Oct 21 '12 at 17:21

1 Answers1

2

After looking at this answer:

Don't attempt to allocate memory for userspace from the kernel - this is a huge violation of the kernel's abstraction layering.

I decided to go the route of having the user space program allocate the memory itself, after asking the kernel how much memory is necessary.

This means that I can simply copy the structure into both the user and kernel space files, and there is no need to #include a kernel file for the structure definition.

Community
  • 1
  • 1
Casey Kuball
  • 7,717
  • 5
  • 38
  • 70
  • 2
    Be sure to point out to your teacher why you altered the specification, including the potential and serious security implications of his preferred approach. – Nik Bougalis Feb 24 '13 at 19:22