From patchwork Wed May 30 14:11:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Enderborg X-Patchwork-Id: 10439083 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 AB25060327 for ; Wed, 30 May 2018 14:21:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6F488290A3 for ; Wed, 30 May 2018 14:21:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 69FFC28FAB; Wed, 30 May 2018 14:21:47 +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=-5.2 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from upbd19pa10.eemsg.mail.mil (upbd19pa10.eemsg.mail.mil [214.24.27.85]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DCF7729060 for ; Wed, 30 May 2018 14:21:25 +0000 (UTC) Received: from emsm-gh1-uea11.ncsc.mil ([214.29.60.3]) by upbd19pa10.eemsg.mail.mil with ESMTP; 30 May 2018 14:21:23 +0000 X-IronPort-AV: E=Sophos;i="5.49,460,1520899200"; d="scan'208";a="13920464" IronPort-PHdr: =?us-ascii?q?9a23=3A4QnixhG3+7Xt2k7mlQgna51GYnF86YWxBRYc79?= =?us-ascii?q?8ds5kLTJ7+rsq7bnLW6fgltlLVR4KTs6sC17KL9fi4EUU7or+5+EgYd5JNUx?= =?us-ascii?q?JXwe43pCcHRPC/NEvgMfTxZDY7FskRHHVs/nW8LFQHUJ2mPw6arXK99yMdFQ?= =?us-ascii?q?viPgRpOOv1BpTSj8Oq3Oyu5pHfeQpFiCa9bL9oMBm6sRjau9ULj4dlNqs/0A?= =?us-ascii?q?bCrGFSe+RRy2NoJFaTkAj568yt4pNt8Dletuw4+cJYXqr0Y6o3TbpDDDQ7KG?= =?us-ascii?q?81/9HktQPCTQSU+HQRVHgdnwdSDAjE6BH6WYrxsjf/u+Fg1iSWIdH6QLYpUj?= =?us-ascii?q?m58axlVAHnhzsGNz4h8WHYlMpwjL5AoBm8oxBz2pPYbJ2JOPZ7eK7Sc8kaRW?= =?us-ascii?q?5cVchPUSJPDJ63Y48WA+YcIepUqo/wrEYMoxSjHwmhHOPhxCFGiHH12qM10e?= =?us-ascii?q?ohHg7b0gw4Hd8CrXrZo8n6OqgMSuC417XIwDfZYv9Kwzrx9JbEfxY8qv+MR7?= =?us-ascii?q?Jwds/RxFE1GQzbklWft5blNC6a2OQLrmeU8fBgWvmoi249pAF6vz+ixt8yhY?= =?us-ascii?q?nVmI0V0ErI+jt/wIkoO9K4UlV0Ydm+EJtfrCyaLIx2QsUiQm1ypCk6zbgGtI?= =?us-ascii?q?e9cSMXy5on3wbSZ+GIfoWH+B7uVPudLS1miH9qZr6znQu+/VCux+D+TMW4zV?= =?us-ascii?q?hHoy5fntXRtn0A1gbf5taDR/Z740yvwyyA1xrJ5eFBOU00kK3bJIM/zbMojZ?= =?us-ascii?q?oTtFjDHjfxmEXrkK+abkUk9fas6+TgerjmuoWTN5V1igHjKaQigNC/AOQkPQ?= =?us-ascii?q?gOWGiX4+K826H4/ULlWrlKi/w2kq3BvJDbI8QUuLK5DhdI3oss5BuzFTer3M?= =?us-ascii?q?kCkXUZI19JZgiLg5XxN1HLOv/4DPO/g1q2kDdswvDLJqbhDYvJLnjClrfhYL?= =?us-ascii?q?l851dHxwo00NBf4Y5bBa8aIP/oRk/wtMDXDh8+MwCuxebnE89y2pkRWWKIHK?= =?us-ascii?q?+VKLnSvkOQ5uIzP+mMY5cYuDT6K/gj/fHukX85lkUbfaSy35sXb3a4HvF8LE?= =?us-ascii?q?WCfXrjnM0BEXwQsgo5Vuzqh0WIUSRPaHaqQ6I8+jY7BZqkDYfBXI+inL+B3D?= =?us-ascii?q?y8Hp1QZ2BGFEuBEXnsd4WZVPYDcz+SIsl9kjwZT7ShTJUh1R62vg/g17VnNv?= =?us-ascii?q?bU+jEftZ/7zNh6+fbcmg809Tx1E8Sd1HqAT2BqkWwWWTA6xqd/oVZyyl2by6?= =?us-ascii?q?h3n+RYFcBP5/NOSgo1KJncz+p8C9/vRA3BetaJRU28Tdq4GzExScg9w9gUY0?= =?us-ascii?q?ZyA9+ilAzM3zK2A78JkLyGHIE78r7G0HjrPMty13HG1Kw9gFY8WctPKXeqhq?= =?us-ascii?q?hh+AjPH4TJiVmWl762daQA2y7A7GaDzWySvE5GVA5/T6DFUm4DZkvMrdX0/U?= =?us-ascii?q?TCT6ewBrQhNwtO08+CKq9RZd3uglRKXvDjOM7RY2ipgWe/GQ6Ixq+QbIrtY2?= =?us-ascii?q?gc0iTdCEwBkw8N53aLLgY+CTm8rGLZFjxhD0rvY1nr8el8tny0UlM0wxuNb0?= =?us-ascii?q?172Lq/4gQViuCES/MPwrIEvz8sqztuHFmn2dLZF9uApxF6caVZedM94U5L1X?= =?us-ascii?q?nXtgxmJJCgKLpihlEGeQRto0zuzwl3CplHkcUyr3Ml1glyKaWF0F5adDOXx5?= =?us-ascii?q?PwOrrKKmXo+xCvcaHW0EnE0NmK4qcP9Og4q1L7sQ6zC0Ui6XRn3MdP03aH/J?= =?us-ascii?q?rFEA8SXYj2UkYt+Bhwv6vabTUl54PIyX1sNrG5vSPY1NItGuQl0QqgftdYMK?= =?us-ascii?q?6fDw/9D8waCNaoKOw2mlimdAgIPOZM+64oJ8mmbeeJ2La3POZ8mzKrlX5H75?= =?us-ascii?q?1g3U+X+Cp8T+HJ04wDw/6GwguNTy38g0u5ssDrhYBEYikfHnGxySj+A45Rfb?= =?us-ascii?q?FycJ0QCWeoJM22yNB+iITrW3JC8l6sGU8G0tezeRWOd1z9wRFQ1UMPrH2pgy?= =?us-ascii?q?S4yyB0nC8zrqqExyHO3frtdAAcNW5WQWlul1DsIZK7j9oCRkincxAplAe55U?= =?us-ascii?q?b936VbuqV/IHXPQUdPZSj6NX1tUqu3trqEbM5C85cosSRRUOume1CaTaTxox?= =?us-ascii?q?wA0yPsB2Fe3iw0dym2upXlmBx3kGadLHdorHrFYM1w3gnQ5NjdRf5XwzoHSz?= =?us-ascii?q?J1iSLPBli9Odmp/Mmbl4zZvuC4SW2hSoVZcTP3woOYqCu7+WpqDAWln/C0nt?= =?us-ascii?q?3nFRY10TXn2NltWyTFtw38YpT32KShK+5neVNoBFDk4cpgBo5+ipcwhI0X2X?= =?us-ascii?q?UChZWa43wHkXzoPNVYx63+amENRTgVzN7J+gTl31djLn2RzYLjSnqd2tdhZ8?= =?us-ascii?q?W9Ym4OwiIy9d1KCKOK47xchyR1pEa4ohzLYfVmgzcd0uUh6GQBg+0TowotyT?= =?us-ascii?q?idAqoOEkZGMyzskA6I79+go6lNYmagb6Sw3lJknd+9FLGCvh1cWHHhd5c8Gy?= =?us-ascii?q?9/895yMEzK0HLu6oHoYt/QYswPtheMiRfPk/BVKI4tlvoNnSdnIXjyvWAhy+?= =?us-ascii?q?MgkRNu3I26vYieJ2Vj5q25BARUNjrvZ8Mc4jvtl7pRnt6K34CzGZVsAjYLXZ?= =?us-ascii?q?vsTf22Cz8SsPPnNwiAEDIitnebBbrfHQia6Eh4tX7PFY6kN22PLnkD0dpiXA?= =?us-ascii?q?WdJFBYgA0MUjU1hJg5FhytxMzka0p56C4e6UP/qhtW0O1oLwP/UmDdpAi2dj?= =?us-ascii?q?g0VIKTLB1M7gFN/03VK9CR7vpvHyFE+Z2stBGCJXCeZwRPC2EJRlGICkv9Pr?= =?us-ascii?q?aw/9nA8umZBu24L/fUZ7WBt/BeXe+SxZ2zyotm4yqMNsKXM3lsFf00xFdMXW?= =?us-ascii?q?tjFMTfhzUPTDcXmjnXYMGHoRew4Cp3rtqw8P7zQgLg+ZOPC6dOMdVo4x22h7?= =?us-ascii?q?2DOPSIhCZhMjtY2JIMxWXTyLgD0l4SiidueCOrEbsctC7CVqbQlrVQDx4BZC?= =?us-ascii?q?N5LNFI4L4k3glRJc7bjcv42aVjgfIyD1dFVEfhmt2yZcAQOGGyKk/ICFyQNL?= =?us-ascii?q?uYIT3Lwsf3Yb6zSLBLkOpVtwewuSuAE0P5MDWMjSXpVwuoMeFKli2bOwZeuI?= =?us-ascii?q?6leBZ3FWfjVM7magG8MNJviz02wLk0hnfUOm4HKjVzaV1CrqeX7S9ChfV/AW?= =?us-ascii?q?NB5GJ/LeaYgyaZ8/XYKpEOvPRwAyR0mOVa4HIhxrRI8i5LX/11lzHUrtJ0pF?= =?us-ascii?q?GmiOaPwCJ9UBVSsjZLmJ6LvUJ6NKrD+ZlPQ2jE8wwW4GWXExQFud1lCtj1tK?= =?us-ascii?q?BRztjAj6XzKThY/9LT58scCNDeKNibP3o5LRrpBDnUARMZTT6sMGHTnVZdkP?= =?us-ascii?q?aT93KLqJg1sYLsmJ0QRb9YT1E6CvQaCkF5E9MYO5d3QikokbiFg84U/XC+tg?= =?us-ascii?q?XeRN1GvpDbUfKfGffvKDaZjLlcYBsIxbL4LZgNOYDg3kxia0V6nJ7UFEbKWt?= =?us-ascii?q?BNuCJhZBcuoEpR6Hh+UnEz20X9ZwOr/nAcD/q0kwU1igt5euQt6C3j41EsJl?= =?us-ascii?q?rJpSs8ik8xlsv5gTqJaj7+ML+wXZ1KCyrzr0UxKI30Qx1rYgKoh0xrKDfESq?= =?us-ascii?q?lKgLthb2BklQjcuZVXGf5GU6JFYAUcxfeJaPU0yV5csDmoxVdb5evZDptvjB?= =?us-ascii?q?YlfoSyr3JBxg1jd8U4KrbKJKpTyVhRiLmOsTG02eAs2g8eJloN8WOIdC4Opk?= =?us-ascii?q?MIKqEsJzC08ex09QyChzxDdXAIV/otuPJl6EU9OuWHzy/73L5DLF2xO/aYL6?= =?us-ascii?q?ODtGjKjdSITU8o1kMUi0lF+qB70dw9fEqQVkAvyqaRFhsSOMXeLgFVatZd+2?= =?us-ascii?q?LIfSaSq+nNx4x6P5mlHODyUeCOrLoUgl6jHAsxA4QM78EBHp6w0EHYLcbqN6?= =?us-ascii?q?MKyRQt5QvxP1qJFvJJdwyXkD0fucGw0Id33ZVBJjEaGWhyKyG35rfLqQA0mP?= =?us-ascii?q?WDWdc3YnEdXosCLH07Q9a1my9DsHRGFTW33P8ZxBKE7zDiuiTaFCP8YMZ7ZP?= =?us-ascii?q?eIeRNsD8m79i4h/KiwklPY6IjRJ3/kOtR4od/A8/kappadB/NTV7l9vF/Wm5?= =?us-ascii?q?NESHyyT27PDdm1KoDqa4kqbNz7Fna6Ulu7izIuV8n/JcujILKUjA/vXotbrI?= =?us-ascii?q?6b3DU/OsCnDTEeBw18p+cd66JgfQcDeYY0YQb0twQiMKyyOBuX0te0TGmxMj?= =?us-ascii?q?ZZU/5fzeG+Z7xW0SUsdPO6x2U8QZE61eW39lQNRJ4ShBHE2fmjf5VeUTT0Gn?= =?us-ascii?q?FFYQXAvzA5l296Oesp3uc/2gnHsUcCPDCPdexpbmNEv9U9BVOdIXV2FmQ4SE?= =?us-ascii?q?WGjYrG+AKs2a4d/zdFldZOzeJFqGT+voPYYD+0Vq2ns4nasyohbdgjoq1+K4?= =?us-ascii?q?/jL9CHtJzAgDPQUoPcsgqfUC61D/BagMRfIDpEQPlUnmEoIckGtpBb6UoySM?= =?us-ascii?q?g+O71PCK8jpr2xZztrFygSwjMdV4OHwTwNn/y816HclhiObJQoKAYEv4lagt?= =?us-ascii?q?sBTy52ZTsTpLekV4XSjWCEUGYKIAAX7QRC/w8Ak4hwfuf+4IXWUJBM0TlWo+?= =?us-ascii?q?lvUivKEJlo+EH3SmaMgVj3UP+hifCm3RpOzPLw1dkWQARwCVJAx+ZQjEcoK6?= =?us-ascii?q?p6K6gRvo7Lrj+Hbln2vGTzx+u6PFNR09Hbd0XkDIrZsmrxSjEc+XoRRYJU1H?= =?us-ascii?q?HTCZESnBFjZKYtulpMPJiselzi6Dw824RpA764WNirx1k/t3YJXSOqHMdaBu?= =?us-ascii?q?57rl3XQCVlbI6vqJr7IZVeWGhQ+IeSq11BikViLza5yYZAK8FK+jMMXj9Pri?= =?us-ascii?q?uGsdSvVsJDwtF5D4UQIthhpnjxAqVEN4aNo3cuoLzg1mfZ+ywgsFe93DizB7?= =?us-ascii?q?K3QP9Y/2IEHgUkPHiRqk4qD+Qw6GjS6UzNvkpy/+hFGriFlV9xryplHpBSGj?= =?us-ascii?q?ZJ0mioIE99THZar+lXKrnZfsJHTvYuYh+vPgAxGuQ930yV5010m2n2YzBqvA?= =?us-ascii?q?tA5y/dRxU0VTUSgrr1gz0RtNyoOT8ARJJUdjghayDFKxyFlixJoBlfbFxlVI?= =?us-ascii?q?4DDtZD5b4bwZNe/tDeRka0NSEFQBtiOxog0fpEiU5MqliXeTzGAAqzcvbPrw?= =?us-ascii?q?d3ctuPo86vMPT55h1Iiof9vOA/7aUDSGWsmRexTtDGs4/8qtqKu1OSdKfiLe?= =?us-ascii?q?Kzf2LOQSPRjRC0mbckFYPF/zbSMApcL5l112YkbYLmCW7RMhRMP7gbKFZDVa?= =?us-ascii?q?BmddVGpfhXZ8p+d6YN/a9iGA6HRg/1F4O1t/RGKEjcRSjFLyqd6OO/uZzc4a?= =?us-ascii?q?bbSef+esyG32zHTL5vPpdm9Tn7HK/n0Y1E9Urs3fdt7Ud6RkLYMy2aqdThOw?= =?us-ascii?q?cL5NWjdkT+v50mBzXWAIxqnHrq3EFAeNIdQze2/5QA1JNZ9HHwRPp60kfptu?= =?us-ascii?q?1S+aNk6Y4q7L930sq0Ob3dKfJBsU9gGBSUABtl9ok1CmhlW29RevMRKOvWfa?= =?us-ascii?q?kBgsDutuH3F6gT6BKL/uxUcsbIKF/alcm+ED6cTwZInAAbqT4VNgGczeKKm7?= =?us-ascii?q?doSca5ouj0wkAt41m7LhMdybBi+4eF9bSSpO/WaRvRwqIIWq70ScPvtr4soV?= =?us-ascii?q?+d5eU4lL4SfWx4ewunEOwGW84cwGfgyLomzSMqE8PNBbLv4uVDV24jnjL9h5?= =?us-ascii?q?99A0gWGukKEraR+oRehGg4kfTDNtIKaqBChnqPFRm8H78Hzn6r7TeXIGZ7jR?= =?us-ascii?q?zV1hHwQHm87Fnooi9kTyrMyM3jkklOVrWtA0ddQTapM1disDyTJAroqMb3ua?= =?us-ascii?q?Mt4UEyKWzksdKAmXCvOLxJAsL/I8acLjMspFINi50xRMKg1pwHGdanJ9cR6n?= =?us-ascii?q?5+ZOPE62y3iy9Bv7tHh43G78GU+/TYB2OvgLGBprWW2j9Y1mY3sk0l5tCnLP?= =?us-ascii?q?HO6MWAQ+602GYJUyd/pwzBUgaupbzatFAVN1aE0EXKmIwWJtFWx2Q41kX96e?= =?us-ascii?q?c/R9I86RtRGZzdZ/MYojDzIiH7zUyYY9ItWSmUyyFXEU7tEVlkBKg833r9vN?= =?us-ascii?q?rTmnfM51IoRodxd0v9hRx0Fok4Mlwi6FwWwioFDAgMZguWDKmyCkT5MYQEVU?= =?us-ascii?q?YCaROd3Li5YKs33lN8wqmp5ODNaexwHa0NNuxSjgSWhlhUBooWsbECQLJ7Y1?= =?us-ascii?q?Jd+7TYphL8BIj7X/jrjn4wNfypQs9E8cAWrWYi4h2lSxqm95hD864RiIqUea?= =?us-ascii?q?5cfZjMoMd84l9o5TERcCxNnB9/jxS+XeAHuu/j5tnbsJy16uehT6stQ/sY9w?= =?us-ascii?q?I0BmtklZfwhk4soc3P3edGVoLVkZj/8BxKI3OSvoba0gVzKe0KK42xZ7Zs7X?= =?us-ascii?q?QHJy8ZJ3IVJtqbcPw87iBiMTnJ4FxCGMwMb8sCPMXRgQBUllHpWLZL+8rUBl?= =?us-ascii?q?CYEJxze9k14WT4zj418J08Uvvv6TKtKpDf6ktCP/Vdgyl2k9LCvucVy+LICC?= =?us-ascii?q?cL+XmZdwR1wiSaxpmPDPbw/eOMxMvIWFMGGi42TppSJTuD+QyhXeq1l5TpXx?= =?us-ascii?q?iK6s/ynpIxbkaQSWGwnKgftKZDD/JAgD3h3jdCDoD1m+6Vs9205WtWqF1ICo?= =?us-ascii?q?Bz4AbBGKVCI5p7OBP4ltKxSkh7HCv/d9nedgAyt+qO2ucM/+J+OlP8ZYAFLB?= =?us-ascii?q?IExbb65GFbTwR0Tr75oEqZUfgXZNR4VPPOtmpV5p54K68TIFido4TnrjhMqF?= =?us-ascii?q?AxDg4mdrswrjhBe0nVmw1VXaf0t6IahgsaT9F5pVdGGXisN2Im+zrHSaNVgb?= =?us-ascii?q?GUCPwU8TWTTasOXl5qMixkQBO135NudKWvnfxdtGNJgD99quAw0zN6XBu8pT?= =?us-ascii?q?Hsp6UV1D075r64sikBtGdeTuWalCfIFUlDzOoUgqgBEXri7ka8YHYbZovo/L?= =?us-ascii?q?ZnPdjg9ZUm43knbxUsYSkGXeW4Cy7ulK6JA42PsNdZhBGTosXOaaG8ITIVNr?= =?us-ascii?q?QnxhLpX2J93RTGnBZ07GsLRS2t7dE8JIWnOMYq2jSnFHPedFYN/qNJqtX+uU?= =?us-ascii?q?QMTOssZlNr2H9j3dSfRi0RWMzPHH44jg8gaWpaa59D8RsaGLMzgjaUv6lJ4h?= =?us-ascii?q?0UYC3KHYu74IXQm9nH2WUlR9dw2m3WvrGFho8t0HB9n9N07yiOuGkdduDBV8?= =?us-ascii?q?9sA2Pz1ptEyeHlZvWiqOYHSIx8xLSmSv8CPdGp+XGq15VyRk+l2rMeEkK8MO?= =?us-ascii?q?AZ2rjbUyalSWufWemQbWiMnjA5PVD25RmpKF03dchLo1U6MuvYiZ5WjxfhXq?= =?us-ascii?q?9sRiWMuV/by3QuMeEAeAI1v4eoYBcHTPMXZ+iAJegux+A+CFQMb3/VByd2Df?= =?us-ascii?q?G5sUK1lohhJ3pg+Vn6Yfjq8g3+MtuSHx4EEZTArp5w4vy3XWSBNmVlzBJsPU?= =?us-ascii?q?l47eDfF04+tuVEaZaegcDQh8hn0e4Cb/ptKiM9utsPlY9i6oSZy9mKfg/Lzp?= =?us-ascii?q?bzJNDVpf6YD+fZz0s0ZmEJGoYeNFft6pk3JJg0XbHeB7Fepxs0Hq88UdoqMG?= =?us-ascii?q?KnsOlMJR53OivWY665yp3yr/+PToNdunuT61U3NiqasBoGnLj8dhB2d5CngT?= =?us-ascii?q?3JJZk0Qj9Q54l2BgBOAJpEG8RGqRGuRZGThvf/w/Kr+kgyg+YQsLG4Xv3S3c?= =?us-ascii?q?64xK1pVoJb/lSPNT3cQq5xjRIhxsa7h/rbmrz2E9njYptQVuF+T3WDbvnDGZ?= =?us-ascii?q?+lKymmPdj1cEpLtbWb1eQ9GjmYYiH0W+KkqTerOfN/qRE3w4p5ce7R5Dkg67?= =?us-ascii?q?XS3tziIWpco3Hn5VKOKZQXyFHGC+vEU1oARf6I/GhiB6E/d4b49O4Sd9clxY?= =?us-ascii?q?7Yq11o4TBD1taVC7SwpU/LnERgfNTUK1W/n25tXYgMPQT6KkYnnHXYtmWYBH?= =?us-ascii?q?NQM8ypAddijczTDRH34UR132Y3aTgFUj7sRNGMKS0Y1ti4aQmi6g1GFZAAkv?= =?us-ascii?q?SxdEp+sbe9H60gcK5Ig+qn/JhP155JIiXLVc4Qd3XLIaV5MxJRB+HLtV5uaR?= =?us-ascii?q?kB5fx9EL88eJzGDQtBeGKL6i70ywbTmwWgb9Wx0KOCIw4S83Na3/Tb1zVQ4Q?= =?us-ascii?q?izvLCShci1A57Da5SjZPPOPTBtezeWSC44FlymsQO8tuYJpryVJ2sSuFoTeC?= =?us-ascii?q?26EwkVt+Zkqt2GXTybovFqYJBf3KPSYCv3UiAt0fNrXnwR50mRX/oOExXXZH?= =?us-ascii?q?b9gW1a/RavPeJI4Wm6NO+l/oZ+AMcuK9IVNPCURsDXP/VXJjNukzQda4PeN9?= =?us-ascii?q?HfrrNs1FXOQCNZFqTT71SRQQaQReDU3DPkW4gZ/sA0tyMk98iWn3pxFKLFMg?= =?us-ascii?q?=3D=3D?= X-IPAS-Result: =?us-ascii?q?A2CuAgANsg5b/wHyM5BcGgEBAQEBAgEBAQEIAQEBAYNBA?= =?us-ascii?q?4EFXBYSjFqMAYMIkzwUgWEmEwGGXiE1FwECAQEBAQEBAgFrKEIOAYFkJAGCT?= =?us-ascii?q?wMDAQIXDRMUIA4DCQEBPgIICAMBLRURBgEHCwUYBIMBggEDAacdM4N4AQGES?= =?us-ascii?q?4FoiDeBVD+BD4dNARIBBwSFaAKHPAiGCosXBwKBZ4xuC40MK5IqATZhcU0jU?= =?us-ascii?q?IJDgiAXjWEBN216AQGIDoRGDheCIQEB?= Received: from tarius.tycho.ncsc.mil ([144.51.242.1]) by emsm-gh1-uea11.NCSC.MIL with ESMTP; 30 May 2018 14:21:22 +0000 Received: from prometheus.infosec.tycho.ncsc.mil (prometheus.infosec.tycho.ncsc.mil [192.168.25.40]) by tarius.tycho.ncsc.mil (8.14.4/8.14.4) with ESMTP id w4UELKfb011821; Wed, 30 May 2018 10:21:21 -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 w4UEDsaP011052 for ; Wed, 30 May 2018 10:13:54 -0400 Received: from goalie.tycho.ncsc.mil (goalie.infosec.tycho.ncsc.mil [144.51.242.250]) by tarius.tycho.ncsc.mil (8.14.4/8.14.4) with ESMTP id w4UEDwhA011095; Wed, 30 May 2018 10:13:58 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A1DPAABYsQ5bly0bGNZcHAEBAQQBAQoBA?= =?us-ascii?q?YNBgWQWEot7jGCDCJM8FIFkhHcCghwhNBgBAgEBAQEBAQIUAQEBAQEGGAaGAAM?= =?us-ascii?q?DGg1iPxJXBgESgyKCBAGnGTODeAEBhEuBaIg3gVQ/gQ+HaASFaAKHPAiGCosXB?= =?us-ascii?q?wKBZ4xuC40MK5IpggpNI4MTgiAOCRGNUAE3bY1QgkYBAQ?= X-IPAS-Result: =?us-ascii?q?A1DPAABYsQ5bly0bGNZcHAEBAQQBAQoBAYNBgWQWEot7jGC?= =?us-ascii?q?DCJM8FIFkhHcCghwhNBgBAgEBAQEBAQIUAQEBAQEGGAaGAAMDGg1iPxJXBgESg?= =?us-ascii?q?yKCBAGnGTODeAEBhEuBaIg3gVQ/gQ+HaASFaAKHPAiGCosXBwKBZ4xuC40MK5I?= =?us-ascii?q?pggpNI4MTgiAOCRGNUAE3bY1QgkYBAQ?= X-IronPort-AV: E=Sophos;i="5.49,460,1520913600"; d="scan'208";a="288406" Received: from emsm-gh1-uea10.ncsc.mil ([214.29.60.34]) by goalie.tycho.ncsc.mil with ESMTP; 30 May 2018 10:13:58 -0400 IronPort-PHdr: =?us-ascii?q?9a23=3Axqa4Bx/MxHSABv9uRHKM819IXTAuvvDOBiVQ1K?= =?us-ascii?q?B+0e8fIJqq85mqBkHD//Il1AaPAd2Graocw8Pt8InYEVQa5piAtH1QOLdtbD?= =?us-ascii?q?Qizfssogo7HcSeAlf6JvO5JwYzHcBFSUM3tyrjaRsdF8nxfUDdrWOv5jAOBB?= =?us-ascii?q?r/KRB1JuPoEYLOksi7ze+/94HTbglSmDaxfa55IQmrownWqsQYm5ZpJLwryh?= =?us-ascii?q?vOrHtIeuBWyn1tKFmOgRvy5dq+8YB6/ShItP0v68BPUaPhf6QlVrNYFygpM3?= =?us-ascii?q?o05MLwqxbOSxaE62YGXWUXlhpIBBXF7A3/U5zsvCb2qvZx1S+HNsDtU7s6RS?= =?us-ascii?q?qt4LtqSB/wiScIKTg58H3MisdtiK5XuQ+tqwBjz4LRZoyeKfhwcb7Hfd4CWG?= =?us-ascii?q?RPXthfWSJCDI27bYQPAeUOMvpDoonhu1cDtweyCBOwCO/zzDJDm3/43bc90+?= =?us-ascii?q?QkCQzIxhIvH84Qv3TOsd77O6ESXv2rw6nS1jrDaOlW2Tjg44XPahAuv+2MUq?= =?us-ascii?q?xqccbL10YvER7KgUuKqYP+ODOVzOsNvnOA7+pnU+Kui3QrpB12ojiq38ohjJ?= =?us-ascii?q?TCiIENyl3c6yl13Yk4KcemREN0e9KoDplduzuVOoZ2Ws8vTWNltDwnxrAIvZ?= =?us-ascii?q?O3ZjUGxZQmyhLFdfCKd46F6Q/5WumLOzd3nndldaq/hxms9UigzfXxWceu3l?= =?us-ascii?q?hEsCdInMfBuGoR2hDP68WLUOVy8Vmk2TaU2ADf8ORELlo1larfMZIhx78wlp?= =?us-ascii?q?4LvUTCGC/5hln2gbeIekk59eWk8frrb7r8qpOCNYJ4kA7zP6Q2lsy6G+s4Mw?= =?us-ascii?q?wOX2aB+eS70b3u5Vf3T6tWjvIoiKnVqp/UJcIGqaGnGQ9ayYEj6wywDzq9y9?= =?us-ascii?q?QYmn8HLVJfdB2biIjpPknCIOrkAvenn1SsjDBryujdPrL8GZXANWTDkbf9cr?= =?us-ascii?q?Z97E5Q0gwzzctF6J5OBbEBJ+zzUFfrtNPEFh85LxC0w+H/BdVmyIweXWOPAq?= =?us-ascii?q?mEMKLdqlKI+uIuLPWMZI8Sojr9LeMl6OT0gX82nl8dY/rh4ZxCPGi1Avl8ZU?= =?us-ascii?q?ifbXf2iNAbHk8RuQwvCuftjQvGGQZaenL6eqU7/DxzXJqvEIPrXomwhPmE2y?= =?us-ascii?q?ChE9tdYWUQThi3DXrwd4iCE8wJYSaWL94pxicITpC9WoQh0leorwa8xL15eK?= =?us-ascii?q?6c1zcZvtrb3cJ0/KWHmAk77z1vJ9yUyWCWV2V9lW5OQCU5iuQ3g0V4x0zL9K?= =?us-ascii?q?9imf1DXYhR7vZESUE+c5vb1fZ7EPj1QAvKetrPQ1GjFJHuLTg3T981i/0TeU?= =?us-ascii?q?lwHc7q2hzK2SunB709krGPAJUy9bKa1H/0cYI153Hb2+EFglUoRdFDfTmqgq?= =?us-ascii?q?Nz+Q/JC6bTnkmZnrrsfqMZimqFoHyOyWuIoVFwTB97UaKDW2sWIETRs4K9rh?= =?us-ascii?q?fGTrmzGfE8PwBc08+eO+5PbdH0iVhuWvjuIpLdbni3lmP2AgyHkPfEOI7rfX?= =?us-ascii?q?gNmSbQEk4JlygN8nuccwszHCGspyTZFjM4URqlWE72/uQ2hTv9Bm89ywWbaQ?= =?us-ascii?q?cpg6G44BEYrfyVT/cC2PQPvyJ3730+JF+g25r7Q5zIggFCcaNabMJ3qANf3H?= =?us-ascii?q?/dsgd+FpihKb1ywEAYfhgxvknrkR5wD9MTv9ItqSYSwRZ/M+q11l9MbTmfx5?= =?us-ascii?q?+4bqXaNmTouh2pZ6PM0FbE3/6N/aEerv8/rgOw70mSCkM+/iA/gJFu2HyG68?= =?us-ascii?q?CPVVJKC8ijW1sr9xV8u7DRazU84IWRz3B3LK2oqWCbie8RKMB+4S6JJo4ZPa?= =?us-ascii?q?6BDwC0FsQbA46rKeh501SqbxdROudU+eZ0Os69bPKJ1eatO/oohzOpi2lLoc?= =?us-ascii?q?h930uA+jA6S7vO2JAIzg=3D=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0DAAAAUsQ5bly0bGNZcHQEBBQELAYN?= =?us-ascii?q?BgWQWEot7jGCDCJM8FIFkhHcCghwhNBgBAgEBAQEBAQIBEwEBAQEBBhgGV4I?= =?us-ascii?q?1JAGCTwMDGg1iPxJXBgESgyKCBAGnFzODeAEBhEuBaIg3gVQ/gQ+HaASFaAK?= =?us-ascii?q?HPAiGCosXBwKBZ4xuC40MK5IpggpNI4MTgiAOCRGNUAE3bY1QgkYBAQ?= X-IPAS-Result: =?us-ascii?q?A0DAAAAUsQ5bly0bGNZcHQEBBQELAYNBgWQWEot7jGCDC?= =?us-ascii?q?JM8FIFkhHcCghwhNBgBAgEBAQEBAQIBEwEBAQEBBhgGV4I1JAGCTwMDGg1iP?= =?us-ascii?q?xJXBgESgyKCBAGnFzODeAEBhEuBaIg3gVQ/gQ+HaASFaAKHPAiGCosXBwKBZ?= =?us-ascii?q?4xuC40MK5IpggpNI4MTgiAOCRGNUAE3bY1QgkYBAQ?= X-IronPort-AV: E=Sophos;i="5.49,460,1520899200"; d="scan'208";a="12288871" X-IronPort-Outbreak-Status: No, level 0, Unknown - Unknown Received: from updc3cpa06.eemsg.mail.mil ([214.24.27.45]) by EMSM-GH1-UEA10.NCSC.MIL with ESMTP; 30 May 2018 14:13:55 +0000 X-EEMSG-check-005: 0 X-EEMSG-check-006: 000-001;7da15818-c4ba-4592-83b9-1376580dcbf4 Received: from localhost.localdomain (localhost [127.0.0.1]) by UPDCF3IC16.oob.disa.mil (Postfix) with SMTP id 40wsy93MFTz2Vp8Y; Wed, 30 May 2018 14:13:21 +0000 (UTC) Received: from UPDC3CPA11_EEMSG_MP27.eemsg.mil (unknown [192.168.18.22]) by UPDCF3IC16.oob.disa.mil (Postfix) with ESMTP id 40wsy86Snzz2Vp8k; Wed, 30 May 2018 14:13:20 +0000 (UTC) Authentication-Results: UPDC3CPA11.eemsg.mail.mil; dkim=none (message not signed) header.i=none X-EEMSG-check-008: 20988258|UPDC3CPA11_EEMSG_MP27.csd.disa.mil X-EEMSG-SBRS: 3.5 X-EEMSG-ORIG-IP: 37.139.156.29 X-EEMSG-check-002: true X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0DNAADHrg5bhx2ciyVcHAEBAQQBAQoBAYU7Eot7jGCDCJM8FIFkhHcCCIIUITQYAQIBAQEBAQECFAEBAQoLCQgoL4UpAwMaDWI/ElcGARKDIoIFpn0zg3gBAYRLgWgJAYgtgVQ/gQ+HaASFaAKHPAiGCosXBwKBZ4xuC40MK5IpggpNI4MTgiAOCY1hATc9MI1QgkYBAQ X-IPAS-Result: A0DNAADHrg5bhx2ciyVcHAEBAQQBAQoBAYU7Eot7jGCDCJM8FIFkhHcCCIIUITQYAQIBAQEBAQECFAEBAQoLCQgoL4UpAwMaDWI/ElcGARKDIoIFpn0zg3gBAYRLgWgJAYgtgVQ/gQ+HaASFaAKHPAiGCosXBwKBZ4xuC40MK5IpggpNI4MTgiAOCY1hATc9MI1QgkYBAQ Received: from seldsegrel01.sonyericsson.com ([37.139.156.29]) by UPDC3CPA11.eemsg.mail.mil with ESMTP; 30 May 2018 14:13:18 +0000 X-EEMSG-check-009: 444-444 From: Peter Enderborg To: , Paul Moore , Stephen Smalley , Eric Paris , James Morris , Daniel Jurgens , Doug Ledford , , , , "Serge E . Hallyn" , "Paul E . McKenney" Date: Wed, 30 May 2018 16:11:01 +0200 Message-ID: <20180530141104.28569-3-peter.enderborg@sony.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180530141104.28569-1-peter.enderborg@sony.com> References: <20180530141104.28569-1-peter.enderborg@sony.com> MIME-Version: 1.0 X-Mailman-Approved-At: Wed, 30 May 2018 10:18:15 -0400 Subject: [PATCH V3 2/5 selinux-next] selinux: Introduce selinux_ruleset struct 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 This is a preparation for moving locking to rcu type. We move policydb, sidtab and map to this structure which is dynamic allocated. To help out the handlig a policydb_copy are added. It is intended to be used in atomic context within a rcu lock, so there are help functions that do vmalloc allocation that are intended to be on the outside of the lock. hastab_insert had a cond_sched call that is removed. When switched to rcu lock the lock can be preempted. Signed-off-by: Peter Enderborg --- security/selinux/ss/hashtab.c | 1 - security/selinux/ss/policydb.c | 48 +++++++ security/selinux/ss/policydb.h | 6 +- security/selinux/ss/services.c | 292 +++++++++++++++++++++++------------------ security/selinux/ss/services.h | 12 +- 5 files changed, 226 insertions(+), 133 deletions(-) diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c index 0944b1f8060e..967b6e3d25c6 100644 --- a/security/selinux/ss/hashtab.c +++ b/security/selinux/ss/hashtab.c @@ -44,7 +44,6 @@ int hashtab_insert(struct hashtab *h, void *key, void *datum) u32 hvalue; struct hashtab_node *prev, *cur, *newnode; - cond_resched(); if (!h || h->nel == HASHTAB_MAX_NODES) return -EINVAL; diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 2a0e21d8c275..93d134d057a7 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -3535,3 +3535,51 @@ int policydb_write(struct policydb *p, void *fp) return 0; } + +int policydb_flattened_alloc(struct policydb *db, void **tmpbuf, size_t *size) +{ + int rc = 0; + + *size = db->len; + *tmpbuf = vmalloc(*size); + + if (!*tmpbuf) { + rc = -ENOMEM; + printk(KERN_ERR "SELinux: vmalloc failed for %ld\n", *size); + } + return rc; +} + +int policydb_flattened_free(void *tmpbuf) +{ + vfree(tmpbuf); + return 0; +} + +int policydb_copy(struct policydb *olddb, struct policydb *newdb, + void **tmpstorage, size_t size) +{ + struct policy_file fp; + void *data = *tmpstorage; + int rc; + + if (size != olddb->len) { + rc = -EAGAIN; + goto out; + } + fp.data = data; + fp.len = size; + rc = policydb_write(olddb, &fp); + if (rc) + goto out; + + fp.len = size; + fp.data = data; + rc = policydb_read(newdb, &fp); + if (rc) + goto out; + + newdb->len = size; +out: + return rc; +} diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index 215f8f30ac5a..3e2f86b5b674 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h @@ -320,7 +320,11 @@ extern int policydb_type_isvalid(struct policydb *p, unsigned int type); extern int policydb_role_isvalid(struct policydb *p, unsigned int role); extern int policydb_read(struct policydb *p, void *fp); extern int policydb_write(struct policydb *p, void *fp); - +extern int policydb_copy(struct policydb *olddb, struct policydb *newdb, + void **tmpstorage, size_t size); +extern int policydb_flattened_alloc(struct policydb *db, + void **tmpbuf, size_t *size); +extern int policydb_flattened_free(void *tmpbuf); #define PERM_SYMTAB_SIZE 32 #define POLICYDB_CONFIG_MLS 1 diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 8057e19dc15f..4f3ce389084c 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -86,6 +86,10 @@ void selinux_ss_init(struct selinux_ss **ss) { rwlock_init(&selinux_ss.policy_rwlock); mutex_init(&selinux_ss.status_lock); + selinux_ss.active_set = kzalloc(sizeof(struct selinux_ruleset), + GFP_KERNEL); + selinux_ss.active_set->sidtab = kzalloc(sizeof(struct sidtab), + GFP_KERNEL); *ss = &selinux_ss; } @@ -249,7 +253,7 @@ static void map_decision(struct selinux_map *map, int security_mls_enabled(struct selinux_state *state) { - struct policydb *p = &state->ss->policydb; + struct policydb *p = &state->ss->active_set->policydb; return p->mls_enabled; } @@ -733,7 +737,7 @@ static int security_validtrans_handle_fail(struct selinux_state *state, struct context *tcontext, u16 tclass) { - struct policydb *p = &state->ss->policydb; + struct policydb *p = &state->ss->active_set->policydb; char *o = NULL, *n = NULL, *t = NULL; u32 olen, nlen, tlen; @@ -777,11 +781,11 @@ static int security_compute_validatetrans(struct selinux_state *state, read_lock(&state->ss->policy_rwlock); - policydb = &state->ss->policydb; - sidtab = &state->ss->sidtab; + policydb = &state->ss->active_set->policydb; + sidtab = state->ss->active_set->sidtab; if (!user) - tclass = unmap_class(&state->ss->map, orig_tclass); + tclass = unmap_class(&state->ss->active_set->map, orig_tclass); else tclass = orig_tclass; @@ -877,8 +881,8 @@ int security_bounded_transition(struct selinux_state *state, read_lock(&state->ss->policy_rwlock); - policydb = &state->ss->policydb; - sidtab = &state->ss->sidtab; + policydb = &state->ss->active_set->policydb; + sidtab = state->ss->active_set->sidtab; rc = -EINVAL; old_context = sidtab_search(sidtab, old_sid); @@ -1035,8 +1039,8 @@ void security_compute_xperms_decision(struct selinux_state *state, if (!state->initialized) goto allow; - policydb = &state->ss->policydb; - sidtab = &state->ss->sidtab; + policydb = &state->ss->active_set->policydb; + sidtab = state->ss->active_set->sidtab; scontext = sidtab_search(sidtab, ssid); if (!scontext) { @@ -1052,7 +1056,7 @@ void security_compute_xperms_decision(struct selinux_state *state, goto out; } - tclass = unmap_class(&state->ss->map, orig_tclass); + tclass = unmap_class(&state->ss->active_set->map, orig_tclass); if (unlikely(orig_tclass && !tclass)) { if (policydb->allow_unknown) goto allow; @@ -1124,8 +1128,8 @@ void security_compute_av(struct selinux_state *state, if (!state->initialized) goto allow; - policydb = &state->ss->policydb; - sidtab = &state->ss->sidtab; + policydb = &state->ss->active_set->policydb; + sidtab = state->ss->active_set->sidtab; scontext = sidtab_search(sidtab, ssid); if (!scontext) { @@ -1145,7 +1149,7 @@ void security_compute_av(struct selinux_state *state, goto out; } - tclass = unmap_class(&state->ss->map, orig_tclass); + tclass = unmap_class(&state->ss->active_set->map, orig_tclass); if (unlikely(orig_tclass && !tclass)) { if (policydb->allow_unknown) goto allow; @@ -1153,7 +1157,7 @@ void security_compute_av(struct selinux_state *state, } context_struct_compute_av(policydb, scontext, tcontext, tclass, avd, xperms); - map_decision(&state->ss->map, orig_tclass, avd, + map_decision(&state->ss->active_set->map, orig_tclass, avd, policydb->allow_unknown); out: read_unlock(&state->ss->policy_rwlock); @@ -1178,8 +1182,8 @@ void security_compute_av_user(struct selinux_state *state, if (!state->initialized) goto allow; - policydb = &state->ss->policydb; - sidtab = &state->ss->sidtab; + policydb = &state->ss->active_set->policydb; + sidtab = state->ss->active_set->sidtab; scontext = sidtab_search(sidtab, ssid); if (!scontext) { @@ -1316,8 +1320,8 @@ static int security_sid_to_context_core(struct selinux_state *state, goto out; } read_lock(&state->ss->policy_rwlock); - policydb = &state->ss->policydb; - sidtab = &state->ss->sidtab; + policydb = &state->ss->active_set->policydb; + sidtab = state->ss->active_set->sidtab; if (force) context = sidtab_search_force(sidtab, sid); else @@ -1488,8 +1492,8 @@ static int security_context_to_sid_core(struct selinux_state *state, goto out; } read_lock(&state->ss->policy_rwlock); - policydb = &state->ss->policydb; - sidtab = &state->ss->sidtab; + policydb = &state->ss->active_set->policydb; + sidtab = state->ss->active_set->sidtab; rc = string_to_context_struct(policydb, sidtab, scontext2, scontext_len, &context, def_sid); if (rc == -EINVAL && force) { @@ -1576,7 +1580,7 @@ static int compute_sid_handle_invalid_context( u16 tclass, struct context *newcontext) { - struct policydb *policydb = &state->ss->policydb; + struct policydb *policydb = &state->ss->active_set->policydb; char *s = NULL, *t = NULL, *n = NULL; u32 slen, tlen, nlen; @@ -1665,16 +1669,17 @@ static int security_compute_sid(struct selinux_state *state, read_lock(&state->ss->policy_rwlock); if (kern) { - tclass = unmap_class(&state->ss->map, orig_tclass); + tclass = unmap_class(&state->ss->active_set->map, orig_tclass); sock = security_is_socket_class(orig_tclass); } else { + struct selinux_map *amap = &state->ss->active_set->map; tclass = orig_tclass; - sock = security_is_socket_class(map_class(&state->ss->map, + sock = security_is_socket_class(map_class(amap, tclass)); } - policydb = &state->ss->policydb; - sidtab = &state->ss->sidtab; + policydb = &state->ss->active_set->policydb; + sidtab = state->ss->active_set->sidtab; scontext = sidtab_search(sidtab, ssid); if (!scontext) { @@ -1903,7 +1908,7 @@ static inline int convert_context_handle_invalid_context( struct selinux_state *state, struct context *context) { - struct policydb *policydb = &state->ss->policydb; + struct policydb *policydb = &state->ss->active_set->policydb; char *s; u32 len; @@ -2071,9 +2076,9 @@ static int convert_context(u32 key, goto out; } -static void security_load_policycaps(struct selinux_state *state) +static void security_load_policycaps(struct selinux_state *state, + struct policydb *p) { - struct policydb *p = &state->ss->policydb; unsigned int i; struct ebitmap_node *node; @@ -2107,47 +2112,47 @@ static int security_preserve_bools(struct selinux_state *state, */ int security_load_policy(struct selinux_state *state, void *data, size_t len) { - struct policydb *policydb; - struct sidtab *sidtab; - struct policydb *oldpolicydb, *newpolicydb; - struct sidtab oldsidtab, newsidtab; - struct selinux_mapping *oldmapping; struct selinux_map newmap; struct convert_context_args args; u32 seqno; int rc = 0; + struct selinux_ruleset *next_set, *old_set; struct policy_file file = { data, len }, *fp = &file; - oldpolicydb = kzalloc(2 * sizeof(*oldpolicydb), GFP_KERNEL); - if (!oldpolicydb) { + next_set = kzalloc(sizeof(struct selinux_ruleset), GFP_KERNEL); + if (!next_set) { rc = -ENOMEM; goto out; } - newpolicydb = oldpolicydb + 1; - - policydb = &state->ss->policydb; - sidtab = &state->ss->sidtab; + next_set->sidtab = kzalloc(sizeof(struct sidtab), GFP_KERNEL); + if (!next_set->sidtab) { + rc = -ENOMEM; + kfree(next_set); + goto out; + } if (!state->initialized) { - rc = policydb_read(policydb, fp); + old_set = state->ss->active_set; + rc = policydb_read(&next_set->policydb, fp); if (rc) goto out; - policydb->len = len; - rc = selinux_set_mapping(policydb, secclass_map, - &state->ss->map); + next_set->policydb.len = len; + rc = selinux_set_mapping(&next_set->policydb, secclass_map, + &next_set->map); if (rc) { - policydb_destroy(policydb); + policydb_destroy(&next_set->policydb); goto out; } - rc = policydb_load_isids(policydb, sidtab); + rc = policydb_load_isids(&next_set->policydb, next_set->sidtab); if (rc) { - policydb_destroy(policydb); + policydb_destroy(&next_set->policydb); goto out; } - security_load_policycaps(state); + security_load_policycaps(state, &next_set->policydb); + state->ss->active_set = next_set; state->initialized = 1; seqno = ++state->ss->latest_granting; selinux_complete_init(); @@ -2156,45 +2161,48 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len) selinux_status_update_policyload(state, seqno); selinux_netlbl_cache_invalidate(); selinux_xfrm_notify_policyload(); + kfree(old_set->sidtab); + kfree(old_set); goto out; } - + old_set = state->ss->active_set; #if 0 sidtab_hash_eval(sidtab, "sids"); #endif - rc = policydb_read(newpolicydb, fp); + rc = policydb_read(&next_set->policydb, fp); if (rc) goto out; - newpolicydb->len = len; + next_set->policydb.len = len; + /* If switching between different policy types, log MLS status */ - if (policydb->mls_enabled && !newpolicydb->mls_enabled) + if (old_set->policydb.mls_enabled && !next_set->policydb.mls_enabled) printk(KERN_INFO "SELinux: Disabling MLS support...\n"); - else if (!policydb->mls_enabled && newpolicydb->mls_enabled) + else if (!old_set->policydb.mls_enabled + && next_set->policydb.mls_enabled) printk(KERN_INFO "SELinux: Enabling MLS support...\n"); - - rc = policydb_load_isids(newpolicydb, &newsidtab); + rc = policydb_load_isids(&next_set->policydb, next_set->sidtab); if (rc) { printk(KERN_ERR "SELinux: unable to load the initial SIDs\n"); - policydb_destroy(newpolicydb); + policydb_destroy(&next_set->policydb); goto out; } - rc = selinux_set_mapping(newpolicydb, secclass_map, &newmap); + rc = selinux_set_mapping(&next_set->policydb, secclass_map, &newmap); if (rc) goto err; - rc = security_preserve_bools(state, newpolicydb); + rc = security_preserve_bools(state, &next_set->policydb); if (rc) { printk(KERN_ERR "SELinux: unable to preserve booleans\n"); goto err; } /* Clone the SID table. */ - sidtab_shutdown(sidtab); + sidtab_shutdown(old_set->sidtab); - rc = sidtab_map(sidtab, clone_sid, &newsidtab); + rc = sidtab_map(old_set->sidtab, clone_sid, next_set->sidtab); if (rc) goto err; @@ -2203,9 +2211,9 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len) * in the new SID table. */ args.state = state; - args.oldp = policydb; - args.newp = newpolicydb; - rc = sidtab_map(&newsidtab, convert_context, &args); + args.oldp = &old_set->policydb; + args.newp = &next_set->policydb; + rc = sidtab_map(next_set->sidtab, convert_context, &args); if (rc) { printk(KERN_ERR "SELinux: unable to convert the internal" " representation of contexts in the new SID" @@ -2213,48 +2221,43 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len) goto err; } - /* Save the old policydb and SID table to free later. */ - memcpy(oldpolicydb, policydb, sizeof(*policydb)); - sidtab_set(&oldsidtab, sidtab); + next_set->map.mapping = newmap.mapping; + next_set->map.size = newmap.size; /* Install the new policydb and SID table. */ write_lock_irq(&state->ss->policy_rwlock); - memcpy(policydb, newpolicydb, sizeof(*policydb)); - sidtab_set(sidtab, &newsidtab); - security_load_policycaps(state); - oldmapping = state->ss->map.mapping; - state->ss->map.mapping = newmap.mapping; - state->ss->map.size = newmap.size; + security_load_policycaps(state, &next_set->policydb); seqno = ++state->ss->latest_granting; + state->ss->active_set = next_set; write_unlock_irq(&state->ss->policy_rwlock); - /* Free the old policydb and SID table. */ - policydb_destroy(oldpolicydb); - sidtab_destroy(&oldsidtab); - kfree(oldmapping); - avc_ss_reset(state->avc, seqno); selnl_notify_policyload(seqno); selinux_status_update_policyload(state, seqno); selinux_netlbl_cache_invalidate(); selinux_xfrm_notify_policyload(); + /* Free the old policydb and SID table. */ + policydb_destroy(&old_set->policydb); + sidtab_destroy(old_set->sidtab); + kfree(old_set->sidtab); + kfree(old_set->map.mapping); + kfree(old_set); rc = 0; goto out; err: kfree(newmap.mapping); - sidtab_destroy(&newsidtab); - policydb_destroy(newpolicydb); - + sidtab_destroy(next_set->sidtab); + policydb_destroy(&next_set->policydb); + kfree(next_set); out: - kfree(oldpolicydb); return rc; } size_t security_policydb_len(struct selinux_state *state) { - struct policydb *p = &state->ss->policydb; + struct policydb *p = &state->ss->active_set->policydb; size_t len; read_lock(&state->ss->policy_rwlock); @@ -2280,8 +2283,8 @@ int security_port_sid(struct selinux_state *state, read_lock(&state->ss->policy_rwlock); - policydb = &state->ss->policydb; - sidtab = &state->ss->sidtab; + policydb = &state->ss->active_set->policydb; + sidtab = state->ss->active_set->sidtab; c = policydb->ocontexts[OCON_PORT]; while (c) { @@ -2326,8 +2329,8 @@ int security_ib_pkey_sid(struct selinux_state *state, read_lock(&state->ss->policy_rwlock); - policydb = &state->ss->policydb; - sidtab = &state->ss->sidtab; + policydb = &state->ss->active_set->policydb; + sidtab = state->ss->active_set->sidtab; c = policydb->ocontexts[OCON_IBPKEY]; while (c) { @@ -2372,8 +2375,8 @@ int security_ib_endport_sid(struct selinux_state *state, read_lock(&state->ss->policy_rwlock); - policydb = &state->ss->policydb; - sidtab = &state->ss->sidtab; + policydb = &state->ss->active_set->policydb; + sidtab = state->ss->active_set->sidtab; c = policydb->ocontexts[OCON_IBENDPORT]; while (c) { @@ -2418,8 +2421,8 @@ int security_netif_sid(struct selinux_state *state, read_lock(&state->ss->policy_rwlock); - policydb = &state->ss->policydb; - sidtab = &state->ss->sidtab; + policydb = &state->ss->active_set->policydb; + sidtab = state->ss->active_set->sidtab; c = policydb->ocontexts[OCON_NETIF]; while (c) { @@ -2483,8 +2486,8 @@ int security_node_sid(struct selinux_state *state, read_lock(&state->ss->policy_rwlock); - policydb = &state->ss->policydb; - sidtab = &state->ss->sidtab; + policydb = &state->ss->active_set->policydb; + sidtab = state->ss->active_set->sidtab; switch (domain) { case AF_INET: { @@ -2583,8 +2586,8 @@ int security_get_user_sids(struct selinux_state *state, read_lock(&state->ss->policy_rwlock); - policydb = &state->ss->policydb; - sidtab = &state->ss->sidtab; + policydb = &state->ss->active_set->policydb; + sidtab = state->ss->active_set->sidtab; context_init(&usercon); @@ -2685,8 +2688,8 @@ static inline int __security_genfs_sid(struct selinux_state *state, u16 orig_sclass, u32 *sid) { - struct policydb *policydb = &state->ss->policydb; - struct sidtab *sidtab = &state->ss->sidtab; + struct policydb *policydb = &state->ss->active_set->policydb; + struct sidtab *sidtab = state->ss->active_set->sidtab; int len; u16 sclass; struct genfs *genfs; @@ -2696,7 +2699,7 @@ static inline int __security_genfs_sid(struct selinux_state *state, while (path[0] == '/' && path[1] == '/') path++; - sclass = unmap_class(&state->ss->map, orig_sclass); + sclass = unmap_class(&state->ss->active_set->map, orig_sclass); *sid = SECINITSID_UNLABELED; for (genfs = policydb->genfs; genfs; genfs = genfs->next) { @@ -2771,8 +2774,8 @@ int security_fs_use(struct selinux_state *state, struct super_block *sb) read_lock(&state->ss->policy_rwlock); - policydb = &state->ss->policydb; - sidtab = &state->ss->sidtab; + policydb = &state->ss->active_set->policydb; + sidtab = state->ss->active_set->sidtab; c = policydb->ocontexts[OCON_FSUSE]; while (c) { @@ -2821,7 +2824,7 @@ int security_get_bools(struct selinux_state *state, read_lock(&state->ss->policy_rwlock); - policydb = &state->ss->policydb; + policydb = &state->ss->active_set->policydb; *names = NULL; *values = NULL; @@ -2866,53 +2869,86 @@ int security_get_bools(struct selinux_state *state, int security_set_bools(struct selinux_state *state, int len, int *values) { - struct policydb *policydb; int i, rc; int lenp, seqno = 0; struct cond_node *cur; + struct selinux_ruleset *next_set, *old_set = NULL; + void *storage; + size_t size; - write_lock_irq(&state->ss->policy_rwlock); + next_set = kzalloc(sizeof(struct selinux_ruleset), GFP_KERNEL); + if (!next_set) { + rc = -ENOMEM; + goto errout; + } + + rc = policydb_flattened_alloc(&state->ss->active_set->policydb, + &storage, &size); + if (rc) { + kfree(next_set); + goto errout; + } - policydb = &state->ss->policydb; + write_lock_irq(&state->ss->policy_rwlock); + old_set = state->ss->active_set; + memcpy(next_set, old_set, sizeof(struct selinux_ruleset)); + rc = policydb_copy(&old_set->policydb, &next_set->policydb, + &storage, size); + if (rc) + goto out; rc = -EFAULT; - lenp = policydb->p_bools.nprim; + lenp = next_set->policydb.p_bools.nprim; if (len != lenp) goto out; for (i = 0; i < len; i++) { - if (!!values[i] != policydb->bool_val_to_struct[i]->state) { + if (!!values[i] != + next_set->policydb.bool_val_to_struct[i]->state) { audit_log(current->audit_context, GFP_ATOMIC, AUDIT_MAC_CONFIG_CHANGE, "bool=%s val=%d old_val=%d auid=%u ses=%u", - sym_name(policydb, SYM_BOOLS, i), + sym_name(&next_set->policydb, SYM_BOOLS, i), !!values[i], - policydb->bool_val_to_struct[i]->state, + next_set->policydb.bool_val_to_struct[i]->state, from_kuid(&init_user_ns, audit_get_loginuid(current)), audit_get_sessionid(current)); } if (values[i]) - policydb->bool_val_to_struct[i]->state = 1; + next_set->policydb.bool_val_to_struct[i]->state = 1; else - policydb->bool_val_to_struct[i]->state = 0; + next_set->policydb.bool_val_to_struct[i]->state = 0; } - for (cur = policydb->cond_list; cur; cur = cur->next) { - rc = evaluate_cond_node(policydb, cur); + for (cur = next_set->policydb.cond_list; cur; cur = cur->next) { + rc = evaluate_cond_node(&next_set->policydb, cur); if (rc) goto out; } seqno = ++state->ss->latest_granting; + state->ss->active_set = next_set; rc = 0; out: - write_unlock_irq(&state->ss->policy_rwlock); if (!rc) { + seqno = ++state->ss->latest_granting; + state->ss->active_set = next_set; + rc = 0; + write_unlock_irq(&state->ss->policy_rwlock); avc_ss_reset(state->avc, seqno); selnl_notify_policyload(seqno); selinux_status_update_policyload(state, seqno); selinux_xfrm_notify_policyload(); + policydb_destroy(&old_set->policydb); + kfree(old_set); + } else { + printk(KERN_ERR "SELinux: %s failed %d\n", __func__, rc); + write_unlock_irq(&state->ss->policy_rwlock); + kfree(next_set); } + policydb_flattened_free(storage); + + errout: return rc; } @@ -2925,7 +2961,7 @@ int security_get_bool_value(struct selinux_state *state, read_lock(&state->ss->policy_rwlock); - policydb = &state->ss->policydb; + policydb = &state->ss->active_set->policydb; rc = -EFAULT; len = policydb->p_bools.nprim; @@ -2977,8 +3013,8 @@ static int security_preserve_bools(struct selinux_state *state, int security_sid_mls_copy(struct selinux_state *state, u32 sid, u32 mls_sid, u32 *new_sid) { - struct policydb *policydb = &state->ss->policydb; - struct sidtab *sidtab = &state->ss->sidtab; + struct policydb *policydb = &state->ss->active_set->policydb; + struct sidtab *sidtab = state->ss->active_set->sidtab; struct context *context1; struct context *context2; struct context newcon; @@ -3068,8 +3104,8 @@ int security_net_peersid_resolve(struct selinux_state *state, u32 xfrm_sid, u32 *peer_sid) { - struct policydb *policydb = &state->ss->policydb; - struct sidtab *sidtab = &state->ss->sidtab; + struct policydb *policydb = &state->ss->active_set->policydb; + struct sidtab *sidtab = state->ss->active_set->sidtab; int rc; struct context *nlbl_ctx; struct context *xfrm_ctx; @@ -3146,7 +3182,7 @@ static int get_classes_callback(void *k, void *d, void *args) int security_get_classes(struct selinux_state *state, char ***classes, int *nclasses) { - struct policydb *policydb = &state->ss->policydb; + struct policydb *policydb = &state->ss->active_set->policydb; int rc; if (!state->initialized) { @@ -3193,7 +3229,7 @@ static int get_permissions_callback(void *k, void *d, void *args) int security_get_permissions(struct selinux_state *state, char *class, char ***perms, int *nperms) { - struct policydb *policydb = &state->ss->policydb; + struct policydb *policydb = &state->ss->active_set->policydb; int rc, i; struct class_datum *match; @@ -3239,12 +3275,12 @@ int security_get_permissions(struct selinux_state *state, int security_get_reject_unknown(struct selinux_state *state) { - return state->ss->policydb.reject_unknown; + return state->ss->active_set->policydb.reject_unknown; } int security_get_allow_unknown(struct selinux_state *state) { - return state->ss->policydb.allow_unknown; + return state->ss->active_set->policydb.allow_unknown; } /** @@ -3260,7 +3296,7 @@ int security_get_allow_unknown(struct selinux_state *state) int security_policycap_supported(struct selinux_state *state, unsigned int req_cap) { - struct policydb *policydb = &state->ss->policydb; + struct policydb *policydb = &state->ss->active_set->policydb; int rc; read_lock(&state->ss->policy_rwlock); @@ -3288,7 +3324,7 @@ void selinux_audit_rule_free(void *vrule) int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) { struct selinux_state *state = &selinux_state; - struct policydb *policydb = &state->ss->policydb; + struct policydb *policydb = &state->ss->active_set->policydb; struct selinux_audit_rule *tmprule; struct role_datum *roledatum; struct type_datum *typedatum; @@ -3430,7 +3466,7 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule, goto out; } - ctxt = sidtab_search(&state->ss->sidtab, sid); + ctxt = sidtab_search(state->ss->active_set->sidtab, sid); if (unlikely(!ctxt)) { WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n", sid); @@ -3592,8 +3628,8 @@ int security_netlbl_secattr_to_sid(struct selinux_state *state, struct netlbl_lsm_secattr *secattr, u32 *sid) { - struct policydb *policydb = &state->ss->policydb; - struct sidtab *sidtab = &state->ss->sidtab; + struct policydb *policydb = &state->ss->active_set->policydb; + struct sidtab *sidtab = state->ss->active_set->sidtab; int rc; struct context *ctx; struct context ctx_new; @@ -3661,7 +3697,7 @@ int security_netlbl_secattr_to_sid(struct selinux_state *state, int security_netlbl_sid_to_secattr(struct selinux_state *state, u32 sid, struct netlbl_lsm_secattr *secattr) { - struct policydb *policydb = &state->ss->policydb; + struct policydb *policydb = &state->ss->active_set->policydb; int rc; struct context *ctx; @@ -3671,7 +3707,7 @@ int security_netlbl_sid_to_secattr(struct selinux_state *state, read_lock(&state->ss->policy_rwlock); rc = -ENOENT; - ctx = sidtab_search(&state->ss->sidtab, sid); + ctx = sidtab_search(state->ss->active_set->sidtab, sid); if (ctx == NULL) goto out; @@ -3700,7 +3736,7 @@ int security_netlbl_sid_to_secattr(struct selinux_state *state, int security_read_policy(struct selinux_state *state, void **data, size_t *len) { - struct policydb *policydb = &state->ss->policydb; + struct policydb *policydb = &state->ss->active_set->policydb; int rc; struct policy_file fp; diff --git a/security/selinux/ss/services.h b/security/selinux/ss/services.h index 24c7bdcc8075..9219649c70ed 100644 --- a/security/selinux/ss/services.h +++ b/security/selinux/ss/services.h @@ -23,12 +23,18 @@ struct selinux_map { u16 size; /* array size of mapping */ }; -struct selinux_ss { - struct sidtab sidtab; +/* sidtab is stored as a pointer. We can then choice to + * use the old pointer or create a new sittab. + */ +struct selinux_ruleset { + struct sidtab *sidtab; struct policydb policydb; + struct selinux_map map; +}; +struct selinux_ss { + struct selinux_ruleset *active_set; /* rcu pointer */ rwlock_t policy_rwlock; u32 latest_granting; - struct selinux_map map; struct page *status_page; struct mutex status_lock; };