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/21510] New: Linux setrlimit consolidation breaks LTP: setrlimit02


https://sourceware.org/bugzilla/show_bug.cgi?id=21510

            Bug ID: 21510
           Summary: Linux setrlimit consolidation breaks LTP: setrlimit02
           Product: glibc
           Version: 2.25
               URL: https://sourceware.org/git/?p=glibc.git;a=commit;h=045
                    c13d18554ae626dfc62f392afb33856c6321d
            Status: UNCONFIRMED
          Keywords: glibc_2.24, glibc_2.25
          Severity: normal
          Priority: P2
         Component: libc
          Assignee: unassigned at sourceware dot org
          Reporter: bernhard.kaindl at thalesgroup dot com
                CC: adhemerval.zanella at linaro dot org, drepper.fsp at gmail dot com,
                    joseph at codesourcery dot com
  Target Milestone: 2.26
             Flags: review?

Commit 045c13 (*) Consolidate Linux setrlimit and getrlimit implementation -
https://patchwork.ozlabs.org/patch/685203/ breaks the LTP and and documented
behavior, causing terminated programs which handled errors by checking retcode:

Expected result of setrlimit() with an invalid struct rlimit pointer (-1) from
man ugetrlimit:
EFAULT A pointer argument points to a location outside the accessible address
space.

Actual result with glibc-2.25 (and I expect also 2.24 due to same code):
Program receives SIGBUS on x86-32 and SIGSEGV on other archs like ppc32.
Maybe, only 32 bit archs are affected.

Program received signal SIGBUS, Bus error.
(gdb) bt
#0  __setrlimit (resource=RLIMIT_NOFILE, rlim=0xffffffff) at
../sysdeps/unix/sysv/linux/setrlimit.c:40

__setrlimit (enum __rlimit_resource resource, const struct rlimit *rlim)
{
# ifdef __NR_prlimit64
  struct rlimit64 rlim64;

  if (rlim->rlim_cur == RLIM_INFINITY) <=== This is line 40.

#1  0x08049be4 in main (ac=1, av=0xbffffc54) at setrlimit02.c:95
                        TEST(setrlimit(TC[i].resource, TC[i].rlim));

The test case calls setrlmit() with 0xffffffff and expect EFAULT as documented.
Commit 045c13
(*) The offending change to __setrlimit() was added by Commit 045c13:+int
+__setrlimit (enum __rlimit_resource resource, const struct rlimit *rlim)
+{
+# ifdef __NR_prlimit64
+  struct rlimit64 rlim64;
+
+  if (rlim->rlim_cur == RLIM_INFINITY)
+    rlim64.rlim_cur = RLIM64_INFINITY;
+  else
+    rlim64.rlim_cur = rlim->rlim_cur;
+  if (rlim->rlim_max == RLIM_INFINITY)
+    rlim64.rlim_max = RLIM64_INFINITY;
+  else
+    rlim64.rlim_max = rlim->rlim_max;
+
+  int res = INLINE_SYSCALL_CALL (prlimit64, 0, resource, &rlim64, NULL);
+  if (res == 0 || errno != ENOSYS)
+    return res;
+# endif
+  return INLINE_SYSCALL_CALL (setrlimit, resource, rlim);
+}

For comparsion, sysdeps/unix/sysv/linux/setrlimit64.c from glibc-2.23:
setrlimit64 (enum __rlimit_resource resource, const struct rlimit64 *rlimits)
{
#ifdef __ASSUME_PRLIMIT64
  return INLINE_SYSCALL (prlimit64, 4, 0, resource, rlimits, NULL);
#else
# ifdef __NR_prlimit64
  int res = INLINE_SYSCALL (prlimit64, 4, 0, resource, rlimits, NULL);
  if (res == 0 || errno != ENOSYS)
    return res;
# endif
  struct rlimit rlimits32;

  if (rlimits->rlim_cur >= RLIM_INFINITY)
    rlimits32.rlim_cur = RLIM_INFINITY;
  else
    rlimits32.rlim_cur = rlimits->rlim_cur;
  if (rlimits->rlim_max >= RLIM_INFINITY)
    rlimits32.rlim_max = RLIM_INFINITY;
  else
    rlimits32.rlim_max = rlimits->rlim_max;

  return __setrlimit (resource, &rlimits32);
#endif
}

It appears to me, taht the RLIM_INFINITY are not for prlimit64, but commit
045c13 does it in __setrimit as shown above.

Since commit 045c13, Joseph Myers changed some code to assume that prlimit64 is
always available:
ttps://sourceware.org/git/?p=glibc.git&a=search&h=HEAD&st=commit&s=rlimit

But it appears he missed a few places :
glibc-2.25$ grep -r INLINE_SYSCALL_CALL.*etrlimit
sysdeps/unix/sysv/linux/setrlimit64.c:  res = INLINE_SYSCALL_CALL (setrlimit,
resource, &rlimits32);
sysdeps/unix/sysv/linux/getrlimit.c:  return INLINE_SYSCALL_CALL (ugetrlimit,
resource, rlim);
sysdeps/unix/sysv/linux/getrlimit.c:  return INLINE_SYSCALL_CALL (getrlimit,
resource, rlim);
sysdeps/unix/sysv/linux/getrlimit64.c:  if (INLINE_SYSCALL_CALL (ugetrlimit,
resource, &rlimits32) < 0)
sysdeps/unix/sysv/linux/setrlimit.c:  return INLINE_SYSCALL_CALL (setrlimit,
resource, rlim);

With the RLIM_INFINITY checks removed completely, (if what I saw that they are
obsolete, is indeed true) this issue should be resolved too.

-- 
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]