From owner-freebsd-questions@FreeBSD.ORG Thu Aug 22 23:46:43 2013 Return-Path: Delivered-To: freebsd-questions@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 0EA15B99 for ; Thu, 22 Aug 2013 23:46:43 +0000 (UTC) (envelope-from mattmiller1@gmail.com) Received: from mail-qc0-x22f.google.com (mail-qc0-x22f.google.com [IPv6:2607:f8b0:400d:c01::22f]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id C84E32EF6 for ; Thu, 22 Aug 2013 23:46:42 +0000 (UTC) Received: by mail-qc0-f175.google.com with SMTP id m4so1390358qcy.20 for ; Thu, 22 Aug 2013 16:46:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:from:date:message-id:subject:to:content-type; bh=8LUvNwJL+2MLzs68kFvvcM2TbexmRjhDSM+11KTfxJA=; b=sD+3PnZcQQ3sc6zWNXUGYsqU9PIcNh/2U1GqVdLOdMYWAIzGCzKFq827Zto52JlGqN rUO3UnAhc/D2TEnXXOz0FB6ZSEQ9XD/QFAfkXDAEyXcnQYG3MqYguZ0RX59sMCvwn3BO pCMQtUZpTeAC+qqaCq4b/1zvBv64NisdxqVR4M5oHRYewl4MgpXt7BashJk+QJODYKOj vxkH+1AHdh/uzQ8z2nFTioGFDOIFmh6d1AEBUyZkGaO8Doxmp+WV2NTNrrXFvwg/bNxb ZVcICP9odiIgHSc769SYIt9yarvcA3cum4IWO47+//L1NAmszSaLc4qnTjveqwYzm1WR bYbA== X-Received: by 10.224.119.78 with SMTP id y14mr21197245qaq.11.1377215201875; Thu, 22 Aug 2013 16:46:41 -0700 (PDT) MIME-Version: 1.0 Sender: mattmiller1@gmail.com Received: by 10.49.51.194 with HTTP; Thu, 22 Aug 2013 16:46:01 -0700 (PDT) From: Matt Miller Date: Thu, 22 Aug 2013 19:46:01 -0400 X-Google-Sender-Auth: 8ZHsXkJx0NR-9nay_EU7cckdHuc Message-ID: Subject: kern_jail_set() Error Scenario Question To: freebsd-questions@freebsd.org Content-Type: text/plain; charset=ISO-8859-1 X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Aug 2013 23:46:43 -0000 We ran into the following scenario in an application recently and were wondering if the behavior of kern_jail_set() is as expected here. This was an application bug where we were in, say, the JID 1 context and tried to call jailparam_set() with the flags (JAIL_CREATE | JAIL_UPDATE) and the "jid" param set to 1. The basic idea was to create or update JID 1 with some params, but the error was we were already in the JID 1 context. So, our understanding is this shouldn't work since JID 1 already exists and you can only modify it from a proper ancestor. However, rather than getting an error back from jailparam_set(), it ended up creating a second prison with JID 1, so there were two prisons existing with JID 1 at that point. This is based on 8.2.0 code, but, at first glance, it looks like the logic causing this may be the same in head. Looking at kern_jail_set(), what happens here is: 1. We find a prison with JID=1, however since it's not a proper child we set pr = NULL in line 1024: 1011 pr = prison_find(jid); 1012 if (pr != NULL) { 1013 ppr = pr->pr_parent; 1014 /* Create: jid must not exist. */ 1015 if (cuflags == JAIL_CREATE) { 1016 mtx_unlock(&pr->pr_mtx); 1017 error = EEXIST; 1018 vfs_opterror(opts, "jail %d already exists", 1019 jid); 1020 goto done_unlock_list; 1021 } 1022 if (!prison_ischild(mypr, pr)) { 1023 mtx_unlock(&pr->pr_mtx); 1024 pr = NULL; 1025 } else if (pr->pr_uref == 0) { 2. Since pr is NULL, we create a new prison. Since the jid is not zero, we insert it in the list and set its pr_id. At this point, we have two prisons with a JID of 1 and the same parent prison. 1166 /* If there's no prison to update, create a new one and link it in. */ 1167 if (pr == NULL) { ... 1185 pr = malloc(sizeof(*pr), M_PRISON, M_WAITOK | M_ZERO); 1186 if (jid == 0) { ... 1212 } else { 1213 /* 1214 * The jail already has a jid (that did not yet exist), 1215 * so just find where to insert it. 1216 */ 1217 TAILQ_FOREACH(tpr, &allprison, pr_list) 1218 if (tpr->pr_id >= jid) { 1219 TAILQ_INSERT_BEFORE(tpr, pr, pr_list); 1220 break; 1221 } 1222 } ... 1229 pr->pr_parent = ppr; 1230 pr->pr_id = jid; We wanted to see if this is per design or a situation that should avoid creating the second prison and return an error. Thanks, Matt