bugThe GNU Hurd - Bugs: bug #15403, can't mlock mmap'd memory

 
 

bug #15403: can't mlock mmap'd memory

Submitted by:  Ben Asselstine <benasselstine>
Submitted on:  Sat 07 Jan 2006 08:45:13 PM UTC  
 
Category:  None Severity:  3 - Normal
Priority:  7 - High Item Group:  None
Status:  Confirmed Privacy:  Public
Assigned to:  None Originator Name:  Ben Asselstine
Open/Closed:  Open Reproducibility:  Every Time
Size (loc):  None Planned Release:  None
Effort:  0.00
Wiki-like text discussion box: 

Add a New Comment(Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

Tue 17 Jan 2006 11:05:45 PM UTC, comment #1:

Hi,

Some tests seem to show that only stacked objects can be mlock()ed.

Mlock() is implemented through vm_wire(blabla, VM_PROT_ALL): `Specify that the range of the virtual address space of the target task must not cause page faults for the indicated accesses.'

This is wrong: doing it on text segments can't work for instance, since page-write faults must still occur on them (since they're read-only). Same remark for data segments / executability, etc. The actual check is performed in vm_map_pageable_common(): if (entry->protection & access_type) != access_type, it returns KERN_FAILURE.

A simple solution would be to change the implementation of mlock(): make it call just vm_wire(blabla, VM_PROT_READ), which will work for both code, data, and stack. Yes, it is sufficient for preventing the process from copy-on-write faults too, because even if VM_PROT_WRITE is not given, vm_map_pageable_common() will perform the copy. This solution will however probably not work for pages that were mprotect(PROT_NONE)-ed (i.e. entry->protection == 0, not even VM_PROT_READ).

Another solution would be to add an additionnal VM_PROT_LOCKED flag that would exactly mean what mlock() needs: the page is resident and no copy on write will happen. And then use only that one in glibc. It shouldn't be very difficult to implement.

Regards,
Samuel

Samuel Thibault <sthibaul>
Project Member
Sat 07 Jan 2006 08:45:13 PM UTC, original submission:

In trying to get gnupg to work on the Hurd, I boiled the problem down to the following code snippet:

---
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>

int main()
{
char *pool;
int err;
long int pgsize = getpagesize();

pool = mmap( 0, 32768 + pgsize, PROT_READ|PROT_WRITE,
MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
//pool = malloc (32768 + pgsize);

if( !pool )
return 2;

pool += (pgsize - ((long int)pool % pgsize));
err = mlock( pool, 32768);
printf ("err is %d, errno = %d\n", err, errno);
if (err)
printf ("EKERN_FAILURE = %d\n", EKERN_FAILURE);

return err;
}
---

One strange thing to note is that mlock'ing malloc'ed memory works.

I think the EKERN_FAILURE comes from gnumach/vm/vm_map.c:vm_map_pageable_common, but I'm not certain as I haven't run it through a debugger.

I hope that somebody else has the skill required to investigate this bug further.

Regards,

Ben

Ben Asselstine <benasselstine>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #2172:  patch-glibc-mlock added by sthibaul (770B - application/octet-stream - Simple fix. Does not work for non-readable pages, but should be sufficient for far most uses for now.)

 

Depends on the following items: None found

Items that depend on this one: None found

 

CC list is empty

 

Do you think this task is very important?
If so, you can add your encouragement to it.
This task has 0 encouragements so far.

Only logged-in users can vote.

 

 

 

Follow 4 latest changes.

Date Changed by Updated Field Previous Value => Replaced by
2006-01-18 sthibaul Attached File- => Added patch-glibc-mlock, #3292
2006-01-08 ams Priority5 - Normal => 7 - High
    StatusNone => Confirmed
2006-01-07 benasselstine Carbon-Copy- => Added -email is unavailable-

Back to the top


Powered by Savane 3.3