file: strengthen exec access control
[project/rpcd.git] / exec.c
diff --git a/exec.c b/exec.c
index a5f6561cbefb405d9de9fcf03750c93d2a9cf6d1..3cd7384999ad460f979c2ce96e534467d3ecadf2 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -1,7 +1,7 @@
 /*
  * rpcd - UBUS RPC server
  *
- *   Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
+ *   Copyright (C) 2013-2014 Jo-Philipp Wich <jow@openwrt.org>
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -50,7 +50,7 @@ rpc_errno_status(void)
        }
 }
 
-static const char *
+const char *
 rpc_exec_lookup(const char *cmd)
 {
        struct stat s;
@@ -131,13 +131,13 @@ rpc_exec_reply(struct rpc_exec_context *c, int rv)
                        rpc_ustream_to_blobmsg(&c->blob, &c->opipe.stream, "stdout");
                        rpc_ustream_to_blobmsg(&c->blob, &c->epipe.stream, "stderr");
                }
+       }
 
-               if (c->finish_cb)
-                       rv = c->finish_cb(&c->blob, c->stat, c->priv);
+       if (c->finish_cb)
+               rv = c->finish_cb(&c->blob, c->stat, c->priv);
 
-               if (rv == UBUS_STATUS_OK)
-                       ubus_send_reply(c->context, &c->request, c->blob.head);
-       }
+       if (rv == UBUS_STATUS_OK)
+               ubus_send_reply(c->context, &c->request, c->blob.head);
 
        ubus_complete_deferred_request(c->context, &c->request, rv);
 
@@ -175,6 +175,12 @@ rpc_exec_process_cb(struct uloop_process *p, int stat)
 
        ustream_poll(&c->opipe.stream);
        ustream_poll(&c->epipe.stream);
+
+       close(c->opipe.fd.fd);
+       close(c->epipe.fd.fd);
+
+       ustream_poll(&c->opipe.stream);
+       ustream_poll(&c->epipe.stream);
 }
 
 static void
@@ -307,7 +313,7 @@ rpc_exec(const char **args, rpc_exec_write_cb_t in,
        switch ((pid = fork()))
        {
        case -1:
-               return rpc_errno_status();
+               goto fail_fork;
 
        case 0:
                uloop_done();
@@ -344,7 +350,7 @@ rpc_exec(const char **args, rpc_exec_write_cb_t in,
                uloop_process_add(&c->process);
 
                c->timeout.cb = rpc_exec_timeout_cb;
-               uloop_timeout_set(&c->timeout, RPC_EXEC_MAX_RUNTIME);
+               uloop_timeout_set(&c->timeout, rpc_exec_timeout);
 
                if (c->stdin_cb)
                {
@@ -366,6 +372,10 @@ rpc_exec(const char **args, rpc_exec_write_cb_t in,
 
        return UBUS_STATUS_OK;
 
+fail_fork:
+       close(epipe[0]);
+       close(epipe[1]);
+
 fail_epipe:
        close(opipe[0]);
        close(opipe[1]);
@@ -375,5 +385,6 @@ fail_opipe:
        close(ipipe[1]);
 
 fail_ipipe:
+       free(c);
        return rpc_errno_status();
 }