Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp617966imm; Fri, 31 Aug 2018 08:49:06 -0700 (PDT) X-Google-Smtp-Source: ANB0VdZd/ZIzQdECp/+VgzXaWN+NNvTZjlo2EwvuFwk7K2bM8rL/M12TNX8bHqV/ttnemkTW40J6 X-Received: by 2002:a63:cd4c:: with SMTP id a12-v6mr15077495pgj.15.1535730546067; Fri, 31 Aug 2018 08:49:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535730546; cv=none; d=google.com; s=arc-20160816; b=Jw/3UxJM/V5nxG+ATdRzJYUqFrEDJprqOYUKUQSzNAyPYrRNQln+sQQrFcndkr5JKL XXZSpAzHq/a8d1T+5y7dB0qAnXPwRehmNBy/ANsfeiOM+hq9fAqs1d+Ss2Ria1MYk9E3 BF5HfBQSE94hUvbVUxX+KtxyHYWacKamCk0/go+vi62FObIxhJDkE1i/j2QGQLh6rVg/ yhwUsVK881JeArVzP+gWGmIjkQBZUdl803TpKB5V3kBOUMoz5hE4m4l1uGaJD0W6InPO NQBhQosk0crZEzfWCzISPn3ek45EMwJ3lun/QN1/4SUvYVq+D593cHF9ziyscrMe/eN5 3T4A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature :arc-authentication-results; bh=PMYAtSjmJSSZCIscgWpdE9VXJTFtliGnv4BV5VEPwZM=; b=oWN/jiiNyUFiOA1j4fp6yZ5bKKaYACnfa7GAjOMPqDcCcDuCS5LMlmwGz4Zc42vjyy Kj2gTGhq5Kdp/DYB74ImU7JMpu1tBtqGB1t9yh9qke/hTTw73xsyiHqusElm8uMOS/HW j/D0hUHdsckwx5kJOZ2CUoM0lL3HU3bKlRbi+I7ZLsKSg/OD4Hl5QfE5vgqeQ62ikndY rRQg/n2T1fHahsq0oU12g8rG0ifmSMN2D8HXLqR52cj+YBNthnDwqjhwshH8DVfZzfjv jxn8q0DOP2SWebo1o3MzTb02Poq2xQkzjpYXWYy9V5htM08PE8yjeFs2BzYqniB38nW9 2tiw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b="RYWJG/K5"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 71-v6si10879385pfa.305.2018.08.31.08.48.51; Fri, 31 Aug 2018 08:49:06 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b="RYWJG/K5"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729107AbeHaTzG (ORCPT + 99 others); Fri, 31 Aug 2018 15:55:06 -0400 Received: from mail-oi0-f68.google.com ([209.85.218.68]:46004 "EHLO mail-oi0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727973AbeHaTzG (ORCPT ); Fri, 31 Aug 2018 15:55:06 -0400 Received: by mail-oi0-f68.google.com with SMTP id t68-v6so22405258oie.12 for ; Fri, 31 Aug 2018 08:47:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=PMYAtSjmJSSZCIscgWpdE9VXJTFtliGnv4BV5VEPwZM=; b=RYWJG/K55uduEX7gOOvy4yFrBdff1y1ydNUFb2GqZHu+79KhsS90gAZ6Qz/1jn6Mlg 5n/5dcIQyGM3OuOa2crVNyrJJCMbLvTwI/Y8UkEgKiKIrwwYH+F/68NMOpj1OyUKzm9R 0gECxa8Rs4VHr3DTmKf4vRpYNRrygZ8M5KkO8u4E/wwdKjwME4lV+EetXnan1BZBxQa2 beljzkqI+NLREdM8FhLVpRf/geDED3sV1/JgXjb5oe8miN0DBLykr5orL2+XnvveXW7S RTFxxznXGAqtwIFK978/Dn6LYwQ2Jc+biiBMjE+DdVbuNGm1ouhK+ngBpgCYf012YW6Y e1Ww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=PMYAtSjmJSSZCIscgWpdE9VXJTFtliGnv4BV5VEPwZM=; b=UIvplSUI6NPJlB/NyG96rhiwSbZnbN0tPyDa8vS8wf1xOlzWqahyNzocMcgrxfz4Xm 0RvEvRruO8yfHTK0XiI0mBGP+ol7hyj+21B68k9au3B7VfnFYBu9HABnwqg/69j6C7Zq /lAdzI6mUBaK8uizR9NdB3hj/4MwUMqnvcIbfjROeGFNp+96pU8NnlQAVgD8NNnzmPwS HLOScTUKK9DmtqQ9z9Mn18pzPY9OYE+pzv6lUCnZdJ6OmPcDW45yLUAO4h9Ep/KVu45z HjQ4wiOlPM1843ebNs3HKkV2kLzVLuJylYOwZhXJ08y9ym+rkHdnMYyuQDA00s+nL3wL 84CA== X-Gm-Message-State: APzg51AfMMmVuwEF42R2lB9kRAAAiW6G4ZYxH2Z0bKFfZcu4RlCekmQH W7eYAKZxS0636v8G2ZITm0gPSBTrk6/YLGXPR1IwAw== X-Received: by 2002:aca:c585:: with SMTP id v127-v6mr8124839oif.348.1535730419531; Fri, 31 Aug 2018 08:46:59 -0700 (PDT) MIME-Version: 1.0 References: <20180806211932.198488-1-jannh@google.com> In-Reply-To: From: Jann Horn Date: Fri, 31 Aug 2018 17:46:33 +0200 Message-ID: Subject: Re: [PATCH] selinux: refactor mls_context_to_sid() and make it stricter To: Paul Moore Cc: Stephen Smalley , Eric Paris , selinux@tycho.nsa.gov, James Morris , "Serge E. Hallyn" , linux-security-module , kernel list Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Aug 9, 2018 at 3:56 AM Paul Moore wrote: > > On Mon, Aug 6, 2018 at 5:19 PM Jann Horn wrote: > > > > The intended behavior change for this patch is to reject any MLS strings > > that contain (trailing) garbage if p->mls_enabled is true. > > > > As suggested by Paul Moore, change mls_context_to_sid() so that the two > > parts of the range are extracted before the rest of the parsing. Because > > now we don't have to scan for two different separators simultaneously > > everywhere, we can actually switch to strchr() everywhere instead of the > > open-coded loops that scan for two separators at once. > > > > mls_context_to_sid() used to signal how much of the input string was parsed > > by updating `*scontext`. However, there is actually no case in which > > mls_context_to_sid() only parses a subset of the input and still returns > > a success (other than the buggy case with a second '-' in which it > > incorrectly claims to have consumed the entire string). Turn `scontext` > > into a simple pointer argument and stop redundantly checking whether the > > entire input was consumed in string_to_context_struct(). This also lets us > > remove the `scontext_len` argument from `string_to_context_struct()`. [...] > > - /* Extract low sensitivity. */ > > - scontextp = p = *scontext; > > - while (*p && *p != ':' && *p != '-') > > - p++; > > - > > - delim = *p; > > - if (delim != '\0') > > - *p++ = '\0'; > > + /* > > + * If we're dealing with a range, figure out where the two parts > > + * of the range begin. > > + */ > > + rangep[0] = scontext; > > + rangep[1] = strchr(scontext, '-'); > > + if (rangep[1]) { > > + rangep[1][0] = '\0'; > > + rangep[1]++; > > + } > > > > + /* For each part of the range: */ > > for (l = 0; l < 2; l++) { > > - levdatum = hashtab_search(pol->p_levels.table, scontextp); > > - if (!levdatum) { > > - rc = -EINVAL; > > - goto out; > > - } > > + /* Split sensitivity and category set. */ > > + sensitivity = rangep[l]; > > + if (sensitivity == NULL) > > + break; > > + next_cat = strchr(sensitivity, ':'); > > + if (next_cat) > > + *(next_cat++) = '\0'; > > > > + /* Parse sensitivity. */ > > + levdatum = hashtab_search(pol->p_levels.table, sensitivity); > > + if (!levdatum) > > + return -EINVAL; > > context->range.level[l].sens = levdatum->level->sens; > > > > - if (delim == ':') { > > - /* Extract category set. */ > > - while (1) { > > - scontextp = p; > > - while (*p && *p != ',' && *p != '-') > > - p++; > > - delim = *p; > > - if (delim != '\0') > > - *p++ = '\0'; > > - > > - /* Separate into range if exists */ > > - rngptr = strchr(scontextp, '.'); > > - if (rngptr != NULL) { > > - /* Remove '.' */ > > - *rngptr++ = '\0'; > > - } > > + /* Extract category set. */ > > + while (next_cat != NULL) { > > + cur_cat = next_cat; > > + next_cat = strchr(next_cat, ','); > > + if (next_cat != NULL) > > + *(next_cat++) = '\0'; > > + > > + /* Separate into range if exists */ > > + rngptr = strchr(cur_cat, '.'); > > + if (rngptr != NULL) { > > + /* Remove '.' */ > > On the chance you need to respin this patch, you can probably get rid > of the above comment and the if-body braces; we don't have "Remove X" > comments in other similar places in this function. I'll amend that. > > + *rngptr++ = '\0'; > > + } > > > > - catdatum = hashtab_search(pol->p_cats.table, > > - scontextp); > > - if (!catdatum) { > > - rc = -EINVAL; > > - goto out; > > - } > > + catdatum = hashtab_search(pol->p_cats.table, cur_cat); > > + if (!catdatum) > > + return -EINVAL; > > > > - rc = ebitmap_set_bit(&context->range.level[l].cat, > > - catdatum->value - 1, 1); > > - if (rc) > > - goto out; > > - > > - /* If range, set all categories in range */ > > - if (rngptr) { > > - int i; > > - > > - rngdatum = hashtab_search(pol->p_cats.table, rngptr); > > - if (!rngdatum) { > > - rc = -EINVAL; > > - goto out; > > - } > > - > > - if (catdatum->value >= rngdatum->value) { > > - rc = -EINVAL; > > - goto out; > > - } > > - > > - for (i = catdatum->value; i < rngdatum->value; i++) { > > - rc = ebitmap_set_bit(&context->range.level[l].cat, i, 1); > > - if (rc) > > - goto out; > > - } > > - } > > + rc = ebitmap_set_bit(&context->range.level[l].cat, > > + catdatum->value - 1, 1); > > + if (rc) > > + return rc; > > + > > + /* If range, set all categories in range */ > > + if (rngptr == NULL) > > + continue; > > + > > + rngdatum = hashtab_search(pol->p_cats.table, rngptr); > > + if (!rngdatum) > > + return -EINVAL; > > + > > + if (catdatum->value >= rngdatum->value) > > + return -EINVAL; > > > > - if (delim != ',') > > - break; > > + for (i = catdatum->value; i < rngdatum->value; i++) { > > + rc = ebitmap_set_bit(&context->range.level[l].cat, i, 1); > > + if (rc) > > + return rc; > > } > > } > > - if (delim == '-') { > > - /* Extract high sensitivity. */ > > - scontextp = p; > > - while (*p && *p != ':') > > - p++; > > - > > - delim = *p; > > - if (delim != '\0') > > - *p++ = '\0'; > > - } else > > - break; > > } > > > > - if (l == 0) { > > + /* If we didn't see a '-', the range start is also the range end. */ > > + if (rangep[1] == NULL) { > > context->range.level[1].sens = context->range.level[0].sens; > > rc = ebitmap_cpy(&context->range.level[1].cat, > > &context->range.level[0].cat); > > if (rc) > > - goto out; > > + return rc; > > } > > - *scontext = ++p; > > - rc = 0; > > -out: > > - return rc; > > + > > + return 0; > > In the case where we have a MLS policy loaded (pol->mls_enabled != 0) > and scontext is empty (scontext[0] = '\0'), we could end up returning > 0 couldn't we? It seems like we might want a quick check for this > before we parse the low/high portions of the field into the rangep > array. I don't think so. In the first loop iteration, `sensitivity` will be an empty string, and so the hashtab_search() should return NULL, leading to -EINVAL. Am I missing something? > As an aside, I believe my other comments on this patch still stand. > It's a nice improvement but I think there are some other small things > that need to be addressed. Is there anything I need to fix apart from the overly verbose comment and the unnecessary curly braces?