All of lore.kernel.org
 help / color / mirror / Atom feed
From: George Dunlap <george.dunlap@citrix.com>
To: xen-devel@lists.xenproject.org
Cc: Ian Jackson <ian.jackson@citrix.com>,
	Wei Liu <wei.liu2@citrix.com>,
	George Dunlap <george.dunlap@citrix.com>
Subject: [PATCH 9/9] libxl: Kill QEMU with "reaper" ruid
Date: Fri, 23 Nov 2018 17:15:02 +0000	[thread overview]
Message-ID: <20181123171502.29519-9-george.dunlap@citrix.com> (raw)
In-Reply-To: <20181123171502.29519-1-george.dunlap@citrix.com>

Using kill(-1) to killing an untrusted dm process with the real uid
equal to the dm_uid isn't guaranteed to succeed: the process in
question may be able to kill the reaper process after the setresuid()
and before the kill().

Instead, set the real uid to the QEMU user for domain 0
(QEMU_USER_RANGE_BASE + 0).  The reaper process will still be able to
kill the dm process, but not vice versa.

This, in turn, requires locking to make sure that only one reaper
process is using that uid at a time; otherwise one reaper process may
kill the other reaper process.

Create a lockfile in RUNDIR/dm-reaper-lock, and grab the lock before
executing kill.

In the event that we can't get the lock for some reason, go ahead with
the kill using dm_uid for both real and effective UIDs.  This isn't
guaranteed to work, but it's no worse than not trying to kill the
process at all.

Signed-off-by: George Dunlap <george.dunlap@citrix.com>
---
CC: Ian Jackson <ian.jackson@citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
---
 tools/libxl/libxl_dm.c | 67 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 63 insertions(+), 4 deletions(-)

diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 0997865773..846d23bddd 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -211,7 +211,16 @@ end_search:
     state->dm_uid = uid;
     return 0;
 }
-                                   
+
+static int libxl__get_reaper_uid(libxl__gc *gc)
+{
+    struct passwd *user_base, user_pwbuf;
+    int ret;
+    ret = userlookup_helper_getpwnam(gc, LIBXL_QEMU_USER_RANGE_BASE,
+                                         &user_pwbuf, &user_base);
+    return (ret < 0) ? ret : user_base->pw_uid;
+}
+
 const char *libxl__domain_device_model(libxl__gc *gc,
                                        const libxl_domain_build_info *info)
 {
@@ -2719,12 +2728,62 @@ void libxl__destroy_device_model(libxl__egc *egc,
     
     if (!reaper_pid) { /* child */
         const char * call;
+        const char * lockfile;
+        int fd;
+        uid_t reaper_uid = dm_uid;
+
+        /* 
+         * Try to kill the devicemodel by uid.  The safest way to do
+         * this is to set euid == dm_uid, but the ruid to something
+         * else.  If we can't get an ruid, carry on trying to kill the
+         * process anyway using dm_uid for the ruid.
+         */
+
+        /* Try to lock the "reaper uid" */
+        lockfile = GCSPRINTF("%s/dm-reaper-lock", libxl__run_dir_path());
 
         /* 
-         * FIXME: the second uid needs to be distinct to avoid being
-         * killed by a potential rogue process
+         * NB that since we've just forked, we can't have any
+         * threads; so we don't need the libxl__carefd
+         * infrastructure here.
          */
-        ret = setresuid(dm_uid, dm_uid, 0);
+        fd = open(lockfile, O_RDWR|O_CREAT, 0666);
+        if (fd < 0) {
+            /* All other errno: EBADF, EINVAL, ENOLCK, EWOULDBLOCK */
+            LOGED(ERROR, domid,
+                  "unexpected error while trying to open lockfile %s, errno=%d",
+                  lockfile, errno);
+            goto kill;
+        }
+
+        /* Try to lock the file */
+        while (flock(fd, LOCK_EX)) {
+            switch (errno) {
+            case EINTR:
+                /* Signal received, retry */
+                continue;
+            default:
+                /* All other errno: EBADF, EINVAL, ENOLCK, EWOULDBLOCK */
+                LOGED(ERROR, domid,
+                      "unexpected error while trying to lock %s, fd=%d, errno=%d",
+                      lockfile, fd, errno);
+                goto kill;
+            }
+        }
+
+        /* Get reaper_uid */
+        reaper_uid = libxl__get_reaper_uid(gc);
+        if (reaper_uid < 0) {
+            LOGE(ERROR, "Couldn't get reaper UID");
+            reaper_uid = dm_uid;
+        }
+        
+    kill:
+        if (reaper_uid == dm_uid)
+            LOG(WARN, "Couldn't get separate reaper uid;"
+                "carrying on with unsafe kill");
+        
+        ret = setresuid(reaper_uid, dm_uid, 0);
         if (ret) {
             call = "setresuid";
             goto badchild;
-- 
2.19.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply	other threads:[~2018-11-23 17:15 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-23 17:14 [PATCH 1/9] libxl: Remove redundant pidpath setting George Dunlap
2018-11-23 17:14 ` [PATCH 2/9] libxl: Move dm user determination logic into a helper function George Dunlap
2018-11-28 15:20   ` Wei Liu
2018-11-28 16:33   ` Ian Jackson
2018-11-30 12:46   ` George Dunlap
2018-11-23 17:14 ` [PATCH 3/9] libxl: Get rid of support for QEMU_USER_BASE (xen-qemuuser-domidNN) George Dunlap
2018-11-28 15:32   ` Wei Liu
2018-11-30 12:53     ` George Dunlap
2018-11-30 16:56       ` Wei Liu
2018-11-28 16:34   ` Ian Jackson
2018-11-28 17:02     ` George Dunlap
2018-11-29 12:19       ` Ian Jackson
2018-11-23 17:14 ` [PATCH 4/9] dm_depriv: Describe expected usage of device_model_user parameter George Dunlap
2018-11-28 15:37   ` Wei Liu
2018-11-28 16:36   ` Ian Jackson
2018-11-28 17:27     ` George Dunlap
2018-11-29 12:20       ` Ian Jackson
2018-11-23 17:14 ` [PATCH 5/9] libxl: Do root checks once in libxl__domain_get_device_model_uid George Dunlap
2018-11-28 16:39   ` Ian Jackson
2018-11-28 17:38     ` George Dunlap
2018-11-29 17:09       ` Ian Jackson
2018-11-29 17:43         ` George Dunlap
2018-11-23 17:14 ` [PATCH 6/9] libxl: Move qmp cleanup into devicemodel destroy function George Dunlap
2018-11-28 16:39   ` Ian Jackson
2018-11-23 17:15 ` [PATCH 7/9] libxl: Make killing of device model asynchronous George Dunlap
2018-11-28 16:43   ` Ian Jackson
2018-11-30 16:12     ` George Dunlap
2018-11-30 16:14       ` George Dunlap
2018-11-30 16:22         ` Ian Jackson
2018-11-30 16:22       ` Ian Jackson
2018-11-23 17:15 ` [PATCH 8/9] libxl: Kill QEMU by uid when possible George Dunlap
2018-11-23 17:18   ` George Dunlap
2018-11-28 15:57     ` Anthony PERARD
2018-11-29 11:55       ` Wei Liu
2018-11-29 12:00         ` George Dunlap
2018-11-29 12:26           ` Ian Jackson
2018-11-29 12:38             ` George Dunlap
2018-11-29 17:16               ` Ian Jackson
2018-11-28 16:56   ` Ian Jackson
2018-11-28 17:55     ` George Dunlap
2018-11-29 17:01       ` Ian Jackson
2018-11-30 16:37     ` George Dunlap
2018-11-23 17:15 ` George Dunlap [this message]
2018-11-28 17:02   ` [PATCH 9/9] libxl: Kill QEMU with "reaper" ruid Ian Jackson
2018-11-28 18:33     ` George Dunlap
2018-11-29 11:39       ` George Dunlap
2018-11-29 17:15       ` Ian Jackson
2018-11-28 15:20 ` [PATCH 1/9] libxl: Remove redundant pidpath setting Wei Liu
2018-11-28 16:25 ` Ian Jackson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181123171502.29519-9-george.dunlap@citrix.com \
    --to=george.dunlap@citrix.com \
    --cc=ian.jackson@citrix.com \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.