1 |
commit: ae5b1676fa2785c6d8e6090cca75f1df20ff1768 |
2 |
Author: Andreas Sturmlechner <asturm <AT> gentoo <DOT> org> |
3 |
AuthorDate: Sun May 27 16:52:13 2018 +0000 |
4 |
Commit: Andreas Sturmlechner <asturm <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun May 27 16:52:40 2018 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=ae5b1676 |
7 |
|
8 |
kde-plasma/kwallet-pam: Re-add accidentally removed patches |
9 |
|
10 |
Closes: https://bugs.gentoo.org/656694 |
11 |
Package-Manager: Portage-2.3.40, Repoman-2.3.9 |
12 |
|
13 |
.../kwallet-pam-5.11.5-CVE-2018-10380-1.patch | 206 +++++++++++++++++++++ |
14 |
.../kwallet-pam-5.11.5-CVE-2018-10380-2.patch | 135 ++++++++++++++ |
15 |
.../kwallet-pam-5.11.5-CVE-2018-10380-3.patch | 54 ++++++ |
16 |
3 files changed, 395 insertions(+) |
17 |
|
18 |
diff --git a/kde-plasma/kwallet-pam/files/kwallet-pam-5.11.5-CVE-2018-10380-1.patch b/kde-plasma/kwallet-pam/files/kwallet-pam-5.11.5-CVE-2018-10380-1.patch |
19 |
new file mode 100644 |
20 |
index 00000000000..70ade02a825 |
21 |
--- /dev/null |
22 |
+++ b/kde-plasma/kwallet-pam/files/kwallet-pam-5.11.5-CVE-2018-10380-1.patch |
23 |
@@ -0,0 +1,206 @@ |
24 |
+From 2134dec85ce19d6378d03cddfae9e5e464cb24c0 Mon Sep 17 00:00:00 2001 |
25 |
+From: Albert Astals Cid <aacid@×××.org> |
26 |
+Date: Tue, 1 May 2018 12:29:02 +0200 |
27 |
+Subject: Move salt creation to an unprivileged process |
28 |
+ |
29 |
+Opening files for writing as root is very tricky since through the power |
30 |
+of symlinks we can get tricked to write in places we don't want to and |
31 |
+we don't really need to be root to create the salt file |
32 |
+--- |
33 |
+ pam_kwallet.c | 121 ++++++++++++++++++++++++++++++++++------------------------ |
34 |
+ 1 file changed, 71 insertions(+), 50 deletions(-) |
35 |
+ |
36 |
+diff --git a/pam_kwallet.c b/pam_kwallet.c |
37 |
+index 20d9603..083c9aa 100644 |
38 |
+--- a/pam_kwallet.c |
39 |
++++ b/pam_kwallet.c |
40 |
+@@ -82,7 +82,7 @@ const static char *envVar = "PAM_KWALLET_LOGIN"; |
41 |
+ |
42 |
+ static int argumentsParsed = -1; |
43 |
+ |
44 |
+-int kwallet_hash(const char *passphrase, struct passwd *userInfo, char *key); |
45 |
++int kwallet_hash(pam_handle_t *pamh, const char *passphrase, struct passwd *userInfo, char *key); |
46 |
+ |
47 |
+ static void parseArguments(int argc, const char **argv) |
48 |
+ { |
49 |
+@@ -325,7 +325,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, cons |
50 |
+ } |
51 |
+ |
52 |
+ char *key = malloc(KWALLET_PAM_KEYSIZE); |
53 |
+- if (!key || kwallet_hash(password, userInfo, key) != 0) { |
54 |
++ if (!key || kwallet_hash(pamh, password, userInfo, key) != 0) { |
55 |
+ free(key); |
56 |
+ pam_syslog(pamh, LOG_ERR, "%s: Fail into creating the hash", logPrefix); |
57 |
+ return PAM_IGNORE; |
58 |
+@@ -352,6 +352,26 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, cons |
59 |
+ return PAM_SUCCESS; |
60 |
+ } |
61 |
+ |
62 |
++static int drop_privileges(struct passwd *userInfo) |
63 |
++{ |
64 |
++ /* When dropping privileges from root, the `setgroups` call will |
65 |
++ * remove any extraneous groups. If we don't call this, then |
66 |
++ * even though our uid has dropped, we may still have groups |
67 |
++ * that enable us to do super-user things. This will fail if we |
68 |
++ * aren't root, so don't bother checking the return value, this |
69 |
++ * is just done as an optimistic privilege dropping function. |
70 |
++ */ |
71 |
++ setgroups(0, NULL); |
72 |
++ |
73 |
++ //Change to the user in case we are not it yet |
74 |
++ if (setgid (userInfo->pw_gid) < 0 || setuid (userInfo->pw_uid) < 0 || |
75 |
++ setegid (userInfo->pw_gid) < 0 || seteuid (userInfo->pw_uid) < 0) { |
76 |
++ return -1; |
77 |
++ } |
78 |
++ |
79 |
++ return 0; |
80 |
++} |
81 |
++ |
82 |
+ static void execute_kwallet(pam_handle_t *pamh, struct passwd *userInfo, int toWalletPipe[2], int envSocket) |
83 |
+ { |
84 |
+ //In the child pam_syslog does not work, using syslog directly |
85 |
+@@ -366,18 +386,8 @@ static void execute_kwallet(pam_handle_t *pamh, struct passwd *userInfo, int toW |
86 |
+ //This is the side of the pipe PAM will send the hash to |
87 |
+ close (toWalletPipe[1]); |
88 |
+ |
89 |
+- /* When dropping privileges from root, the `setgroups` call will |
90 |
+- * remove any extraneous groups. If we don't call this, then |
91 |
+- * even though our uid has dropped, we may still have groups |
92 |
+- * that enable us to do super-user things. This will fail if we |
93 |
+- * aren't root, so don't bother checking the return value, this |
94 |
+- * is just done as an optimistic privilege dropping function. |
95 |
+- */ |
96 |
+- setgroups(0, NULL); |
97 |
+- |
98 |
+ //Change to the user in case we are not it yet |
99 |
+- if (setgid (userInfo->pw_gid) < 0 || setuid (userInfo->pw_uid) < 0 || |
100 |
+- setegid (userInfo->pw_gid) < 0 || seteuid (userInfo->pw_uid) < 0) { |
101 |
++ if (drop_privileges(userInfo) < 0) { |
102 |
+ syslog(LOG_ERR, "%s: could not set gid/uid/euid/egit for kwalletd", logPrefix); |
103 |
+ goto cleanup; |
104 |
+ } |
105 |
+@@ -619,7 +629,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const c |
106 |
+ return PAM_SUCCESS; |
107 |
+ } |
108 |
+ |
109 |
+-int mkpath(char *path, struct passwd *userInfo) |
110 |
++static int mkpath(char *path) |
111 |
+ { |
112 |
+ struct stat sb; |
113 |
+ char *slash; |
114 |
+@@ -639,10 +649,6 @@ int mkpath(char *path, struct passwd *userInfo) |
115 |
+ errno != EEXIST)) { |
116 |
+ syslog(LOG_ERR, "%s: Couldn't create directory: %s because: %d-%s", logPrefix, path, errno, strerror(errno)); |
117 |
+ return (-1); |
118 |
+- } else { |
119 |
+- if (chown(path, userInfo->pw_uid, userInfo->pw_gid) == -1) { |
120 |
+- syslog(LOG_INFO, "%s: Couldn't change ownership of: %s", logPrefix, path); |
121 |
+- } |
122 |
+ } |
123 |
+ } else if (!S_ISDIR(sb.st_mode)) { |
124 |
+ return (-1); |
125 |
+@@ -654,34 +660,49 @@ int mkpath(char *path, struct passwd *userInfo) |
126 |
+ return (0); |
127 |
+ } |
128 |
+ |
129 |
+-static char* createNewSalt(const char *path, struct passwd *userInfo) |
130 |
++static void createNewSalt(pam_handle_t *pamh, const char *path, struct passwd *userInfo) |
131 |
+ { |
132 |
+- unlink(path);//in case the file already exists |
133 |
++ const int pid = fork(); |
134 |
++ if (pid == -1) { |
135 |
++ pam_syslog(pamh, LOG_ERR, "%s: Couldn't fork to create salt file", logPrefix); |
136 |
++ } else if (pid == 0) { |
137 |
++ // Child process |
138 |
++ if (drop_privileges(userInfo) < 0) { |
139 |
++ syslog(LOG_ERR, "%s: could not set gid/uid/euid/egit for salt file creation", logPrefix); |
140 |
++ exit(-1); |
141 |
++ } |
142 |
+ |
143 |
+- char *dir = strdup(path); |
144 |
+- dir[strlen(dir) - 14] = '\0';//remove kdewallet.salt |
145 |
+- mkpath(dir, userInfo);//create the path in case it does not exists |
146 |
+- free(dir); |
147 |
++ unlink(path);//in case the file already exists |
148 |
+ |
149 |
+- char *salt = gcry_random_bytes(KWALLET_PAM_SALTSIZE, GCRY_STRONG_RANDOM); |
150 |
+- FILE *fd = fopen(path, "w"); |
151 |
++ char *dir = strdup(path); |
152 |
++ dir[strlen(dir) - 14] = '\0';//remove kdewallet.salt |
153 |
++ mkpath(dir); //create the path in case it does not exists |
154 |
++ free(dir); |
155 |
+ |
156 |
+- //If the file can't be created |
157 |
+- if (fd == NULL) { |
158 |
+- syslog(LOG_ERR, "%s: Couldn't open file: %s because: %d-%s", logPrefix, path, errno, strerror(errno)); |
159 |
+- return NULL; |
160 |
+- } |
161 |
++ char *salt = gcry_random_bytes(KWALLET_PAM_SALTSIZE, GCRY_STRONG_RANDOM); |
162 |
++ FILE *fd = fopen(path, "w"); |
163 |
+ |
164 |
+- fwrite(salt, KWALLET_PAM_SALTSIZE, 1, fd); |
165 |
+- fclose(fd); |
166 |
++ //If the file can't be created |
167 |
++ if (fd == NULL) { |
168 |
++ syslog(LOG_ERR, "%s: Couldn't open file: %s because: %d-%s", logPrefix, path, errno, strerror(errno)); |
169 |
++ exit(-2); |
170 |
++ } |
171 |
+ |
172 |
+- if (chown(path, userInfo->pw_uid, userInfo->pw_gid) == -1) { |
173 |
+- syslog(LOG_ERR, "%s: Couldn't change ownership of the created salt file", logPrefix); |
174 |
+- } |
175 |
++ fwrite(salt, KWALLET_PAM_SALTSIZE, 1, fd); |
176 |
++ fclose(fd); |
177 |
+ |
178 |
+- return salt; |
179 |
++ exit(0); // success |
180 |
++ } else { |
181 |
++ // pam process, just wait for child to finish |
182 |
++ int status; |
183 |
++ waitpid(pid, &status, 0); |
184 |
++ if (status != 0) { |
185 |
++ pam_syslog(pamh, LOG_ERR, "%s: Couldn't create salt file", logPrefix); |
186 |
++ } |
187 |
++ } |
188 |
+ } |
189 |
+-int kwallet_hash(const char *passphrase, struct passwd *userInfo, char *key) |
190 |
++ |
191 |
++int kwallet_hash(pam_handle_t *pamh, const char *passphrase, struct passwd *userInfo, char *key) |
192 |
+ { |
193 |
+ if (!gcry_check_version("1.5.0")) { |
194 |
+ syslog(LOG_ERR, "%s-kwalletd: libcrypt version is too old", logPrefix); |
195 |
+@@ -700,19 +721,19 @@ int kwallet_hash(const char *passphrase, struct passwd *userInfo, char *key) |
196 |
+ struct stat info; |
197 |
+ char *salt = NULL; |
198 |
+ if (stat(path, &info) != 0 || info.st_size == 0) { |
199 |
+- salt = createNewSalt(path, userInfo); |
200 |
+- } else { |
201 |
+- FILE *fd = fopen(path, "r"); |
202 |
+- if (fd == NULL) { |
203 |
+- syslog(LOG_ERR, "%s: Couldn't open file: %s because: %d-%s", logPrefix, path, errno, strerror(errno)); |
204 |
+- free(path); |
205 |
+- return 1; |
206 |
+- } |
207 |
+- salt = (char*) malloc(KWALLET_PAM_SALTSIZE); |
208 |
+- memset(salt, '\0', KWALLET_PAM_SALTSIZE); |
209 |
+- fread(salt, KWALLET_PAM_SALTSIZE, 1, fd); |
210 |
+- fclose(fd); |
211 |
++ createNewSalt(pamh, path, userInfo); |
212 |
+ } |
213 |
++ |
214 |
++ FILE *fd = fopen(path, "r"); |
215 |
++ if (fd == NULL) { |
216 |
++ syslog(LOG_ERR, "%s: Couldn't open file: %s because: %d-%s", logPrefix, path, errno, strerror(errno)); |
217 |
++ free(path); |
218 |
++ return 1; |
219 |
++ } |
220 |
++ salt = (char*) malloc(KWALLET_PAM_SALTSIZE); |
221 |
++ memset(salt, '\0', KWALLET_PAM_SALTSIZE); |
222 |
++ fread(salt, KWALLET_PAM_SALTSIZE, 1, fd); |
223 |
++ fclose(fd); |
224 |
+ free(path); |
225 |
+ |
226 |
+ if (salt == NULL) { |
227 |
+-- |
228 |
+cgit v0.11.2 |
229 |
+ |
230 |
|
231 |
diff --git a/kde-plasma/kwallet-pam/files/kwallet-pam-5.11.5-CVE-2018-10380-2.patch b/kde-plasma/kwallet-pam/files/kwallet-pam-5.11.5-CVE-2018-10380-2.patch |
232 |
new file mode 100644 |
233 |
index 00000000000..2f88e0c3cea |
234 |
--- /dev/null |
235 |
+++ b/kde-plasma/kwallet-pam/files/kwallet-pam-5.11.5-CVE-2018-10380-2.patch |
236 |
@@ -0,0 +1,135 @@ |
237 |
+From 01d4143fda5bddb6dca37b23304dc239a5fb38b5 Mon Sep 17 00:00:00 2001 |
238 |
+From: Albert Astals Cid <aacid@×××.org> |
239 |
+Date: Tue, 1 May 2018 12:32:24 +0200 |
240 |
+Subject: Move socket creation to unprivileged codepath |
241 |
+ |
242 |
+We don't need to be creating the socket as root, and doing so, |
243 |
+specially having a chown is problematic security wise. |
244 |
+--- |
245 |
+ pam_kwallet.c | 77 ++++++++++++++++++++++++++++------------------------------- |
246 |
+ 1 file changed, 36 insertions(+), 41 deletions(-) |
247 |
+ |
248 |
+diff --git a/pam_kwallet.c b/pam_kwallet.c |
249 |
+index 083c9aa..b9c984a 100644 |
250 |
+--- a/pam_kwallet.c |
251 |
++++ b/pam_kwallet.c |
252 |
+@@ -372,13 +372,13 @@ static int drop_privileges(struct passwd *userInfo) |
253 |
+ return 0; |
254 |
+ } |
255 |
+ |
256 |
+-static void execute_kwallet(pam_handle_t *pamh, struct passwd *userInfo, int toWalletPipe[2], int envSocket) |
257 |
++static void execute_kwallet(pam_handle_t *pamh, struct passwd *userInfo, int toWalletPipe[2], char *fullSocket) |
258 |
+ { |
259 |
+ //In the child pam_syslog does not work, using syslog directly |
260 |
+ int x = 2; |
261 |
+ //Close fd that are not of interest of kwallet |
262 |
+ for (; x < 64; ++x) { |
263 |
+- if (x != toWalletPipe[0] && x != envSocket) { |
264 |
++ if (x != toWalletPipe[0]) { |
265 |
+ close (x); |
266 |
+ } |
267 |
+ } |
268 |
+@@ -392,6 +392,39 @@ static void execute_kwallet(pam_handle_t *pamh, struct passwd *userInfo, int toW |
269 |
+ goto cleanup; |
270 |
+ } |
271 |
+ |
272 |
++ int envSocket; |
273 |
++ if ((envSocket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { |
274 |
++ pam_syslog(pamh, LOG_ERR, "%s: couldn't create socket", logPrefix); |
275 |
++ return; |
276 |
++ } |
277 |
++ |
278 |
++ struct sockaddr_un local; |
279 |
++ local.sun_family = AF_UNIX; |
280 |
++ |
281 |
++ if (strlen(fullSocket) > sizeof(local.sun_path)) { |
282 |
++ pam_syslog(pamh, LOG_ERR, "%s: socket path %s too long to open", |
283 |
++ logPrefix, fullSocket); |
284 |
++ free(fullSocket); |
285 |
++ return; |
286 |
++ } |
287 |
++ strcpy(local.sun_path, fullSocket); |
288 |
++ free(fullSocket); |
289 |
++ fullSocket = NULL; |
290 |
++ unlink(local.sun_path);//Just in case it exists from a previous login |
291 |
++ |
292 |
++ pam_syslog(pamh, LOG_INFO, "%s: final socket path: %s", logPrefix, local.sun_path); |
293 |
++ |
294 |
++ size_t len = strlen(local.sun_path) + sizeof(local.sun_family); |
295 |
++ if (bind(envSocket, (struct sockaddr *)&local, len) == -1) { |
296 |
++ pam_syslog(pamh, LOG_INFO, "%s-kwalletd: Couldn't bind to local file\n", logPrefix); |
297 |
++ return; |
298 |
++ } |
299 |
++ |
300 |
++ if (listen(envSocket, 5) == -1) { |
301 |
++ pam_syslog(pamh, LOG_INFO, "%s-kwalletd: Couldn't listen in socket\n", logPrefix); |
302 |
++ return; |
303 |
++ } |
304 |
++ |
305 |
+ // Fork twice to daemonize kwallet |
306 |
+ setsid(); |
307 |
+ pid_t pid = fork(); |
308 |
+@@ -452,12 +485,6 @@ static void start_kwallet(pam_handle_t *pamh, struct passwd *userInfo, const cha |
309 |
+ pam_syslog(pamh, LOG_ERR, "%s: Couldn't create pipes", logPrefix); |
310 |
+ } |
311 |
+ |
312 |
+- int envSocket; |
313 |
+- if ((envSocket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { |
314 |
+- pam_syslog(pamh, LOG_ERR, "%s: couldn't create socket", logPrefix); |
315 |
+- return; |
316 |
+- } |
317 |
+- |
318 |
+ #ifdef KWALLET5 |
319 |
+ const char *socketPrefix = "kwallet5"; |
320 |
+ #else |
321 |
+@@ -493,38 +520,6 @@ static void start_kwallet(pam_handle_t *pamh, struct passwd *userInfo, const cha |
322 |
+ return; |
323 |
+ } |
324 |
+ |
325 |
+- struct sockaddr_un local; |
326 |
+- local.sun_family = AF_UNIX; |
327 |
+- |
328 |
+- if (strlen(fullSocket) > sizeof(local.sun_path)) { |
329 |
+- pam_syslog(pamh, LOG_ERR, "%s: socket path %s too long to open", |
330 |
+- logPrefix, fullSocket); |
331 |
+- free(fullSocket); |
332 |
+- return; |
333 |
+- } |
334 |
+- strcpy(local.sun_path, fullSocket); |
335 |
+- free(fullSocket); |
336 |
+- fullSocket = NULL; |
337 |
+- unlink(local.sun_path);//Just in case it exists from a previous login |
338 |
+- |
339 |
+- pam_syslog(pamh, LOG_INFO, "%s: final socket path: %s", logPrefix, local.sun_path); |
340 |
+- |
341 |
+- size_t len = strlen(local.sun_path) + sizeof(local.sun_family); |
342 |
+- if (bind(envSocket, (struct sockaddr *)&local, len) == -1) { |
343 |
+- pam_syslog(pamh, LOG_INFO, "%s-kwalletd: Couldn't bind to local file\n", logPrefix); |
344 |
+- return; |
345 |
+- } |
346 |
+- |
347 |
+- if (listen(envSocket, 5) == -1) { |
348 |
+- pam_syslog(pamh, LOG_INFO, "%s-kwalletd: Couldn't listen in socket\n", logPrefix); |
349 |
+- return; |
350 |
+- } |
351 |
+- |
352 |
+- if (chown(local.sun_path, userInfo->pw_uid, userInfo->pw_gid) == -1) { |
353 |
+- pam_syslog(pamh, LOG_INFO, "%s: Couldn't change ownership of the socket", logPrefix); |
354 |
+- return; |
355 |
+- } |
356 |
+- |
357 |
+ pid_t pid; |
358 |
+ int status; |
359 |
+ switch (pid = fork ()) { |
360 |
+@@ -534,7 +529,7 @@ static void start_kwallet(pam_handle_t *pamh, struct passwd *userInfo, const cha |
361 |
+ |
362 |
+ //Child fork, will contain kwalletd |
363 |
+ case 0: |
364 |
+- execute_kwallet(pamh, userInfo, toWalletPipe, envSocket); |
365 |
++ execute_kwallet(pamh, userInfo, toWalletPipe, fullSocket); |
366 |
+ /* Should never be reached */ |
367 |
+ break; |
368 |
+ |
369 |
+-- |
370 |
+cgit v0.11.2 |
371 |
+ |
372 |
|
373 |
diff --git a/kde-plasma/kwallet-pam/files/kwallet-pam-5.11.5-CVE-2018-10380-3.patch b/kde-plasma/kwallet-pam/files/kwallet-pam-5.11.5-CVE-2018-10380-3.patch |
374 |
new file mode 100644 |
375 |
index 00000000000..de882e45453 |
376 |
--- /dev/null |
377 |
+++ b/kde-plasma/kwallet-pam/files/kwallet-pam-5.11.5-CVE-2018-10380-3.patch |
378 |
@@ -0,0 +1,54 @@ |
379 |
+From 8da1a47035fc92bc1496059583772bc4bd6e8ba6 Mon Sep 17 00:00:00 2001 |
380 |
+From: Maximiliano Curia <maxy@××××××××××××××.ar> |
381 |
+Date: Fri, 4 May 2018 22:06:06 +0200 |
382 |
+Subject: Avoid giving an stderr to kwallet |
383 |
+ |
384 |
+Summary: |
385 |
+The fixes for CVE-2018-10380 introduced a regression for most users not |
386 |
+using kde, and some for kde sessions. In particular the reorder of the |
387 |
+close calls and creating a new socket caused that the socket is always |
388 |
+assigned the file descriptor 2, aka stderr. |
389 |
+ |
390 |
+BUG: 393856 |
391 |
+ |
392 |
+Test Plan: It works |
393 |
+ |
394 |
+Reviewers: #plasma, aacid |
395 |
+ |
396 |
+Reviewed By: aacid |
397 |
+ |
398 |
+Subscribers: asturmlechner, rdieter, davidedmundson, plasma-devel |
399 |
+ |
400 |
+Tags: #plasma |
401 |
+ |
402 |
+Differential Revision: https://phabricator.kde.org/D12702 |
403 |
+--- |
404 |
+ pam_kwallet.c | 5 ++++- |
405 |
+ 1 file changed, 4 insertions(+), 1 deletion(-) |
406 |
+ |
407 |
+diff --git a/pam_kwallet.c b/pam_kwallet.c |
408 |
+index b9c984a..661ed8d 100644 |
409 |
+--- a/pam_kwallet.c |
410 |
++++ b/pam_kwallet.c |
411 |
+@@ -375,7 +375,8 @@ static int drop_privileges(struct passwd *userInfo) |
412 |
+ static void execute_kwallet(pam_handle_t *pamh, struct passwd *userInfo, int toWalletPipe[2], char *fullSocket) |
413 |
+ { |
414 |
+ //In the child pam_syslog does not work, using syslog directly |
415 |
+- int x = 2; |
416 |
++ //keep stderr open so socket doesn't returns us that fd |
417 |
++ int x = 3; |
418 |
+ //Close fd that are not of interest of kwallet |
419 |
+ for (; x < 64; ++x) { |
420 |
+ if (x != toWalletPipe[0]) { |
421 |
+@@ -424,6 +425,8 @@ static void execute_kwallet(pam_handle_t *pamh, struct passwd *userInfo, int toW |
422 |
+ pam_syslog(pamh, LOG_INFO, "%s-kwalletd: Couldn't listen in socket\n", logPrefix); |
423 |
+ return; |
424 |
+ } |
425 |
++ //finally close stderr |
426 |
++ close(2); |
427 |
+ |
428 |
+ // Fork twice to daemonize kwallet |
429 |
+ setsid(); |
430 |
+-- |
431 |
+cgit v0.11.2 |
432 |
+ |