This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libc/12201] Fix setrlimit/getrlimit 32-bit platforms for limits > 2^32-1


http://sourceware.org/bugzilla/show_bug.cgi?id=12201

Michael Kerrisk <mtk.manpages at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|WAITING                     |NEW

--- Comment #2 from Michael Kerrisk <mtk.manpages at gmail dot com> 2010-11-11 05:33:45 UTC ---
(In reply to comment #1)
> What exactly are you talking about?

It was fairly carefully explained in the kernel.org bug report...

> We are using ugetrlimit for some time.  At
> the same time setrlimit was changed.  These syscalls now match exactly the
> required userlevel semantic.

No, they do not. Look at the following.

$ cat rlimit_large.c 
/* rlimit_large.c
*/
#define _FILE_OFFSET_BITS 64
#include <sys/resource.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#define errMsg(msg)             { perror(msg); }

#define errExit(msg)            { perror(msg); exit(EXIT_FAILURE); }

static void
printRlimit(const char *msg, int resource)
{
    struct rlimit rlim;

    if (getrlimit(resource, &rlim) == -1) errExit("getrlimit");

    printf("%s soft=", msg);
    if (rlim.rlim_cur == RLIM_INFINITY)
        printf("infinite");
    else if (rlim.rlim_cur == RLIM_SAVED_CUR)
        printf("unrepresentable");
    else
        printf("%lld", (long long) rlim.rlim_cur);

    printf("; hard=");
    if (rlim.rlim_max == RLIM_INFINITY)
        printf("infinite\n");
    else if (rlim.rlim_max == RLIM_SAVED_MAX)
        printf("unrepresentable");
    else
        printf("%lld\n", (long long) rlim.rlim_max);
} /* printRlimit */

int
main(int argc, char *argv[])
{
    struct rlimit rl;
    printf("sizeof(rl.rlim_cur) = %ld\n", (long) sizeof(rl.rlim_cur));

    /* Show the value of the glibc constant, just for interest */

    printf("RLIM_INFINITY = %llx\n", (unsigned long long) RLIM_INFINITY);

    if (getrlimit(RLIMIT_FSIZE, &rl) == -1) errExit("setrlimit");
    printRlimit("Initial RLIMIT_FSIZE limits          : ", RLIMIT_FSIZE);

#define VAL1 10000
    rl.rlim_cur = VAL1;
    printf("About to set rlim_cur to %lld\n", (long long) rl.rlim_cur);
    if (setrlimit(RLIMIT_FSIZE, &rl) == -1) errExit("setrlimit");
    if (getrlimit(RLIMIT_FSIZE, &rl) == -1) errExit("setrlimit");
    printRlimit("RLIMIT_FSIZE limits after setrlimit(): ", RLIMIT_FSIZE);

#define VAL2 4999222333LL
    rl.rlim_cur = VAL2;
    printf("About to set rlim_cur to %lld\n", (long long) rl.rlim_cur);
    if (setrlimit(RLIMIT_FSIZE, &rl) == -1) errExit("setrlimit");
    if (getrlimit(RLIMIT_FSIZE, &rl) == -1) errExit("setrlimit");
    printRlimit("RLIMIT_FSIZE limits after setrlimit(): ", RLIMIT_FSIZE);

    exit(EXIT_SUCCESS);
} /* main */

$ cc rlimit_large.c 
$ ./a.out
sizeof(rl.rlim_cur) = 8
RLIM_INFINITY = ffffffffffffffff
Initial RLIMIT_FSIZE limits          :  soft=infinite; hard=infinite
About to set rlim_cur to 10000
RLIMIT_FSIZE limits after setrlimit():  soft=10000; hard=infinite
About to set rlim_cur to 4999222333
RLIMIT_FSIZE limits after setrlimit():  soft=infinite; hard=infinite


The last line of output indicates the problem: a limit > (2^32)-1 got turned
into RLIM_INFINITY, even though it is representable in 8 bytes. It's a kernel
problem, but glibc's wrappers could now workaround that kernel problem by using
prlimit().

-- 
Configure bugmail: http://sourceware.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]