Пример исходного кода из "Программирование ядра Linux" - PullRequest
8 голосов
/ 29 июня 2011

читал книгу Роберта Лава, глава 5 о системных вызовах, и нашел этот простой пример немного сомнительным:

asmlinkage long sys_silly_copy(unsigned long *src, unsigned long *dst, unsigned long len)
{
   unsigned long buf;

   if (copy_from_user(&buf, src, len))
     return -EFAULT;

   ...
}

Как мы видим, 'buf' является объектом типа 'unsigned long' и определен настек ядра, т.е. его начальное значение скорее всего мусор.В любом случае, допустимо ли копировать байты len в стек, где находится buf, то есть он может перезаписать что-нибудь полезное?Возможно, это хорошо только для этого конкретного примера?

Ответы [ 2 ]

15 голосов
/ 29 июня 2011

Это очень сомнительно. На самом деле, это совершенно опасно. Я дам автору здесь преимущество сомнения, поскольку они просто пытаются показать, как работают copy_from_user и copy_to_user, но они действительно должны были привести пример, который не был так опасен.

Особенно , поскольку в книге много лирического рассказа о том, как вы должны быть особенно осторожными:

Системные вызовы должны тщательно проверять все их параметры, чтобы убедиться, что они действительны и legal.The системный вызов выполняется в пространстве ядра, и если пользователь может передать неверный ввод в ядро без ограничений, безопасность и стабильность системы могут пострадать.

, а затем предоставляет пользователю возможность полностью уничтожить ядро: -)


Текст из имеющейся у меня копии гласит:

Давайте рассмотрим пример системного вызова, который использует copy_from_user() и copy_to_user(). Этот системный вызов silly_copy() совершенно бесполезен; он копирует данные из своего первого параметра во второй. Это неоптимально в том смысле, что он включает в себя промежуточное и постороннее копирование в пространство ядра без какой-либо выгоды. Но это помогает проиллюстрировать это.

/*
* silly_copy - pointless syscall that copies the len bytes from
* ‘src’ to ‘dst’ using the kernel as an intermediary in the copy.
* Intended as an example of copying to and from the kernel.
*/
SYSCALL_DEFINE3(silly_copy,
                unsigned long *, src,
                unsigned long *, dst,
                unsigned long len)
{
    unsigned long buf;

    /* copy src, which is in the user’s address space, into buf */
    if (copy_from_user(&buf, src, len))
        return -EFAULT;

    /* copy buf into dst, which is in the user’s address space */
    if (copy_to_user(dst, &buf, len))
        return -EFAULT;

    /* return amount of data copied */
    return len;
}

Кроме катастрофического сбоя не проверки параметров, я почти уверен, что последний параметр SYSCALL_DEFINE3 пропускает запятую (хотя это будет просто опечатка).

Гораздо лучший пример, без выделения произвольной памяти, будет выглядеть следующим образом:

SYSCALL_DEFINE3(silly_copy,
                unsigned long *, src,
                unsigned long *, dst,
                unsigned long,   len)
{
    unsigned long buf[64];                 /* Buffer for chunks */
    unsigned long lenleft = len;           /* Remaining size */
    unsigned long chunklen = sizeof(buf);  /* Initial chunk length */

    /* Loop handling chunk sizes */

    while (lenleft > 0) {
        /* Change chunk length on last chunk */

        if (lenleft < chunklen) chunklen = lenleft;

        /* copy src(user) to buf(kernel) then dst(user) */

        if (copy_from_user(buf, src, chunklen)) return -EFAULT;
        if (copy_to_user(dst, buf, chunklen)) return -EFAULT;

        /* Adjust pointers and remaining size */

        src += chunklen; dst += chunklen; lenleft -= chunklen;
    }

    /* return amount of data copied */
    return len;
}

Любому, кто пытается реализовать этот системный вызов, рекомендуется избегать этого конкретного примера в книге, хотя я полагаю, что, как минимум, это даст вам хороший опыт отладки ядра: -)

0 голосов
/ 07 июня 2014
int init_module(void)
{

    mempool_t *mempool;

    struct kmem_cache *kmem_cache;
    void *p0 , *p1;
    kmem_cache = kmem_cache_create("Ashrama" ,100 , 0 ,SLAB_PANIC ,NULL);
    mempool = mempool_create(4 , mempool_alloc_slab , mempool_free_slab , kmem_cache);
    p0 = mempool_alloc(mempool, SLAB_PANIC);
    p1 = mempool_alloc(mempool , SLAB_PANIC);
    strcpy(p0 , "Ranjan.B.M");
    strcpy(p1 , "Mithun.V");
    mempool_free( p0 , mempool);
    printk(KERN_ALERT"%s",p0);
    printk(KERN_ALERT"%s",p1);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...