From patchwork Thu Aug 22 00:37:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thi=C3=A9baud_Weksteen?= X-Patchwork-Id: 13772265 X-Patchwork-Delegate: plautrba@redhat.com Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 290F7101C8 for ; Thu, 22 Aug 2024 00:38:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724287093; cv=none; b=LRyilDnVg0duuL8csOU+ugBuUtdEBrogh0HmA06d+eBqGICYq5cmy6IyPd0KU+QWN1JpGJsO1qcGAT8YhaCANcQdewEKfm8eYo4nm1Oz8DQaUxrX0r8Eg1fLpqK+fU01NHmVJB5tU4CNPHY6TlDk5rK0Z9mkP5cwJPUPQdztNK8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724287093; c=relaxed/simple; bh=HTFBcUwfrgVZ1G0Wt9lteHAvCIrExCdAYvi9Reg4dyY=; h=Date:Mime-Version:Message-ID:Subject:From:To:Cc:Content-Type; b=kCGqrJjdeB6Isi7L4ykByOxt/MXVL/WtTGTb18TmGEGYfVOFJ2EtpNhsKeITNBSUr85fgYskF2YVHRDWcvIuIOxg+HaTKKN+i34Fmucy/I4zrZ5L85SE6dtXzmwPs04x7eBqVR3eONLqF0vvFaAQfz/KneS0nPki4s15pid7EsQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--tweek.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=c6HEEBZ9; arc=none smtp.client-ip=209.85.128.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--tweek.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="c6HEEBZ9" Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-6af4700a594so6621507b3.0 for ; Wed, 21 Aug 2024 17:38:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1724287091; x=1724891891; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id :mime-version:date:from:to:cc:subject:date:message-id:reply-to; bh=XEflHXtA+5PsiYpOTAkPvnA4WKakQYg6REX03fMAbjU=; b=c6HEEBZ96D00z/oreBSwB8aktIbFW3enISjOIBaT/eRQagR+VrVu+bZxnVPqrDOtsn 6Wy6Zn2c5Fg/uDHjXfkYAsdhDEljhiyc46iLxTAqr/yiiYZ0VjrLFheQ6UVyJhzQfT5i Czsy7pqOESPtGCBmz61oevywyBCHcmotEqiFyuItEfhyESt5FI8wHT1asnKqKpIqOcnW 28iWw5xqlNP5CHVpVV9re0SSad/BgE/qO8bajg+15tX57FJGYhfvTRlpBnYVdUJxL3q6 VPjB2VsaUR09UShOsztzDS81RPFw909WlpqQYauwMAnt3aoDfZpADX3ha3WTBDDTUUy3 6Fcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724287091; x=1724891891; h=content-transfer-encoding:cc:to:from:subject:message-id :mime-version:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=XEflHXtA+5PsiYpOTAkPvnA4WKakQYg6REX03fMAbjU=; b=TsIf83gsgmixwVFardgw0tgbR3dlf03M+oCLIPahnxn4iZVw0e7J9gJqfgnLHUjKr4 JLq3OG4YWkdci5dt2f/+J3ThxLV+uHypoYLRt/3CU1CLwcLEXp82vJBe1gemw+xgawcA oJt6oxP4c7aTYbnhZ+/IFH+Hbt9RFvVAY5LcUxl/AAuD+Lxej4j+a44/iO0Zk6cYNgYE GEYT4DCUTLL0k+BATT/qk43oo7dsodPh2SGrVU/SDLdWyINSPRDVr/g4lU0XIMlkYUVP Zcqmw3npsQLKR8milK3FGUfgB+EMkvqWkwt1ID4s2zkHEexU5JasEfrlE1sb8L9/b/Yj uFtQ== X-Forwarded-Encrypted: i=1; AJvYcCUKc89yrqkwVTvElLyw7EnLlsZXabq4k7XnzwVi0GRw/HFxXsxMJMlREj/gDMJvtB49X5UaXWNq@vger.kernel.org X-Gm-Message-State: AOJu0Ywp83FhF3yhTJ/sLjoXpSws5SHSw04RLt55H9DRyJ9PEcw1akHH zIqazae/uW7YdGNA/xG0R3bopEn5sYR8AxehRS9sZoUc90YmZkxTHk/L1+HqI3L4BcS1XPEXfw= = X-Google-Smtp-Source: AGHT+IG7B0RNjcFY6oZJ7T3CMpXG0CHy8oMUhF6tkWNeGPyroh6H9MDhXHjLcDThKxfwd5lvmAol5o+grQ== X-Received: from tweek-syd.c.googlers.com ([fda3:e722:ac3:cc00:b7:3870:c0a8:26]) (user=tweek job=sendgmr) by 2002:a05:690c:4988:b0:690:8ad7:55f9 with SMTP id 00721157ae682-6c09b912365mr1991267b3.2.1724287091122; Wed, 21 Aug 2024 17:38:11 -0700 (PDT) Date: Thu, 22 Aug 2024 10:37:55 +1000 Precedence: bulk X-Mailing-List: selinux@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240822003757.1998016-1-tweek@google.com> Subject: [PATCH 1/3] libsepol: Rename ioctl xperms structures and functions From: " =?utf-8?q?Thi=C3=A9baud_Weksteen?= " To: paul@paul-moore.com Cc: brambonne@google.com, jeffv@google.com, selinux@vger.kernel.org, stephen.smalley.work@gmail.com, " =?utf-8?q?Thi=C3=A9baud_Weksteen?= " The ioctl extended permission structures and functions can be reused for other extended permissions. Use the more generic term "xperm" instead of "ioctl". Signed-off-by: Thiébaud Weksteen Acked-by: Stephen Smalley --- checkpolicy/policy_define.c | 72 ++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c index 4931f23d..4f6b2266 100644 --- a/checkpolicy/policy_define.c +++ b/checkpolicy/policy_define.c @@ -1874,27 +1874,27 @@ avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl) return sl; } -typedef struct av_ioctl_range { +typedef struct av_xperm_range { uint16_t low; uint16_t high; -} av_ioctl_range_t; +} av_xperm_range_t; -struct av_ioctl_range_list { +struct av_xperm_range_list { uint8_t omit; - av_ioctl_range_t range; - struct av_ioctl_range_list *next; + av_xperm_range_t range; + struct av_xperm_range_list *next; }; -static int avrule_sort_ioctls(struct av_ioctl_range_list **rangehead) +static int avrule_sort_xperms(struct av_xperm_range_list **rangehead) { - struct av_ioctl_range_list *r, *r2, *sorted, *sortedhead = NULL; + struct av_xperm_range_list *r, *r2, *sorted, *sortedhead = NULL; /* order list by range.low */ for (r = *rangehead; r != NULL; r = r->next) { - sorted = malloc(sizeof(struct av_ioctl_range_list)); + sorted = malloc(sizeof(struct av_xperm_range_list)); if (sorted == NULL) goto error; - memcpy(sorted, r, sizeof(struct av_ioctl_range_list)); + memcpy(sorted, r, sizeof(struct av_xperm_range_list)); sorted->next = NULL; if (sortedhead == NULL) { sortedhead = sorted; @@ -1933,9 +1933,9 @@ error: return -1; } -static void avrule_merge_ioctls(struct av_ioctl_range_list **rangehead) +static void avrule_merge_xperms(struct av_xperm_range_list **rangehead) { - struct av_ioctl_range_list *r, *tmp; + struct av_xperm_range_list *r, *tmp; r = *rangehead; while (r != NULL && r->next != NULL) { /* merge */ @@ -1952,15 +1952,15 @@ static void avrule_merge_ioctls(struct av_ioctl_range_list **rangehead) } } -static int avrule_read_ioctls(struct av_ioctl_range_list **rangehead) +static int avrule_read_xperm_ranges(struct av_xperm_range_list **rangehead) { char *id; - struct av_ioctl_range_list *rnew, *r = NULL; + struct av_xperm_range_list *rnew, *r = NULL; uint8_t omit = 0; *rangehead = NULL; - /* read in all the ioctl commands */ + /* read in all the ioctl/netlink commands */ while ((id = queue_remove(id_queue))) { if (strcmp(id,"~") == 0) { /* these are values to be omitted */ @@ -1979,7 +1979,7 @@ static int avrule_read_ioctls(struct av_ioctl_range_list **rangehead) free(id); } else { /* read in new low value */ - rnew = malloc(sizeof(struct av_ioctl_range_list)); + rnew = malloc(sizeof(struct av_xperm_range_list)); if (rnew == NULL) goto error; rnew->next = NULL; @@ -2006,11 +2006,11 @@ error: } /* flip to included ranges */ -static int avrule_omit_ioctls(struct av_ioctl_range_list **rangehead) +static int avrule_omit_xperms(struct av_xperm_range_list **rangehead) { - struct av_ioctl_range_list *rnew, *r, *newhead, *r2; + struct av_xperm_range_list *rnew, *r, *newhead, *r2; - rnew = calloc(1, sizeof(struct av_ioctl_range_list)); + rnew = calloc(1, sizeof(struct av_xperm_range_list)); if (!rnew) goto error; @@ -2028,7 +2028,7 @@ static int avrule_omit_ioctls(struct av_ioctl_range_list **rangehead) while (r) { r2->range.high = r->range.low - 1; - rnew = calloc(1, sizeof(struct av_ioctl_range_list)); + rnew = calloc(1, sizeof(struct av_xperm_range_list)); if (!rnew) goto error; r2->next = rnew; @@ -2054,26 +2054,26 @@ error: return -1; } -static int avrule_ioctl_ranges(struct av_ioctl_range_list **rangelist) +static int avrule_xperm_ranges(struct av_xperm_range_list **rangelist) { - struct av_ioctl_range_list *rangehead; + struct av_xperm_range_list *rangehead; uint8_t omit; /* read in ranges to include and omit */ - if (avrule_read_ioctls(&rangehead)) + if (avrule_read_xperm_ranges(&rangehead)) return -1; if (rangehead == NULL) { - yyerror("error processing ioctl commands"); + yyerror("error processing ioctl/netlink commands"); return -1; } omit = rangehead->omit; - /* sort and merge the input ioctls */ - if (avrule_sort_ioctls(&rangehead)) + /* sort and merge the input ranges */ + if (avrule_sort_xperms(&rangehead)) return -1; - avrule_merge_ioctls(&rangehead); + avrule_merge_xperms(&rangehead); /* flip ranges if these are omitted */ if (omit) { - if (avrule_omit_ioctls(&rangehead)) + if (avrule_omit_xperms(&rangehead)) return -1; } @@ -2261,11 +2261,11 @@ static int avrule_xperms_used(const av_extended_perms_t *xperms) #define IOC_DRIV(x) ((x) >> 8) #define IOC_FUNC(x) ((x) & 0xff) #define IOC_CMD(driver, func) (((driver) << 8) + (func)) -static int avrule_ioctl_partialdriver(struct av_ioctl_range_list *rangelist, +static int avrule_xperm_partialdriver(struct av_xperm_range_list *rangelist, av_extended_perms_t *complete_driver, av_extended_perms_t **extended_perms) { - struct av_ioctl_range_list *r; + struct av_xperm_range_list *r; av_extended_perms_t *xperms; uint8_t low, high; @@ -2300,10 +2300,10 @@ static int avrule_ioctl_partialdriver(struct av_ioctl_range_list *rangelist, } -static int avrule_ioctl_completedriver(struct av_ioctl_range_list *rangelist, +static int avrule_ioctl_completedriver(struct av_xperm_range_list *rangelist, av_extended_perms_t **extended_perms) { - struct av_ioctl_range_list *r; + struct av_xperm_range_list *r; av_extended_perms_t *xperms; uint16_t low, high; xperms = calloc(1, sizeof(av_extended_perms_t)); @@ -2342,10 +2342,10 @@ static int avrule_ioctl_completedriver(struct av_ioctl_range_list *rangelist, return 0; } -static int avrule_ioctl_func(struct av_ioctl_range_list *rangelist, +static int avrule_ioctl_func(struct av_xperm_range_list *rangelist, av_extended_perms_t **extended_perms, unsigned int driver) { - struct av_ioctl_range_list *r; + struct av_xperm_range_list *r; av_extended_perms_t *xperms; uint16_t low, high; @@ -2457,13 +2457,13 @@ static int avrule_cpy(avrule_t *dest, const avrule_t *src) static int define_te_avtab_ioctl(const avrule_t *avrule_template) { avrule_t *avrule; - struct av_ioctl_range_list *rangelist, *r; + struct av_xperm_range_list *rangelist, *r; av_extended_perms_t *complete_driver, *partial_driver, *xperms; unsigned int i; /* organize ioctl ranges */ - if (avrule_ioctl_ranges(&rangelist)) + if (avrule_xperm_ranges(&rangelist)) return -1; /* create rule for ioctl driver types that are entirely enabled */ @@ -2482,7 +2482,7 @@ static int define_te_avtab_ioctl(const avrule_t *avrule_template) } /* flag ioctl driver codes that are partially enabled */ - if (avrule_ioctl_partialdriver(rangelist, complete_driver, &partial_driver)) + if (avrule_xperm_partialdriver(rangelist, complete_driver, &partial_driver)) return -1; if (!partial_driver || !avrule_xperms_used(partial_driver)) From patchwork Thu Aug 22 00:37:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thi=C3=A9baud_Weksteen?= X-Patchwork-Id: 13772266 X-Patchwork-Delegate: plautrba@redhat.com Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 446894C74 for ; Thu, 22 Aug 2024 00:38:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724287127; cv=none; b=IB0FFUuZLlWw9bhB707fm87DMMLKP/euh+f8fgc0kLvykOHkFIQeAXwzKxIViO2+eH6bKnRM3ihPybOHfXeBLutBw2Uu16nG/JUo13INe8JnDGCA7Hn1SqiVCPDvWGs+oNsKxD6/0t+newkEZXG7Yi2hVsq4Ao038mmJmpijy2A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724287127; c=relaxed/simple; bh=U2d/5CVM4BmwCJ2lgbDno2NP+QEuzgNumjUOxjb63Ss=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=qKYyY33XGD1yxtIF9iD/7wo7EtiwEcmjdX5Zf1SlpETiBkxuaXeEz/8iJMLnTqoQp9YFPniT6UurjKeE1Z0prQqoPUHK73KLtxPnoUhasRwqfyeLvzohY9TAC+UWsayvPBVJJ04apKz665RnDFWGmUm98sU0lwyEyoIuwBaHrPU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--tweek.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=slEtNSB1; arc=none smtp.client-ip=209.85.128.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--tweek.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="slEtNSB1" Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-690404fd230so5358647b3.3 for ; Wed, 21 Aug 2024 17:38:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1724287124; x=1724891924; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=BHDtl+MEtT0w71HRhOjcg4vDjJvGDqZH4AcWRYKMkzY=; b=slEtNSB1elDktDdf+N6w4Dr47+uKlE41jVK2RgmAVpiRb/giciFH4JNNlJ9Rtg4ylx G5bUX34pACJV3/NE4tDDI61boU8ghF4KLERHnwh5KKxW/fwSay9NPfsooCUyKdAr8JSX ayuu1vk8n7SWA07VIvFQ+3Voeoe4mswbSZyVC/MTpw+KunGCsFEh8MRwsGzbYgzbh7Gv m3wj7QbAlbYDagCwzqzTdXzM/OURG7ZEux2YJTnArudiLrQjRIyKMIyst7zzI4Q/ZhI4 ejp8J9P59e+yC8wUfPQqDIk25TuFCXLRHQ561WOqoewxArfVFfDpStJ0kBDor1DXiCGO L8vw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724287124; x=1724891924; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=BHDtl+MEtT0w71HRhOjcg4vDjJvGDqZH4AcWRYKMkzY=; b=Xfav9gcUiyneXe3YSCZ6XshhDSBIADnKeUNfQ1NSOJLd0kiIjy6hBx0OcpHJvxHIFQ WYOIPQcmLnzYNlkfFJuy6kPlsUyB3WdK7fSE8rMeaQCGzYj3N8ZZ24E3fkxGyEcjdmKD wieEUuRHh/HFiuQnqara1SnWCFFnoXK0gpfzJ5WEDzJbGrV8YN54p09lJbqgUQRoEtFH M/oqxPfAgdTGfT/tUzH+GLOhAQe82Npkq2e49yPtLu73QXYhFt8fjKPB+VYmYkgdVUGl T5qLTKEpvA2d5+JLGRuO+hKYeU2pLzWINE8hBVAYt9b7GF7rLZpCHmDWbFkmbbMzxATg PVkg== X-Forwarded-Encrypted: i=1; AJvYcCXbcoWb2xdTq8zr91LUWaoJ3cMlisEy43d1cXHTS5qp1QiCd5EwOAu75tvITPMGjA+AkozACIoH@vger.kernel.org X-Gm-Message-State: AOJu0YyNtNTltSgQp2O8d9/ttohbX/iq0+gxKk9NRXggqs41nBMedzEF 21xFQVKqdJuecWOJ+IcoCRC5GmI9Y02HaXzU67LnfpoombjSkmFQ2uBS2K77m9HLw+g4RH5ZWw= = X-Google-Smtp-Source: AGHT+IHYEnIgdXhLnGc8NgGRab46aLG6j9ATtRGjRU8PUX6AGCP7CWiHwTboeJvVl9KMumPx1Tl2DPCDHA== X-Received: from tweek-syd.c.googlers.com ([fda3:e722:ac3:cc00:b7:3870:c0a8:26]) (user=tweek job=sendgmr) by 2002:a25:a301:0:b0:e11:6ad4:6271 with SMTP id 3f1490d57ef6-e1665411bd7mr6018276.1.1724287124047; Wed, 21 Aug 2024 17:38:44 -0700 (PDT) Date: Thu, 22 Aug 2024 10:37:56 +1000 In-Reply-To: <20240822003757.1998016-1-tweek@google.com> Precedence: bulk X-Mailing-List: selinux@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240822003757.1998016-1-tweek@google.com> X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240822003757.1998016-2-tweek@google.com> Subject: [PATCH 2/3] libsepol: Support nlmsg extended permissions From: " =?utf-8?q?Thi=C3=A9baud_Weksteen?= " To: paul@paul-moore.com Cc: brambonne@google.com, jeffv@google.com, selinux@vger.kernel.org, stephen.smalley.work@gmail.com, " =?utf-8?q?Thi=C3=A9baud_Weksteen?= " Add support for AVTAB_XPERMS_NLMSG as extended permissions for netlink sockets. The behaviour is similar to the existing AVTAB_XPERMS_IOCTLFUNCTION. Signed-off-by: Thiébaud Weksteen Acked-by: Stephen Smalley --- checkpolicy/policy_define.c | 64 +++++++++++++++-- checkpolicy/test/dismod.c | 2 + libsepol/cil/src/cil.c | 2 + libsepol/cil/src/cil_binary.c | 84 ++++++++++++++++------ libsepol/cil/src/cil_build_ast.c | 4 +- libsepol/cil/src/cil_internal.h | 2 + libsepol/cil/src/cil_policy.c | 2 + libsepol/cil/src/cil_verify.c | 3 + libsepol/cil/src/cil_write_ast.c | 16 ++++- libsepol/include/sepol/policydb/avtab.h | 1 + libsepol/include/sepol/policydb/policydb.h | 1 + libsepol/src/expand.c | 3 + libsepol/src/kernel_to_cil.c | 21 ++++-- libsepol/src/module_to_cil.c | 20 ++++-- libsepol/src/policydb_validate.c | 2 + libsepol/src/util.c | 14 ++-- 16 files changed, 200 insertions(+), 41 deletions(-) diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c index 4f6b2266..6b062657 100644 --- a/checkpolicy/policy_define.c +++ b/checkpolicy/policy_define.c @@ -2342,8 +2342,8 @@ static int avrule_ioctl_completedriver(struct av_xperm_range_list *rangelist, return 0; } -static int avrule_ioctl_func(struct av_xperm_range_list *rangelist, - av_extended_perms_t **extended_perms, unsigned int driver) +static int avrule_xperm_func(struct av_xperm_range_list *rangelist, + av_extended_perms_t **extended_perms, unsigned int driver, uint8_t specified) { struct av_xperm_range_list *r; av_extended_perms_t *xperms; @@ -2379,7 +2379,7 @@ static int avrule_ioctl_func(struct av_xperm_range_list *rangelist, high = IOC_FUNC(high); avrule_xperm_setrangebits(low, high, xperms); xperms->driver = driver; - xperms->specified = AVRULE_XPERMS_IOCTLFUNCTION; + xperms->specified = specified; r = r->next; } @@ -2495,7 +2495,61 @@ static int define_te_avtab_ioctl(const avrule_t *avrule_template) */ i = 0; while (xperms_for_each_bit(&i, partial_driver)) { - if (avrule_ioctl_func(rangelist, &xperms, i)) + if (avrule_xperm_func(rangelist, &xperms, i, AVRULE_XPERMS_IOCTLFUNCTION)) + return -1; + + if (xperms) { + avrule = (avrule_t *) calloc(1, sizeof(avrule_t)); + if (!avrule) { + yyerror("out of memory"); + return -1; + } + if (avrule_cpy(avrule, avrule_template)) + return -1; + avrule->xperms = xperms; + append_avrule(avrule); + } + } + +done: + if (partial_driver) + free(partial_driver); + + while (rangelist != NULL) { + r = rangelist; + rangelist = rangelist->next; + free(r); + } + + return 0; +} + +static int define_te_avtab_netlink(const avrule_t *avrule_template) +{ + avrule_t *avrule; + struct av_xperm_range_list *rangelist, *r; + av_extended_perms_t *partial_driver, *xperms; + unsigned int i; + + /* organize ranges */ + if (avrule_xperm_ranges(&rangelist)) + return -1; + + /* flag driver codes that are partially enabled */ + if (avrule_xperm_partialdriver(rangelist, NULL, &partial_driver)) + return -1; + + if (!partial_driver || !avrule_xperms_used(partial_driver)) + goto done; + + /* + * create rule for each partially used driver codes + * "partially used" meaning that the code number e.g. socket 0x89 + * has some permission bits set and others not set. + */ + i = 0; + while (xperms_for_each_bit(&i, partial_driver)) { + if (avrule_xperm_func(rangelist, &xperms, i, AVRULE_XPERMS_NLMSG)) return -1; if (xperms) { @@ -2546,6 +2600,8 @@ int define_te_avtab_extended_perms(int which) id = queue_remove(id_queue); if (strcmp(id,"ioctl") == 0) { rc = define_te_avtab_ioctl(avrule_template); + } else if (strcmp(id,"nlmsg") == 0) { + rc = define_te_avtab_netlink(avrule_template); } else { yyerror2("only ioctl extended permissions are supported, found %s", id); rc = -1; diff --git a/checkpolicy/test/dismod.c b/checkpolicy/test/dismod.c index bd45c95e..4868190f 100644 --- a/checkpolicy/test/dismod.c +++ b/checkpolicy/test/dismod.c @@ -353,6 +353,8 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy, xperms.specified = AVTAB_XPERMS_IOCTLFUNCTION; else if (avrule->xperms->specified == AVRULE_XPERMS_IOCTLDRIVER) xperms.specified = AVTAB_XPERMS_IOCTLDRIVER; + else if (avrule->xperms->specified == AVRULE_XPERMS_NLMSG) + xperms.specified = AVTAB_XPERMS_NLMSG; else { fprintf(fp, " ERROR: no valid xperms specified\n"); return -1; diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c index 067e28a6..5521c7ea 100644 --- a/libsepol/cil/src/cil.c +++ b/libsepol/cil/src/cil.c @@ -221,6 +221,7 @@ char *CIL_KEY_DONTAUDITX; char *CIL_KEY_NEVERALLOWX; char *CIL_KEY_PERMISSIONX; char *CIL_KEY_IOCTL; +char *CIL_KEY_NLMSG; char *CIL_KEY_UNORDERED; char *CIL_KEY_SRC_INFO; char *CIL_KEY_SRC_CIL; @@ -393,6 +394,7 @@ static void cil_init_keys(void) CIL_KEY_NEVERALLOWX = cil_strpool_add("neverallowx"); CIL_KEY_PERMISSIONX = cil_strpool_add("permissionx"); CIL_KEY_IOCTL = cil_strpool_add("ioctl"); + CIL_KEY_NLMSG = cil_strpool_add("nlmsg"); CIL_KEY_UNORDERED = cil_strpool_add("unordered"); CIL_KEY_SRC_INFO = cil_strpool_add(""); CIL_KEY_SRC_CIL = cil_strpool_add("cil"); diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c index c8144a5a..3dec1883 100644 --- a/libsepol/cil/src/cil_binary.c +++ b/libsepol/cil/src/cil_binary.c @@ -66,6 +66,7 @@ struct cil_args_binary { int pass; hashtab_t role_trans_table; hashtab_t avrulex_ioctl_table; + hashtab_t avrulex_nlmsg_table; void **type_value_to_cil; }; @@ -1671,11 +1672,22 @@ static void __avrule_xperm_setrangebits(uint16_t low, uint16_t high, struct avta } } +static char* __cil_xperm_kind_to_str(uint32_t xperm_kind) +{ + switch (xperm_kind) { + case CIL_PERMX_KIND_IOCTL: + return CIL_KEY_IOCTL; + case CIL_PERMX_KIND_NLMSG: + return CIL_KEY_NLMSG; + default: + return (char *) "unknown"; + } +} #define IOC_DRIV(x) (x >> 8) #define IOC_FUNC(x) (x & 0xff) -static int __cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t *xperms, struct cil_list **xperms_list) +static int __cil_permx_bitmap_to_sepol_xperms_list(uint32_t kind, ebitmap_t *xperms, struct cil_list **xperms_list) { ebitmap_node_t *node; unsigned int i; @@ -1705,7 +1717,7 @@ static int __cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t *xperms, struct cil high = i; start_new_range = 1; - if (IOC_FUNC(low) == 0x00 && IOC_FUNC(high) == 0xff) { + if (kind == CIL_PERMX_KIND_IOCTL && IOC_FUNC(low) == 0x00 && IOC_FUNC(high) == 0xff) { if (!complete) { complete = cil_calloc(1, sizeof(*complete)); complete->driver = 0x0; @@ -1722,7 +1734,14 @@ static int __cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t *xperms, struct cil if (!partial) { partial = cil_calloc(1, sizeof(*partial)); partial->driver = IOC_DRIV(low); - partial->specified = AVTAB_XPERMS_IOCTLFUNCTION; + switch (kind) { + case CIL_PERMX_KIND_IOCTL: + partial->specified = AVTAB_XPERMS_IOCTLFUNCTION; + break; + case CIL_PERMX_KIND_NLMSG: + partial->specified = AVTAB_XPERMS_NLMSG; + break; + } } __avrule_xperm_setrangebits(IOC_FUNC(low), IOC_FUNC(high), partial); @@ -1740,7 +1759,7 @@ static int __cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t *xperms, struct cil return SEPOL_OK; } -static int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datum, void *args) +static int __cil_avrulex_xperm_to_policydb(hashtab_key_t k, hashtab_datum_t datum, uint32_t xperm_kind, void *args) { int rc = SEPOL_OK; struct policydb *pdb; @@ -1750,6 +1769,7 @@ static int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datu struct cil_list_item *item; class_datum_t *sepol_obj; uint32_t data = 0; + char *kind = NULL; avtab_key = (avtab_key_t *)k; pdb = args; @@ -1759,13 +1779,14 @@ static int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datu // setting the data for an extended avtab isn't really necessary because // it is ignored by the kernel. However, neverallow checking requires that // the data value be set, so set it for that to work. - rc = __perm_str_to_datum(CIL_KEY_IOCTL, sepol_obj, &data); + kind = __cil_xperm_kind_to_str(xperm_kind); + rc = __perm_str_to_datum(kind, sepol_obj, &data); if (rc != SEPOL_OK) { goto exit; } avtab_datum.data = data; - rc = __cil_permx_bitmap_to_sepol_xperms_list(datum, &xperms_list); + rc = __cil_permx_bitmap_to_sepol_xperms_list(xperm_kind, datum, &xperms_list); if (rc != SEPOL_OK) { goto exit; } @@ -1790,7 +1811,15 @@ exit: return rc; } -static int __cil_avrulex_ioctl_to_hashtable(hashtab_t h, uint16_t kind, uint32_t src, uint32_t tgt, uint32_t obj, ebitmap_t *xperms) +static int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datum, void *args) { + return __cil_avrulex_xperm_to_policydb(k, datum, CIL_PERMX_KIND_IOCTL, args); +} + +static int __cil_avrulex_nlmsg_to_policydb(hashtab_key_t k, hashtab_datum_t datum, void *args) { + return __cil_avrulex_xperm_to_policydb(k, datum, CIL_PERMX_KIND_NLMSG, args); +} + +static int __cil_avrulex_xperm_to_hashtable(hashtab_t h, uint16_t kind, uint32_t src, uint32_t tgt, uint32_t obj, ebitmap_t *xperms) { uint16_t specified; avtab_key_t *avtab_key; @@ -1870,7 +1899,11 @@ static int __cil_avrulex_to_hashtable_helper(policydb_t *pdb, uint16_t kind, str switch (permx->kind) { case CIL_PERMX_KIND_IOCTL: - rc = __cil_avrulex_ioctl_to_hashtable(args->avrulex_ioctl_table, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms); + rc = __cil_avrulex_xperm_to_hashtable(args->avrulex_ioctl_table, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms); + if (rc != SEPOL_OK) goto exit; + break; + case CIL_PERMX_KIND_NLMSG: + rc = __cil_avrulex_xperm_to_hashtable(args->avrulex_nlmsg_table, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms); if (rc != SEPOL_OK) goto exit; break; default: @@ -2037,7 +2070,7 @@ exit: return rc; } -static int __cil_avrulex_ioctl_destroy(hashtab_key_t k, hashtab_datum_t datum, __attribute__((unused)) void *args) +static int __cil_avrulex_xperm_destroy(hashtab_key_t k, hashtab_datum_t datum, __attribute__((unused)) void *args) { free(k); ebitmap_destroy(datum); @@ -4630,6 +4663,9 @@ static int __cil_permx_to_sepol_class_perms(policydb_t *pdb, struct cil_permissi case CIL_PERMX_KIND_IOCTL: perm_str = CIL_KEY_IOCTL; break; + case CIL_PERMX_KIND_NLMSG: + perm_str = CIL_KEY_NLMSG; + break; default: rc = SEPOL_ERR; goto exit; @@ -4769,17 +4805,10 @@ static void __cil_print_classperm(struct cil_list *cp_list) static void __cil_print_permissionx(struct cil_permissionx *px) { - const char *kind_str = ""; + const char *kind_str = NULL; char *expr_str; - switch (px->kind) { - case CIL_PERMX_KIND_IOCTL: - kind_str = CIL_KEY_IOCTL; - break; - default: - kind_str = "unknown"; - break; - } + kind_str = __cil_xperm_kind_to_str(px->kind); __cil_expr_to_string(px->expr_str, CIL_PERMISSIONX, &expr_str); @@ -4928,7 +4957,7 @@ static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct goto exit; } - rc = __cil_permx_bitmap_to_sepol_xperms_list(cil_rule->perms.x.permx->perms, &xperms); + rc = __cil_permx_bitmap_to_sepol_xperms_list(cil_rule->perms.x.permx->kind, cil_rule->perms.x.permx->perms, &xperms); if (rc != SEPOL_OK) { goto exit; } @@ -5137,6 +5166,7 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p struct cil_list *neverallows = NULL; hashtab_t role_trans_table = NULL; hashtab_t avrulex_ioctl_table = NULL; + hashtab_t avrulex_nlmsg_table = NULL; void **type_value_to_cil = NULL; struct cil_class **class_value_to_cil = NULL; struct cil_perm ***perm_value_to_cil = NULL; @@ -5184,6 +5214,12 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p goto exit; } + avrulex_nlmsg_table = hashtab_create(avrulex_hash, avrulex_compare, AVRULEX_TABLE_SIZE); + if (!avrulex_nlmsg_table) { + cil_log(CIL_INFO, "Failure to create hashtab for avrulex\n"); + goto exit; + } + cil_list_init(&neverallows, CIL_LIST_ITEM); extra_args.db = db; @@ -5191,6 +5227,7 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p extra_args.neverallows = neverallows; extra_args.role_trans_table = role_trans_table; extra_args.avrulex_ioctl_table = avrulex_ioctl_table; + extra_args.avrulex_nlmsg_table = avrulex_nlmsg_table; extra_args.type_value_to_cil = type_value_to_cil; for (i = 1; i <= 3; i++) { @@ -5216,6 +5253,11 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p cil_log(CIL_INFO, "Failure creating avrulex rules\n"); goto exit; } + rc = hashtab_map(avrulex_nlmsg_table, __cil_avrulex_nlmsg_to_policydb, pdb); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failure creating avrulex rules\n"); + goto exit; + } } } @@ -5287,8 +5329,10 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p exit: hashtab_destroy(role_trans_table); - hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_destroy, NULL); + hashtab_map(avrulex_ioctl_table, __cil_avrulex_xperm_destroy, NULL); hashtab_destroy(avrulex_ioctl_table); + hashtab_map(avrulex_nlmsg_table, __cil_avrulex_xperm_destroy, NULL); + hashtab_destroy(avrulex_nlmsg_table); free(type_value_to_cil); free(class_value_to_cil); if (perm_value_to_cil != NULL) { diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c index 56dac891..87178294 100644 --- a/libsepol/cil/src/cil_build_ast.c +++ b/libsepol/cil/src/cil_build_ast.c @@ -2153,8 +2153,10 @@ static int cil_fill_permissionx(struct cil_tree_node *parse_current, struct cil_ if (parse_current->data == CIL_KEY_IOCTL) { permx->kind = CIL_PERMX_KIND_IOCTL; + } else if (parse_current->data == CIL_KEY_NLMSG) { + permx->kind = CIL_PERMX_KIND_NLMSG; } else { - cil_log(CIL_ERR, "Unknown permissionx kind, %s. Must be \"ioctl\"\n", (char *)parse_current->data); + cil_log(CIL_ERR, "Unknown permissionx kind, %s. Must be \"ioctl\" or \"nlmsg\"\n", (char *)parse_current->data); rc = SEPOL_ERR; goto exit; } diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h index 47b67c89..959b31e3 100644 --- a/libsepol/cil/src/cil_internal.h +++ b/libsepol/cil/src/cil_internal.h @@ -238,6 +238,7 @@ extern char *CIL_KEY_DONTAUDITX; extern char *CIL_KEY_NEVERALLOWX; extern char *CIL_KEY_PERMISSIONX; extern char *CIL_KEY_IOCTL; +extern char *CIL_KEY_NLMSG; extern char *CIL_KEY_UNORDERED; extern char *CIL_KEY_SRC_INFO; extern char *CIL_KEY_SRC_CIL; @@ -636,6 +637,7 @@ struct cil_avrule { }; #define CIL_PERMX_KIND_IOCTL 1 +#define CIL_PERMX_KIND_NLMSG 2 struct cil_permissionx { struct cil_symtab_datum datum; uint32_t kind; diff --git a/libsepol/cil/src/cil_policy.c b/libsepol/cil/src/cil_policy.c index e9a8f75d..c497c8ab 100644 --- a/libsepol/cil/src/cil_policy.c +++ b/libsepol/cil/src/cil_policy.c @@ -1112,6 +1112,8 @@ static void cil_xperms_to_policy(FILE *out, struct cil_permissionx *permx) if (permx->kind == CIL_PERMX_KIND_IOCTL) { kind = "ioctl"; + } else if (permx->kind == CIL_PERMX_KIND_NLMSG) { + kind = "nlmsg"; } else { kind = "???"; } diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c index 4ef2cbab..9621a247 100644 --- a/libsepol/cil/src/cil_verify.c +++ b/libsepol/cil/src/cil_verify.c @@ -1513,6 +1513,9 @@ static int __cil_verify_permissionx(struct cil_permissionx *permx, struct cil_tr case CIL_PERMX_KIND_IOCTL: kind_str = CIL_KEY_IOCTL; break; + case CIL_PERMX_KIND_NLMSG: + kind_str = CIL_KEY_NLMSG; + break; default: cil_tree_log(node, CIL_ERR, "Invalid permissionx kind (%d)", permx->kind); rc = SEPOL_ERR; diff --git a/libsepol/cil/src/cil_write_ast.c b/libsepol/cil/src/cil_write_ast.c index 46bd84db..cd1b6e6c 100644 --- a/libsepol/cil/src/cil_write_ast.c +++ b/libsepol/cil/src/cil_write_ast.c @@ -303,7 +303,13 @@ static void write_permx(FILE *out, struct cil_permissionx *permx) fprintf(out, "%s", datum_to_str(DATUM(permx))); } else { fprintf(out, "("); - fprintf(out, "%s ", permx->kind == CIL_PERMX_KIND_IOCTL ? "ioctl" : ""); + if (permx->kind == CIL_PERMX_KIND_IOCTL) { + fprintf(out, "ioctl "); + } else if (permx->kind == CIL_PERMX_KIND_NLMSG) { + fprintf(out, "nlmsg "); + } else { + fprintf(out, " "); + } fprintf(out, "%s ", datum_or_str(DATUM(permx->obj), permx->obj_str)); write_expr(out, permx->expr_str); fprintf(out, ")"); @@ -825,7 +831,13 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node) case CIL_PERMISSIONX: { struct cil_permissionx *permx = node->data; fprintf(out, "(permissionx %s (", datum_to_str(DATUM(permx))); - fprintf(out, "%s ", permx->kind == CIL_PERMX_KIND_IOCTL ? "ioctl" : ""); + if (permx->kind == CIL_PERMX_KIND_IOCTL) { + fprintf(out, "ioctl "); + } else if (permx->kind == CIL_PERMX_KIND_NLMSG) { + fprintf(out, "nlmsg "); + } else { + fprintf(out, " "); + } fprintf(out, "%s ", datum_or_str(DATUM(permx->obj), permx->obj_str)); write_expr(out, permx->expr_str); fprintf(out, "))\n"); diff --git a/libsepol/include/sepol/policydb/avtab.h b/libsepol/include/sepol/policydb/avtab.h index 2ab99c39..6e154cfe 100644 --- a/libsepol/include/sepol/policydb/avtab.h +++ b/libsepol/include/sepol/policydb/avtab.h @@ -74,6 +74,7 @@ typedef struct avtab_extended_perms { #define AVTAB_XPERMS_IOCTLFUNCTION 0x01 #define AVTAB_XPERMS_IOCTLDRIVER 0x02 +#define AVTAB_XPERMS_NLMSG 0x03 /* extension of the avtab_key specified */ uint8_t specified; uint8_t driver; diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h index 856faeb7..104a7dc8 100644 --- a/libsepol/include/sepol/policydb/policydb.h +++ b/libsepol/include/sepol/policydb/policydb.h @@ -259,6 +259,7 @@ typedef struct class_perm_node { typedef struct av_extended_perms { #define AVRULE_XPERMS_IOCTLFUNCTION 0x01 #define AVRULE_XPERMS_IOCTLDRIVER 0x02 +#define AVRULE_XPERMS_NLMSG 0x03 uint8_t specified; uint8_t driver; /* 256 bits of permissions */ diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c index e63414b1..7032a83f 100644 --- a/libsepol/src/expand.c +++ b/libsepol/src/expand.c @@ -1821,6 +1821,9 @@ static int allocate_xperms(sepol_handle_t * handle, avtab_datum_t * avdatump, case AVRULE_XPERMS_IOCTLDRIVER: xperms->specified = AVTAB_XPERMS_IOCTLDRIVER; break; + case AVRULE_XPERMS_NLMSG: + xperms->specified = AVTAB_XPERMS_NLMSG; + break; default: return -1; } diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c index f94cb245..7243b3c0 100644 --- a/libsepol/src/kernel_to_cil.c +++ b/libsepol/src/kernel_to_cil.c @@ -1651,7 +1651,8 @@ static char *xperms_to_str(const avtab_extended_perms_t *xperms) size_t remaining, size = 128; if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) - && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) { + && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER) + && (xperms->specified != AVTAB_XPERMS_NLMSG)) { return NULL; } @@ -1681,7 +1682,8 @@ retry: continue; } - if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) { + if ((xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) + || (xperms->specified == AVTAB_XPERMS_NLMSG)) { value = xperms->driver<<8 | bit; if (in_range) { low_value = xperms->driver<<8 | low_bit; @@ -1690,7 +1692,7 @@ retry: } else { len = snprintf(p, remaining, " 0x%hx", value); } - } else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) { + } else if (xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { value = bit << 8; if (in_range) { low_value = low_bit << 8; @@ -1728,7 +1730,7 @@ static char *avtab_node_to_str(struct policydb *pdb, avtab_key_t *key, avtab_dat uint32_t data = datum->data; type_datum_t *type; const char *flavor, *tgt; - char *src, *class, *perms, *new; + char *src, *class, *perms, *new, *xperm; char *rule = NULL; switch (0xFFF & key->specified) { @@ -1795,9 +1797,16 @@ static char *avtab_node_to_str(struct policydb *pdb, avtab_key_t *key, avtab_dat ERR(NULL, "Failed to generate extended permission string"); goto exit; } - + if (datum->xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION || datum->xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + xperm = (char *) "ioctl"; + } else if (datum->xperms->specified == AVTAB_XPERMS_NLMSG) { + xperm = (char *) "nlmsg"; + } else { + ERR(NULL, "Unknown extended permssion"); + goto exit; + } rule = create_str("(%s %s %s (%s %s (%s)))", - flavor, src, tgt, "ioctl", class, perms); + flavor, src, tgt, xperm, class, perms); free(perms); } else { new = pdb->p_type_val_to_name[data - 1]; diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c index 2dbf137e..79636897 100644 --- a/libsepol/src/module_to_cil.c +++ b/libsepol/src/module_to_cil.c @@ -630,7 +630,8 @@ static int xperms_to_cil(const av_extended_perms_t *xperms) int first = 1; if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) - && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) + && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER) + && (xperms->specified != AVTAB_XPERMS_NLMSG)) return -1; for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) { @@ -652,7 +653,8 @@ static int xperms_to_cil(const av_extended_perms_t *xperms) else first = 0; - if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) { + if ((xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) + || (xperms->specified == AVTAB_XPERMS_NLMSG)) { value = xperms->driver<<8 | bit; if (in_range) { low_value = xperms->driver<<8 | low_bit; @@ -661,7 +663,7 @@ static int xperms_to_cil(const av_extended_perms_t *xperms) } else { cil_printf("0x%hx", value); } - } else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) { + } else if (xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { value = bit << 8; if (in_range) { low_value = low_bit << 8; @@ -680,6 +682,7 @@ static int avrulex_to_cil(int indent, struct policydb *pdb, uint32_t type, const { int rc = -1; const char *rule; + const char *xperm; const struct class_perm_node *classperm; switch (type) { @@ -701,10 +704,19 @@ static int avrulex_to_cil(int indent, struct policydb *pdb, uint32_t type, const goto exit; } + if (xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION || xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { + xperm = "ioctl"; + } else if (xperms->specified == AVTAB_XPERMS_NLMSG) { + xperm = "nlmsg"; + } else { + ERR(NULL, "Unkown avrule xperms->specified: %i", xperms->specified); + rc = -1; + goto exit; + } for (classperm = classperms; classperm != NULL; classperm = classperm->next) { cil_indent(indent); cil_printf("(%s %s %s (%s %s (", rule, src, tgt, - "ioctl", pdb->p_class_val_to_name[classperm->tclass - 1]); + xperm, pdb->p_class_val_to_name[classperm->tclass - 1]); xperms_to_cil(xperms); cil_printf(")))\n"); } diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c index 121fd46c..5035313b 100644 --- a/libsepol/src/policydb_validate.c +++ b/libsepol/src/policydb_validate.c @@ -921,6 +921,7 @@ static int validate_xperms(const avtab_extended_perms_t *xperms) switch (xperms->specified) { case AVTAB_XPERMS_IOCTLDRIVER: case AVTAB_XPERMS_IOCTLFUNCTION: + case AVTAB_XPERMS_NLMSG: break; default: goto bad; @@ -1067,6 +1068,7 @@ static int validate_avrules(sepol_handle_t *handle, const avrule_t *avrule, int switch (avrule->xperms->specified) { case AVRULE_XPERMS_IOCTLFUNCTION: case AVRULE_XPERMS_IOCTLDRIVER: + case AVRULE_XPERMS_NLMSG: break; default: goto bad; diff --git a/libsepol/src/util.c b/libsepol/src/util.c index b1eb9b38..a4befbd9 100644 --- a/libsepol/src/util.c +++ b/libsepol/src/util.c @@ -146,7 +146,8 @@ char *sepol_extended_perms_to_string(const avtab_extended_perms_t *xperms) size_t remaining, size = 128; if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) - && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) + && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER) + && (xperms->specified != AVTAB_XPERMS_NLMSG)) return NULL; retry: @@ -158,7 +159,12 @@ retry: buffer = p; remaining = size; - len = snprintf(p, remaining, "ioctl { "); + if ((xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION) + || (xperms->specified == AVTAB_XPERMS_IOCTLDRIVER)) { + len = snprintf(p, remaining, "ioctl { "); + } else { + len = snprintf(p, remaining, "nlmsg { "); + } if (len < 0 || (size_t)len >= remaining) goto err; p += len; @@ -179,7 +185,7 @@ retry: continue; } - if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) { + if (xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION || xperms->specified == AVTAB_XPERMS_NLMSG) { value = xperms->driver<<8 | bit; if (in_range) { low_value = xperms->driver<<8 | low_bit; @@ -187,7 +193,7 @@ retry: } else { len = snprintf(p, remaining, "0x%hx ", value); } - } else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) { + } else if (xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { value = bit << 8; if (in_range) { low_value = low_bit << 8; From patchwork Thu Aug 22 00:37:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Thi=C3=A9baud_Weksteen?= X-Patchwork-Id: 13772267 X-Patchwork-Delegate: plautrba@redhat.com Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B2A734C8D for ; Thu, 22 Aug 2024 00:39:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724287159; cv=none; b=ehOHgkhA6eBOPDkJal8zb9uFPs9Yl4VrfBymZTqUXy57wasLZTeStB+KuZQD6/9HJ2toMhuT91HjecSj8XqYXZmf+LDkLleLd4BmM/exAda/rBbAShSdGn1k9xS44McBe9JghBEAKnDeIIhiHoTnI6ib3JhHqIUjPIg8D/lDEzg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724287159; c=relaxed/simple; bh=oVkOAEt44SPB+4p0wqPT/Mn4PiIl0Kw3mLocwQm04oQ=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=C+ye7ZGrYf5QhaSX26E5V11BlnZHUQYrAnzK+vpZ2NfHy/S0d/zNLgihavoxEKylNjpjhZuo2hM4/J2mf7Kc11NQjzEfPD7PWO/FUcbKrHeDnk1viv3jKG3hNHOOEzzaMWtgRTpwaJEnP0/EfQzMeJ3eyvA8i7ZL75r0C9Hnp1g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--tweek.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=jSZv1Zuk; arc=none smtp.client-ip=209.85.128.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--tweek.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="jSZv1Zuk" Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-69a0536b23aso6117477b3.3 for ; Wed, 21 Aug 2024 17:39:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1724287156; x=1724891956; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=ke15B4oKXomvm2GlrT46AeYAwzBPFoBjFx6xgv0XDrI=; b=jSZv1Zuk3dM0H99QMi5LqMHLTuGsUwk35CCSBlZLdlhBKn1YGt6gvgPzeJW9LFQR6r ndDWG89Xfnl0rSrdSPB7/VAHawvjmcU3ucuxmWZf9Cmy8NnG8flRJfNw2neC5mwPlGeQ 9fcD3o8LoEwx44WDEfiKxFQgAKJTXG9BXy+QD5Y2FhrSsOj9CmRMKEYqWWDIjU5nJdLX uEx2+rhBiW3tJXNPgU/9v/bShRkRD+xgNQgzGdHvrXkeo/e+chq41dfROrRb2k4X6rH0 fs4jwAJz9QY+OEIMeJJ0+4anmCbhcuOsUGlm3vlFHcRikzw9bjyorNErMkinJyKhm05g 0s9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1724287156; x=1724891956; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=ke15B4oKXomvm2GlrT46AeYAwzBPFoBjFx6xgv0XDrI=; b=Lbkf7d4SDWWGQaVhXcWtmcbBJTNvITVzkUOY+NqqT9QJ517vDaDmiMH6Gt8W2H7WTN o1fc++mQvRvFJ0oprvMZKu2JD5/FVdQHLQibb1p72Z+/q6IviJyHxzWOsw37oKq1859P mqCRYg/3CMONbwoFeDL/ct14efXZzZpMvcQlCB+8sl6HOQXC3VTlXXbCaIeQGwCmNBKI t8nENx4EeLcnbmWMD4wxFz0PYZlPe94NpkZ/p8mnPwJL7MfO4V68C4lNv7CtssyjVCF3 cGar+/p83dt0btHhyvJVjcXWctLNJpCst3bE//QTDDUEMIBjeSsP2O+FAmDNtIdlX0Ks jjcA== X-Forwarded-Encrypted: i=1; AJvYcCU8Ch7/+t/FLeVbPw3e8XCInAx5rhHQct4zuu7iW7Jf/fhP06gSeVMRr8/lGLsgcakosyZRtQMh@vger.kernel.org X-Gm-Message-State: AOJu0Yy6bMmTYp3gmL+O0oDf9cGJ+gDYteO4F5t+N6DQ2Aaqp/wRE5+2 E1FAG6i42nTvSekBCfbEfnu3450JkHgHcRuBykqTRRIiHv4KQ3UCp0BpupXIvs4Ip7QQhCDlGg= = X-Google-Smtp-Source: AGHT+IHxYUlCvUSSRdXzU4xmyXIEdcGLsxmdCheml1w45FIzHvU+JPmKUO5pg8yVqRVaPPC6TP/v0KTs/A== X-Received: from tweek-syd.c.googlers.com ([fda3:e722:ac3:cc00:b7:3870:c0a8:26]) (user=tweek job=sendgmr) by 2002:a05:690c:4a0d:b0:6ad:4eda:ca25 with SMTP id 00721157ae682-6c09b62c7acmr3312647b3.2.1724287156702; Wed, 21 Aug 2024 17:39:16 -0700 (PDT) Date: Thu, 22 Aug 2024 10:37:57 +1000 In-Reply-To: <20240822003757.1998016-1-tweek@google.com> Precedence: bulk X-Mailing-List: selinux@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240822003757.1998016-1-tweek@google.com> X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240822003757.1998016-3-tweek@google.com> Subject: [PATCH 3/3] libsepol: Add policy capability netlink_xperm From: " =?utf-8?q?Thi=C3=A9baud_Weksteen?= " To: paul@paul-moore.com Cc: brambonne@google.com, jeffv@google.com, selinux@vger.kernel.org, stephen.smalley.work@gmail.com, " =?utf-8?q?Thi=C3=A9baud_Weksteen?= " This capability can be enabled to change the kernel's behaviour and use the extended permissions for netlink messages. Signed-off-by: Thiébaud Weksteen Acked-by: Stephen Smalley --- libsepol/include/sepol/policydb/polcaps.h | 1 + libsepol/src/polcaps.c | 1 + 2 files changed, 2 insertions(+) diff --git a/libsepol/include/sepol/policydb/polcaps.h b/libsepol/include/sepol/policydb/polcaps.h index 14bcc6cb..1aa9b30a 100644 --- a/libsepol/include/sepol/policydb/polcaps.h +++ b/libsepol/include/sepol/policydb/polcaps.h @@ -16,6 +16,7 @@ enum { POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS, POLICYDB_CAP_IOCTL_SKIP_CLOEXEC, POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT, + POLICYDB_CAP_NETLINK_XPERM, __POLICYDB_CAP_MAX }; #define POLICYDB_CAP_MAX (__POLICYDB_CAP_MAX - 1) diff --git a/libsepol/src/polcaps.c b/libsepol/src/polcaps.c index 8289443a..6b28c84e 100644 --- a/libsepol/src/polcaps.c +++ b/libsepol/src/polcaps.c @@ -15,6 +15,7 @@ static const char * const polcap_names[POLICYDB_CAP_MAX + 1] = { [POLICYDB_CAP_GENFS_SECLABEL_SYMLINKS] = "genfs_seclabel_symlinks", [POLICYDB_CAP_IOCTL_SKIP_CLOEXEC] = "ioctl_skip_cloexec", [POLICYDB_CAP_USERSPACE_INITIAL_CONTEXT] = "userspace_initial_context", + [POLICYDB_CAP_NETLINK_XPERM] = "netlink_xperm", }; int sepol_polcap_getnum(const char *name)