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

 
 

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

Submitter:  Ben Asselstine <benasselstine>
Submitted:  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: 


* Mandatory Fields

Add a New Comment Rich Markup
   

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>
Group administrator
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

 

There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

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.13-4448.
Corresponding source code