Browse Source

prlimit: add name redirection and fix incorrect parameters to syscall

The tst-rlimit/tst-rlimit64 tests pointed to several issueses in
prlimit() function for 32-bit CPUs. This patch adds name redirection to
prlimit64 in prlimit declaration to provide correct support for 64-bit
offset (_FILE_OFFSET_BITS=64) on 32-bit CPUs and fixes improper field
assignment and incorrect syscall paramerets in the prlimit() function.

Fixes: 8c2f6218 ("setrlimit/getrlimit: fix prlimit64 syscall use for 32-bit CPUs")
Signed-off-by: Pavel Kozlov <pavel.kozlov@synopsys.com>
Pavel Kozlov 5 months ago
parent
commit
4bf3912213
2 changed files with 21 additions and 6 deletions
  1. 15 3
      include/sys/resource.h
  2. 6 3
      libc/sysdeps/linux/common/prlimit.c

+ 15 - 3
include/sys/resource.h

@@ -103,13 +103,25 @@ libc_hidden_proto(setpriority)
 
 #ifdef __USE_GNU
 /* Modify and return resource limits of a process atomically.  */
+# ifndef __USE_FILE_OFFSET64
 extern int prlimit (__pid_t __pid, enum __rlimit_resource __resource,
-		      const struct rlimit *__new_limit,
-		      struct rlimit *__old_limit) __THROW;
-
+		    const struct rlimit *__new_limit,
+		    struct rlimit *__old_limit) __THROW;
+# else
+#  ifdef __REDIRECT_NTH
+extern int __REDIRECT_NTH (prlimit, (__pid_t __pid,
+				     enum __rlimit_resource __resource,
+				     const struct rlimit *__new_limit,
+				     struct rlimit *__old_limit), prlimit64);
+#  else
+#   define prlimit prlimit64
+#  endif
+# endif
+# ifdef __USE_LARGEFILE64
 extern int prlimit64 (__pid_t __pid, enum __rlimit_resource __resource,
 		      const struct rlimit64 *__new_limit,
 		      struct rlimit64 *__old_limit) __THROW;
+# endif
 #endif
 
 __END_DECLS

+ 6 - 3
libc/sysdeps/linux/common/prlimit.c

@@ -25,7 +25,9 @@ prlimit (__pid_t pid, enum __rlimit_resource resource,
 	 const struct rlimit *new_rlimit, struct rlimit *old_rlimit)
 {
 	struct rlimit64 new_rlimit64;
+	struct rlimit64 *new_rlimit64_ptr = NULL;
 	struct rlimit64 old_rlimit64;
+	struct rlimit64 *old_rlimit64_ptr = (old_rlimit != NULL ? &old_rlimit64 : NULL);
 	int res;
 
 	if (new_rlimit != NULL) {
@@ -37,10 +39,11 @@ prlimit (__pid_t pid, enum __rlimit_resource resource,
 			new_rlimit64.rlim_max = RLIM64_INFINITY;
 		else
 			new_rlimit64.rlim_max = new_rlimit->rlim_max;
+		new_rlimit64_ptr = &new_rlimit64;
 	}
 
-	res = INLINE_SYSCALL (prlimit64, 4, pid, resource, &new_rlimit64,
-			      &old_rlimit64);
+	res = INLINE_SYSCALL (prlimit64, 4, pid, resource, new_rlimit64_ptr,
+			      old_rlimit64_ptr);
 
 	if (res == 0 && old_rlimit != NULL) {
 		/* If the syscall succeeds but the values do not fit into a
@@ -64,7 +67,7 @@ prlimit (__pid_t pid, enum __rlimit_resource resource,
 				__set_errno(EOVERFLOW);
 				return -1;
 			}
-			old_rlimit->rlim_cur = RLIM_INFINITY;
+			old_rlimit->rlim_max = RLIM_INFINITY;
 		}
 	}