Skip to content
Advertisement

System call that shows processes filtered by their status

I am making a system call that loops through every process with a certain status (passed to the syscall as a parameter) and show their Name, PID, UID and the name of their children. This is what I have so far:

asmlinkage int sys_procinfo(int state){
    struct task_struct *task;
    struct task_struct *child_ptr;
    struct list_head *list;


    for_each_process(task) {
        if(task->state == state){
            /* print info about the parent */
            printk(KERN_INFO "nombre:%s[pid:%d]estado:%ld[uid:%d]n", task->comm, task->pid, task->state, task->uid);


            list_for_each(list, &task->children) {
                child_ptr = list_entry(list, struct task_struct, sibling);
                /* child_ptr now points to one of current's children */
                printk(KERN_INFO "Hijo %sn", child_ptr->comm);
            }
        }
    }
    return 0;
}

This prints all of the system’s processes and their children, completely ignoring the condition if(task->state == state), which is very weird to me. I need to print only the info of the processes that are in the state ‘state’ (e.g. TASK_RUNNING = 0, EXIT_ZOMBIE = 32, TASK_WAKING = 256, TASK_INTERRUPTIBLE = 1, etc).

Oh, and I also would like the syscall to return its syscall number, but I defined it for two systems: 32 and 64bits, and their numbers in the syscall_32.tbl and syscall_64.tbl tables are different, so I think I can’t hardcode the syscall number. Is there any macro I can use to return that value?

Thanks. PS: I’m working on kubuntu 16.04LTS, and I’m using the kernel “linux-3.16.43.tar.xz” from The Linux Kernel Archives

Advertisement

Answer

I think the issue was that ‘task’ wasn’t initialized, but that’s a little weird since it should have pointed to every process anyway in the for_each_process() macro. What I did was to first point to the init (or systemd) process and then loop through every process and their children. This is the sys.c file in the kernel and it prints the name of every process running in the state ‘state’ (if it’s a valid state) along their PID and UID, plus the name of their children. It can be called like syscall(SYS_procinfo_64, state);

asmlinkage int sys_procinfo(int state) {
    struct task_struct *tarea;
    struct task_struct *hijo;
    struct list_head *lista_procesos;

    if(state != 0 && state != 1 && state != 2 && state != 4 && state != 8 && state != 16 && state != 32
        && state != 64 && state != 128 && state != 256 && state != 512 && state != 1024 && state != 2048
        && state != 4096){
        /* Si el estado ingresado no es valido, retornar -1 */
        return -1;
    }
    /* tarea apunta hacia init para recorrer los procesos */
    for (tarea = current; tarea != &init_task; tarea = tarea->parent)
        ;
    /* recorrer todos los procesos con el puntero tarea */
    for_each_process(tarea) {
        /* mostrar informacion de procesos en el estado 'state' */
        if(tarea->state == state || task->exit_state == state) {
            /* informacion del padre */
            printk(KERN_INFO "Proceso %s     pid: %d    uid: %un", tarea->comm, tarea->pid, current_uid().val);
            /* informacion de los hijos */
            list_for_each(lista_procesos, &tarea->children) {
                hijo = list_entry(lista_procesos, struct task_struct, sibling);
                printk(KERN_INFO "Hijo %sn", hijo->comm);
            }
        }
    }
    return state;
}
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement