* 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: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
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(¤t->mm->mmap_sem);
error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
up_write(¤t->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 (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(¤t->mm->mmap_sem);
> error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
> up_write(¤t->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