1 |
jpp |
1.1 |
diff -up sudo-1.8.6p3/src/sudo.c.nprocfix sudo-1.8.6p3/src/sudo.c |
2 |
|
|
--- sudo-1.8.6p3/src/sudo.c.nprocfix 2013-08-08 14:35:57.288259678 +0200 |
3 |
|
|
+++ sudo-1.8.6p3/src/sudo.c 2013-08-08 15:02:16.288182205 +0200 |
4 |
|
|
@@ -808,26 +808,11 @@ sudo_check_suid(const char *path) |
5 |
|
|
static void |
6 |
|
|
disable_coredumps(void) |
7 |
|
|
{ |
8 |
|
|
-#if defined(__linux__) || defined(RLIMIT_CORE) |
9 |
|
|
+#if defined(RLIMIT_CORE) |
10 |
|
|
struct rlimit rl; |
11 |
|
|
-#endif |
12 |
|
|
+ |
13 |
|
|
debug_decl(disable_coredumps, SUDO_DEBUG_UTIL) |
14 |
|
|
|
15 |
|
|
-#if defined(__linux__) |
16 |
|
|
- /* |
17 |
|
|
- * Unlimit the number of processes since Linux's setuid() will |
18 |
|
|
- * apply resource limits when changing uid and return EAGAIN if |
19 |
|
|
- * nproc would be violated by the uid switch. |
20 |
|
|
- */ |
21 |
|
|
- (void) getrlimit(RLIMIT_NPROC, &nproclimit); |
22 |
|
|
- rl.rlim_cur = rl.rlim_max = RLIM_INFINITY; |
23 |
|
|
- if (setrlimit(RLIMIT_NPROC, &rl)) { |
24 |
|
|
- memcpy(&rl, &nproclimit, sizeof(struct rlimit)); |
25 |
|
|
- rl.rlim_cur = rl.rlim_max; |
26 |
|
|
- (void)setrlimit(RLIMIT_NPROC, &rl); |
27 |
|
|
- } |
28 |
|
|
-#endif /* __linux__ */ |
29 |
|
|
-#ifdef RLIMIT_CORE |
30 |
|
|
/* |
31 |
|
|
* Turn off core dumps? |
32 |
|
|
*/ |
33 |
|
|
@@ -841,6 +826,44 @@ disable_coredumps(void) |
34 |
|
|
debug_return; |
35 |
|
|
} |
36 |
|
|
|
37 |
|
|
+/* |
38 |
|
|
+ * Unlimit the number of processes since Linux's setuid() will |
39 |
|
|
+ * apply resource limits when changing uid and return EAGAIN if |
40 |
|
|
+ * nproc would be exceeded by the uid switch. |
41 |
|
|
+ */ |
42 |
|
|
+static void |
43 |
|
|
+unlimit_nproc(void) |
44 |
|
|
+{ |
45 |
|
|
+#ifdef __linux__ |
46 |
|
|
+ struct rlimit rl; |
47 |
|
|
+ debug_decl(unlimit_nproc, SUDO_DEBUG_UTIL) |
48 |
|
|
+ |
49 |
|
|
+ (void) getrlimit(RLIMIT_NPROC, &nproclimit); |
50 |
|
|
+ rl.rlim_cur = rl.rlim_max = RLIM_INFINITY; |
51 |
|
|
+ if (setrlimit(RLIMIT_NPROC, &rl) != 0) { |
52 |
|
|
+ memcpy(&rl, &nproclimit, sizeof(struct rlimit)); |
53 |
|
|
+ rl.rlim_cur = rl.rlim_max; |
54 |
|
|
+ (void)setrlimit(RLIMIT_NPROC, &rl); |
55 |
|
|
+ } |
56 |
|
|
+ debug_return; |
57 |
|
|
+#endif /* __linux__ */ |
58 |
|
|
+} |
59 |
|
|
+ |
60 |
|
|
+/* |
61 |
|
|
+ * Restore saved value of RLIMIT_NPROC. |
62 |
|
|
+ */ |
63 |
|
|
+static void |
64 |
|
|
+restore_nproc(void) |
65 |
|
|
+{ |
66 |
|
|
+#ifdef __linux__ |
67 |
|
|
+ debug_decl(restore_nproc, SUDO_DEBUG_UTIL) |
68 |
|
|
+ |
69 |
|
|
+ (void) setrlimit(RLIMIT_NPROC, &nproclimit); |
70 |
|
|
+ |
71 |
|
|
+ debug_return; |
72 |
|
|
+#endif /* __linux__ */ |
73 |
|
|
+ } |
74 |
|
|
+ |
75 |
|
|
#ifdef HAVE_PROJECT_H |
76 |
|
|
static void |
77 |
|
|
set_project(struct passwd *pw) |
78 |
|
|
@@ -1027,6 +1050,12 @@ exec_setup(struct command_details *detai |
79 |
|
|
} |
80 |
|
|
} |
81 |
|
|
|
82 |
|
|
+ /* |
83 |
|
|
+ * Unlimit the number of processes since Linux's setuid() will |
84 |
|
|
+ * return EAGAIN if RLIMIT_NPROC would be exceeded by the uid switch. |
85 |
|
|
+ */ |
86 |
|
|
+ unlimit_nproc(); |
87 |
|
|
+ |
88 |
|
|
#ifdef HAVE_SETRESUID |
89 |
|
|
if (setresuid(details->uid, details->euid, details->euid) != 0) { |
90 |
|
|
warning(_("unable to change to runas uid (%u, %u)"), details->uid, |
91 |
|
|
@@ -1047,6 +1076,9 @@ exec_setup(struct command_details *detai |
92 |
|
|
} |
93 |
|
|
#endif /* !HAVE_SETRESUID && !HAVE_SETREUID */ |
94 |
|
|
|
95 |
|
|
+ /* Restore previous value of RLIMIT_NPROC. */ |
96 |
|
|
+ restore_nproc(); |
97 |
|
|
+ |
98 |
|
|
/* |
99 |
|
|
* Only change cwd if we have chroot()ed or the policy modules |
100 |
|
|
* specifies a different cwd. Must be done after uid change. |
101 |
|
|
@@ -1061,33 +1093,6 @@ exec_setup(struct command_details *detai |
102 |
|
|
} |
103 |
|
|
} |
104 |
|
|
|
105 |
|
|
- /* |
106 |
|
|
- * SuSE Enterprise Linux uses RLIMIT_NPROC and _SC_CHILD_MAX |
107 |
|
|
- * interchangably. This causes problems when setting RLIMIT_NPROC |
108 |
|
|
- * to RLIM_INFINITY due to a bug in bash where bash tries to honor |
109 |
|
|
- * the value of _SC_CHILD_MAX but treats a value of -1 as an error, |
110 |
|
|
- * and uses a default value of 32 instead. |
111 |
|
|
- * |
112 |
|
|
- * To work around this problem, we restore the nproc resource limit |
113 |
|
|
- * if sysconf(_SC_CHILD_MAX) is negative. In most cases, pam_limits |
114 |
|
|
- * will set RLIMIT_NPROC for us. |
115 |
|
|
- * |
116 |
|
|
- * We must do this *after* the uid change to avoid potential EAGAIN |
117 |
|
|
- * from setuid(). |
118 |
|
|
- */ |
119 |
|
|
-#if defined(__linux__) && defined(_SC_CHILD_MAX) |
120 |
|
|
- { |
121 |
|
|
- struct rlimit rl; |
122 |
|
|
- long l; |
123 |
|
|
- errno = 0; |
124 |
|
|
- l = sysconf(_SC_CHILD_MAX); |
125 |
|
|
- if (l == -1 && errno == 0 && getrlimit(RLIMIT_NPROC, &rl) == 0) { |
126 |
|
|
- if (rl.rlim_cur == RLIM_INFINITY && rl.rlim_max == RLIM_INFINITY) |
127 |
|
|
- (void) setrlimit(RLIMIT_NPROC, &nproclimit); |
128 |
|
|
- } |
129 |
|
|
- } |
130 |
|
|
-#endif |
131 |
|
|
- |
132 |
|
|
rval = true; |
133 |
|
|
|
134 |
|
|
done: |