All of lore.kernel.org
 help / color / mirror / Atom feed
* allocate memory in userspace
@ 2002-07-01 17:26 Timo Benk
  2002-07-01 17:49 ` Erik Andersen
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Timo Benk @ 2002-07-01 17:26 UTC (permalink / raw)
  To: linux-kernel; +Cc: Timo Benk

Hi,

I am a kernel newbie and i am writing a module. I 
need to allocate some memory in userspace because
i want to access syscalls like open(), lstat() etc.
I need to call these methods in the kernel, and in
my special case there is no other way, but i 
do not want to reimplement all the syscalls.

I read that it should be possible, but i cannot
find any example or recipe on how to do it.
It should work with do_mmap() and fd=-1 and
MAP_ANON, but i jusst can't get it to work.

Do you now any working example, or a good reference
for the do_mmap() call? 

Thanks in advance,

-timo

-- 
gpg key fingerprint = 6832 C8EC D823 4059 0CD1  6FBF 9383 7DBD 109E 98DC


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: allocate memory in userspace
  2002-07-01 17:26 allocate memory in userspace Timo Benk
@ 2002-07-01 17:49 ` Erik Andersen
  2002-07-02  8:37   ` William Lee Irwin III
  2002-07-01 18:39 ` Calin A. Culianu
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 11+ messages in thread
From: Erik Andersen @ 2002-07-01 17:49 UTC (permalink / raw)
  To: Timo Benk; +Cc: linux-kernel

On Mon Jul 01, 2002 at 07:26:59PM +0200, Timo Benk wrote:
> Hi,
> 
> I am a kernel newbie and i am writing a module. I 
> need to allocate some memory in userspace because
> i want to access syscalls like open(), lstat() etc.
> I need to call these methods in the kernel, and in
> my special case there is no other way, but i 
> do not want to reimplement all the syscalls.

So use the C library and call malloc()

> I read that it should be possible, but i cannot
> find any example or recipe on how to do it.
> It should work with do_mmap() and fd=-1 and
> MAP_ANON, but i jusst can't get it to work.

void *malloc(size_t size)
{
    void *result;
    if (size == 0)
	return NULL;
    result = mmap((void *) 0, size + sizeof(size_t), PROT_READ | PROT_WRITE, 
	    MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
    if (result == MAP_FAILED)
	return 0;
    * (size_t *) result = size;
    return(result + sizeof(size_t));
}

void * calloc(size_t nelem, size_t size)
{
    void *result;
    result = malloc(size * nelem);
    if (result)
	memset(result, 0, nelem * size);
    return result;
}

void *realloc(void *ptr, size_t size)
{
    void *newptr = NULL;
    if (size > 0) {
	newptr = malloc(size);
	if (newptr && ptr) {
	    memcpy(newptr, ptr, * ((size_t *) (ptr - sizeof(size_t))));
	    free(ptr);
	}
    }
    else {
	free(ptr);
    }
    return newptr;
}

void free(void *ptr)
{
    if (ptr) {
	ptr -= sizeof(size_t);
	munmap(ptr, * (size_t *) ptr);
    }
}


 -Erik

--
Erik B. Andersen             http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: allocate memory in userspace
  2002-07-01 17:26 allocate memory in userspace Timo Benk
  2002-07-01 17:49 ` Erik Andersen
@ 2002-07-01 18:39 ` Calin A. Culianu
  2002-07-02  7:51 ` allocate memory in userspace (Answer) Timo Benk
  2002-07-02 12:19 ` allocate memory in userspace Brian Gerst
  3 siblings, 0 replies; 11+ messages in thread
From: Calin A. Culianu @ 2002-07-01 18:39 UTC (permalink / raw)
  To: Timo Benk; +Cc: linux-kernel


Why don't you just exec a process?

On Mon, 1 Jul 2002, Timo Benk wrote:

> Hi,
>
> I am a kernel newbie and i am writing a module. I
> need to allocate some memory in userspace because
> i want to access syscalls like open(), lstat() etc.
> I need to call these methods in the kernel, and in
> my special case there is no other way, but i
> do not want to reimplement all the syscalls.
>
> I read that it should be possible, but i cannot
> find any example or recipe on how to do it.
> It should work with do_mmap() and fd=-1 and
> MAP_ANON, but i jusst can't get it to work.
>
> Do you now any working example, or a good reference
> for the do_mmap() call?
>
> Thanks in advance,
>
> -timo
>
>


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: allocate memory in userspace (Answer)
  2002-07-01 17:26 allocate memory in userspace Timo Benk
  2002-07-01 17:49 ` Erik Andersen
  2002-07-01 18:39 ` Calin A. Culianu
@ 2002-07-02  7:51 ` Timo Benk
  2002-07-02 10:24   ` Timo Benk
  2002-07-02 12:19 ` allocate memory in userspace Brian Gerst
  3 siblings, 1 reply; 11+ messages in thread
From: Timo Benk @ 2002-07-02  7:51 UTC (permalink / raw)
  To: linux-kernel; +Cc: Timo Benk

Hi,

I found the following function in arch/i386/kernel/sys_i386.c:

---<snip>---
/* common code for old and new mmaps */
long do_mmap2
	(
		unsigned long addr, unsigned long len,
		unsigned long prot, unsigned long flags,
		unsigned long fd,   unsigned long pgoff
	)
{
	int error = -EBADF;
	struct file * file = NULL;

	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
	if (!(flags & MAP_ANONYMOUS)) {
		file = fget(fd);
		if (!file)
			goto out;
	}

	down_write(&current->mm->mmap_sem);
	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
	up_write(&current->mm->mmap_sem);

	if (file)
		fput(file);
out:
	return error;
}
---<snap>---

the following code works for me(of course
don't forget to munmap the memory).
---<snip>---	
	char *userspace;
	char kernelspace[2048];

	userspace = (char*)do_mmap2
			(
				0, 
				2048, 
				PROT_READ|PROT_WRITE, 
				MAP_PRIVATE|MAP_ANON, 
				-1, 
				0
			);
			
	copy_to_user( userspace, "/dev/hda", 9 );
	
	copy_from_user( kernelspace, userspace, 9 );
	printk("%s\n",kernelspace);
---<snap>---	

Hope that helps any other struggling newbie:-)

-timo

-- 
gpg key fingerprint = 6832 C8EC D823 4059 0CD1  6FBF 9383 7DBD 109E 98DC


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: allocate memory in userspace
  2002-07-01 17:49 ` Erik Andersen
@ 2002-07-02  8:37   ` William Lee Irwin III
  2002-07-02  8:44     ` William Lee Irwin III
  0 siblings, 1 reply; 11+ messages in thread
From: William Lee Irwin III @ 2002-07-02  8:37 UTC (permalink / raw)
  To: Erik Andersen, Timo Benk, linux-kernel

On Mon, Jul 01, 2002 at 11:49:13AM -0600, Erik Andersen wrote:
> void *malloc(size_t size)
> {
>     void *result;
>     if (size == 0)
> 	return NULL;
>     result = mmap((void *) 0, size + sizeof(size_t), PROT_READ | PROT_WRITE, 
> 	    MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
>     if (result == MAP_FAILED)
> 	return 0;
>     * (size_t *) result = size;
>     return(result + sizeof(size_t));
> }

This looks like a very bad idea. Userspace allocators should make some
attempt at avoiding diving into the kernel at every allocation like this.
Also, they should be intelligent enough to get around TASK_UNMAPPED_BASE.
Wilson's allocator survey has an excellent discussion of the issues.
Doug Lea has a better example of a userspace memory allocator.


Cheers,
Bill

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: allocate memory in userspace
  2002-07-02  8:37   ` William Lee Irwin III
@ 2002-07-02  8:44     ` William Lee Irwin III
  2002-07-02  9:00       ` Erik Andersen
  0 siblings, 1 reply; 11+ messages in thread
From: William Lee Irwin III @ 2002-07-02  8:44 UTC (permalink / raw)
  To: Erik Andersen, Timo Benk, linux-kernel

On Mon, Jul 01, 2002 at 11:49:13AM -0600, Erik Andersen wrote:
>> void *malloc(size_t size)
>> {
>>     void *result;
>>     if (size == 0)
>> 	return NULL;
>>     result = mmap((void *) 0, size + sizeof(size_t), PROT_READ | PROT_WRITE, 
>> 	    MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
>>     if (result == MAP_FAILED)
>> 	return 0;
>>     * (size_t *) result = size;
>>     return(result + sizeof(size_t));
>> }

On Tue, Jul 02, 2002 at 01:37:37AM -0700, William Lee Irwin III wrote:
> This looks like a very bad idea. Userspace allocators should make some
> attempt at avoiding diving into the kernel at every allocation like this.

Sorry, I also forgot the rather severe internal fragmentation this is
likely to suffer due to page-level restrictions on mmap's operation.

Cheers,
Bill

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: allocate memory in userspace
  2002-07-02  8:44     ` William Lee Irwin III
@ 2002-07-02  9:00       ` Erik Andersen
  0 siblings, 0 replies; 11+ messages in thread
From: Erik Andersen @ 2002-07-02  9:00 UTC (permalink / raw)
  To: William Lee Irwin III, Timo Benk, linux-kernel

On Tue Jul 02, 2002 at 01:44:18AM -0700, William Lee Irwin III wrote:
> On Mon, Jul 01, 2002 at 11:49:13AM -0600, Erik Andersen wrote:
> >> void *malloc(size_t size)
> >> {
> >>     void *result;
> >>     if (size == 0)
> >> 	return NULL;
> >>     result = mmap((void *) 0, size + sizeof(size_t), PROT_READ | PROT_WRITE, 
> >> 	    MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
> >>     if (result == MAP_FAILED)
> >> 	return 0;
> >>     * (size_t *) result = size;
> >>     return(result + sizeof(size_t));
> >> }
> 
> On Tue, Jul 02, 2002 at 01:37:37AM -0700, William Lee Irwin III wrote:
> > This looks like a very bad idea. Userspace allocators should make some
> > attempt at avoiding diving into the kernel at every allocation like this.
> 
> Sorry, I also forgot the rather severe internal fragmentation this is
> likely to suffer due to page-level restrictions on mmap's operation.

Of course.  No question there -- actually using such an allocator
(with a standard linux kernel) would be a terrible idea.  I was
merely providing a trivial answer to his question on how to use
mmap to allocate memory.

 -Erik

--
Erik B. Andersen             http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: allocate memory in userspace
       [not found] <20020701172659.GA4431@toshiba.suse.lists.linux.kernel>
@ 2002-07-02  9:30 ` Andi Kleen
  2002-07-02 10:21   ` Timo Benk
  0 siblings, 1 reply; 11+ messages in thread
From: Andi Kleen @ 2002-07-02  9:30 UTC (permalink / raw)
  To: Timo Benk; +Cc: linux-kernel

Timo Benk <t_benk@web.de> writes:

> I am a kernel newbie and i am writing a module. I 
> need to allocate some memory in userspace because
> i want to access syscalls like open(), lstat() etc.
> I need to call these methods in the kernel, and in
> my special case there is no other way, but i 
> do not want to reimplement all the syscalls.
> 
> I read that it should be possible, but i cannot
> find any example or recipe on how to do it.

mm_segment_t oldfs = get_fs(); 
set_fs(KERNEL_DS); 
ret = sys_yoursyscall(kernelargs ...) 
set_fs(oldfs); 

Do not even think about using mmap or accessing sys_call_table for this.
Your other post was so tasteless that it would be good if you retracted
it with a followup because it would be very bad to have such an bad example 
in the l-k archives open to innocent search machine users uncommented.

-Andi

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: allocate memory in userspace
  2002-07-02  9:30 ` Andi Kleen
@ 2002-07-02 10:21   ` Timo Benk
  0 siblings, 0 replies; 11+ messages in thread
From: Timo Benk @ 2002-07-02 10:21 UTC (permalink / raw)
  To: linux-kernel; +Cc: Timo Benk

On Tue, Jul 02, 2002 at 11:30:34AM +0200, Andi Kleen wrote:
> Timo Benk <t_benk@web.de> writes:
> 
> > I am a kernel newbie and i am writing a module. I 
> > need to allocate some memory in userspace because
> > i want to access syscalls like open(), lstat() etc.
> > I need to call these methods in the kernel, and in
> > my special case there is no other way, but i 
> > do not want to reimplement all the syscalls.
> > 
> > I read that it should be possible, but i cannot
> > find any example or recipe on how to do it.
> 
> mm_segment_t oldfs = get_fs(); 
> set_fs(KERNEL_DS); 
> ret = sys_yoursyscall(kernelargs ...) 
> set_fs(oldfs); 
Thank you very much for that hint.

> Do not even think about using mmap or accessing sys_call_table for this.
> Your other post was so tasteless that it would be good if you retracted
> it with a followup because it would be very bad to have such an bad example 
> in the l-k archives open to innocent search machine users uncommented.
I will post a followup, but please tell me
a) a good doc for that topic where i can read why it is so bad
b) a reference for the do_mmap call

While searching through the ng archives i just found (lots of) hints
that this can be done with mmap, so that was my approach to solve
the problem.

Maybe it will be better that you (or any other) will comment what
is so bad, as i told in my first post i am a newbie, so please keep
that in mind.

-timo

-- 
gpg key fingerprint = 6832 C8EC D823 4059 0CD1  6FBF 9383 7DBD 109E 98DC


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: allocate memory in userspace (Answer)
  2002-07-02  7:51 ` allocate memory in userspace (Answer) Timo Benk
@ 2002-07-02 10:24   ` Timo Benk
  0 siblings, 0 replies; 11+ messages in thread
From: Timo Benk @ 2002-07-02 10:24 UTC (permalink / raw)
  To: linux-kernel; +Cc: Timo Benk

As stated by Andy Kleen this is not a good solution.
This is his post to the topic:

----<snip>----
> I am a kernel newbie and i am writing a module. I 
> need to allocate some memory in userspace because
> i want to access syscalls like open(), lstat() etc.
> I need to call these methods in the kernel, and in
> my special case there is no other way, but i 
> do not want to reimplement all the syscalls.
> 
> I read that it should be possible, but i cannot
> find any example or recipe on how to do it.

mm_segment_t oldfs = get_fs();
set_fs(KERNEL_DS);
ret = sys_yoursyscall(kernelargs ...)
set_fs(oldfs);

Do not even think about using mmap or accessing sys_call_table for this.
Your other post was so tasteless that it would be good if you retracted
it with a followup because it would be very bad to have such an bad
example
in the l-k archives open to innocent search machine users uncommented.

-Andi
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
----<snap>-----

On Tue, Jul 02, 2002 at 09:51:17AM +0200, Timo Benk wrote:
> Hi,
> 
> I found the following function in arch/i386/kernel/sys_i386.c:
> 
> ---<snip>---
> /* common code for old and new mmaps */
> long do_mmap2
> 	(
> 		unsigned long addr, unsigned long len,
> 		unsigned long prot, unsigned long flags,
> 		unsigned long fd,   unsigned long pgoff
> 	)
> {
> 	int error = -EBADF;
> 	struct file * file = NULL;
> 
> 	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
> 	if (!(flags & MAP_ANONYMOUS)) {
> 		file = fget(fd);
> 		if (!file)
> 			goto out;
> 	}
> 
> 	down_write(&current->mm->mmap_sem);
> 	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
> 	up_write(&current->mm->mmap_sem);
> 
> 	if (file)
> 		fput(file);
> out:
> 	return error;
> }
> ---<snap>---
> 
> the following code works for me(of course
> don't forget to munmap the memory).
> ---<snip>---	
> 	char *userspace;
> 	char kernelspace[2048];
> 
> 	userspace = (char*)do_mmap2
> 			(
> 				0, 
> 				2048, 
> 				PROT_READ|PROT_WRITE, 
> 				MAP_PRIVATE|MAP_ANON, 
> 				-1, 
> 				0
> 			);
> 			
> 	copy_to_user( userspace, "/dev/hda", 9 );
> 	
> 	copy_from_user( kernelspace, userspace, 9 );
> 	printk("%s\n",kernelspace);
> ---<snap>---	
> 
> Hope that helps any other struggling newbie:-)
> 
> -timo
> 
> -- 
> gpg key fingerprint = 6832 C8EC D823 4059 0CD1  6FBF 9383 7DBD 109E 98DC
> 

-- 
gpg key fingerprint = 6832 C8EC D823 4059 0CD1  6FBF 9383 7DBD 109E 98DC


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: allocate memory in userspace
  2002-07-01 17:26 allocate memory in userspace Timo Benk
                   ` (2 preceding siblings ...)
  2002-07-02  7:51 ` allocate memory in userspace (Answer) Timo Benk
@ 2002-07-02 12:19 ` Brian Gerst
  3 siblings, 0 replies; 11+ messages in thread
From: Brian Gerst @ 2002-07-02 12:19 UTC (permalink / raw)
  To: Timo Benk; +Cc: linux-kernel

Timo Benk wrote:
> Hi,
> 
> I am a kernel newbie and i am writing a module. I 
> need to allocate some memory in userspace because
> i want to access syscalls like open(), lstat() etc.
> I need to call these methods in the kernel, and in
> my special case there is no other way, but i 
> do not want to reimplement all the syscalls.

What are you trying to do with this module?  If you are needing to use 
syscalls like open(), you are probably trying to do something that is 
forbidden in kernel space.  For example, trying to read a configuration 
file.

Recommended reading:
http://www.linux.org.uk/~ajh/ols2002_proceedings.pdf.gz
The chapter named "How NOT to write kernel drivers", especially sections 
7 and 8.

--
				Brian Gerst


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2002-07-02 12:22 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-07-01 17:26 allocate memory in userspace Timo Benk
2002-07-01 17:49 ` Erik Andersen
2002-07-02  8:37   ` William Lee Irwin III
2002-07-02  8:44     ` William Lee Irwin III
2002-07-02  9:00       ` Erik Andersen
2002-07-01 18:39 ` Calin A. Culianu
2002-07-02  7:51 ` allocate memory in userspace (Answer) Timo Benk
2002-07-02 10:24   ` Timo Benk
2002-07-02 12:19 ` allocate memory in userspace Brian Gerst
     [not found] <20020701172659.GA4431@toshiba.suse.lists.linux.kernel>
2002-07-02  9:30 ` Andi Kleen
2002-07-02 10:21   ` Timo Benk

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.