From patchwork Wed Dec 6 10:17:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Haines X-Patchwork-Id: 10096093 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 A804160327 for ; Wed, 6 Dec 2017 14:44:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 937E22908F for ; Wed, 6 Dec 2017 14:44:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 85239297C2; Wed, 6 Dec 2017 14:44:42 +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.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from ucol19pa12.eemsg.mail.mil (ucol19pa12.eemsg.mail.mil [214.24.24.85]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B5A302908F for ; Wed, 6 Dec 2017 14:44:40 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.45,368,1508803200"; d="scan'208";a="448504119" Received: from emsm-gh1-uea11.ncsc.mil ([214.29.60.3]) by ucol19pa12.eemsg.mail.mil with ESMTP/TLS/AES256-SHA; 06 Dec 2017 14:44:29 +0000 X-IronPort-AV: E=Sophos;i="5.45,368,1508803200"; d="scan'208";a="6770434" IronPort-PHdr: =?us-ascii?q?9a23=3AEa66sBfNCboK6YCa0qc2JwDIlGMj4u6mDksu8pMi?= =?us-ascii?q?zoh2WeGdxcmyZhaN2/xhgRfzUJnB7Loc0qyN4vCmATRIyK3CmUhKSIZLWR4BhJ?= =?us-ascii?q?detC0bK+nBN3fGKuX3ZTcxBsVIWQwt1Xi6NU9IBJS2PAWK8TW94jEIBxrwKxd+?= =?us-ascii?q?KPjrFY7OlcS30P2594HObwlSijewZbB/IA+qoQnNq8IbnZZsJqEtxxXTv3BGYf?= =?us-ascii?q?5WxWRmJVKSmxbz+MK994N9/ipTpvws6ddOXb31cKokQ7NYCi8mM30u683wqRbD?= =?us-ascii?q?VwqP6WACXWgQjxFFHhLK7BD+Xpf2ryv6qu9w0zSUMMHqUbw5Xymp4KlxSB/slS?= =?us-ascii?q?wJKTg3/m/KgcB0la5WoRetqhpiyIDWfY6VLuJzcKPDc90URmRPWdtfVzRDD4+h?= =?us-ascii?q?YYYAEfEBMP1Eo4XhvVYCsQGzCRWwCO7p1zRGhmX23ao/0+k5DQ/G3RAvH9IUv3?= =?us-ascii?q?TOsdr+KaUcXvq0zKnO0zrDdO5d1DDn6IjJbh8hoeuDXahtfsXJ1UYgDwPFgU+R?= =?us-ascii?q?qYzjITyVzf8AvHOH7+phU+Kvl3Aoqxt3ojex2scgkJXGhoUQyl3d8yhy3Yg7Jd?= =?us-ascii?q?q9SEFhYN6kFoNdtySAOItsXswuWWBouCA0yr0BoZK7ZDIFyIkjxxLGbvyHdI+I?= =?us-ascii?q?4gj9W+qLPTh4g3dldbSijBix6Uit0vDwW8a73VpQridJj8PAum4C2hDN8MSLV+?= =?us-ascii?q?Nx80Sg1DqVygze5e5JLVopmafUKpMt2KM8mocRvEnFAyT4gl/5jLWMeUUh4uWo?= =?us-ascii?q?7uPnbaj4qZKELI90jx3+MrwpmsyiHeQ0KggOUHaf+eS7zLDj4Vf2QK9Ljv0ria?= =?us-ascii?q?nVqozaJMQHqa65BA9ZyIAj5AqkDzi6ytgYmHgHLFZddBKGiYjmJU3OLejlAfqw?= =?us-ascii?q?jFmgijdmy+3cMrH/DZjBMGLPnKr5cbZ48UFcyQ4zzd5F55JTD7EMOOnzVVH1tN?= =?us-ascii?q?zZCB85LgO1z//8B9V6y4MeX36ADbGCMK7JrV+J5v4gI+mLZIMPvjb9MOIq6+Th?= =?us-ascii?q?jX8+h18RZbOp0ocPaHCkAvRmJF2UYXjrgtcHC2gKogo+Q/bsiFCZUz5TYHCyX6?= =?us-ascii?q?cm6TEgFIKpE53DRpu3jLyGxie7EYVcZnpaBVCUDXfoa4KEVu8OaCKQOMBujj8E?= =?us-ascii?q?VaOmS48n1BGuqhT3y7RjLurJ9SwXro/j1N5p5+3Ojx0y8iZ0D8uF2WGXU250hn?= =?us-ascii?q?8IRyMx3K1nr019y1OD0a1mjPxCDtFT6e1GXRo9NZ7G1eN6E8ryWgXDftiXVFmm?= =?us-ascii?q?Xs+qATYrTtI+29UOeVpyG82+jhDf2CqnG6IamKCOBJwz9KLcw2X9Kt1jy3nYzq?= =?us-ascii?q?khjlgnQsxJNWG8gK5w6RTTDZbTk0qFj6aqabgc3CnV+Wie0WqBpltYXRVsXqXC?= =?us-ascii?q?WHAQelHZrc/l5k/YSb+hF6gnOBNbycGeMqtKdsHpjVJeSfbjOdXeZGSxlny1BR?= =?us-ascii?q?aM37+MbYzqd38b3CrHEkgEkAET/WiYOgQkACeuvX7eBiR0FV3ze0Ps7fV+qHSj?= =?us-ascii?q?Q0861QGFdUth2Ka0+h4OnvGcTusT3rMdtCc6pTR0B0yx39XMC9qPvwBhZrlTYc?= =?us-ascii?q?sh4Fdb0mLUrw99MYajL6Blm14TaAd3sFnt1xVwF4VMi88qrGklzABqM6KXzEtB?= =?us-ascii?q?dy+E3ZD3IrDYMHT9/Aqua6HIwFHTy8yZ9bsK6PgirFXjpg6pHFI483p7y9lVz2?= =?us-ascii?q?ec5pLSAQoITJ3+T1069xd/p7DVeCU94Z3b1WF0O6murjDCw84pBPciyhu4ZNdf?= =?us-ascii?q?PrmEFAjpE80GHMWuM+oqm1+nbxIBJu9S8rQ4P8W4ePuawKSrJvpvnCq6jWRb54?= =?us-ascii?q?BwykyN+DB4Su7UwZkF2eqY0xCZVzjilleuqd33mYVeaTEVBGq/xjDuBJRNaa1q?= =?us-ascii?q?YYYLFWCuLtWrxtpjmpHtWmRX9Fq4Clwa38+pfAadYEbm3Q1Mz0gXp2KomTegxT?= =?us-ascii?q?xujz4ptraf3DDJw+n6choHO2pLRG18glf3OoW7lc4VXFKvbwQzkxul/0n6zbBB?= =?us-ascii?q?pKtjN2nTXVtIfy/uImF8U6u/qqaCY8lV6J8yrSpXUOO8YVaVSrPmpxsa0iXjEH?= =?us-ascii?q?FExDA8bT2qvY/5nxNigmKHMHlztGbZed13xRrH4NzcROVR3iYfSCljlzbXAlm8?= =?us-ascii?q?P9+0/dSbjJrDqfi+V2OnVp1SbSbr1pmMtC2l6m12GRe/hey8msX7EQgm1i/2z8?= =?us-ascii?q?NqVSLMrBb4fIbrzbi1MeVpf0RzH1/89tZ1Gppknos3npEQ1mAQho+J8nofjWfz?= =?us-ascii?q?LdJb1Lr9bHUTQz4L2MXY4Av7101lNXKJwZz2VmmHzstmfdm6bXsc2jgh4MBSFK?= =?us-ascii?q?eU8LtEkDNtolWisALRZeZyni8Hxvso9H4VnfsJtREwziWGHL8SB1JYMTb3lxSP?= =?us-ascii?q?8tC+trlYa3ihcbi3zkp+ks6uAKuEog5CRHbzYo0iEjNo7sVjLFLM12X+6p/ieN?= =?us-ascii?q?bNdt8TqBuUnArAj+RPLpI+iOYKjzJ9OW3hpX0l1/I7jRt20JGipoeHNmFt8bml?= =?us-ascii?q?DR5ZKj30Z9of+j/3gqZYhMqW2JqvHpp5EDURQJToVe6oEC4Vtfn/OQaBCjs8qm?= =?us-ascii?q?ucGbraBgKf5llpoG/IE5CxLX6XPGMZzdJgRBaDOENfnBoYXDIgnp42Dgqq3tDu?= =?us-ascii?q?cF9l5jAN4V71sh5MxfhsNxn7TGjfuBuoZS0uR5WEKhpZ8B1C51zJPsOE9uJ8AT?= =?us-ascii?q?tU/pu/owyRMmabfRhHDXkVWkyYAFDuJqOu6cPO8uSCA+qxNf/OYbKOqOFFTfiH?= =?us-ascii?q?2Zev3pFh/zaWOcWFJmNiAOEj2kpfQXB5HNzUmzsVSyMJii3NdNSUpBGg+i1wtc?= =?us-ascii?q?Cy6+7kVx7q5YeVDLtSK9pv8QisgaifL+6QmDp5KTFA25MK33/H0qAf3EYJhiFg?= =?us-ascii?q?djmtC68AtTLDTKLRnK9YFRgbZD9yNMRS66IwxA5NOdTUitntzL53kuY1C0tZVV?= =?us-ascii?q?zmgsypfdIFLHqjO1PBBUaLKLOGKCbKw87pf6yzV6dcjOJOtx2/oTybCVPsPiyf?= =?us-ascii?q?lzn1UBCiKfpDgzqcMBxauYG9aQptCXP5QNL9dBK0LMV7jSYozr0wh3PKM3McMD?= =?us-ascii?q?dnfkxRrryQ9z5Ygu5lF21P9HVlMfKEmyGf7+XCLZYWq/RrCDxul+1G+HQ616dV?= =?us-ascii?q?7CZcSfNumSvSodluo1e9n+aS1DVoSxtOpSxNhI6RukViI6rZ/IFaWXnY5BIN8X?= =?us-ascii?q?mQCxMSqtR/Bd3gob5QxcbUmaL0MDdN7dTU/c4GCMjVLMKIK30hMBXzFD7TFgsF?= =?us-ascii?q?QiahNXvDiExFjPGS6nqVo4AmqpjrnZoCUKVbVFs0F/wEDERqB8YCIJBpUTMnir?= =?us-ascii?q?OUkMkI5X+ioxbLX8VaoorLVvSMDvXzMDyZl6VLZwMUwbPkKoQeLo772kxmalZk?= =?us-ascii?q?h4nKHk3QXd5DoiJ/cg80vEVN8H97TmItwU7lbB2i4GMLH/6ughE2khd+Yfgq9D?= =?us-ascii?q?r05Vc4OEDFpC8rnUkyntXlmiyRfyT3LKerXoFWCjD4t04vPZPnWwx1dxG9nVR4?= =?us-ascii?q?NDfYQLJcl6Fgen5wiADCo5RPA+JTTa1fbRALxPGXfegn0VNSqiW/309I++vEBY?= =?us-ascii?q?FklAQ0bZ6mt2hA1B57bN4pOazQI7JEwUVXhqKIuC+ny/4+wAsfJ0sW6mydZjQI?= =?us-ascii?q?uEsSOrkhPSqo8fRm6RaelDtbZGgMS/0qr+p3+UwnJeSAzj/v06VYJ0+rLeyfNa?= =?us-ascii?q?SZumbblcGWXlwwy1kIl0hZ/bl2y8sjdVSbV1w3xruLCxsJLdbCKR1Sb8dK8HjT?= =?us-ascii?q?ejyOvvvLwZN0OIWwDe/oTemTtKoOhUKkBgkpFZwW7ssdBpmszF3YLcD/Ib4e1x?= =?us-ascii?q?ot4AXrJFOYDPVGYx+EjDAHo8Sjw5BtxoldOisRAWNjPiWr/rzXvBMlgOKfXNcq?= =?us-ascii?q?ZXcXRpcENnMzWM29hy5Zv3RBASKq3eIYyAmN9STzqj7WDDbic9ppfO2Uag90CN?= =?us-ascii?q?Gq5TU/9LC7hkTT8pXfO271K8xtutrP6OMcoJaHDelbQKJmvEfdgYZYQWWmU2DS?= =?us-ascii?q?EdKvIZj/dZUsZ8TuCnmmSly/ly41T8DpMdm2MKeIhxrlSpxJv4mFwj8jL9S9GS?= =?us-ascii?q?sEGxZwve0D47h8ZQIbaZohfRHorxg+N7C4IAqA3dWuXmetKT9ST/ZByOW3fKFY?= =?us-ascii?q?wDQ3Ye+70nQgSIs2z+6t8U4CXJsKlA3Rxe6/Z4lCVij+AmZdewPOpSUll2hhMe?= =?us-ascii?q?Iywvwnzh3RrFcSKSyGeutyZWNYuNE8AE+dLm9tCmokXVOci5TM4hK01bAI4yRd?= =?us-ascii?q?h8pU0fFCsHXmpJ/QeiisWKuwppjOryogd8Ipo7NvPoznI8uGspzenjjeTJnfsg?= =?us-ascii?q?2FTCC6GOBAmthVOi5YRudHmX09M8wcpYVB8VYxVts5J7FXBqggvKylaTplDS4X?= =?us-ascii?q?zC8WTYCA0ScDguiixbTViA2ccJM4MBwLqJ9CmMcSUzZqYiMCo6+uT4DWmHWeSm?= =?us-ascii?q?gIPggT8QVM5AQPloJrcOHq+ozIQ4NIyz5RvvJ7TzDLGoNu91TlVmGcmUL4R+m5?= =?us-ascii?q?k+y1wQJSy+rh3cMBWB5iD0hR3eVWm1ApKLF2KqkQopXFviWOdUzkoGLn0PGmK0?= =?us-ascii?q?VJyc3Ia134C5LItWv6Ui0A53IUQZFAyHTBGpQOiQp4aL0mpFJUII+4fEb+4iYr?= =?us-ascii?q?x4VtH7ajUsCqyEwprXEcRyelC9BBEf1psErLWD15ZJCmsInlO5JXQmJL5J2Rt1?= =?us-ascii?q?JZn153Py6/15VcN9lH4iQQUzhXvTWdoNyyRdVD2cBsFZ8DONN/tGrmFaxZJpeR?= =?us-ascii?q?u2U2taLrynDH4TAwqlC6xC+8G6WgVeJW43UeGhk1J2SZskQvDews/XnJ/1/QrF?= =?us-ascii?q?905PlUBqKTjUpvvTlxBJZOCShV1Xq9NVR8UGFGs/lGKKTSa8FTWPcyagOzNxE8?= =?us-ascii?q?CPIr0VeE8l1znXf8fyN9rBBa+zzHUwkySyYVnq/nmScCpcG/JT8aV5VIYC07by?= =?us-ascii?q?jbNg2bmTpYvApEZkFuXJAZHMhK968H0otT48XNV1ygKScbUxx+Lgg4y+ZQlVZf?= =?us-ascii?q?sEWEfiDQFRKode3TshJtYMiRsNWkLO/+/AdakIPorP4396MfR328gwKtRcrSr4?= =?us-ascii?q?jmtt2FrkGObrv3M/WgYX/dSzjBlQywha06AJbU4ifeKxdbK51myXo+e5fhF2/L?= =?us-ascii?q?PRNCJ60FO0pXT6d6ac9JoupCfc9rZL4J+bNxBhKAXh7vGpagrONBLlbIQTTRNT?= =?us-ascii?q?uB//e6oYLO6bzdVengadCNx3ndRaJ3JY126T7hG7flyYVe4Fb52u9x9kNmTljL?= =?us-ascii?q?KyKBo87nJgMF/smicVbtsYMyEDPKGphwlmHtxkZae8oRXSKq7IwSyIlF53boVe?= =?us-ascii?q?J4zk/zvfVU97lg8oQ34rZpycKuKafTL/Rav1VnDQKPBgV27JUtHXRwR3xMYu8L?= =?us-ascii?q?NvjdZ6MZjdrhq+rvDawY9AWV+/BFadvAP0zBnMi/BS2bSRxAhggBsiQWLgqb1/?= =?us-ascii?q?6CgK90Ut2ope3210Mi+VS+KQQGzL9174ee5qWIvPPXbwfWzbUcRqflXMfzoao3?= =?us-ascii?q?u0OO5fwkk6UDendpbA2mDucdUNIdxmb6wqwwyyIjDd/DFar6+PFfT3I5gi7gm5?= =?us-ascii?q?dlElUSAfMUGLqG8J9QnmgmhuPZMccWfbpammaVEh6kEKENxmK36yeNJ2llmB7O?= =?us-ascii?q?2QnqQWyv9F/2sTN4QSzUwtfhk0pVU6K6BUJMUCupJ0B4qjKPPAzntNbtv6Q68l?= =?us-ascii?q?02OHT+tN2RjGuhJK9XH8rnKdydICg7vkgYg4EqS9y0x48bBcSyL8sL/HF5dPve?= =?us-ascii?q?5HuhkzVdrKdfm4re/saV9+3MEnmhlK2bpa+CxDJZyngkpVEw8M2gNvXV6tKWRP?= =?us-ascii?q?SnyngeQD1iuwvbWB61sKbUo0oTOUyR30fBgJYKMc1B3XkkykHm4/AuQMop+wVC?= =?us-ascii?q?ConAZ/0DpTfpODv32FqfeMw4Vi2f0ztRA1L0HkJ1GLAm12LsoM3JlXnR+1oyRo?= =?us-ascii?q?lzbUDnhgJ4D58+KU0z7Fgb2C0DERICaRqDFrGnGVzlLZcYVUgEcRmH06K1er0p?= =?us-ascii?q?0k1vwrOi/+vTbe1gB6UTNvZSlBOOnENBFpIQr6IeXKp2e0VB+67PugjiF4/nUu?= =?us-ascii?q?DplXUuM/21Xsda8cceu3s5/Am/Qxug6ZFe77cUk52IcrBLYYLMvc9m9Utn4yAA?= =?us-ascii?q?djBVihhlkxy5SfwcpPzk4tXDrJWo6PyhW7o2SuoL8Bg0A2B+j5ruj1A5vdHYyf?= =?us-ascii?q?tTSo3PhYT46gBNLGaAuJzG3BlkNeoON4Wrca5l93UAISgeO30OMsSNZvk54i9i?= =?us-ascii?q?KjPT6EJeAsICYtMYJsnNmRtOhk3vRr5T6tLRGkWEBIdra8Ao8233xSg68ZQgSe?= =?us-ascii?q?bg8ya6K43Q4V9LPvNDijhsld3ZqegaxPrdEi4X7meDZxhy2COCxIGHC+zs8uWU?= =?us-ascii?q?1NHUS1QGEzY0U4daJDqC/xarSfa1lJXtTwOb987ygJM4dEKLRXyxnb8IsrhNEe?= =?us-ascii?q?5ekCr72iVRFoHvi/KTrdWs9HNdtkdbH4Zr8R3FBKJfM416ORTmjMarQFNxBi/i?= =?us-ascii?q?eM7Jdxouv/GWyv0L4+VkOEv0fZUbLQ4cy7Lm9XpVSRNjSLzosVaXU+IRYMBrSf?= =?us-ascii?q?3eoXBT941gN7UDPF6Dq5z2tj1Iskw5ABc1aL8sqTxXbkbOnAlSW6f6prEAjg8c?= =?us-ascii?q?XMViuU9LH2KwOX4x6yDBVatLkKmbEOYV/SmLTqwST0VoNTtzQxG12JRuY7upmv?= =?us-ascii?q?RHsmJanixju/Uq1j1mRAemuSLyva4N3igg+L6gvjUbpXNFVvmekzvPCVhb0PQK?= =?us-ascii?q?jKIcBm3+6Vy9fHYDb5X94L19KcTm64Yh/2w1YQ8/cC0eQeSgFybwgruNAoyOs9?= =?us-ascii?q?JchxmNtd7MbbCpLigSMbI9xgzlR3Rn1AjRggpo+nMRQjq89N8kOJm9OcE9yyWz?= =?us-ascii?q?B2fbckoM77hSsMv1sl4LUPc2aU1/z2p+yMSHQTcNRMPXEWYvkgckcXlEcI5E6R?= =?us-ascii?q?ICD6kohTKIsbNc/gAaZzfUFoql95LVncfP3nk9VsllyX7Mpq2CnZMqy3xlm9V7?= =?us-ascii?q?7iKUv3QSbePYWdd2Anfvzodf1fD+Z/K1v+AJVoRmzLWhUOccPcS4+Gq22ZBqWk?= =?us-ascii?q?q7ybQEG1q2LvUPxrDBUyeqUWeYQ/iEc3CQnzYlNU7//RepLkUtaMdLs0AyLPDP?= =?us-ascii?q?hptdlw39S7N7WD+cpVjBzGwsKekabR45uJ+7ewwWS+4cf++cJewwz/AlEFsMa2?= =?us-ascii?q?XGHTBqC++3rVGtgJJ7NGt+7kngZ+Ti7BzmOsOIGhYYCY7asoJx+fuiS2KFOH9g?= =?us-ascii?q?ygByPUZt++fbFlQxrfNcc42KkNjRndt71+kFe+1qMS0ntd4Zgphj5pWM0MeWbR?= =?us-ascii?q?HRyY7/JdTPrfeEA/3fzkIqemZBX7oHYAP14Zs1Pto4W73VALtYsg4QBa8gQJwu?= =?us-ascii?q?L23x7r17LBtvcg7NY7S5msvqqfiIZptTvHDb9U8wLCHAux0Dzfy0UAN7b5C2h3?= =?us-ascii?q?noJpA/WC5BpcV3ChR6BItPB98Arw2/Dp6WnaG7jMWx+1l7u+8RqqfwDOrF1NGn?= =?us-ascii?q?0IVwRZRa4laLPDnJDqlxnktllviyguvH0pTpEsPid9YEW/R6T2PGcbLGAJuwKi?= =?us-ascii?q?iPOsP9fE5G9aSQ0LRnXRWNN2jFWP+duSmlMuh0yVkqwYx/OuzIxXoi6K+fkN3/?= =?us-ascii?q?e21WuA+9onOTcphS9lrHAarZRR0QAf6E9nt1WLYccZPc6ugDK5ohzcKa7g016y?= =?us-ascii?q?5NlIOBIq68vgrX10lmb5PHPQ7s3CokXYQiPhuyKw0vjHXfp3CbBm5Tfea+Lsw4?= =?us-ascii?q?uteeDhX36wFRkGAra3UJTnDpTteYI2Qs0PW+bQyM+RljBcoCmfK6Y0g1quu5Tu?= =?us-ascii?q?w+acYNovmjqLhSyYUhECrIXsUPen/d?= X-IPAS-Result: =?us-ascii?q?A2BDAgBBASha/wHyM5BdGgEBAQEBAgEBAQEIAQEBAYMRKQN?= =?us-ascii?q?mbiePFo4JgnuWBxSBfiULimxBFgEBAQEBAQEBAQFqKII4JIJOAhcNGQE4AQIDC?= =?us-ascii?q?QIFQwgDAVoSBYgXAzSBNwEDFQMBDKsGOoMKBYEChFSBbSYECIUIVIM/gnWDDhN?= =?us-ascii?q?ggTsEhg8FijkMiTWPA4d2jRaTaI0BiwwmCiiBTjIaI4J4CQqCECAPHIFneIckA?= =?us-ascii?q?SUHghoBAQE?= Received: from tarius.tycho.ncsc.mil ([144.51.242.1]) by emsm-gh1-uea11.NCSC.MIL with ESMTP; 06 Dec 2017 14:44:24 +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 vB6Ehi08007069; Wed, 6 Dec 2017 09:43:53 -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 vB6AHxTJ053503 for ; Wed, 6 Dec 2017 05:17:59 -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 vB6AHt05006143; Wed, 6 Dec 2017 05:17:55 -0500 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A1B8AQDZwidaZCMbGNZdHAEBAQQBAQoBA?= =?us-ascii?q?YMRKQMkAUFuJ44ijnuCe5YHFIIBDx6FGIVSPxgBAQEBAQEBAQEEHBSGIg0ZATg?= =?us-ascii?q?BFYEpEogcAzSBNwEDFQMBDKwBOoMKBYEChFWBbQEBAQcCARkECIUCVIM/gnWDD?= =?us-ascii?q?hNggTsEhg8FijkMiTWPA4d2jRaTaI0BiwwfggcyGiOCeAkKghAgDxyBZ3iHWwE?= =?us-ascii?q?lB4IaAQEB?= X-IPAS-Result: =?us-ascii?q?A1B8AQDZwidaZCMbGNZdHAEBAQQBAQoBAYMRKQMkAUFuJ44?= =?us-ascii?q?ijnuCe5YHFIIBDx6FGIVSPxgBAQEBAQEBAQEEHBSGIg0ZATgBFYEpEogcAzSBN?= =?us-ascii?q?wEDFQMBDKwBOoMKBYEChFWBbQEBAQcCARkECIUCVIM/gnWDDhNggTsEhg8Fijk?= =?us-ascii?q?MiTWPA4d2jRaTaI0BiwwfggcyGiOCeAkKghAgDxyBZ3iHWwElB4IaAQEB?= X-IronPort-AV: E=Sophos;i="5.45,367,1508817600"; d="scan'208";a="142126" Received: from emsm-gh1-uea11.ncsc.mil ([214.29.60.35]) by goalie.tycho.ncsc.mil with ESMTP; 06 Dec 2017 05:17:54 -0500 IronPort-PHdr: =?us-ascii?q?9a23=3A/wz50hMei40a/UBmtUsl6mtUPXoX/o7sNwtQ0KIM?= =?us-ascii?q?zox0I/T+rarrMEGX3/hxlliBBdydsKMUzbKO+4nbGkU4qa6bt34DdJEeHzQksu?= =?us-ascii?q?4x2zIaPcieFEfgJ+TrZSFpVO5LVVti4m3peRMNQJW2aFLduGC94iAPERvjKwV1?= =?us-ascii?q?Ov71GonPhMiryuy+4ZPebgFLiTanfb9+MAi9oBnMuMURnYZsMLs6xAHTontPde?= =?us-ascii?q?RWxGdoKkyWkh3h+Mq+/4Nt/jpJtf45+MFOTav1f6IjTbxFFzsmKHw65NfqtRbY?= =?us-ascii?q?UwSC4GYXX3gMnRpJBwjF6wz6Xov0vyDnuOdxxDWWMMvrRr0yRD+s7bpkSAXwhS?= =?us-ascii?q?kaNzA37m/ZhM93gq9AvB6tuwZyz5LObY2JKPZzeL7Wc9MARWpGW8ZcTzBPAoKg?= =?us-ascii?q?YIsPFeUBJ/tXpJT/qVQUrBu+AxejBPjywTJPnH/23LE10+Q7HgHcwQMvB84Bv2?= =?us-ascii?q?zUrNrvNacSV/66zLLTwDrYc/NW2DH96JTWfRA7p/GDQ65wfdDNxkkoEgPIl1Od?= =?us-ascii?q?opHrMTOS0+QCqWmb7+x4WOKqkWEnsR1+riKuxscqhInJgZoZykje+iVkxIY5PN?= =?us-ascii?q?i4SEl8Yd6+DpRcrT2VN4xzQs4kXmpmuz46x6UYtZKmcyUG0ooryhHFZ/CZcYWE?= =?us-ascii?q?+BzuWeaJLTp7hX9pYq+zihm9/ES61+HxWci53ExXoiZYkNTBsG0G2QbJ5cidUP?= =?us-ascii?q?R9+1+s2TaR2ADX7eFJOV00lbLAJJE837I9koITvl7fEiPogkn5krGZdkA/+uin?= =?us-ascii?q?8ejnZ6/ppp6YN4NujwH+M6AultS+AeQ+LAcOQ3CW9fqh2LDs50H1XrpHguconq?= =?us-ascii?q?TbqpzXK8QWqra8AwBP04Yj7xi/Dy2h0NQdhXQHNlNFdw6Hj4fzIVHBPej3Auun?= =?us-ascii?q?jFSsijhrxvbGMaP6ApjWNXfDjLbhfbBh60FC0gozy85Q545OBr4dJ/LzX1f9tM?= =?us-ascii?q?bEAR8hLwy03+HnBc1m1owDQmKCGbOZMaPOvl+I4eIjOe+MZJQPtzrnJPgl4ODu?= =?us-ascii?q?h2cjmVABZampwYcXaHegE/R9PUqZZXvsgtEcEWYFpQc+UOzrh0GCUT5UfXqyWb?= =?us-ascii?q?k86SshBIKpCofDWNPlvLvUxyq/H5tLdkhaG1uMFjHubIzCVPASLGqUL9NtnyIs?= =?us-ascii?q?S7esUcki2AuouQu8zKBoaqLQ+ysFpdf438Rtz/PcmAt09jFuCcmZlWaXQCU8mm?= =?us-ascii?q?IOWi9zx610vFZ81kbG1K90nvhVPcJc6ukPUQogM5PYietgBIPcQAXEK+2IQ1av?= =?us-ascii?q?WNnuITgwSN8qi4sUYk19Es+uuRv03yOrBbIOv7aXBZoo/7ja0mS3LMF4nSWVnJ?= =?us-ascii?q?I9hkUrF5McfVatgbRyolDe?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0B9AQDZwidaZCMbGNZdHAEBAQQBAQoBA?= =?us-ascii?q?YMRKQMkAUFuJ44ijnuCe5YHFIIBDx6FGIVSPxgBAQEBAQEBAQEBAxwUX4I4IoJ?= =?us-ascii?q?pDRkBOAEVgSkSiBwDNIE3AQMVAwEMrAE6gwoFgQKEVYFtAQEBBwIBGQQIhQJUg?= =?us-ascii?q?z+CdYMOE2CBOwSCbwyDFAWKOQyJNY8Dh3aNFpNojQGLDB+CBzIaI4J4CQqCECA?= =?us-ascii?q?PHIFneIdbASUHghoBAQE?= X-IPAS-Result: =?us-ascii?q?A0B9AQDZwidaZCMbGNZdHAEBAQQBAQoBAYMRKQMkAUFuJ44?= =?us-ascii?q?ijnuCe5YHFIIBDx6FGIVSPxgBAQEBAQEBAQEBAxwUX4I4IoJpDRkBOAEVgSkSi?= =?us-ascii?q?BwDNIE3AQMVAwEMrAE6gwoFgQKEVYFtAQEBBwIBGQQIhQJUgz+CdYMOE2CBOwS?= =?us-ascii?q?CbwyDFAWKOQyJNY8Dh3aNFpNojQGLDB+CBzIaI4J4CQqCECAPHIFneIdbASUHg?= =?us-ascii?q?hoBAQE?= X-IronPort-AV: E=Sophos;i="5.45,367,1508803200"; d="scan'208";a="6760187" X-IronPort-Outbreak-Status: No, level 0, Unknown - Unknown Received: from upbd19pa02.eemsg.mail.mil ([214.24.27.35]) by emsm-gh1-uea11.NCSC.MIL with ESMTP; 06 Dec 2017 10:17:52 +0000 X-EEMSG-check-005: 0 X-EEMSG-check-006: 000-001;cc79efac-b6da-4e86-aa1d-df07633d5384 Received: from localhost.localdomain (localhost [127.0.0.1]) by UPDCF3IC07.oob.disa.mil (Postfix) with SMTP id 3ysF1C6Sdsz1wySH; Wed, 6 Dec 2017 10:17:51 +0000 (UTC) Received: from UPBD19PA06.eemsg.mil (unknown [192.168.18.7]) by UPDCF3IC07.oob.disa.mil (Postfix) with ESMTP id 3ysF164x6vz1wyM9; Wed, 6 Dec 2017 10:17:46 +0000 (UTC) Authentication-Results: upbd19pa06.eemsg.mail.mil; dkim=permerror (key too small) header.i=@btinternet.com X-EEMSG-check-008: 277786154|UPBD19PA06_EEMSG_MP6.csd.disa.mil X-EEMSG-check-001: false X-EEMSG-SBRS: 3.5 X-EEMSG-ORIG-IP: 65.20.0.182 X-EEMSG-check-002: true X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0B/AAABwidah7YAFEFdGwEBAQEDAQEBCQEBAYMRgRJuJ6AYlgcUggEPHoUYhVJAFwEBAQEBAQEBARMBAQEIDQkIKC+FQw0ZATgBFYEpEogcAzSBNwEDFQQMq306gwoFgQKEVYFtAQEIAhoECIUChBOCdYMOE2CBOwSCbwyDFAWKOQyJNY8Dh3aNFpNojQGLDCABggUyGiOCeAkKghAgDxAMgWd4h1sBJQeCGgEBAQ X-IPAS-Result: A0B/AAABwidah7YAFEFdGwEBAQEDAQEBCQEBAYMRgRJuJ6AYlgcUggEPHoUYhVJAFwEBAQEBAQEBARMBAQEIDQkIKC+FQw0ZATgBFYEpEogcAzSBNwEDFQQMq306gwoFgQKEVYFtAQEIAhoECIUChBOCdYMOE2CBOwSCbwyDFAWKOQyJNY8Dh3aNFpNojQGLDCABggUyGiOCeAkKghAgDxAMgWd4h1sBJQeCGgEBAQ Received: from rgout05.bt.lon5.cpcloud.co.uk ([65.20.0.182]) by upbd19pa06.eemsg.mail.mil with ESMTP; 06 Dec 2017 10:17:45 +0000 X-OWM-Source-IP: 86.144.146.117 (GB) X-OWM-Env-Sender: richard_c_haines@btinternet.com X-Junkmail-Premium-Raw: score=10/50, refid=2.7.2:2017.12.6.93616:17:10.433, ip=, rules=__HAS_FROM, __FRAUD_WEBMAIL_FROM, __TO_MALFORMED_2, __TO_NO_NAME, __HAS_CC_HDR, __MULTIPLE_RCPTS_CC_X2, __CC_NAME, __CC_NAME_DIFF_FROM_ACC, __SUBJ_ALPHA_END, __HAS_MSGID, __SANE_MSGID, __HAS_X_MAILER, __FROM_DOMAIN_IN_ANY_CC1, __TO_IN_SUBJECT, __ANY_URI, __HTTPS_URI, __URI_WITH_PATH, INFO_TLD, __FRAUD_BODY_WEBMAIL, __CP_URI_IN_BODY, __MULTIPLE_URI_TEXT, __URI_IN_BODY, __URI_NOT_IMG, __NO_HTML_TAG_RAW, BODY_SIZE_10000_PLUS, __MIME_TEXT_P1, __MIME_TEXT_ONLY, __URI_NS, HTML_00_01, HTML_00_10, __FRAUD_WEBMAIL, __FROM_DOMAIN_IN_RCPT, __CC_REAL_NAMES, MULTIPLE_RCPTS, __PHISH_SPEAR_STRUCTURE_1, TO_IN_SUBJECT, __MIME_TEXT_P, URI_WITH_PATH_ONLY Received: from localhost.localdomain (86.144.146.117) by rgout05.bt.lon5.cpcloud.co.uk (9.0.019.13-1) (authenticated as richard_c_haines@btinternet.com) id 59FAA6F203922BA1; Wed, 6 Dec 2017 10:17:43 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=btinternet.com; s=btcpcloud; t=1512555465; bh=eDfxF6WR0DqxOoiIpPgjyzJ79wKBCE2zfnXNJV0r5xk=; h=From:To:Cc:Subject:Date:Message-Id:X-Mailer; b=uR1/ikKD2beB4S8hla8GPWkcUKxGy56o2WlpBjEfLhg45jWGIz08Hz53z4AuOzCtV1oBCoRAJ6btRV1H6s1Pliw0MFNG2lNKMSi56vhLz8J9eTg+oBum4RnxtI7sryl7bB9bS41hl+nLy1j4MBI+ogE3NYT7OBubWmJoh0FE4Zk= X-EEMSG-check-009: 444-444 From: Richard Haines To: selinux@tycho.nsa.gov, netdev@vger.kernel.org, linux-sctp@vger.kernel.org, linux-security-module@vger.kernel.org Date: Wed, 6 Dec 2017 10:17:36 +0000 Message-Id: <20171206101736.3217-1-richard_c_haines@btinternet.com> X-Mailer: git-send-email 2.14.3 X-Mailman-Approved-At: Wed, 06 Dec 2017 09:43:42 -0500 Subject: [PATCH V2] 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: Cc: marcelo.leitner@gmail.com, nhorman@tuxdriver.com, vyasevich@gmail.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 Acked-by: David S. Miller --- V2 Changes Remove lock from selinux_sctp_assoc_request() Fix selinux_sctp_sk_clone() kbuild test robot catch [1] [1] https://marc.info/?l=selinux&m=151198281817779&w=2 Documentation/security/SELinux-sctp.rst | 104 ++++++++++++ security/selinux/hooks.c | 270 +++++++++++++++++++++++++++++--- security/selinux/include/classmap.h | 2 +- security/selinux/include/netlabel.h | 20 ++- security/selinux/include/objsec.h | 4 + security/selinux/netlabel.c | 144 +++++++++++++++-- 6 files changed, 512 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..f6a9162 --- /dev/null +++ b/Documentation/security/SELinux-sctp.rst @@ -0,0 +1,104 @@ +SCTP SELinux Support +===================== + +Security Hooks +=============== + +The ``Documentation/security/LSM-sctp.rst`` document describes how the +following sctp security hooks are utilised:: + + security_sctp_assoc_request() + security_sctp_bind_connect() + security_sctp_sk_clone() + security_inet_conn_established() + + +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 Bind, Connect and ASCONF Chunk Parameter Permission Checks +================================================================ +The hook ``security_sctp_bind_connect()`` is called by SCTP to check +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 | + ------------------------------------------------------------------ + + +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 0110bb5..954bfcf 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 */ @@ -4136,6 +4138,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; } @@ -4209,6 +4228,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; @@ -4398,6 +4430,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); } @@ -4418,11 +4454,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; @@ -4434,7 +4466,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; @@ -4488,6 +4526,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; @@ -4502,7 +4544,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; @@ -4516,7 +4558,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; @@ -4527,10 +4573,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; @@ -4538,7 +4586,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; @@ -4552,10 +4605,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; @@ -4563,13 +4625,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) @@ -4832,7 +4905,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; @@ -4945,6 +5019,161 @@ 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; + + err = selinux_netlbl_sctp_socket_connect(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) { @@ -6433,6 +6662,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 35ffb29..099065e 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -175,7 +175,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 75686d5..73668db 100644 --- a/security/selinux/include/netlabel.h +++ b/security/selinux/include/netlabel.h @@ -33,6 +33,7 @@ #include #include #include +#include #include "avc.h" #include "objsec.h" @@ -53,9 +54,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, @@ -65,6 +68,7 @@ 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_sctp_socket_connect(struct sock *sk, struct sockaddr *addr); #else static inline void selinux_netlbl_cache_invalidate(void) @@ -114,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) { @@ -123,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) { @@ -146,6 +159,11 @@ static inline int selinux_netlbl_socket_connect(struct sock *sk, { return 0; } +static inline int selinux_netlbl_sctp_socket_connect(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 6ebc61e..e319d5d 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 aaba667..ddb5d55 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -250,6 +250,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); @@ -270,6 +271,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 @@ -319,6 +375,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 @@ -470,7 +542,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 * @@ -479,18 +552,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 */ @@ -498,18 +566,72 @@ 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 - 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; + struct sk_security_struct *sksec = sk->sk_security; + + if (sksec->nlbl_state != NLBL_REQSKB && + sksec->nlbl_state != NLBL_CONNLABELED) + return 0; + + lock_sock(sk); + rc = selinux_netlbl_socket_connect_helper(sk, addr); release_sock(sk); + + return rc; +} + +/** + * selinux_netlbl_sctp_socket_connect - Label an SCTP client-side socket on a + * connect + * @sk: the socket to label + * @addr: the destination address + * + * Description: + * Attempt to label a connected socket with NetLabel using the given address + * when called by the SCTP protocol layer. 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_netlbl_socket_connect() + * Returns zero values on success, negative values on failure. + * + */ +int selinux_netlbl_sctp_socket_connect(struct sock *sk, struct sockaddr *addr) +{ + int rc; + struct sk_security_struct *sksec = sk->sk_security; + + if (sksec->nlbl_state != NLBL_REQSKB && + sksec->nlbl_state != NLBL_CONNLABELED) + return 0; + + rc = selinux_netlbl_socket_connect_helper(sk, addr); + return rc; }