• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

external/koush/Superuser


Commit MetaInfo

Revision2055ffc80c015004301d3f1555dcde6190a85c9a (tree)
Time2013-11-24 23:43:57
AuthorPeter Wu <lekensteyn@gmai...>
CommiterPeter Wu

Log Message

daemon: do not leak resources

Before this patch, the client was responsible for removing FIFOs before
connecting. That left a whole bunch of FIFOs in the SuperUser /dev/...
directory. After This patch, the daemon removes FIFOs as soon as the client is
connected. (This is detected by making the daemon read from the control socket.)

This patch becomes unnecessary when file descriptors can be passed though
processes.

Change Summary

Incremental Difference

--- a/Superuser/jni/su/daemon.c
+++ b/Superuser/jni/su/daemon.c
@@ -242,10 +242,13 @@ static int daemon_accept(int fd) {
242242 }
243243 if (mkfifo(errfile, 0660) != 0) {
244244 PLOGE("mkfifo %s", errfile);
245+ unlink(outfile);
245246 exit(-1);
246247 }
247248 if (mkfifo(infile, 0660) != 0) {
248249 PLOGE("mkfifo %s", infile);
250+ unlink(errfile);
251+ unlink(outfile);
249252 exit(-1);
250253 }
251254
@@ -265,11 +268,15 @@ static int daemon_accept(int fd) {
265268 ptm = open("/dev/ptmx", O_RDWR);
266269 if (ptm <= 0) {
267270 PLOGE("ptm");
268- exit(-1);
271+ goto unlink_n_exit;
269272 }
270273 if(grantpt(ptm) || unlockpt(ptm) || ((devname = (char*) ptsname(ptm)) == 0)) {
271274 PLOGE("ptm setup");
272275 close(ptm);
276+unlink_n_exit:
277+ unlink(infile);
278+ unlink(errfile);
279+ unlink(outfile);
273280 exit(-1);
274281 }
275282 LOGD("devname: %s", devname);
@@ -278,19 +285,25 @@ static int daemon_accept(int fd) {
278285 int outfd = open(outfile, O_WRONLY);
279286 if (outfd <= 0) {
280287 PLOGE("outfd daemon %s", outfile);
281- goto done;
288+ goto unlink_n_exit;
282289 }
283290 int errfd = open(errfile, O_WRONLY);
284291 if (errfd <= 0) {
285292 PLOGE("errfd daemon %s", errfile);
286- goto done;
293+ goto unlink_n_exit;
287294 }
288295 int infd = open(infile, O_RDONLY);
289296 if (infd <= 0) {
290297 PLOGE("infd daemon %s", infile);
291- goto done;
298+ goto unlink_n_exit;
292299 }
293300
301+ // Wait for client to open pipes, then remove
302+ read_int(fd);
303+ unlink(infile);
304+ unlink(errfile);
305+ unlink(outfile);
306+
294307 int code;
295308 // now fork and run main, watch for the child pid exit, and send that
296309 // across the control channel as the response.
@@ -361,7 +374,13 @@ static int daemon_accept(int fd) {
361374 int status;
362375 LOGD("waiting for child exit");
363376 if (waitpid(child, &status, 0) > 0) {
364- code = WEXITSTATUS(status);
377+ if (WIFEXITED(status)) {
378+ code = WEXITSTATUS(status);
379+ } else if (WIFSIGNALED(status)) {
380+ code = 128 + WTERMSIG(status);
381+ } else {
382+ code = -1;
383+ }
365384 }
366385 else {
367386 code = -1;
@@ -448,9 +467,6 @@ int connect_daemon(int argc, char *argv[]) {
448467 sprintf(outfile, "%s/%d.stdout", REQUESTOR_DAEMON_PATH, getpid());
449468 sprintf(errfile, "%s/%d.stderr", REQUESTOR_DAEMON_PATH, getpid());
450469 sprintf(infile, "%s/%d.stdin", REQUESTOR_DAEMON_PATH, getpid());
451- unlink(errfile);
452- unlink(infile);
453- unlink(outfile);
454470
455471 struct sockaddr_un sun;
456472
@@ -511,11 +527,19 @@ int connect_daemon(int argc, char *argv[]) {
511527 exit(-1);
512528 }
513529
530+ // notify daemon that the pipes are open.
531+ write_int(socketfd, 1);
532+
514533 pump_async(STDIN_FILENO, infd);
515534 pump_async(errfd, STDERR_FILENO);
516535 pump(outfd, STDOUT_FILENO);
517536
537+ close(infd);
538+ close(errfd);
539+ close(outfd);
540+
518541 int code = read_int(socketfd);
542+ close(socketfd);
519543 LOGD("client exited %d", code);
520544 return code;
521545 }