From patchwork Thu Jul 27 13:10:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petr Lautrbach X-Patchwork-Id: 9866913 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 357E96038C for ; Thu, 27 Jul 2017 13:20:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 25ADE2882C for ; Thu, 27 Jul 2017 13:20:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 246A12883C; Thu, 27 Jul 2017 13:20:20 +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=ham 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 3F06F28831 for ; Thu, 27 Jul 2017 13:20:12 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.40,419,1496102400"; d="scan'208";a="361511713" Received: from emsm-gh1-uea10.ncsc.mil ([214.29.60.2]) by ucol19pa12.eemsg.mail.mil with ESMTP; 27 Jul 2017 13:20:13 +0000 X-IronPort-AV: E=Sophos;i="5.40,419,1496102400"; d="scan'208";a="487821" IronPort-PHdr: =?us-ascii?q?9a23=3AGPvifBfIls04FohJ6gCHpIrYlGMj4u6mDksu8pMi?= =?us-ascii?q?zoh2WeGdxcq7ZRWN2/xhgRfzUJnB7Loc0qyN4vCmBD1Lv8zJmUtBWaQEbwUCh8?= =?us-ascii?q?QSkl5oK+++Imq/EsTXaTcnFt9JTl5v8iLzG0FUHMHjew+a+SXqvnYdFRrlKAV6?= =?us-ascii?q?OPn+FJLMgMSrzeCy/IDYbxlViDanb75/KBa7oR/Ru8QSjodvK7g9wQbVr3VVfO?= =?us-ascii?q?hb2XlmLk+JkRbm4cew8p9j8yBOtP8k6sVNT6b0cbkmQLJBFDgpPHw768PttRnY?= =?us-ascii?q?UAuA/WAcXXkMkhpJGAfK8hf3VYrsvyTgt+p93C6aPdDqTb0xRD+v4btnRAPuhS?= =?us-ascii?q?waOTE56mXXgdFugqxdrhyquhhzz5fJbI2JMfZzeL7Wc9EHSmpbRstfVzJPDI2/?= =?us-ascii?q?YYQNAeoPIP5Yoovgq1YAsxS+HhKhCP/zxjJSmnP6wbE23/gnHArb3AIgBdUOsH?= =?us-ascii?q?HModvvKqgSTfq1x7TOwzrZcvNWxS3955PSfR89ofGHQLV9cdLVyUY1CgPFkk+Q?= =?us-ascii?q?ppf/MD6OzOQCrXWU7+p6WuKzkWIotwZxoj22y8oql4LHiIUVylXe+iV4xoY4Pd?= =?us-ascii?q?O5SFR6Yd64DpRcrTqaN4twT8g/QG9ooD43xqAJtJO0ZiQHyIkrywTBZ/GIbYSE?= =?us-ascii?q?+A/vWP6PLTtkgH9pYq+zihis/US61+HxVce53ExUoidGlNTHq2oD2AbJ6sedT/?= =?us-ascii?q?tw5kKh2TGS2A/N8uxEOkU0lbbDK54m374wioIfsUTdES/yn0X7lLOWeV8++uip?= =?us-ascii?q?9uTnea/qpoOcNoBoigH+Nb4imsqjDuQjLgcCRW2b+eW41LH7/E35RqtFjuEun6?= =?us-ascii?q?XEv53XKt4Xq66kDwNPzIou5AizAy273NgAmHkINlNFeBaJj4jzPFHOJej1Deyh?= =?us-ascii?q?jFSokTdrwe3GP7L4DprWKXjDjbHhcqpj5E5H0wcz0dBe6I5UCrEGOv7zXFTxu8?= =?us-ascii?q?bCAh82NAy03f7rCM9h2YMGRWKPHqiZPbvQsV+P4OIgOfWMZI8Ptzb7MPUl5fnu?= =?us-ascii?q?jXk8mVAHZqmpwYUYaGqjHvh8JEWZe3XsiM8bEWgWpgo+UPDqiFqaXD5RZXa9Rb?= =?us-ascii?q?4z5jIgCIKhC4fDR56tjaeP3Ce/A51XaXtJCk2KEXf0aoWIQfAMaDidIsV5iDwL?= =?us-ascii?q?SaChS5M91RGprAL606RoIfHK9S0etJLjyN916vbSlR4s6zN7Ed6R02aXT2F7hm?= =?us-ascii?q?kIXSM53LhjoUxhzVeOybV3g/teFdxV+vxGTAM6NZ/HwuNgFd/yQAXBcs2OSFa8?= =?us-ascii?q?TdWsGSsxQc4pw98Sf0Z9HM2vgQ3f3yWwGb8YjKCEBJsx8q3AxXfxPNp9x2zA1K?= =?us-ascii?q?Y/k1ksWtFPOnG+hq5j6wjTAJbEk0Sfl6a2a6sc2DDC9GKdwmqSpkFZUBV9UaLd?= =?us-ascii?q?XX8BYEvWqM725kLGT7C1DrQmPRFNycmYKqtFctfpl0lJRO//ONTCZGK8g2exBB?= =?us-ascii?q?ePxrOKd4fqfmEd0DzcCEgCiQwT+2yJNRI9BiegvWLREiZiFVTxbEPw6eN+sm+0?= =?us-ascii?q?TlcozwGWaE1sz6S6+gYPivyGSvMTxakJuD87pDVuHVa9xMrWC96aqAV9YqpQe9?= =?us-ascii?q?Q94E1I1WjBrQxyIoSgL7x+hl4Zawl2sULu1xFyCopei8gnt30qwxRvJqKfylNO?= =?us-ascii?q?bSuY3Yr3Or3VNGb94AyvZ7TR2lHE39ac4r0P5+ggq1X/oAGpEVIv83t909ZP1X?= =?us-ascii?q?uT+pTKDBEJXJL0SkY39gF2p6rUYykm/Y/U0mdsMaasuD/Yx90pHPclygqnf9pH?= =?us-ascii?q?M6OLDgzyE8oHB8W1K+wlgVupbhUZPOxI8640JcymfeOc2KG3JOZggC6mjWNf7Y?= =?us-ascii?q?9nz02M7St8RfDS35se2f6Xwg6HWy37jFe7vcD9gZpEai0KHmqj1SjkA5ZcabFo?= =?us-ascii?q?coYPF2iuONG3x9V5h5P2QH5X6F+jCE0A2M+1eBqddUbx3QtO2kQLuXangze3zy?= =?us-ascii?q?RokzE1qaqSxDbOzPn/exccNW5LQWZjgU3qIYeqk9AQRFKoYBQxlBu5+Ub6wLBW?= =?us-ascii?q?pL9xL2nJRkdIZDT2Inp5Uqu2sbqDbctP54kusSlNVuSzf0yaQKbnoxQGyyPjA3?= =?us-ascii?q?dexDcjejCkoJr5mwB6h3yHLHZot3fZZ99/xQ3E69zBQP5dxD0GRDN3iTPPHFiz?= =?us-ascii?q?I8Gp/cmIl5fEqu2+S3+uWYBScSbxyYONrze05WpvARKjhf+zgcHnHRI80SDly9?= =?us-ascii?q?lgTT/IowrkYon3y6S6NvpqfldpBFDg98p6HZt+npEsi5EQ3ngagJqV8GEDkWfy?= =?us-ascii?q?N9VUw7j+bH0XST4M2d7V7xDv2Fd/IXKR24L5SnKdz9NlZ9m7eWMWxjsx79tUB6?= =?us-ascii?q?eQ7bxEmzZ1o1WjoALKefh9nzEdyfoy534Bme0JvhQizjmFCLAIAUZYJTDslwiP?= =?us-ascii?q?792mtqVXY2Kvcbyu20pkgd+hC7+DrxpHWHbkZpgiBjV87sJlMFLDyHfz8J3reM?= =?us-ascii?q?HMbdIPsR2Ziw/AgPJIKJI1jPYFnzBrNnn6vX0h1+47ihpu0Iq/vISbLWVt+762?= =?us-ascii?q?DgReNjLre8MZ4ivtgrpGnsaKw4CvGY1sGjYVU5vuVvKlCzESuurhNwaVFj0ztG?= =?us-ascii?q?ubFaDYHQ+F50dst2jPHIyzN3GLOHkZys1vRAGHK0xChAAbQi06kYQ/FgC22sPh?= =?us-ascii?q?alx05i0K5lHmsBtM0fhkNwL4UmfCvgendik7SJaYLBpM4QFN+V3ZMcqA4eJvBy?= =?us-ascii?q?tY5IGurBSRKmyHYARFFX8JWkqZCF34ILmu48TP8+iCCuq4MfTOfa2EqfZCWPeQ?= =?us-ascii?q?2ZKvzoxm8i6UNsqVI3liC+Y21VZCXXBlG8XVgjsPRDYRly7XaM6bvhi88DVtrs?= =?us-ascii?q?+j6PTrRB7v5YyXBrtRMdRv/w65jLyGN+6XiiZ5JyhX1o8QxX/Iz7gf2UAdhzto?= =?us-ascii?q?dzazDbQKrTTNQ77Imq9LEx4bbDt+NMVS4KI6wglNPsvbh8j71rFmk/E1DE1FWk?= =?us-ascii?q?b5msGzYswKIX+yO0/bBEqRM7SGPzLLydntYaygUb1QkPlUtxqotDaBCUPiMC6P?= =?us-ascii?q?lzzzWBCrNuFNjDqWMwZCt4G4aBptDnLjTN3+YB2hLNB3lSE2waEzhn7SO24cKy?= =?us-ascii?q?ZzfF5WrrKK6yNYnvJ/G3da43V/MeaEnjyV7+7CKpYZqfFrGDh7l/pG4HQmzLtY?= =?us-ascii?q?9CdEROZvlyvKtt5juF+mkuiVyjp8TBpOpDdLhISRskVkJarZ94NPWXLe8BIK92?= =?us-ascii?q?WQBAwAp8F5Bd33p6BQ1t/PmbroJzhZ9N7U+cocB9PIKMKcKnYhKgTmFyLOAAse?= =?us-ascii?q?UzGrMWDfh0pAkPCd7XCaspg7qoLxmJoVULNaWkY6Fu8BCkRiGtwOOpB3Xikrkb?= =?us-ascii?q?SDls4H+WK+rAXNRMVdpp3HUPOSAfHrKDmHlrlJfAEHzq3iLYQULIH73FZialZi?= =?us-ascii?q?loTQB0XQRcxNojFmbgIsu0pN8Xd+Tmo120/+dwyi/mQcFf+ukR4wkAd+Zv4t9D?= =?us-ascii?q?j06VctOlXKvDcwkFU2mdj9mz+RfyT+LLmuUoxNDCr0r1Y+MpX+QwlvbA2ymVdr?= =?us-ascii?q?NDDLRr5LiLtgb29rghfGuZRTAf5cUbFEYBgIyPGLYPUo1E5Qqj+gxU5G++TFD4?= =?us-ascii?q?BtlBEtcZGyrHJNwB5sbNkwJaPMPqVJ1URQiriIviC2yuA72BUeKFoV8GOOZC4I?= =?us-ascii?q?v1QFNr84KCWy+uxh8g+CmzxYeGgQTfUqpOlq9kA8O+iaySLvzaJDIFirN+ODN6?= =?us-ascii?q?OZp3TAlcmQT1MqyEwIjFdK8qJs0cg/c0qZTFsgzLqLFxsUMsrCJxlVb9BM+3nT?= =?us-ascii?q?ZyqOt/vCwY5tNYWnCu/oVfOOtLoTgk+8AQkmBZoM7sUcEZm3y0zXN93nLKQCyR?= =?us-ascii?q?Qj/wTkOkmKDOlTeBKKjDcGo9uzzJlp0olBPjsdG3lyMT2r5rbLoQ8nmOeMXMwo?= =?us-ascii?q?bXgAUYsELGg5WNOhli5CpXtADyS30vgDxwSY6z/8uyLQAyPmb9Z6ePeUYhBsCd?= =?us-ascii?q?Gx+Tkl9ai5l0LX+I3EJ27mLdRipsPP6eQCqpaDDPNUV6dys0HdmolfXHGqXGjP?= =?us-ascii?q?EcOvK5j3cYksYsT+CmymXVynlzI1U8DxMc62LqeWhQHoRIBUsJSU3T04KcC9ET?= =?us-ascii?q?QeFAtqqOEY+KJwfwsDbIQnYRTwrQQxK7S/IBuE0tWpW2uiNCdZT/xYzeW8e7xb?= =?us-ascii?q?0jEhbvGkx3s6T5E7zu638UgXSJEMkB7e2e6pZ5NCXijrBnxdZwLPqDI6l2h7Nu?= =?us-ascii?q?c92OE/wA/IsVQHPDCLc/RpZ3Bes9E6G1ySPW18CnAkSF+EkYrD/gms0qgO/ytc?= =?us-ascii?q?mtZU1vFFsHj+v5LEfT2sWayqpo/OvCY6a9gpvbFxO5T5IsSarJPegiDfTJ7Ivw?= =?us-ascii?q?2KSi61DfxamsRLLSJZR/lJl2clOdAGuYVf6EoxUNs+KKJVCKU2oLCldyZkBzYI?= =?us-ascii?q?zSAFT4OAwCACguCk1rTAkheQcYgtPwIcv5VHgtodVSl2YiUEq6K4TIrWlnWLSm?= =?us-ascii?q?4SLAcd8ARA/gQAmZFsfur9+orHUIdMyyJKo/JzSibEDYdn913gR26MnFf4Vuuu?= =?us-ascii?q?k/ay3Q1I1vLt0sMXWBllCUhS3+xWjFcnKKlrK6kMuY7HqiWIdUX7vG3xyOumI1?= =?us-ascii?q?1RydbMeVPhEYTLr3bxXCoH9HIIQo9PzW3QGo4JkwplcqoroktDIJy+cEbk+zMk?= =?us-ascii?q?35hpH6W/Vc2z21klr2wJSDuxHtVdDOFmtFbXWDx7bJCxtJXqJYldQm9K9J2asV?= =?us-ascii?q?dZn11nMzSlxppEN8FN/jkMUSBVoTqHptuyT9ZM1NRqD58WONh/pWnyGKdFOJiX?= =?us-ascii?q?rH02vr3vynDZ+zAgvle13i+zG6qiQ+Jf4WIeBh0jJ36CpUk3E+ss7mDS/0jDs1?= =?us-ascii?q?xu4+hbBrmPjUBwoDlnHZBDHTdJ2m67IFttVnVGtP9aKKvNecxGX/YyfQOvOwA5?= =?us-ascii?q?FfM+x0yJ+kV0km3jYy18sQta/y7dUhIxVSkShbftgiMRpd29OT8dUJJIdjQhby?= =?us-ascii?q?HKKw6BniBXphlfYVlwW58FGtZF560b3YxM88XYU0asNCcFUAZhNg8j0PpflE9D?= =?us-ascii?q?sFmDdizHCwqna+rPuAVtfciNtM6pMOj5/ABfh4P7t+A48r4OR2G6lQ2oWt/StY?= =?us-ascii?q?n8ucOWtkGWbqf3L/W8YWPdTDjLlR2wha0rD4PQ8CjXLQVWMIR1xmQ8YZj5F2HL?= =?us-ascii?q?OQpJJ7gBK0pcT6B6Zs1MovpGaM98ZKYJ5ahtCwqFRhPoBoOit+RJIUjIRTvANS?= =?us-ascii?q?WB7vKwrp/J4bzbV+fgetSGx2zbTKJvIpd69T77Fq/x3o9Q5kX6xvVg+l50RFXd?= =?us-ascii?q?Ly+Bq9HhKR8R68m5akvupJspEi3KAJ1oinri2llAd9YLQy2t6JkY0o1W52vwSe?= =?us-ascii?q?1izkj+q+lS97566YYp/bxm1cC0KrrMJvhAt09oHASUDB1w9poxGGh/W3xRYugJ?= =?us-ascii?q?JffJZqQZkdrhpP3rF6EM8x2V/PFZacHbKE7fnMm/FiucRgZAnAsbrj4aNASc3e?= =?us-ascii?q?afm6BoUcalufT52kU17liiNB4J0q5i6pqf96qVoO/XcwHRwqIaWqjrQcPzqqoj?= =?us-ascii?q?u1+I6f0jjr4OdXR/Yxe7H+gFSs4d2mDgwLgvzS02F8PDG6zv+OJfV30jhD3tgJ?= =?us-ascii?q?Z9EEsKGvMPAbWE55xekXkil+zfKNIWbrhImnyTGh68Dr8C1Xmr5jOVIGZ/mBHO?= =?us-ascii?q?1ArwQWep41/otiJ4RDbMz9P/kkpUSra3BF1dXyyyOUNitzOPJgXovsLtuasp9E?= =?us-ascii?q?E2LnDktNWVmWujIrxXGcP/JMabISYpul0al4ExScap2YAAHtqxOtER/29ibvHG?= =?us-ascii?q?8WOkjzdBo7tbh4rZ+syV9ejXHXikj62etbqNwStVxWUmsl4k69CvLPfO68eNQ/?= =?us-ascii?q?Sy2GYbVz1/tBfZXx6ptrzbqEgZOUqP0ErQmYwKONRZ0WM51kHg6ugjWsg89B5C?= =?us-ascii?q?FobaevMNuSzzOCbuwVmBed43UTOe0zRPFFLvDVZ4ALQ82H73vM/RkHfQ/FsoRp?= =?us-ascii?q?V/d0P5nhF3CoQ4Jlgr6FcJ3ioCHw8NaQqYDLGzH0jlK5ULVVQbYxSdwLe6Yrs3?= =?us-ascii?q?3VF0wr634O/Tdul8CqoWO/ZTkAGBgV9bGogMvq0GWrJ8fF1d+7DLqQj+EYTnWO?= =?us-ascii?q?LmlXUoP/2vXs9a6dwZt2cl4gunXBqv84lD4KwUiJ+Wba5JeoPMs9pi70h96j4A?= =?us-ascii?q?aDdNjAJ5jxynTeAWvPrj7cTDsJq09uauU74gR+cW9xgxHGl+ioX/gVA9rtHN1u?= =?us-ascii?q?dcTILVhZ758A9TP36AoJza3AVkKeoSN4Kre65t93QGJicEPX0BIcGba+Ii7C9x?= =?us-ascii?q?Ljrc+0ZOAsQWZdMXJMDNgxxbilX1WLFP8crWAkSXC4Zod8Em9WX3yjE18YckUu?= =?us-ascii?q?n69T+2IYvS4E1KP/xekipjjs/CpPISwfrIEicb+36ZawJ6wima0ZmCF+7w/fmQ?= =?us-ascii?q?yNHTT14GBjQ5U5tBKzqC9w2nQfC1lJbwXgOP9MDzhJM+dESNRn2+h6kFqrxDEf?= =?us-ascii?q?JchSX70DleEZr1h/GPv9qv9mRXrFtHH5h37RHfH6VfJJp7Mwzilsa3Xkh8Gjf/?= =?us-ascii?q?eMbMexoyouqZ2OMM7P94N0TgfoIUPxMEy7376XpJVARuU6T5vkyEXe4LYttpVu?= =?us-ascii?q?/EpGhP6Y18M68PIESdpJvyozdHsl82GhEmaKMwrjFBcknOnRFVVLj0uLEalwsc?= =?us-ascii?q?SsR1uUlSFmKsIGg+/SbIVbxJjKmND/wY6jqTQbIIU0V0NSN+RBS52I5wdLutnP?= =?us-ascii?q?BHtH5GnyxmrfguzTNmXhu9tjf2q6ILxz0g5KmytC8dtnxdUuWejyDIBE1FzPQL?= =?us-ascii?q?kagcDHLi5kanYHUZbYvy575nJd/79YQ65nQybhoiczcBXeS6BCH6l7mIDZCXsN?= =?us-ascii?q?JAmB6Nv93DbbCvIigJLbQx0A/tSXd73AjfmhZo7WQKTy6v7N8hPoq9P9gqyjCv?= =?us-ascii?q?GWjBe1YG+rlJv9fptV4XUOs2bktswGdk0siHQC0BXtDAG2Yxjgg5dGpFcZND6R?= =?us-ascii?q?kBF6krgzaFpbdG/gAKYDjOFoSq54jQkd3O2XYjUddg3njWqbGdhpM2zH1lnMt5?= =?us-ascii?q?7i+QuHsIcezVSMtsAmXu2Ydezuz+fO+hsucdSItp0L6hSuMNMtG/+Wuq35VnQk?= =?us-ascii?q?2lyaoQH1q3NO8O3bnaXD2jSWKGReSHaW6MkCglMkTq/xmnMkU3aNtWr086KubC?= =?us-ascii?q?iZpclwrvULxqQiWQoUTWzHckMeMcdgI5pJ2rewoUQ+4Nf+KcP/QhwOUiCFsQaH?= =?us-ascii?q?/EBSl2C++2sF61m4h7P3Rg4Vnkbun29wDmMceSGgMaHoLAqZ5x4/O6THqbOXB8?= =?us-ascii?q?1B1yIFV09+DHGlQtt+9cdo2cncTRh9tn0u4KafNtPTc7utENhoJp8ZOU39uScR?= =?us-ascii?q?HN0pbyIsnYov2ZA/3czEQqfXpXUrgDbgP24IU6OMA2W7vJEbtfoxscGbAwQIY9?= =?us-ascii?q?OGfp6KF0MARzfxbKa7uqhMnquvmGZoBQp3/R8lIwMDnctAMexfCuSgx7dZ+qjW?= =?us-ascii?q?3oIJ8sXjJBs8FtChx+EYtBBcwAqwunA4aKl6ygit6x+kZ6u+oUvqrqDvDFys61?= =?us-ascii?q?34JrX5hV/UaLJireBLF3gkR5ieS/mvnB0oHrCcPjZdwLSvN2QmvEar/aBIWwNC?= =?us-ascii?q?iCOsXme05J67Scyq52Ug2NZCDlWKqLrCqkNPF67kgg0ox4ePDczCcx77HaxNTy?= =?us-ascii?q?e3tbqTm9onKTMptQ8kDKD/TEXx1IUfqF7HplHaoPYIvw9ecON8EiwdeF7wl37T?= =?us-ascii?q?RCy9eFI7O6o0/NwE17c5XbIFHu2yYjVokAOA6/Plc0gW/FtnTdBmxRLtO6Jslp?= =?us-ascii?q?gdaVCAHt5kZ2lW8iem5BGnTnRc2PNmgDwc2zfw6K+xxRD9YFgeG3fVU3trC9Se?= =?us-ascii?q?VyPZVFg+qqvq0dkdl1MyHPWNRaPybIIb9zJDVeEuXPpFkuYh4DqLU1RIY1ZZ6Q?= =?us-ascii?q?L0MDMUeAzz7yzATY3U3zbdys276DIDwK/XVf07LFzT9MqhG7ufmDgc3jV6vWYY?= =?us-ascii?q?rrXP7ULColVjaaRSk9EUap5VeoofwEs+SEIW0HuFAbfjqSCBIPpqBotdXQDGrT?= =?us-ascii?q?mep5fJ0QhfCaQDv9SCtim6o3GClLtFqAQ/0ZFQnZd3XhmnZTuBS+Jv9Q+nLod6?= =?us-ascii?q?aYxqRQW+MKA4ZBceaUQ8XGdvBEJjcplzIZOOCmc93asbk5zgGAcWxMCKTM9VuD?= =?us-ascii?q?XGaKU/ecwHTtRoxTsI8q6QQy/deFpiJrCezsNquDvTSn+Y7w2D6csPDCTGMkS1?= =?us-ascii?q?Y4jOILHC+KxxwWezJMMM0cpEy4Gv3IXE1Lzn98zLs21g=3D=3D?= X-IPAS-Result: =?us-ascii?q?A2D6AgAw6HlZ/wHyM5BcGwEBAQMBAQEJAQEBFgEBAQMBAQE?= =?us-ascii?q?JAQEBgwQoA2RtJ48AkWKMS4pZJQOJB1cBAQEBAQEBAQIBaiiCMySCQgMDAQJ5A?= =?us-ascii?q?wkBARcxCAMBUxkFiFiBRQ0Dsk0iAotPgyiDTYFhgnCLGwEEiWOHA48Ah0+MSQ2?= =?us-ascii?q?CDFeIPygMhmaJU4MDiRxXgQpTJBVJhxt0igABAQE?= Received: from unknown (HELO tarius.tycho.ncsc.mil) ([144.51.242.1]) by EMSM-GH1-UEA10.NCSC.MIL with ESMTP; 27 Jul 2017 13:20:11 +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 v6RDJb7r001728; Thu, 27 Jul 2017 09:19:46 -0400 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 v6RDJZAc064886 for ; Thu, 27 Jul 2017 09:19:35 -0400 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 v6RDJYcI001726 for ; Thu, 27 Jul 2017 09:19:34 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A1CHAAB353lZl3MWGNZcHAEBBAEBCgEBg?= =?us-ascii?q?y8oZ20njwCRYoxLil0khSMCg2JXAQIBAQEBAQITAQEBAQEGGAaFcAMDeRBRVxm?= =?us-ascii?q?IXYFFDQOyUotBAQEIKIMog02BYYJwixsFiWOHA48Ah0+MSQ2CDFeIPzSGZolTg?= =?us-ascii?q?wOJHIFhUyQVSYUmgXV0igABAQE?= X-IPAS-Result: =?us-ascii?q?A1CHAAB353lZl3MWGNZcHAEBBAEBCgEBgy8oZ20njwCRYox?= =?us-ascii?q?Lil0khSMCg2JXAQIBAQEBAQITAQEBAQEGGAaFcAMDeRBRVxmIXYFFDQOyUotBA?= =?us-ascii?q?QEIKIMog02BYYJwixsFiWOHA48Ah0+MSQ2CDFeIPzSGZolTgwOJHIFhUyQVSYU?= =?us-ascii?q?mgXV0igABAQE?= X-IronPort-AV: E=Sophos;i="5.40,419,1496116800"; d="scan'208";a="264" Received: from emsm-gh1-uea10.ncsc.mil ([214.29.60.34]) by goalie.tycho.ncsc.mil with ESMTP; 27 Jul 2017 09:19:31 -0400 IronPort-PHdr: =?us-ascii?q?9a23=3AQyejqhAUfyBjSHZ3KcSiUyQJP3N1i/DPJgcQr6Af?= =?us-ascii?q?oPdwSPv9oMbcNUDSrc9gkEXOFd2CrakV26yL4uu9CCQp2tWoiDg6aptCVhsI24?= =?us-ascii?q?09vjcLJ4q7M3D9N+PgdCcgHc5PBxdP9nC/NlVJSo6lPwWB6nK94iQPFRrhKAF7?= =?us-ascii?q?Ovr6GpLIj8Swyuu+54Dfbx9GiTe5Yr5+NhW7oAHeusQWhYZpN7o8xAbOrnZUYe?= =?us-ascii?q?pd2HlmJUiUnxby58ew+IBs/iFNsP8/9MBOTLv3cb0gQbNXEDopPWY15Nb2tRbY?= =?us-ascii?q?VguA+mEcUmQNnRVWBQXO8Qz3UY3wsiv+sep9xTWaMMjrRr06RTiu86FmQwLuhS?= =?us-ascii?q?waNTA27XvXh9RtgqxbvhyvqR9xzIzaYIyOKPZyYrnQcc8GSWZdQspcUTFKDIOm?= =?us-ascii?q?b4sICuoMJfxWoJfhp1sUsBCwAxOjBP7zyj9SnXD5x7E10+Q8GgzBxAwgG8gBsG?= =?us-ascii?q?nIrNXvL6gdS/u4zLPWwjreb/NZwyv95JLUfRAmpPGBRLR9etffx0koEgPKlFSQ?= =?us-ascii?q?qYr9MjKbzOQNsnSb4PR6WeK0i24qrRx6rDu3xso0lIXFm40Yxkra+Sh22oo5O8?= =?us-ascii?q?O0RFRmbdK5EJZcrz+WO5dyT884Xm1ltjg2xqcbtZO4ciUG0ooryh3ZZveaaYaH?= =?us-ascii?q?+AjjW/yUITpghHJqZra/hxGq/Ei9ye3zSM203EtOoypdiNbAqGwB2wbN5ceZT/?= =?us-ascii?q?t95Uih1SyK1w/J6+FEJVo4la/aK54l2rIwl5wTvlrfHiLuhkn6kaCbel869uWn?= =?us-ascii?q?8ejrfKvqqoWBO4NpigzyKqEulda+AeQ8PAgORW+b+eGk2b37+U32WqhKjuEskq?= =?us-ascii?q?bCqp/XPt4bqbCkDA9VyIkj9wyzACuh0NQdhXUHNk5KeAqbj4j1PFHDOOv4Aum7?= =?us-ascii?q?g1Stljdr2v/HM6b9ApTNMnfDkLDhcax7605H0gU/199f55VKCuJJHPWmQUL1td?= =?us-ascii?q?rFHjclIge0xKDhE9w72YQACkyVBarMCK7Oqxes7/8zOeOFb49d7C75IuU5/fTn?= =?us-ascii?q?pWU0lV8UYe+i2p5BOyPwJehvP0jMOSmkudwGC2pf5gc=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0CHAAAE53lZl3MWGNZcHAEBBAEBCgEBF?= =?us-ascii?q?wEBBAEBCgEBgwQoZ20njwCRYoxLil0khSMCg2JXAQEBAQEBAQECARIBAQEBAQY?= =?us-ascii?q?YBleCMyKCRAMDeRBRVxmIXYFFDQOyUItBAQEIKIMog02BYYJwixsFiWOHA48Ah?= =?us-ascii?q?0+MSQ2CDFeIPzSGZolTgwOJHIFhUyQVSYUmgXV0igABAQE?= X-IPAS-Result: =?us-ascii?q?A0CHAAAE53lZl3MWGNZcHAEBBAEBCgEBFwEBBAEBCgEBgwQ?= =?us-ascii?q?oZ20njwCRYoxLil0khSMCg2JXAQEBAQEBAQECARIBAQEBAQYYBleCMyKCRAMDe?= =?us-ascii?q?RBRVxmIXYFFDQOyUItBAQEIKIMog02BYYJwixsFiWOHA48Ah0+MSQ2CDFeIPzS?= =?us-ascii?q?GZolTgwOJHIFhUyQVSYUmgXV0igABAQE?= X-IronPort-AV: E=Sophos;i="5.40,419,1496102400"; d="scan'208";a="487777" X-IronPort-Outbreak-Status: No, level 0, Unknown - Unknown Received: from ukel19pa20.eemsg.mail.mil ([214.24.22.115]) by EMSM-GH1-UEA10.NCSC.MIL with ESMTP; 27 Jul 2017 13:19:30 +0000 X-EEMSG-check-005: 0 X-EEMSG-check-006: 000-001;8cba4c72-81ac-4b14-b923-624ce4daa8d0 Authentication-Results: ukel19pa19.eemsg.mail.mil; dkim=neutral (message not signed) header.i=none X-EEMSG-check-008: 244109626|UKEL19PA19_EEMSG_MP12.csd.disa.mil X-EEMSG-SBRS: 3.5 X-EEMSG-ORIG-IP: 209.132.183.28 X-EEMSG-check-002: true X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0BTAACW5XlZhxy3hNFcHAEBBAEBCgEBgy8oAWZtJ44Nc5FijEuIS4ISJIUjAoNiPxgBAgEBAQEBAQETAQEBCA0JCCgvhRkDA3kQUVcZiF2BRQ2yTotBAQEIKIMog02BYYJwixsFiWOHA48Ah0+MSQ2CDFeIPzSGZolTgwOJHB+BQlMkFUmFJoF1PjaKAAEBAQ X-IPAS-Result: A0BTAACW5XlZhxy3hNFcHAEBBAEBCgEBgy8oAWZtJ44Nc5FijEuIS4ISJIUjAoNiPxgBAgEBAQEBAQETAQEBCA0JCCgvhRkDA3kQUVcZiF2BRQ2yTotBAQEIKIMog02BYYJwixsFiWOHA48Ah0+MSQ2CDFeIPzSGZolTgwOJHB+BQlMkFUmFJoF1PjaKAAEBAQ Received: from mx1.redhat.com ([209.132.183.28]) by ukel19pa19.eemsg.mail.mil with ESMTP; 27 Jul 2017 13:11:19 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 901091B982B for ; Thu, 27 Jul 2017 13:11:14 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 901091B982B Received: from workstation.brq.redhat.com (unknown [10.43.12.46]) by smtp.corp.redhat.com (Postfix) with ESMTP id 600726A307; Thu, 27 Jul 2017 13:11:09 +0000 (UTC) From: Petr Lautrbach To: selinux@tycho.nsa.gov Date: Thu, 27 Jul 2017 15:10:52 +0200 Message-Id: <20170727131053.7962-3-plautrba@redhat.com> In-Reply-To: <20170727131053.7962-1-plautrba@redhat.com> References: <20170727131053.7962-1-plautrba@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Thu, 27 Jul 2017 13:11:14 +0000 (UTC) Subject: [PATCH 3/4] sepolicy: Make manpage and transition faster 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: Errors-To: selinux-bounces@tycho.nsa.gov Sender: "Selinux" X-Virus-Scanned: ClamAV using ClamSMTP SETools4 and Python 3 versions of map() and filter() uses iterators to generates query results and these iterators can't be imply re-used. It makes manpage and transitions operations really slow as they do lot of queries. This patch changes it in the way that it caches results in lists for all types, allow rules and transitions first and use cached results to filter them using Python's filter() function. Before: $ time sepolicy manpage -d httpd_t sshd_t init_t real 0m53.486s user 0m53.171s sys 0m0.054s After: $ time sepolicy manpage -d httpd_t sshd_t init_t real 0m10.532s user 0m10.368s sys 0m0.114s Signed-off-by: Petr Lautrbach --- python/sepolicy/sepolicy/__init__.py | 62 ++++++++++++++++++++++++---------- python/sepolicy/sepolicy/manpage.py | 29 ++++++++++++---- python/sepolicy/sepolicy/transition.py | 8 +++-- 3 files changed, 73 insertions(+), 26 deletions(-) diff --git a/python/sepolicy/sepolicy/__init__.py b/python/sepolicy/sepolicy/__init__.py index 8fa2c2ae..5cfc0715 100644 --- a/python/sepolicy/sepolicy/__init__.py +++ b/python/sepolicy/sepolicy/__init__.py @@ -99,6 +99,7 @@ local_files = None fcdict = None methods = [] all_types = None +all_types_info = None user_types = None role_allows = None portrecs = None @@ -113,6 +114,8 @@ bools = None all_attributes = None booleans = None booleans_dict = None +all_allow_rules = None +all_transitions = None def get_installed_policy(root="/"): @@ -168,10 +171,10 @@ def info(setype, name=None): q.name = name return ({ - 'aliases': map(str, x.aliases()), + 'aliases': list(map(str, x.aliases())), 'name': str(x), 'permissive': bool(x.ispermissive), - 'attributes': map(str, x.attributes()) + 'attributes': list(map(str, x.attributes())) } for x in q.results()) elif setype == ROLE: @@ -181,8 +184,8 @@ def info(setype, name=None): return ({ 'name': str(x), - 'roles': map(str, x.expand()), - 'types': map(str, x.types()), + 'roles': list(map(str, x.expand())), + 'types': list(map(str, x.types())), } for x in q.results()) elif setype == ATTRIBUTE: @@ -192,7 +195,7 @@ def info(setype, name=None): return ({ 'name': str(x), - 'types': map(str, x.expand()), + 'types': list(map(str, x.expand())), } for x in q.results()) elif setype == PORT: @@ -220,7 +223,7 @@ def info(setype, name=None): return ({ 'range': str(x.mls_range), 'name': str(x), - 'roles': map(str, x.roles), + 'roles': list(map(str, x.roles)), 'level': str(x.mls_level), } for x in q.results()) @@ -362,17 +365,26 @@ def search(types, seinfo=None): def get_conditionals(src, dest, tclass, perm): tdict = {} tlist = [] - if dest.endswith("_t"): - allows = search([ALLOW], {SOURCE: src, TARGET: dest, CLASS: tclass, PERMS: perm}) - else: - # to include attribute - allows = search([ALLOW], {SOURCE: src, CLASS: tclass, PERMS: perm}) - for i in allows: - if i['target'] == dest: - allows = [] - allows.append(i) + src_list = [src] + dest_list = [dest] + # add assigned attributes + try: + src_list += list(filter(lambda x: x['name'] == src, get_all_types_info()))[0]['attributes'] + except: + pass try: - for i in map(lambda y: (y), filter(lambda x: set(perm).issubset(x[PERMS]) and x['boolean'], allows)): + dest_list += list(filter(lambda x: x['name'] == dest, get_all_types_info()))[0]['attributes'] + except: + pass + allows = map(lambda y: y, filter(lambda x: + x['source'] in src_list and + x['target'] in dest_list and + set(perm).issubset(x[PERMS]) and + 'boolean' in x, + get_all_allow_rules())) + + try: + for i in allows: tdict.update({'source': i['source'], 'boolean': i['boolean']}) if tdict not in tlist: tlist.append(tdict) @@ -734,6 +746,11 @@ def get_all_types(): all_types = [x['name'] for x in info(TYPE)] return all_types +def get_all_types_info(): + global all_types_info + if all_types_info is None: + all_types_info = list(info(TYPE)) + return all_types_info def get_user_types(): global user_types @@ -1018,12 +1035,23 @@ def gen_short_name(setype): short_name = domainname + "_" return (domainname, short_name) +def get_all_allow_rules(): + global all_allow_rules + if not all_allow_rules: + all_allow_rules = search([ALLOW]) + return all_allow_rules + +def get_all_transitions(): + global all_transitions + if not all_transitions: + all_transitions = list(search([TRANSITION])) + return all_transitions def get_bools(setype): bools = [] domainbools = [] domainname, short_name = gen_short_name(setype) - for i in map(lambda x: x['boolean'], filter(lambda x: 'boolean' in x, search([ALLOW], {'source': setype}))): + for i in map(lambda x: x['boolean'], filter(lambda x: 'boolean' in x and x['source'] == setype, get_all_allow_rules())): for b in i: if not isinstance(b, tuple): continue diff --git a/python/sepolicy/sepolicy/manpage.py b/python/sepolicy/sepolicy/manpage.py index 7f17ba29..6df6f431 100755 --- a/python/sepolicy/sepolicy/manpage.py +++ b/python/sepolicy/sepolicy/manpage.py @@ -938,7 +938,11 @@ selinux(8), %s(8), semanage(8), restorecon(8), chcon(1), sepolicy(8) return True def _entrypoints(self): - entrypoints = [x['target'] for x in sepolicy.search([sepolicy.ALLOW], {'source': self.type, 'permlist': ['entrypoint'], 'class': 'file'})] + entrypoints = [x['target'] for x in filter(lambda y: + y['source'] == self.type and y['class'] == 'file' and 'entrypoint' in y['permlist'], + sepolicy.get_all_allow_rules() + )] + if len(entrypoints) == 0: return @@ -980,15 +984,23 @@ For example one process might be launched with %(type)s_t:s0:c1,c2, and another """ % {'type': self.domainname}) def _writes(self): - permlist = sepolicy.search([sepolicy.ALLOW], {'source': self.type, 'permlist': ['open', 'write'], 'class': 'file'}) + # add assigned attributes + src_list = [self.type] + try: + src_list += list(filter(lambda x: x['name'] == self.type, sepolicy.get_all_types_info()))[0]['attributes'] + except: + pass + + permlist = list(filter(lambda x: + x['source'] in src_list and + set(['open', 'write']).issubset(x['permlist']) and + x['class'] == 'file', + sepolicy.get_all_allow_rules())) if permlist is None or len(permlist) == 0: return all_writes = [] attributes = ["proc_type", "sysctl_type"] - for i in permlist: - if not i['target'].endswith("_t"): - attributes.append(i['target']) for i in permlist: if self._valid_write(i['target'], attributes): @@ -1187,7 +1199,12 @@ The SELinux user %s_u is able to connect to the following tcp ports. """ % ",".join(ports)) def _home_exec(self): - permlist = sepolicy.search([sepolicy.ALLOW], {'source': self.type, 'target': 'user_home_type', 'class': 'file', 'permlist': ['ioctl', 'read', 'getattr', 'execute', 'execute_no_trans', 'open']}) + permlist = list(filter(lambda x: + x['source'] == self.type and + x['target'] == 'user_home_type' and + x['class'] == 'file' and + set(['ioctl', 'read', 'getattr', 'execute', 'execute_no_trans', 'open']).issubset(set(x['permlist'])), + sepolicy.get_all_allow_rules())) self.fd.write(""" .SH HOME_EXEC """) diff --git a/python/sepolicy/sepolicy/transition.py b/python/sepolicy/sepolicy/transition.py index ad53cef7..7dea8059 100755 --- a/python/sepolicy/sepolicy/transition.py +++ b/python/sepolicy/sepolicy/transition.py @@ -30,7 +30,9 @@ def _entrypoint(src): def _get_trans(src): - return sepolicy.search([sepolicy.TRANSITION], {sepolicy.SOURCE: src, sepolicy.CLASS: "process"}) + src_list = [src] + list(filter(lambda x: x['name'] == src, sepolicy.get_all_types_info()))[0]['attributes'] + trans_list = list(filter(lambda x: x['source'] in src_list and x['class'] == 'process', sepolicy.get_all_transitions())) + return trans_list class setrans: @@ -53,8 +55,8 @@ class setrans: if not self.dest: self.sdict[source]["map"] = trans else: - self.sdict[source]["map"] = map(lambda y: y, filter(lambda x: x["transtype"] == self.dest, trans)) - self.sdict[source]["child"] = map(lambda y: y["transtype"], filter(lambda x: x["transtype"] not in [self.dest, source], trans)) + self.sdict[source]["map"] = list(map(lambda y: y, filter(lambda x: x["transtype"] == self.dest, trans))) + self.sdict[source]["child"] = list(map(lambda y: y["transtype"], filter(lambda x: x["transtype"] not in [self.dest, source], trans))) for s in self.sdict[source]["child"]: self._process(s)