From patchwork Mon Sep 15 22:07:52 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kamal Mostafa X-Patchwork-Id: 389668 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 1CE091400B2; Tue, 16 Sep 2014 08:16:51 +1000 (EST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1XTeZj-000622-KN; Mon, 15 Sep 2014 22:16:47 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1XTeR8-0000aa-TC for kernel-team@lists.ubuntu.com; Mon, 15 Sep 2014 22:07:54 +0000 Received: from c-76-102-4-12.hsd1.ca.comcast.net ([76.102.4.12] helo=fourier) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1XTeR8-0008Md-Ma; Mon, 15 Sep 2014 22:07:54 +0000 Received: from kamal by fourier with local (Exim 4.82) (envelope-from ) id 1XTeR6-0001iK-UN; Mon, 15 Sep 2014 15:07:52 -0700 From: Kamal Mostafa To: Paul Moore Subject: [3.13.y.z extended stable] Patch "netlabel: fix the catmap walking functions" has been added to staging queue Date: Mon, 15 Sep 2014 15:07:52 -0700 Message-Id: <1410818872-6557-1-git-send-email-kamal@canonical.com> X-Mailer: git-send-email 1.9.1 X-Extended-Stable: 3.13 Cc: Kamal Mostafa , kernel-team@lists.ubuntu.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com This is a note to let you know that I have just added a patch titled netlabel: fix the catmap walking functions to the linux-3.13.y-queue branch of the 3.13.y.z extended stable tree which can be found at: http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.13.y-queue This patch is scheduled to be released in version 3.13.11.7. If you, or anyone else, feels it should not be added to this tree, please reply to this email. For more information about the 3.13.y.z tree, see https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable Thanks. -Kamal ------ From a933b7f373731ae4c46c4692d4856feed523301e Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Fri, 1 Aug 2014 11:17:29 -0400 Subject: netlabel: fix the catmap walking functions commit d960a6184a92c8da70d26355bfcb5bd8ad637743 upstream. The two NetLabel LSM secattr catmap walk functions didn't handle certain edge conditions correctly, causing incorrect security labels to be generated in some cases. This patch corrects these problems and converts the functions to use the new _netlbl_secattr_catmap_getnode() function in order to reduce the amount of repeated code. Signed-off-by: Paul Moore Tested-by: Casey Schaufler Signed-off-by: Kamal Mostafa --- net/netlabel/netlabel_kapi.c | 102 +++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 48 deletions(-) -- 1.9.1 diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index 21af4b9..929bfc6 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c @@ -408,6 +408,7 @@ out_entry: #define _CM_F_NONE 0x00000000 #define _CM_F_ALLOC 0x00000001 +#define _CM_F_WALK 0x00000002 /** * _netlbl_secattr_catmap_getnode - Get a individual node from a catmap @@ -417,10 +418,11 @@ out_entry: * @gfp_flags: memory allocation flags * * Description: - * Iterate through the catmap looking for the node associated with @offset; if - * the _CM_F_ALLOC flag is set in @cm_flags and there is no associated node, - * one will be created and inserted into the catmap. Returns a pointer to the - * node on success, NULL on failure. + * Iterate through the catmap looking for the node associated with @offset. + * If the _CM_F_ALLOC flag is set in @cm_flags and there is no associated node, + * one will be created and inserted into the catmap. If the _CM_F_WALK flag is + * set in @cm_flags and there is no associated node, the next highest node will + * be returned. Returns a pointer to the node on success, NULL on failure. * */ static struct netlbl_lsm_secattr_catmap *_netlbl_secattr_catmap_getnode( @@ -432,17 +434,22 @@ static struct netlbl_lsm_secattr_catmap *_netlbl_secattr_catmap_getnode( struct netlbl_lsm_secattr_catmap *iter = *catmap; struct netlbl_lsm_secattr_catmap *prev = NULL; - if (iter == NULL || offset < iter->startbit) + if (iter == NULL) goto secattr_catmap_getnode_alloc; + if (offset < iter->startbit) + goto secattr_catmap_getnode_walk; while (iter && offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) { prev = iter; iter = iter->next; } if (iter == NULL || offset < iter->startbit) - goto secattr_catmap_getnode_alloc; + goto secattr_catmap_getnode_walk; return iter; +secattr_catmap_getnode_walk: + if (cm_flags & _CM_F_WALK) + return iter; secattr_catmap_getnode_alloc: if (!(cm_flags & _CM_F_ALLOC)) return NULL; @@ -477,43 +484,41 @@ int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap, u32 offset) { struct netlbl_lsm_secattr_catmap *iter = catmap; - u32 node_idx; - u32 node_bit; + u32 idx; + u32 bit; NETLBL_CATMAP_MAPTYPE bitmap; + iter = _netlbl_secattr_catmap_getnode(&catmap, offset, _CM_F_WALK, 0); + if (iter == NULL) + return -ENOENT; if (offset > iter->startbit) { - while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) { - iter = iter->next; - if (iter == NULL) - return -ENOENT; - } - node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE; - node_bit = offset - iter->startbit - - (NETLBL_CATMAP_MAPSIZE * node_idx); + offset -= iter->startbit; + idx = offset / NETLBL_CATMAP_MAPSIZE; + bit = offset % NETLBL_CATMAP_MAPSIZE; } else { - node_idx = 0; - node_bit = 0; + idx = 0; + bit = 0; } - bitmap = iter->bitmap[node_idx] >> node_bit; + bitmap = iter->bitmap[idx] >> bit; for (;;) { if (bitmap != 0) { while ((bitmap & NETLBL_CATMAP_BIT) == 0) { bitmap >>= 1; - node_bit++; + bit++; } return iter->startbit + - (NETLBL_CATMAP_MAPSIZE * node_idx) + node_bit; + (NETLBL_CATMAP_MAPSIZE * idx) + bit; } - if (++node_idx >= NETLBL_CATMAP_MAPCNT) { + if (++idx >= NETLBL_CATMAP_MAPCNT) { if (iter->next != NULL) { iter = iter->next; - node_idx = 0; + idx = 0; } else return -ENOENT; } - bitmap = iter->bitmap[node_idx]; - node_bit = 0; + bitmap = iter->bitmap[idx]; + bit = 0; } return -ENOENT; @@ -533,46 +538,47 @@ int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap, int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap, u32 offset) { - struct netlbl_lsm_secattr_catmap *iter = catmap; - u32 node_idx; - u32 node_bit; + struct netlbl_lsm_secattr_catmap *iter; + struct netlbl_lsm_secattr_catmap *prev = NULL; + u32 idx; + u32 bit; NETLBL_CATMAP_MAPTYPE bitmask; NETLBL_CATMAP_MAPTYPE bitmap; + iter = _netlbl_secattr_catmap_getnode(&catmap, offset, _CM_F_WALK, 0); + if (iter == NULL) + return -ENOENT; if (offset > iter->startbit) { - while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) { - iter = iter->next; - if (iter == NULL) - return -ENOENT; - } - node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE; - node_bit = offset - iter->startbit - - (NETLBL_CATMAP_MAPSIZE * node_idx); + offset -= iter->startbit; + idx = offset / NETLBL_CATMAP_MAPSIZE; + bit = offset % NETLBL_CATMAP_MAPSIZE; } else { - node_idx = 0; - node_bit = 0; + idx = 0; + bit = 0; } - bitmask = NETLBL_CATMAP_BIT << node_bit; + bitmask = NETLBL_CATMAP_BIT << bit; for (;;) { - bitmap = iter->bitmap[node_idx]; + bitmap = iter->bitmap[idx]; while (bitmask != 0 && (bitmap & bitmask) != 0) { bitmask <<= 1; - node_bit++; + bit++; } - if (bitmask != 0) + if (prev && idx == 0 && bit == 0) + return prev->startbit + NETLBL_CATMAP_SIZE - 1; + else if (bitmask != 0) return iter->startbit + - (NETLBL_CATMAP_MAPSIZE * node_idx) + - node_bit - 1; - else if (++node_idx >= NETLBL_CATMAP_MAPCNT) { + (NETLBL_CATMAP_MAPSIZE * idx) + bit - 1; + else if (++idx >= NETLBL_CATMAP_MAPCNT) { if (iter->next == NULL) - return iter->startbit + NETLBL_CATMAP_SIZE - 1; + return iter->startbit + NETLBL_CATMAP_SIZE - 1; + prev = iter; iter = iter->next; - node_idx = 0; + idx = 0; } bitmask = NETLBL_CATMAP_BIT; - node_bit = 0; + bit = 0; } return -ENOENT;