Hello.

I want to get argv[0] from "struct linux_binprm".
But it seems that elements of "struct linux_binprm" has changed at 2.6.23-rc1 .
And I want to know how to follow this change.
The following is the code,
but I'm not sure whether get_user_pages()/put_page() usage is correct.
This code is called from security_bprm_check().
Could somebody please review this code?

Regards.



static char *get_argv0(struct linux_binprm *bprm)
{
        char *arg_ptr = kmalloc(PAGE_SIZE, GFP_KERNEL); /* Initial buffer. */
        int arg_len = 0;
        unsigned long pos = bprm->p;
        int i = pos / PAGE_SIZE, offset = pos % PAGE_SIZE;
        if (!bprm->argc || !arg_ptr) goto out;
        while (1) {
                struct page *page;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) && defined(CONFIG_MMU)
                if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, 
NULL) <= 0) goto out;
#else
                page = bprm->page[i];
#endif
                { /* Map and copy to kernel buffer and unmap. */
                        const char *kaddr = kmap(page);
                        if (!kaddr) { /* Mapping failed. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) && defined(CONFIG_MMU)
                                put_page(page);
#endif
                                goto out;
                        }
                        memmove(arg_ptr + arg_len, kaddr + offset, PAGE_SIZE - 
offset);
                        kunmap(page);
                }
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) && defined(CONFIG_MMU)
                put_page(page);
                pos += PAGE_SIZE - offset;
#endif
                arg_len += PAGE_SIZE - offset;
                if (memchr(arg_ptr, '\0', arg_len)) break;
                { /* Initial buffer was too small for argv[0]. Retry after 
expanding buffer. */
                        char *tmp_arg_ptr = kmalloc(arg_len + PAGE_SIZE, 
GFP_KERNEL);
                        if (!tmp_arg_ptr) goto out;
                        memmove(tmp_arg_ptr, arg_ptr, arg_len);
                        kfree(arg_ptr);
                        arg_ptr = tmp_arg_ptr;
                }
                i++;
                offset = 0;
        }
        return arg_ptr;
 out: /* Release initial buffer. */
        kfree(arg_ptr);
        return NULL;
}

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to [EMAIL PROTECTED]
Please read the FAQ at http://kernelnewbies.org/FAQ

Reply via email to