Skip to content
  • KOSAKI Motohiro's avatar
    mlock() fix return values · a477097d
    KOSAKI Motohiro authored
    
    
    Halesh says:
    
    Please find the below testcase provide to test mlock.
    
    Test Case :
    ===========================
    
    #include <sys/resource.h>
    #include <stdio.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/mman.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <stdlib.h>
    
    int main(void)
    {
      int fd,ret, i = 0;
      char *addr, *addr1 = NULL;
      unsigned int page_size;
      struct rlimit rlim;
    
      if (0 != geteuid())
      {
       printf("Execute this pgm as root\n");
       exit(1);
      }
    
      /* create a file */
      if ((fd = open("mmap_test.c",O_RDWR|O_CREAT,0755)) == -1)
      {
       printf("cant create test file\n");
       exit(1);
      }
    
      page_size = sysconf(_SC_PAGE_SIZE);
    
      /* set the MEMLOCK limit */
      rlim.rlim_cur = 2000;
      rlim.rlim_max = 2000;
    
      if ((ret = setrlimit(RLIMIT_MEMLOCK,&rlim)) != 0)
      {
       printf("Cant change limit values\n");
       exit(1);
      }
    
      addr = 0;
      while (1)
      {
      /* map a page into memory each time*/
      if ((addr = (char *) mmap(addr,page_size, PROT_READ |
    PROT_WRITE,MAP_SHARED,fd,0)) == MAP_FAILED)
      {
       printf("cant do mmap on file\n");
       exit(1);
      }
    
      if (0 == i)
        addr1 = addr;
      i++;
      errno = 0;
      /* lock the mapped memory pagewise*/
      if ((ret = mlock((char *)addr, 1500)) == -1)
      {
       printf("errno value is %d\n", errno);
       printf("cant lock maped region\n");
       exit(1);
      }
      addr = addr + page_size;
     }
    }
    ======================================================
    
    This testcase results in an mlock() failure with errno 14 that is EFAULT,
    but it has nowhere been specified that mlock() will return EFAULT.  When I
    tested the same on older kernels like 2.6.18, I got the correct result i.e
    errno 12 (ENOMEM).
    
    I think in source code mlock(2), setting errno ENOMEM has been missed in
    do_mlock() , on mlock_fixup() failure.
    
    SUSv3 requires the following behavior frmo mlock(2).
    
    [ENOMEM]
        Some or all of the address range specified by the addr and
        len arguments does not correspond to valid mapped pages
        in the address space of the process.
    
    [EAGAIN]
        Some or all of the memory identified by the operation could not
        be locked when the call was made.
    
    This rule isn't so nice and slighly strange.  but many people think
    POSIX/SUS compliance is important.
    
    Reported-by: default avatarHalesh Sadashiv <halesh.sadashiv@ap.sony.com>
    Tested-by: default avatarHalesh Sadashiv <halesh.sadashiv@ap.sony.com>
    Signed-off-by: default avatarKOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
    Cc: <stable@kernel.org>		[2.6.25.x, 2.6.26.x]
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    a477097d