From patchwork Tue Feb 13 20:57:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jann Horn via Selinux X-Patchwork-Id: 10217623 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8217F60329 for ; Tue, 13 Feb 2018 21:36:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 702E028C17 for ; Tue, 13 Feb 2018 21:36:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6495928D6D; Tue, 13 Feb 2018 21:36:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from UCOL19PA11.eemsg.mail.mil (ucol19pa11.eemsg.mail.mil [214.24.24.84]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 67D9E28C17 for ; Tue, 13 Feb 2018 21:36:12 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.46,509,1511827200"; d="scan'208";a="444953677" Received: from emsm-gh1-uea10.ncsc.mil ([214.29.60.2]) by UCOL19PA11.eemsg.mail.mil with ESMTP; 13 Feb 2018 21:36:11 +0000 X-IronPort-AV: E=Sophos;i="5.46,509,1511827200"; d="scan'208";a="8659305" IronPort-PHdr: =?us-ascii?q?9a23=3AZrfNCRDyDt1ynbc3VA1yUyQJP3N1i/DPJgcQr6Af?= =?us-ascii?q?oPdwSPnzpcSwAkXT6L1XgUPTWs2DsrQY07GQ6fCrADBRqb+681k6OKRWUBEEjc?= =?us-ascii?q?hE1ycBO+WiTXPBEfjxciYhF95DXlI2t1uyMExSBdqsLwaK+i764jEdAAjwOhRo?= =?us-ascii?q?LerpBIHSk9631+ev8JHPfglEnjWwba98IRmsswnctcYajZZtJ6s11xDEvmZGd+?= =?us-ascii?q?NKyG1yOFmdhQz85sC+/J5i9yRfpfcs/NNeXKv5Yqo1U6VWACwpPG4p6sLrswLD?= =?us-ascii?q?TRaU6XsHTmoWiBtIDBPb4xz8Q5z8rzH1tut52CmdIM32UbU5Uims4qt3VBPljj?= =?us-ascii?q?oMODAj8GHTl8d+kqRVrhy8rBB72oLYfZ2ZOP94c6jAf90VWHBBU95PWSJPAY2y?= =?us-ascii?q?aJYBD/IDMOpFoYTzp0EOogWlBQS3GO/j1iVFimPs0KEmz+gsFxzN0gw6H9IJtX?= =?us-ascii?q?TZtMn7NKYOXuC11qbI1yjMZO5U1zjn6YjIdA4uoeqRVrJucMre01QkGR7bgVWU?= =?us-ascii?q?qIzlOS6V1+sQuGWc9OpvS+avi28hqwFsrTmi3dssi4nViYIVzVDI7yN5wJ0vKt?= =?us-ascii?q?GiR057ZsCkHYJWuiqHOYV2RcYiTHtpuCY80rAGoYS0fDUOyJg+wh7fbPuHc5KW?= =?us-ascii?q?7R75SOmRJjJ4iXR4c7y8nxa/6VWsx+LzW8Wu0FtGszBJnsfDu3wTzRDf99CLR/?= =?us-ascii?q?h880u7xDqC2Q/e5vtELEwqj6bWKoAtz7gtnZQJq0vDBDX5mEDuga+TcUUr5/an?= =?us-ascii?q?5vz8YrXjup+cL4h0ihziMqg2msywH+A4Mg8WUmiH4+u8zrzj/VDiQLlQkv03kr?= =?us-ascii?q?XWsJDdJcgBoK62HxRV3Zo55xa6Djem1MwUnXgBLF1bZBKKl5XlNl7BLfziDfqz?= =?us-ascii?q?nk6gnClkyvzYJLHtH43BLn3Zn7fgebZ95VRcyA02zd1H/JJbFLUBIPP1Wk/su9?= =?us-ascii?q?3UFwQ2Mwupw+bhFNpyyJgeVHmTAq6ZLKzSsViI6vgpI+mXfoAZojn9K/875/L2?= =?us-ascii?q?l382hUcdfbW13ZsQcH24HPNmI0ODbnrwgtcOC2EKsxE8TOztjl2CVCRcZ22uX6?= =?us-ascii?q?0i/DE7E5iqDYDZRoCimLaBxju0HoVKZmBaDVCBCXXod4eeVPgQayKSOchhkjoF?= =?us-ascii?q?Vbi/UIIh2xWutBL1yrV8M+rU/DEYtY/52Nhy/e3Tmgk49SZoAMSFz2GNU2Z0k3?= =?us-ascii?q?sQRzAox69wv0p9ylaf0ah/mPFYFMJc6O1XXQsgMp7c1eN6AcjoWg3dZteJVEqm?= =?us-ascii?q?QtK+DD4sSdIxxdkObFtjFNWmjxDOxDClDKEPl7yMHpA09bjc33fpLcZn13nGzL?= =?us-ascii?q?Uhj0UhQsZXKGKmmrRw9xLICoHVlEWZkrqler4H3C7R7muDy3SBvF1AWg5qTarF?= =?us-ascii?q?RWwfZlfRrdnh50PCSaOuBqojMgRfzM6NNLdKasfpjFhdQ/fjIMrRY2S0m2iqBB?= =?us-ascii?q?aIwqiDbI3lemkH2yXdEkcEmRgJ/XmaLQg+Gjuho2XGAT1uFFPvZEXs/PJ7qHO/?= =?us-ascii?q?V0M0zgeKY1dn17Wv4B4Vhv2cS+0N0b4evicutSl0Fk6n393KE9qAuxZhfKJEbN?= =?us-ascii?q?Iz4VdH0WfZuBJnPpG7IaBtmEMRcwNtv0z0zxV3EIJAkco0o3w20Ap+M6WY0ElO?= =?us-ascii?q?dzmAx5D/JqXXKnXu/BCoc6PW1Eve38yQ+qgT6fQ4sE7uvASxFkoj6nlnyNdU02?= =?us-ascii?q?CG6pXNFgoSXor7Ulwr+Bhiu7Hafi496pvX1XJ2Mqm0tSLC1skqBOQ/yRageMpf?= =?us-ascii?q?PLmDFA/oHM0QH9KuJ/Aym1i1chIEO/hf+7QpMMO8dvuJxrSrMf16kz26iGRL+o?= =?us-ascii?q?d90liD9yBkUO7Hw44Fw+2E3guATzrzkE2ussTploBfeTETHm2/xDP/BIFNZ619?= =?us-ascii?q?Y4ALCXuvI8Kt3Nl+gYDiW2JA/l65G1wGwNOpeQaVb1Hlxw1fyFkYrGeomSu9wD?= =?us-ascii?q?14iTcpobSD3CbW2eTtaAIHOnJXRGlllVrsOoa0j8odXEizcwgkjwCl5UD9x6lV?= =?us-ascii?q?oaRwNW/TTV1OfyfoM2FoSrGwuaaaY85T9JMotj1aUeqmblCeVr7yvQEa0zj4Em?= =?us-ascii?q?tA2j87bSqluoj8nxBgj2KdNnlzpmLDec5s3Rff+MDcRflJ0zoYRSl3lSXXBl+m?= =?us-ascii?q?P9Wz4dqUl5DDsuaxV2+6Up1TcC/rwpmatCu8/2FqBge/n/+rkN39DQc6yTP718?= =?us-ascii?q?VtVSjQqBb8Y5Lr17ijPeJ8YEZoAF7868xnGoBxiYYwn4kQ2XkchpWU4XUHin3/?= =?us-ascii?q?MdNF1qLidHANXyIEw8bJ4Aj5301uNmiJx4X9VnWZ3MRhfcW1YmQY2y8m9MBKFb?= =?us-ascii?q?ub7KdekStyuFq4ohrbYeJhkTcF1fsu9HkajvkKuAUzyCWdGasfHUpGMizqjBSI?= =?us-ascii?q?6c6xrLlNaGaoa7iw21J0ncq9A7GavgFcRHH5d486HSBq88V/NEzD0GXp5YHiZN?= =?us-ascii?q?nfc8gTuwaJkxfbkedVMokxmuARhSpgJGL9p2EqxPA1jRxpx5G6s5aIJ39r/K2n?= =?us-ascii?q?Hh5SLif1aN8L+jHxkaZemd6b356pHpp8ATgLQp3oQu+oED4Is/ToKRqOGiUmqn?= =?us-ascii?q?iHAbrfAROf6EB+onLXCZ+rKnWXKWIFwtVjWBmcJFVTgA4OUzU8hJI5ERqqxMP5?= =?us-ascii?q?ekdj+j8R/kL4qgdLyu9wNBn+UmPfqxmzZzcxT5ifIhRW4R9e50fJMcye6edzED?= =?us-ascii?q?9C8p2nsgONNnSRZx5UAmERRkyEG1fjM6Gg5dba9eiYGu2+L/7VbLWAt+NRSvCI?= =?us-ascii?q?xYi13Yt+5TaMMcePMWd+AP0nwEZDWmp5G8vBkTUVVyMXjz7Nb9KcpBqk5yJ4ss?= =?us-ascii?q?W/8PPtWALz+IeCEKVSPst1+xC3gKaDMOiQiDx/KTlGypMG3WXIx6QH3F4OlyFu?= =?us-ascii?q?cCGgEboatSHTUa3QgbVYDxgHayN0L8tF9Lgz0RVIOcLBjdP1zLF4hOYvC1hZTV?= =?us-ascii?q?zhht2pZcsSLmG7LlPIHl6LNKydKD3FwsH3e7i8SaFejOVVsR2/ozCbHFPiPjuZ?= =?us-ascii?q?kznlTRevMftDjCuDJhxRpJm9cgpxCWjkVN/pcQa0PNhzjT032r00mmjKOXQHMT?= =?us-ascii?q?dib0xBtKaQ4j1cgvV+HWxB83VkIPKYlCeZ9enYN40WveFlAytui+Ja+3M6y71P?= =?us-ascii?q?4CFDXvx1lzPYrsRyrFG+jumP1j1nXQJIqjZKgIKLuVttOb7C+5ZaR3nE5hUN4X?= =?us-ascii?q?+XCxQQqNtvEsfvtLxIytjTiKLzLy9P/MnV/csTAMjULtmKP2c/PhXyGT7bFg0F?= =?us-ascii?q?QSSsNWHFiExXiOuS+WGNrpgmtpjsn4IDRaVUVFMvCPMVFF9oHNsaIJhpWDMklK?= =?us-ascii?q?SUjM8M5XWlqxnQS99WvpfdVvKdGf/vMiqWjaFYZxsUxrP1NZgTNor+20B4cFl6?= =?us-ascii?q?m4XLFFTWXd9WuC1haRE7oEZW/XdiSW0z3l7qZRm24H8PD/K0mAA5ihdma+Q36D?= =?us-ascii?q?js+0s3JkbNpCYokkkxmdXkgSiWcD71LaewQZ9ZBjHxt0gwLpP7WRh6YRe1nUx+?= =?us-ascii?q?OzfOX6hRgKd4dWB3lA/cvoNCGfhCQqJeZB8d3vKXZ/Iz0VRAsCqnw1RH5ejECZ?= =?us-ascii?q?d4kgslb4KspWpa2w1/dN41ObDQJK1Rw1hKmK2OpTGn2forwAACJ0YA63ideC8S?= =?us-ascii?q?uEMVMbkmKTKo/vZy5g2CgTdDfnYDV+YyqPJw6kw9I/iAzz7n07NbN0++LfKfL6?= =?us-ascii?q?KEtGjbjsOHWEkw1lkPl0hL5rh5z9ssc1eOV0Au0LuQFw4FNczcJgFJd8BS7mTc?= =?us-ascii?q?fT6SseXRxpJ4J4G9FufyTeCQsqYVg0WkER0mH4QK88QNBJ6s0FvXLc3/Nr4K1Q?= =?us-ascii?q?0t5Bj3JFWCFPlJYwyEkDMGo8G50Z920pJQKS0aAWV4LSq4/K3XphMwjPqFQtg2?= =?us-ascii?q?fm8QXpEYOXIuRM26hylZsmxcDDm21+IZzxSC7z/8pynLETb8btpia+2Pah92Dt?= =?us-ascii?q?G55yk/+bCsiVHL6pXeO336NdN6t9DV7eMapoqIBO1MQrl4s0bcnY5YR3qwXGPU?= =?us-ascii?q?CtG1JoL/a481Ydz6F3a2SFq/hCwpT83pJtaiMrCIgR30RYZTqISUxy4sNcmmGz?= =?us-ascii?q?4EBhhwuf8M5LhnZQIZeZo6YQTktwMkN6ywOA2YyMmhQ36xKTtKSPlS1f+6Z7pW?= =?us-ascii?q?zyUwbu+6z38gTooiweeu7EADXo0HgBbFyPm/YIleVDT8FWZGewXTvyY5kXZuNv?= =?us-ascii?q?oqyOcl3BzIqUUcMyyMdOFxdGNEvcszCk+JLHpqDWo4Q1ucjYvd7Q62w7Ad4TdS?= =?us-ascii?q?n9ZO3e1Cqnj+sYfVYCiwV6yztZXVry0gYMA8o6JrK4zjJdCJuYjCnjzFVpbQrB?= =?us-ascii?q?OKUCq7F/pcldhQJCNYQPZImWE5N8wJo5BB6U8rWsc4ObNPFLEmpqq2Zjp8ES4S?= =?us-ascii?q?0SgZWpuO3TAYnui827ralhKRcJs4MxwJq5RCjcUDXCFoeC8eo7WjV4rOnW+eVm?= =?us-ascii?q?cLOBsT7RhL5A8Yk49/ZPrl4InWQ59Qyj5Wpf10XzDFF5Zy8Vv0VmWWgV/lSPq8?= =?us-ascii?q?iOylxwRSw+zw0tMDQh5wFVBdx/pKlksvMLx3M64QvorQvT+Se0L6u2btyOW9KV?= =?us-ascii?q?lUzs3UcEb4A5TZumrmVS0c4mYURY5JyHHQD5gSlBB5aKkzrlVWPI+mYlr+5yAj?= =?us-ascii?q?x4lxBba4T92rx1A/oXYFXCqqEttBC+B6sF3MQjFlZY6kqIn9MZVIXmBQ4IGdq0?= =?us-ascii?q?tekEh1Ly65zp9cJtpR4jIQWThAui+RvN2sR81fwcV2FYMDIs9ju3fhH6NJIJiR?= =?us-ascii?q?rGcsurP1zn/W5isxv0qkyzWrA6+3UeZZ8HMEGgkzIGSesEYvBfM28mjO6lDNrk?= =?us-ascii?q?x0/+BDC7iNikV+vi1wEY1QCTZSy3+lNUhzQ2dbvOlALqTabdBcSeEoZRCzIxw+?= =?us-ascii?q?CeIm30uR8EFogHj2fi1yuRFe+y3GQwY0UiwVjav3lj0FtsGrIzkaRIxUbT85dS?= =?us-ascii?q?fKNxqbmTxLvBZYc0xlQJ4ZDcpZ97wZwIdZ8NHPRlqrKSEAQBNtLBk40eZFmU5F?= =?us-ascii?q?rkqYZTjXDRC0evbXrh13YcCRodazLPvn4QhHipnosPwj+qUHQH2mhxOiTc7CoI?= =?us-ascii?q?/7q9KFqFGCdKHmPO2geXXBViTDjQishbc4CJnH5zDTMBFHK5Zg1HUkfYPsCXXM?= =?us-ascii?q?PRRbPaIUO1RUVaZmadVcuO9aY9VoeKET+a9iHhiHXA/gGJSzrPlaKVbeXSjeLz?= =?us-ascii?q?+f/eOhvI3e9qHdSez8ZsyW3XnHXaN3PpB+6TblB7fmy4he+lD52v117EN1VUDG?= =?us-ascii?q?MzydrNTmPg4L4dOtdk/mvpI3ATPWHI1/n2D2y0FGacUXXzaq/4gCx5NB9nn8U+?= =?us-ascii?q?R43VbvsOdK7blr9ZE346x1ycezParSK+5VsVVgAhiPAgVl7IstDXN6R2BMZu8R?= =?us-ascii?q?NPbRcrgYjc/0reD3DLYb6BqP++xWcdHHPV3OmtGjCjGAThxJhAUBpiQcLguSzf?= =?us-ascii?q?6FnLJ7Rti+qOjlwE0t5UO+LhkcwLBr+4iE5rKCpPXLYBvJ0bgERq/qS9v8rrQx?= =?us-ascii?q?ukOS4fkkm6ALemFufgKoDvMSVs8HyWfm16wqyjgsE8zbFbL65PFDT245ni7nm5?= =?us-ascii?q?1lHVUWG/YUEKGO/YtAnmY3hfbZNtwQcqBNgGqPEwCrEqMaw36x9ySXOHVlgg3J?= =?us-ascii?q?0xzoR2Oz6ET7rS5+QSvJ1dvjk0xVVretBUhIRCqpJVV4sC6TMwr0qdr3o7o64F?= =?us-ascii?q?sxMmz+u9KHjHGhN69PH83jONycJjE5pFcQjJ03Wtyv1p4UFMG4INcQ6n5+aOXR?= =?us-ascii?q?63+lki9GuadHhJHe7tuT+vrJAXmql7eapKmVxDBE1ng4ukky6tS7NvHL59CHWP?= =?us-ascii?q?qo2HgMQCd4oQvORQa1qqbcr1AWJ0OEzFvLlJYNPtFD0nkyzlvm6/Q7QNIv6AVe?= =?us-ascii?q?EZ7NZ/IDpD/pIjT73U2SY8kpWSmCzTRYAkj5EV5iGKgzwGjwpt7GlW/M+100QY?= =?us-ascii?q?l9b1fohR1sD4Q2M00t6lkXwjYbEQcXdBCbCKqlCljiLYQZS0cMcwmH3KK9eqct?= =?us-ascii?q?x0J/2LSv5PXcbeZkHaoCKu5djhKSnFhcAp8WqbcRQK5gdF9d+q/XoRLiC4v+U/?= =?us-ascii?q?j9i3UwMfy1QsZH8cEWrHYi+hywRwa85pdD4bcbj4qIdq1ebZjPos989UFn6iAL?= =?us-ascii?q?diBXhxh/lRy5W/gGpO//+tjbrIao6uG2WaYiXeoX7QY7B3h+j5brhFAjoM3X2P?= =?us-ascii?q?lcSoLPlIT/6xpBI3iUt4bGyxN8M/YBK5q3fLZ88HUKPyceKGwIPdqKbPk85Chh?= =?us-ascii?q?MC7N6FxGA8MMY84YPcXWlABQlELpQrFS+dDBFl+eFYhza9gi73DrxzAt7Zs8Tu?= =?us-ascii?q?Hg5SewJZDe815NOPdDgz93lN7YpegVxv3SCDMM4XSCbhh4zSyDx4OKC/bq8uWG?= =?us-ascii?q?0MvUWE8eHi4qT4ddIyKP+QO7Sequj5XlSx6a5MD1jpI/ckKQW3Owkb8KsqZJC+?= =?us-ascii?q?FAjDv00iJZFoDviPKfq8Cs53dPtl1bDIZz6gXIGKdYPpV7PxT0jNWkRkh4Bivi?= =?us-ascii?q?Zc7VdxsuuOyNxucP4uVzLFX+ZY4FIh0ez7L19HtVQhFoSLHoolaTRfgRa8d+SP?= =?us-ascii?q?PYsnBV7pptK64RPFeHopzntTNIqE0rDw8ob78wtSZWdk7UnA1aQ6z0oqIPihMA?= =?us-ascii?q?Ud5lvk9BAWCwN3ww5zrJUaRYl6eQB+YT8jqNUqwCSUNoPT1iQxmtwpVhZ6Opne?= =?us-ascii?q?xbsmNBhi59r/wq0ztoRRSivS3so7kA2Skn+LG+tTUOpWZJTuOAnCfUEV9D1ugF?= =?us-ascii?q?jb8AC3b+7lyxeGUDbIr34LR8OcTg9JUu43chbhUnZSEGW/qvCz3ohaOSHoOPqM?= =?us-ascii?q?5chAKKuMjWaL+zLCsSNrc6yR/4RXhyyAvenBFu8GQVRDWs9tkkK5uhOcw93Cqn?= =?us-ascii?q?BXDbdEoQ4qNOqMb+rkAETO0qaV5622Vj1s+HRjERRMzRBWk6kxIoaWJecJJM8R?= =?us-ascii?q?UaDbUngi6Uvqla+QEZeDnUHZqh+onRhcfHx2IwTNZrxmLTo62KmIkq0Hl7lN9u?= =?us-ascii?q?6S6OonsSffTCU8BwGnjzyptfyevmavSjquAHUopmx6i/X/IZN8mj+He22I90VU?= =?us-ascii?q?O/wbQeBVW5OvcZxrjHSyelVXGYWeOTfmiLmzY2LFX/5QGsLlItc8dKs049Pffe?= =?us-ascii?q?hp5GiQLuT6l4RiOOql/H1GYjK/8VdxoquIe7fAwHVOoRZ+maJegzz/wyEV8Mb3?= =?us-ascii?q?7SHStqEO+7ql+tk5J9O3Vn+0n6Zv7t8g/+OtuIBhYECZLaroJ2+fGiQ2KOI2Nv?= =?us-ascii?q?zB1zPEly8OfSDEoxtu5ac5mPmdjQhtJ70fMKdvt3Ni09oNETkJp56YaIyMeKbQ?= =?us-ascii?q?3RzpHqKNHXuPeYAPrfwF8xd2FHVLoZfQP154InPt42W73TAaFVvRICCqgmWJYh?= =?us-ascii?q?LXv+9LloLANvdQ7cfLa0gsztpuKRfJtUpmTW40k2LCjGvh0M1P20QRZ8b5CwiH?= =?us-ascii?q?X4OIowSS5Zr91xFhtmG5NCG9gOrwqiH5GZmaK2hsSv+0xkoe8KsKvxCvfM1Nij?= =?us-ascii?q?2YV+QYRatgS3O2PKCa1qhFl1pvijiffHlJ/qAIXtfs1AHO52XmLIdJfYEYilbD?= =?us-ascii?q?GDIMTxfwhB6bHYmLZ4VAiBITvyQ7KuqiKpLrNn7F89x4g+e/DciHQp7rfGyJ7p?= =?us-ascii?q?ampGvCa/vDuMM5dC6FHiG+PTRVRXROCD/WIjGrcYPrH57OMfDdt3+tmX4wBp4H?= =?us-ascii?q?xi2cqDLrPp+lXN0UJyb57sJ3zp0ic/VJIiKgi+N1chm2nUtjLWBnEKfea+Lsw4?= =?us-ascii?q?uteeDhX36wFRkGAra3UJBGvhDeycPWkdxtL2MBaH8ANNEsYrg/+8eUl+sLa7D+?= =?us-ascii?q?ZvJMMWyq2RqLwbnIMxeGn0T89AMnSVded7?= X-IPAS-Result: =?us-ascii?q?A2BZAwAsWYNa/wHyM5BVCBoBAQEBAQIBAQEBCAEBAQGDJS1?= =?us-ascii?q?mcCiOfY0ygn4bjTeJHwuBdSUHiAZYFAECAQEBAQEBAgFqKII4JIJPAhcNUgMDC?= =?us-ascii?q?QJICAMBWhIFiAcYAzqBPAEBARUDAbIROoQTYYQKghEyhQGCFRCDL4J4gw4TghI?= =?us-ascii?q?KBIYTBYpfDIlYj2sJiCCNV4MTkT6ZVDYigVArCAIYCCEPgXAaeQmCTByCBniME?= =?us-ascii?q?gElB4IdAQEB?= Received: from tarius.tycho.ncsc.mil ([144.51.242.1]) by EMSM-GH1-UEA10.NCSC.MIL with ESMTP; 13 Feb 2018 21:36:10 +0000 Received: from prometheus.infosec.tycho.ncsc.mil (prometheus [192.168.25.40]) by tarius.tycho.ncsc.mil (8.14.4/8.14.4) with ESMTP id w1DLa9dk000724; Tue, 13 Feb 2018 16:36:10 -0500 Received: from tarius.tycho.ncsc.mil (tarius.infosec.tycho.ncsc.mil [144.51.242.1]) by prometheus.infosec.tycho.ncsc.mil (8.15.2/8.15.2) with ESMTP id w1DKvdjT048424 for ; Tue, 13 Feb 2018 15:57:39 -0500 Received: from goalie.tycho.ncsc.mil (goalie [144.51.242.250]) by tarius.tycho.ncsc.mil (8.14.4/8.14.4) with ESMTP id w1DKvgIB019143; Tue, 13 Feb 2018 15:57:42 -0500 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A1AJAwB7UINal3oVGNZVCB0BAQUBCwGDJ?= =?us-ascii?q?SppcCiOfY0ygn4bjTeJH4IDKYUcgmpYFAECAQEBAQEBAhMBAQEBAQYYBoYbDRk?= =?us-ascii?q?BOAEVgSkSiCQDOoE7AQMVAwGyEDqDDAWBAoRjB4IRAQEIHAQIhQGBNl+DP4J4g?= =?us-ascii?q?w4TghIKBIYTBYpfDIlYj2sJiCCNV4MTkT6ZVDaBcjMaI4MYCYI9DxAMggZ4jBI?= =?us-ascii?q?BJQeCHQEBAQ?= X-IPAS-Result: =?us-ascii?q?A1AJAwB7UINal3oVGNZVCB0BAQUBCwGDJSppcCiOfY0ygn4?= =?us-ascii?q?bjTeJH4IDKYUcgmpYFAECAQEBAQEBAhMBAQEBAQYYBoYbDRkBOAEVgSkSiCQDO?= =?us-ascii?q?oE7AQMVAwGyEDqDDAWBAoRjB4IRAQEIHAQIhQGBNl+DP4J4gw4TghIKBIYTBYp?= =?us-ascii?q?fDIlYj2sJiCCNV4MTkT6ZVDaBcjMaI4MYCYI9DxAMggZ4jBIBJQeCHQEBAQ?= X-IronPort-AV: E=Sophos;i="5.46,509,1511845200"; d="scan'208";a="199214" Received: from emsm-gh1-uea10.ncsc.mil ([214.29.60.34]) by goalie.tycho.ncsc.mil with ESMTP; 13 Feb 2018 15:57:38 -0500 IronPort-PHdr: =?us-ascii?q?9a23=3ASlGCnxIu/VQ5iPdcXNmcpTZWNBhigK39O0sv0rFi?= =?us-ascii?q?tYgfLfvxwZ3uMQTl6Ol3ixeRBMOHs6kC0bqd6vy7EUU7or+5+EgYd5JNUxJXwe?= =?us-ascii?q?43pCcHRPC/NEvgMfTxZDY7FskRHHVs/nW8LFQHUJ2mPw6arXK99yMdFQviPgRp?= =?us-ascii?q?OOv1BpTSj8Oq3Oyu5pHfeQpFiCazbL9oMhm7rgrdutQZjIZsN6081gbHrnxUdu?= =?us-ascii?q?pM2GhmP0iTnxHy5sex+J5s7SFdsO8/+sBDTKv3Yb02QaRXAzo6PW814tbrtQTY?= =?us-ascii?q?QguU+nQcSGQWnQFWDAXD8Rr3Q43+sir+tup6xSmaIcj7Rq06VDi+86tmTgLjhS?= =?us-ascii?q?EaPDA77W7XkNR9gr9brhy/qRJxwInabZqJOPZiZK7RYckXSXZdUstXSidPApm8?= =?us-ascii?q?b4wKD+cZIehYrpXyp1sUohukGAanGeHhxSVJhn/ww6I6yPkqHAbc3AwhA90OsG?= =?us-ascii?q?7brM/oO6gKTe+61KnIwi/Cb/NQxzj985PFfQs9ofGNW7JwbdTeyVMpFwzbklWc?= =?us-ascii?q?s5DqPzSQ1ukUtWWQ8uRuVeWqi2E9qgFxpCCixt82hYnUgoIZ01XE9SJ+wIYvO9?= =?us-ascii?q?K0UlJ0YdmhEJZWqiqUNJN2T9s8T211tys20KMKtJGhcCQU1Zgr3QPTZ+KZf4SQ?= =?us-ascii?q?4R/uVfydLSp2iX9qYr6yhwi+/VKhx+HiUMS/zUxEoTBfktbWs3AAzxzT5daDSv?= =?us-ascii?q?t65kqu1zSB2QPV5OxKP006j7bWJ4M8zrIqiJUcr0HDHjT5mEnsia+ZbEQk+uyy?= =?us-ascii?q?5+TiY7XmooeQN45yig7gLqQjgtKzDfk3PwQUQWSW9v6w2KP+8UHjXblGkOM6nr?= =?us-ascii?q?HcsJ/AJMQboqC5AxVS0oYm8xu/FTam38gYnXYdNlJKZQqIgJTxNFHOOv/4DPG/?= =?us-ascii?q?jEq3kDpw3P/GIrzhApPRLnfdirfhe6hy61JGxAUvytBf4opYCqsdL/LrRk/xqN?= =?us-ascii?q?vYAwciMwOp2ObqE8l914MCVmKPBa+VKqXSsUSS6e41LOmMY5EVsi7nK/c5//7u?= =?us-ascii?q?kWM5mVgFcKmyw5QXbHG4HvJ7I0SWenfsntcAHnsKvgo5VuDqjkaCXiRJa3a9WK?= =?us-ascii?q?I8+GJzNIXzForHR4awkJSdzSy7GdtQfWkABVeSVT/uepmIVukkdi2fOIlinyYC?= =?us-ascii?q?WLznTJUukVmqtQnn2/98JfbM0jMXuIil19Vv4eDX0xYo+ng8C8WbznHIVGx/g3?= =?us-ascii?q?kJWy5z2adzvEhw4kmM3LI+gPFCE9FXofRTXVQUL5nZmtZ7AND7QA6JXt6ITlu9?= =?us-ascii?q?CoG8ADoxR8g99NQ5Y098Hdi5phrf3iy2DqUTmqDND5sxpPGPl0PtLtpwni6VnJ?= =?us-ascii?q?IqiEMrF5NC?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0ALAwDdT4Nal3oVGNZVCB0BAQUBCwGDJ?= =?us-ascii?q?SppcCiOfY0ygn4bjTeJH4IDKYUcgmpYFAECAQEBAQEBAgESAQEBAQEGGAZXgjg?= =?us-ascii?q?igmoNGQE4ARWBKRKIJAM6gTsBAxUDAbITOoMMBYEChGMHghEBAQgcBAiFAYE2X?= =?us-ascii?q?4M/gniDDhOCEgoEgnEMgxYFil8MiViPawmIII1XgxORPplUNoFyMxojgxgJgj0?= =?us-ascii?q?PEAyCBniMEgElB4IdAQEB?= X-IPAS-Result: =?us-ascii?q?A0ALAwDdT4Nal3oVGNZVCB0BAQUBCwGDJSppcCiOfY0ygn4?= =?us-ascii?q?bjTeJH4IDKYUcgmpYFAECAQEBAQEBAgESAQEBAQEGGAZXgjgigmoNGQE4ARWBK?= =?us-ascii?q?RKIJAM6gTsBAxUDAbITOoMMBYEChGMHghEBAQgcBAiFAYE2X4M/gniDDhOCEgo?= =?us-ascii?q?EgnEMgxYFil8MiViPawmIII1XgxORPplUNoFyMxojgxgJgj0PEAyCBniMEgElB?= =?us-ascii?q?4IdAQEB?= X-IronPort-AV: E=Sophos;i="5.46,509,1511827200"; d="scan'208";a="8657355" X-IronPort-Outbreak-Status: No, level 0, Unknown - Unknown Received: from uhil3cpa11.eemsg.mail.mil ([214.24.21.122]) by EMSM-GH1-UEA10.NCSC.MIL with ESMTP; 13 Feb 2018 20:57:37 +0000 X-EEMSG-check-005: 0 X-EEMSG-check-006: 000-001;5869b47a-c521-406c-95e3-59a6a2708e95 X-EEMSG-check-008: 18499021|UHIL3CPA12_EEMSG_MP28.csd.disa.mil X-EEMSG-check-001: false X-EEMSG-SBRS: 3.5 X-EEMSG-ORIG-IP: 65.20.0.227 X-EEMSG-check-002: true X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0BsAQAHUINah+MAFEFVCBwBAQEEAQEKAQGDJYETcCiOfZAwG403iR+CAw8ahRyDQhQBAgEBAQEBAQITAQEBCA0JCCgvhUQNGQE4ARWBKRKIJAM6gTsBAxUEshM6gwwFgQKEYweCEQElBAiFAYE2hB6CeIMOE4ISCgSCcQyDFgWKXwyJWI9rCYggjVeDE5E+mVQ2gXIzGiODGAmCPQ8QDIIGeIwSASUHgh0BAQE X-IPAS-Result: A0BsAQAHUINah+MAFEFVCBwBAQEEAQEKAQGDJYETcCiOfZAwG403iR+CAw8ahRyDQhQBAgEBAQEBAQITAQEBCA0JCCgvhUQNGQE4ARWBKRKIJAM6gTsBAxUEshM6gwwFgQKEYweCEQElBAiFAYE2hB6CeIMOE4ISCgSCcQyDFgWKXwyJWI9rCYggjVeDE5E+mVQ2gXIzGiODGAmCPQ8QDIIGeIwSASUHgh0BAQE Received: from rgout0506.bt.lon5.cpcloud.co.uk (HELO rgout05.bt.lon5.cpcloud.co.uk) ([65.20.0.227]) by UHIL3CPA12.eemsg.mail.mil with ESMTP; 13 Feb 2018 20:57:34 +0000 X-OWM-Source-IP: 86.134.52.62 (GB) X-OWM-Env-Sender: richard_c_haines@btinternet.com X-Junkmail-Premium-Raw: score=8/50, refid=2.7.2:2018.2.12.101816:17:8.707, ip=, rules=NO_URI_FOUND, NO_CTA_URI_FOUND, NO_MESSAGE_ID, NO_URI_HTTPS, TO_MALFORMED Received: from localhost.localdomain (86.134.52.62) by rgout05.bt.lon5.cpcloud.co.uk (9.0.019.21-1) (authenticated as richard_c_haines@btinternet.com) id 5A5E1B750B68BC4A; Tue, 13 Feb 2018 20:57:31 +0000 X-EEMSG-check-009: 444-444 To: selinux@tycho.nsa.gov, netdev@vger.kernel.org, linux-sctp@vger.kernel.org, linux-security-module@vger.kernel.org Date: Tue, 13 Feb 2018 20:57:18 +0000 Message-Id: <20180213205718.4668-1-richard_c_haines@btinternet.com> X-Mailer: git-send-email 2.14.3 X-Mailman-Approved-At: Tue, 13 Feb 2018 16:34:04 -0500 Subject: [PATCH V6 4/4] selinux: Add SCTP support X-BeenThere: selinux@tycho.nsa.gov X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Security-Enhanced Linux \(SELinux\) mailing list" List-Post: List-Help: From: Richard Haines via Selinux Reply-To: Richard Haines Cc: marcelo.leitner@gmail.com, nhorman@tuxdriver.com, vyasevich@gmail.com, james.l.morris@oracle.com, sds@tycho.nsa.gov Errors-To: selinux-bounces@tycho.nsa.gov Sender: "Selinux" X-Virus-Scanned: ClamAV using ClamSMTP The SELinux SCTP implementation is explained in: Documentation/security/SELinux-sctp.rst Signed-off-by: Richard Haines --- Documentation/security/SELinux-sctp.rst | 157 ++++++++++++++++++ security/selinux/hooks.c | 280 +++++++++++++++++++++++++++++--- security/selinux/include/classmap.h | 2 +- security/selinux/include/netlabel.h | 21 ++- security/selinux/include/objsec.h | 4 + security/selinux/netlabel.c | 133 +++++++++++++-- 6 files changed, 565 insertions(+), 32 deletions(-) create mode 100644 Documentation/security/SELinux-sctp.rst diff --git a/Documentation/security/SELinux-sctp.rst b/Documentation/security/SELinux-sctp.rst new file mode 100644 index 0000000..2f66bf3 --- /dev/null +++ b/Documentation/security/SELinux-sctp.rst @@ -0,0 +1,157 @@ +SCTP SELinux Support +===================== + +Security Hooks +=============== + +``Documentation/security/LSM-sctp.rst`` describes the following SCTP security +hooks with the SELinux specifics expanded below:: + + security_sctp_assoc_request() + security_sctp_bind_connect() + security_sctp_sk_clone() + security_inet_conn_established() + + +security_sctp_assoc_request() +----------------------------- +Passes the ``@ep`` and ``@chunk->skb`` of the association INIT packet to the +security module. Returns 0 on success, error on failure. +:: + + @ep - pointer to sctp endpoint structure. + @skb - pointer to skbuff of association packet. + +The security module performs the following operations: + IF this is the first association on ``@ep->base.sk``, then set the peer + sid to that in ``@skb``. This will ensure there is only one peer sid + assigned to ``@ep->base.sk`` that may support multiple associations. + + ELSE validate the ``@ep->base.sk peer_sid`` against the ``@skb peer sid`` + to determine whether the association should be allowed or denied. + + Set the sctp ``@ep sid`` to socket's sid (from ``ep->base.sk``) with + MLS portion taken from ``@skb peer sid``. This will be used by SCTP + TCP style sockets and peeled off connections as they cause a new socket + to be generated. + + If IP security options are configured (CIPSO/CALIPSO), then the ip + options are set on the socket. + + +security_sctp_bind_connect() +----------------------------- +Checks permissions required for ipv4/ipv6 addresses based on the ``@optname`` +as follows:: + + ------------------------------------------------------------------ + | BIND Permission Checks | + | @optname | @address contains | + |----------------------------|-----------------------------------| + | SCTP_SOCKOPT_BINDX_ADD | One or more ipv4 / ipv6 addresses | + | SCTP_PRIMARY_ADDR | Single ipv4 or ipv6 address | + | SCTP_SET_PEER_PRIMARY_ADDR | Single ipv4 or ipv6 address | + ------------------------------------------------------------------ + + ------------------------------------------------------------------ + | CONNECT Permission Checks | + | @optname | @address contains | + |----------------------------|-----------------------------------| + | SCTP_SOCKOPT_CONNECTX | One or more ipv4 / ipv6 addresses | + | SCTP_PARAM_ADD_IP | One or more ipv4 / ipv6 addresses | + | SCTP_SENDMSG_CONNECT | Single ipv4 or ipv6 address | + | SCTP_PARAM_SET_PRIMARY | Single ipv4 or ipv6 address | + ------------------------------------------------------------------ + + +``Documentation/security/LSM-sctp.rst`` gives a summary of the ``@optname`` +entries and also describes ASCONF chunk processing when Dynamic Address +Reconfiguration is enabled. + + +security_sctp_sk_clone() +------------------------- +Called whenever a new socket is created by **accept**\(2) (i.e. a TCP style +socket) or when a socket is 'peeled off' e.g userspace calls +**sctp_peeloff**\(3). ``security_sctp_sk_clone()`` will set the new +sockets sid and peer sid to that contained in the ``@ep sid`` and +``@ep peer sid`` respectively. +:: + + @ep - pointer to current sctp endpoint structure. + @sk - pointer to current sock structure. + @sk - pointer to new sock structure. + + +security_inet_conn_established() +--------------------------------- +Called when a COOKIE ACK is received where it sets the connection's peer sid +to that in ``@skb``:: + + @sk - pointer to sock structure. + @skb - pointer to skbuff of the COOKIE ACK packet. + + +Policy Statements +================== +The following class and permissions to support SCTP are available within the +kernel:: + + class sctp_socket inherits socket { node_bind } + +whenever the following policy capability is enabled:: + + policycap extended_socket_class; + +SELinux SCTP support adds the ``name_connect`` permission for connecting +to a specific port type and the ``association`` permission that is explained +in the section below. + +If userspace tools have been updated, SCTP will support the ``portcon`` +statement as shown in the following example:: + + portcon sctp 1024-1036 system_u:object_r:sctp_ports_t:s0 + + +SCTP Peer Labeling +=================== +An SCTP socket will only have one peer label assigned to it. This will be +assigned during the establishment of the first association. Once the peer +label has been assigned, any new associations will have the ``association`` +permission validated by checking the socket peer sid against the received +packets peer sid to determine whether the association should be allowed or +denied. + +NOTES: + 1) If peer labeling is not enabled, then the peer context will always be + ``SECINITSID_UNLABELED`` (``unlabeled_t`` in Reference Policy). + + 2) As SCTP can support more than one transport address per endpoint + (multi-homing) on a single socket, it is possible to configure policy + and NetLabel to provide different peer labels for each of these. As the + socket peer label is determined by the first associations transport + address, it is recommended that all peer labels are consistent. + + 3) **getpeercon**\(3) may be used by userspace to retrieve the sockets peer + context. + + 4) While not SCTP specific, be aware when using NetLabel that if a label + is assigned to a specific interface, and that interface 'goes down', + then the NetLabel service will remove the entry. Therefore ensure that + the network startup scripts call **netlabelctl**\(8) to set the required + label (see **netlabel-config**\(8) helper script for details). + + 5) The NetLabel SCTP peer labeling rules apply as discussed in the following + set of posts tagged "netlabel" at: http://www.paul-moore.com/blog/t. + + 6) CIPSO is only supported for IPv4 addressing: ``socket(AF_INET, ...)`` + CALIPSO is only supported for IPv6 addressing: ``socket(AF_INET6, ...)`` + + Note the following when testing CIPSO/CALIPSO: + a) CIPSO will send an ICMP packet if an SCTP packet cannot be + delivered because of an invalid label. + b) CALIPSO does not send an ICMP packet, just silently discards it. + + 7) IPSEC is not supported as RFC 3554 - sctp/ipsec support has not been + implemented in userspace (**racoon**\(8) or **ipsec_pluto**\(8)), + although the kernel supports SCTP/IPSEC. diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 8644d86..28a5c4e 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -67,6 +67,8 @@ #include #include #include +#include +#include #include #include /* for Unix socket types */ #include /* for Unix socket types */ @@ -4134,6 +4136,23 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, break; } +#if IS_ENABLED(CONFIG_IP_SCTP) + case IPPROTO_SCTP: { + struct sctphdr _sctph, *sh; + + if (ntohs(ih->frag_off) & IP_OFFSET) + break; + + offset += ihlen; + sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph); + if (sh == NULL) + break; + + ad->u.net->sport = sh->source; + ad->u.net->dport = sh->dest; + break; + } +#endif default: break; } @@ -4207,6 +4226,19 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, break; } +#if IS_ENABLED(CONFIG_IP_SCTP) + case IPPROTO_SCTP: { + struct sctphdr _sctph, *sh; + + sh = skb_header_pointer(skb, offset, sizeof(_sctph), &_sctph); + if (sh == NULL) + break; + + ad->u.net->sport = sh->source; + ad->u.net->dport = sh->dest; + break; + } +#endif /* includes fragments */ default: break; @@ -4396,6 +4428,10 @@ static int selinux_socket_post_create(struct socket *sock, int family, sksec = sock->sk->sk_security; sksec->sclass = sclass; sksec->sid = sid; + /* Allows detection of the first association on this socket */ + if (sksec->sclass == SECCLASS_SCTP_SOCKET) + sksec->sctp_assoc_state = SCTP_ASSOC_UNSET; + err = selinux_netlbl_socket_post_create(sock->sk, family); } @@ -4416,11 +4452,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in if (err) goto out; - /* - * If PF_INET or PF_INET6, check name_bind permission for the port. - * Multiple address binding for SCTP is not supported yet: we just - * check the first address now. - */ + /* If PF_INET or PF_INET6, check name_bind permission for the port. */ family = sk->sk_family; if (family == PF_INET || family == PF_INET6) { char *addrp; @@ -4432,7 +4464,13 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in unsigned short snum; u32 sid, node_perm; - if (family == PF_INET) { + /* + * sctp_bindx(3) calls via selinux_sctp_bind_connect() + * that validates multiple binding addresses. Because of this + * need to check address->sa_family as it is possible to have + * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. + */ + if (address->sa_family == AF_INET) { if (addrlen < sizeof(struct sockaddr_in)) { err = -EINVAL; goto out; @@ -4486,6 +4524,10 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in node_perm = DCCP_SOCKET__NODE_BIND; break; + case SECCLASS_SCTP_SOCKET: + node_perm = SCTP_SOCKET__NODE_BIND; + break; + default: node_perm = RAWIP_SOCKET__NODE_BIND; break; @@ -4500,7 +4542,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in ad.u.net->sport = htons(snum); ad.u.net->family = family; - if (family == PF_INET) + if (address->sa_family == AF_INET) ad.u.net->v4info.saddr = addr4->sin_addr.s_addr; else ad.u.net->v6info.saddr = addr6->sin6_addr; @@ -4514,7 +4556,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in return err; } -static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen) +/* This supports connect(2) and SCTP connect services such as sctp_connectx(3) + * and sctp_sendmsg(3) as described in Documentation/security/LSM-sctp.txt + */ +static int selinux_socket_connect_helper(struct socket *sock, + struct sockaddr *address, int addrlen) { struct sock *sk = sock->sk; struct sk_security_struct *sksec = sk->sk_security; @@ -4525,10 +4571,12 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, return err; /* - * If a TCP or DCCP socket, check name_connect permission for the port. + * If a TCP, DCCP or SCTP socket, check name_connect permission + * for the port. */ if (sksec->sclass == SECCLASS_TCP_SOCKET || - sksec->sclass == SECCLASS_DCCP_SOCKET) { + sksec->sclass == SECCLASS_DCCP_SOCKET || + sksec->sclass == SECCLASS_SCTP_SOCKET) { struct common_audit_data ad; struct lsm_network_audit net = {0,}; struct sockaddr_in *addr4 = NULL; @@ -4536,7 +4584,12 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, unsigned short snum; u32 sid, perm; - if (sk->sk_family == PF_INET) { + /* sctp_connectx(3) calls via selinux_sctp_bind_connect() + * that validates multiple connect addresses. Because of this + * need to check address->sa_family as it is possible to have + * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. + */ + if (address->sa_family == AF_INET) { addr4 = (struct sockaddr_in *)address; if (addrlen < sizeof(struct sockaddr_in)) return -EINVAL; @@ -4550,10 +4603,19 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, err = sel_netport_sid(sk->sk_protocol, snum, &sid); if (err) - goto out; + return err; - perm = (sksec->sclass == SECCLASS_TCP_SOCKET) ? - TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; + switch (sksec->sclass) { + case SECCLASS_TCP_SOCKET: + perm = TCP_SOCKET__NAME_CONNECT; + break; + case SECCLASS_DCCP_SOCKET: + perm = DCCP_SOCKET__NAME_CONNECT; + break; + case SECCLASS_SCTP_SOCKET: + perm = SCTP_SOCKET__NAME_CONNECT; + break; + } ad.type = LSM_AUDIT_DATA_NET; ad.u.net = &net; @@ -4561,13 +4623,24 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, ad.u.net->family = sk->sk_family; err = avc_has_perm(sksec->sid, sid, sksec->sclass, perm, &ad); if (err) - goto out; + return err; } - err = selinux_netlbl_socket_connect(sk, address); + return 0; +} -out: - return err; +/* Supports connect(2), see comments in selinux_socket_connect_helper() */ +static int selinux_socket_connect(struct socket *sock, + struct sockaddr *address, int addrlen) +{ + int err; + struct sock *sk = sock->sk; + + err = selinux_socket_connect_helper(sock, address, addrlen); + if (err) + return err; + + return selinux_netlbl_socket_connect(sk, address); } static int selinux_socket_listen(struct socket *sock, int backlog) @@ -4830,7 +4903,8 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op u32 peer_sid = SECSID_NULL; if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET || - sksec->sclass == SECCLASS_TCP_SOCKET) + sksec->sclass == SECCLASS_TCP_SOCKET || + sksec->sclass == SECCLASS_SCTP_SOCKET) peer_sid = sksec->peer_sid; if (peer_sid == SECSID_NULL) return -ENOPROTOOPT; @@ -4943,6 +5017,171 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent) sksec->sclass = isec->sclass; } +/* Called whenever SCTP receives an INIT chunk. This happens when an incoming + * connect(2), sctp_connectx(3) or sctp_sendmsg(3) (with no association + * already present). + */ +static int selinux_sctp_assoc_request(struct sctp_endpoint *ep, + struct sk_buff *skb) +{ + struct sk_security_struct *sksec = ep->base.sk->sk_security; + struct common_audit_data ad; + struct lsm_network_audit net = {0,}; + u8 peerlbl_active; + u32 peer_sid = SECINITSID_UNLABELED; + u32 conn_sid; + int err = 0; + + if (!selinux_policycap_extsockclass) + return 0; + + peerlbl_active = selinux_peerlbl_enabled(); + + if (peerlbl_active) { + /* This will return peer_sid = SECSID_NULL if there are + * no peer labels, see security_net_peersid_resolve(). + */ + err = selinux_skb_peerlbl_sid(skb, ep->base.sk->sk_family, + &peer_sid); + if (err) + return err; + + if (peer_sid == SECSID_NULL) + peer_sid = SECINITSID_UNLABELED; + } + + if (sksec->sctp_assoc_state == SCTP_ASSOC_UNSET) { + sksec->sctp_assoc_state = SCTP_ASSOC_SET; + + /* Here as first association on socket. As the peer SID + * was allowed by peer recv (and the netif/node checks), + * then it is approved by policy and used as the primary + * peer SID for getpeercon(3). + */ + sksec->peer_sid = peer_sid; + } else if (sksec->peer_sid != peer_sid) { + /* Other association peer SIDs are checked to enforce + * consistency among the peer SIDs. + */ + ad.type = LSM_AUDIT_DATA_NET; + ad.u.net = &net; + ad.u.net->sk = ep->base.sk; + err = avc_has_perm(sksec->peer_sid, peer_sid, sksec->sclass, + SCTP_SOCKET__ASSOCIATION, &ad); + if (err) + return err; + } + + /* Compute the MLS component for the connection and store + * the information in ep. This will be used by SCTP TCP type + * sockets and peeled off connections as they cause a new + * socket to be generated. selinux_sctp_sk_clone() will then + * plug this into the new socket. + */ + err = selinux_conn_sid(sksec->sid, peer_sid, &conn_sid); + if (err) + return err; + + ep->secid = conn_sid; + ep->peer_secid = peer_sid; + + /* Set any NetLabel labels including CIPSO/CALIPSO options. */ + return selinux_netlbl_sctp_assoc_request(ep, skb); +} + +/* Check if sctp IPv4/IPv6 addresses are valid for binding or connecting + * based on their @optname. + */ +static int selinux_sctp_bind_connect(struct sock *sk, int optname, + struct sockaddr *address, + int addrlen) +{ + int len, err = 0, walk_size = 0; + void *addr_buf; + struct sockaddr *addr; + struct socket *sock; + + if (!selinux_policycap_extsockclass) + return 0; + + /* Process one or more addresses that may be IPv4 or IPv6 */ + sock = sk->sk_socket; + addr_buf = address; + + while (walk_size < addrlen) { + addr = addr_buf; + switch (addr->sa_family) { + case AF_INET: + len = sizeof(struct sockaddr_in); + break; + case AF_INET6: + len = sizeof(struct sockaddr_in6); + break; + default: + return -EAFNOSUPPORT; + } + + err = -EINVAL; + switch (optname) { + /* Bind checks */ + case SCTP_PRIMARY_ADDR: + case SCTP_SET_PEER_PRIMARY_ADDR: + case SCTP_SOCKOPT_BINDX_ADD: + err = selinux_socket_bind(sock, addr, len); + break; + /* Connect checks */ + case SCTP_SOCKOPT_CONNECTX: + case SCTP_PARAM_SET_PRIMARY: + case SCTP_PARAM_ADD_IP: + case SCTP_SENDMSG_CONNECT: + err = selinux_socket_connect_helper(sock, addr, len); + if (err) + return err; + + /* As selinux_sctp_bind_connect() is called by the + * SCTP protocol layer, the socket is already locked, + * therefore selinux_netlbl_socket_connect_locked() is + * is called here. The situations handled are: + * sctp_connectx(3), sctp_sendmsg(3), sendmsg(2), + * whenever a new IP address is added or when a new + * primary address is selected. + * Note that an SCTP connect(2) call happens before + * the SCTP protocol layer and is handled via + * selinux_socket_connect(). + */ + err = selinux_netlbl_socket_connect_locked(sk, addr); + break; + } + + if (err) + return err; + + addr_buf += len; + walk_size += len; + } + + return 0; +} + +/* Called whenever a new socket is created by accept(2) or sctp_peeloff(3). */ +static void selinux_sctp_sk_clone(struct sctp_endpoint *ep, struct sock *sk, + struct sock *newsk) +{ + struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *newsksec = newsk->sk_security; + + /* If policy does not support SECCLASS_SCTP_SOCKET then call + * the non-sctp clone version. + */ + if (!selinux_policycap_extsockclass) + return selinux_sk_clone_security(sk, newsk); + + newsksec->sid = ep->secid; + newsksec->peer_sid = ep->peer_secid; + newsksec->sclass = sksec->sclass; + selinux_netlbl_sctp_sk_clone(sk, newsk); +} + static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, struct request_sock *req) { @@ -6563,6 +6802,9 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(sk_clone_security, selinux_sk_clone_security), LSM_HOOK_INIT(sk_getsecid, selinux_sk_getsecid), LSM_HOOK_INIT(sock_graft, selinux_sock_graft), + LSM_HOOK_INIT(sctp_assoc_request, selinux_sctp_assoc_request), + LSM_HOOK_INIT(sctp_sk_clone, selinux_sctp_sk_clone), + LSM_HOOK_INIT(sctp_bind_connect, selinux_sctp_bind_connect), LSM_HOOK_INIT(inet_conn_request, selinux_inet_conn_request), LSM_HOOK_INIT(inet_csk_clone, selinux_inet_csk_clone), LSM_HOOK_INIT(inet_conn_established, selinux_inet_conn_established), diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index acdee77..7f03724 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -176,7 +176,7 @@ struct security_class_mapping secclass_map[] = { { COMMON_CAP2_PERMS, NULL } }, { "sctp_socket", { COMMON_SOCK_PERMS, - "node_bind", NULL } }, + "node_bind", "name_connect", "association", NULL } }, { "icmp_socket", { COMMON_SOCK_PERMS, "node_bind", NULL } }, diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h index e77a5e3..6ef4953 100644 --- a/security/selinux/include/netlabel.h +++ b/security/selinux/include/netlabel.h @@ -32,6 +32,7 @@ #include #include #include +#include #include "avc.h" #include "objsec.h" @@ -52,9 +53,11 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, u16 family, u32 sid); - +int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep, + struct sk_buff *skb); int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family); void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family); +void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk); int selinux_netlbl_socket_post_create(struct sock *sk, u16 family); int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, struct sk_buff *skb, @@ -64,6 +67,8 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, int level, int optname); int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr); +int selinux_netlbl_socket_connect_locked(struct sock *sk, + struct sockaddr *addr); #else static inline void selinux_netlbl_cache_invalidate(void) @@ -113,6 +118,11 @@ static inline int selinux_netlbl_conn_setsid(struct sock *sk, return 0; } +static inline int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep, + struct sk_buff *skb) +{ + return 0; +} static inline int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family) { @@ -122,6 +132,10 @@ static inline void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family) { return; } +static inline void selinux_netlbl_sctp_sk_clone(struct sock *sk, sock *newsk) +{ + return; +} static inline int selinux_netlbl_socket_post_create(struct sock *sk, u16 family) { @@ -145,6 +159,11 @@ static inline int selinux_netlbl_socket_connect(struct sock *sk, { return 0; } +static inline int selinux_netlbl_socket_connect_locked(struct sock *sk, + struct sockaddr *addr) +{ + return 0; +} #endif /* CONFIG_NETLABEL */ #endif diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 3d54468..dabf028 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -130,6 +130,10 @@ struct sk_security_struct { u32 sid; /* SID of this object */ u32 peer_sid; /* SID of peer */ u16 sclass; /* sock security class */ + enum { /* SCTP association state */ + SCTP_ASSOC_UNSET = 0, + SCTP_ASSOC_SET, + } sctp_assoc_state; }; struct tun_security_struct { diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 2c297b9..8730be4 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -249,6 +249,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, sk = skb_to_full_sk(skb); if (sk != NULL) { struct sk_security_struct *sksec = sk->sk_security; + if (sksec->nlbl_state != NLBL_REQSKB) return 0; secattr = selinux_netlbl_sock_getattr(sk, sid); @@ -269,6 +270,61 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, return rc; } +/** + * selinux_netlbl_sctp_assoc_request - Label an incoming sctp association. + * @ep: incoming association endpoint. + * @skb: the packet. + * + * Description: + * A new incoming connection is represented by @ep, ...... + * Returns zero on success, negative values on failure. + * + */ +int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep, + struct sk_buff *skb) +{ + int rc; + struct netlbl_lsm_secattr secattr; + struct sk_security_struct *sksec = ep->base.sk->sk_security; + struct sockaddr *addr; + struct sockaddr_in addr4; +#if IS_ENABLED(CONFIG_IPV6) + struct sockaddr_in6 addr6; +#endif + + if (ep->base.sk->sk_family != PF_INET && + ep->base.sk->sk_family != PF_INET6) + return 0; + + netlbl_secattr_init(&secattr); + rc = security_netlbl_sid_to_secattr(ep->secid, &secattr); + if (rc != 0) + goto assoc_request_return; + + /* Move skb hdr address info to a struct sockaddr and then call + * netlbl_conn_setattr(). + */ + if (ip_hdr(skb)->version == 4) { + addr4.sin_family = AF_INET; + addr4.sin_addr.s_addr = ip_hdr(skb)->saddr; + addr = (struct sockaddr *)&addr4; +#if IS_ENABLED(CONFIG_IPV6) + } else { + addr6.sin6_family = AF_INET6; + addr6.sin6_addr = ipv6_hdr(skb)->saddr; + addr = (struct sockaddr *)&addr6; +#endif + } + + rc = netlbl_conn_setattr(ep->base.sk, addr, &secattr); + if (rc == 0) + sksec->nlbl_state = NLBL_LABELED; + +assoc_request_return: + netlbl_secattr_destroy(&secattr); + return rc; +} + /** * selinux_netlbl_inet_conn_request - Label an incoming stream connection * @req: incoming connection request socket @@ -318,6 +374,22 @@ void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family) sksec->nlbl_state = NLBL_UNSET; } +/** + * selinux_netlbl_sctp_sk_clone - Copy state to the newly created sock + * @sk: current sock + * @newsk: the new sock + * + * Description: + * Called whenever a new socket is created by accept(2) or sctp_peeloff(3). + */ +void selinux_netlbl_sctp_sk_clone(struct sock *sk, struct sock *newsk) +{ + struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *newsksec = newsk->sk_security; + + newsksec->nlbl_state = sksec->nlbl_state; +} + /** * selinux_netlbl_socket_post_create - Label a socket using NetLabel * @sock: the socket to label @@ -469,7 +541,8 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, } /** - * selinux_netlbl_socket_connect - Label a client-side socket on connect + * selinux_netlbl_socket_connect_helper - Help label a client-side socket on + * connect * @sk: the socket to label * @addr: the destination address * @@ -478,18 +551,13 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, * Returns zero values on success, negative values on failure. * */ -int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr) +static int selinux_netlbl_socket_connect_helper(struct sock *sk, + struct sockaddr *addr) { int rc; struct sk_security_struct *sksec = sk->sk_security; struct netlbl_lsm_secattr *secattr; - if (sksec->nlbl_state != NLBL_REQSKB && - sksec->nlbl_state != NLBL_CONNLABELED) - return 0; - - lock_sock(sk); - /* connected sockets are allowed to disconnect when the address family * is set to AF_UNSPEC, if that is what is happening we want to reset * the socket */ @@ -497,18 +565,61 @@ int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr) netlbl_sock_delattr(sk); sksec->nlbl_state = NLBL_REQSKB; rc = 0; - goto socket_connect_return; + return rc; } secattr = selinux_netlbl_sock_genattr(sk); if (secattr == NULL) { rc = -ENOMEM; - goto socket_connect_return; + return rc; } rc = netlbl_conn_setattr(sk, addr, secattr); if (rc == 0) sksec->nlbl_state = NLBL_CONNLABELED; -socket_connect_return: + return rc; +} + +/** + * selinux_netlbl_socket_connect_locked - Label a client-side socket on + * connect + * @sk: the socket to label + * @addr: the destination address + * + * Description: + * Attempt to label a connected socket that already has the socket locked + * with NetLabel using the given address. + * Returns zero values on success, negative values on failure. + * + */ +int selinux_netlbl_socket_connect_locked(struct sock *sk, + struct sockaddr *addr) +{ + struct sk_security_struct *sksec = sk->sk_security; + + if (sksec->nlbl_state != NLBL_REQSKB && + sksec->nlbl_state != NLBL_CONNLABELED) + return 0; + + return selinux_netlbl_socket_connect_helper(sk, addr); +} + +/** + * selinux_netlbl_socket_connect - Label a client-side socket on connect + * @sk: the socket to label + * @addr: the destination address + * + * Description: + * Attempt to label a connected socket with NetLabel using the given address. + * Returns zero values on success, negative values on failure. + * + */ +int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr) +{ + int rc; + + lock_sock(sk); + rc = selinux_netlbl_socket_connect_locked(sk, addr); release_sock(sk); + return rc; }