From patchwork Thu Mar 8 01:53:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Casey Schaufler X-Patchwork-Id: 10268017 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 2BC9F602C8 for ; Thu, 8 Mar 2018 13:02:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 157E229906 for ; Thu, 8 Mar 2018 13:02:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0906B2990E; Thu, 8 Mar 2018 13:02:05 +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=-3.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, NO_RDNS_DOTCOM_HELO,RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from UCOL19PA10.eemsg.mail.mil (ucol19pa10.eemsg.mail.mil [214.24.24.83]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 730112990C for ; Thu, 8 Mar 2018 13:02:00 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.47,441,1515456000"; d="scan'208";a="462374543" Received: from emsm-gh1-uea11.ncsc.mil ([214.29.60.3]) by UCOL19PA10.eemsg.mail.mil with ESMTP; 08 Mar 2018 13:01:58 +0000 X-IronPort-AV: E=Sophos;i="5.47,441,1515456000"; d="scan'208";a="10307280" IronPort-PHdr: =?us-ascii?q?9a23=3AY112XBGYv3JTKySHsckLE51GYnF86YWxBRYc798d?= =?us-ascii?q?s5kLTJ7+oMy6bnLW6fgltlLVR4KTs6sC17KN9fi4EUU7or+5+EgYd5JNUxJXwe?= =?us-ascii?q?43pCcHRPC/NEvgMfTxZDY7FskRHHVs/nW8LFQHUJ2mPw6arXK99yMdFQviPgRp?= =?us-ascii?q?OOv1BpTSj8Oq3Oyu5pHfeQpFiCazbL9oMBm6sRjau9ULj4dlNqs/0AbCrGFSe+?= =?us-ascii?q?RRy2NoJFaTkAj568yt4pNt8Dletuw4+cJYXqr0Y6o3TbpDDDQ7KG81/9HktQPC?= =?us-ascii?q?TQSU+HQRVHgdnwdSDAjE6BH6WYrxsjf/u+Fg1iSWIdH6QLYpUjm58axlVAHnhz?= =?us-ascii?q?sGNz4h8WHYlMpwjL5AoBm8oxBz2pPYbJ2JOPZ7eK7Sc8kaRW5cVchPUSJPDJ63?= =?us-ascii?q?Y48WA+YcIepUqo/wqFwMohSkBQmsA+TvxiZRinLq06A30vktHRja0AA9AtkCtG?= =?us-ascii?q?rYoMnwOKoUTOu7zrTHzS/bYv1I1zfz6IvGfB4vrv6DX71/bcXfx1Q3Fw7Hk1md?= =?us-ascii?q?p5LqPyiO2+QRsWWW9fZsWf6hhmMlrQx6vzihxt0rionMno8Y1ErL9T5nz4c1ON?= =?us-ascii?q?a2VVJ0Yd6+H5tNuSGaM5V5Qtk/SGxvpCk10KYGtoC7fSUR05Qo2x7fZOaac4iG?= =?us-ascii?q?5hLsSvyRLS5ki31/Yr6wmxGy8U25x+D6S8K6005KozJYntTDuX0BzRze5tWdRv?= =?us-ascii?q?dj8UqtxyyD2x3L5uxFIE04j7fXJp8vz7Iqi5YetVnPEjXrlEj2g6KbcFgv9PKy?= =?us-ascii?q?5OT9eLrmo4eRN4pzig7jLKsjgte/AeEkMggWWGib5Pi82KXj/ULnRLVKieU7kr?= =?us-ascii?q?XDv5DAJMQbu7W5DxVJ0ocj9xm/DzCm3M4enXYbN1JKZAiLj43oO1HKOPz4DPG/?= =?us-ascii?q?jEqwkDpz2vzLMbLsDo/NI3TeirvtY7lw51BGxAYu1dxf4ohbCrAFIPL9QE/xs9?= =?us-ascii?q?nYAwciMwOqx+bnCdN91p4RWG6WGaCZN77SsVmU6e0xOOmBf5MVuTbhJPgl4P7i?= =?us-ascii?q?l3k5mUQHcqWz0psXb264Eux8I0qFeXrsnssBEWASswo8S+zqjkeNUSJTZ3moWa?= =?us-ascii?q?Ix/TM7CIWgDYfGXI+tm6CB0zmhHp1NfGxGDUqMEXjwfYWeR/gMcD6SItNmkjEc?= =?us-ascii?q?V7ihSZUu2g2ttA/hzLpnKOvU+jMDuJLt0Nh1+uLSmgov9TxyE8SdznuBT2Zunm?= =?us-ascii?q?MHXzU2xrxwoVRhylef1qh1m/JZFd1X5/NMTAg6L4XRz+JkBN/vXQLBZM2GSE68?= =?us-ascii?q?QtWhAzE+UM4+w8MUb0Z6AdWigQjJ3zC2DL8Ni7yLGJs0/7rB0HftIsZ9zHDG1L?= =?us-ascii?q?U8g1Q9XMtAK3emhq9+9gjUAY7FiUOZmLi2da4Exi7C6H+DzXaSvEFfSAN/TLnF?= =?us-ascii?q?UmoFZkbNsdv54UbCQKO0BrQ8LgtN08iCJbVWatfxl1VJWO/jOMjCY2K2g2qxBR?= =?us-ascii?q?eJxrSKbIfxfmUd2DzRCEkCkwwJ+3aJLxI+BiSgo2LAEjNiD1TvbF3w8eNmsnO0?= =?us-ascii?q?Ulc0zx2Wb01mz7e65AYViuaGS/MSxbIJoz8hpC9uHFa8xNLWE96AqBB9c6pCe9?= =?us-ascii?q?89501H1W3BvQxnIpOgN7xihkIZcwlvsUPuzQ94CoNcnsgrt3Mn1w9yKbqZ0F9Y?= =?us-ascii?q?bDOZ04vwNqfQKmno8xClc7TW1U3G0NaK5qcP7+w1q1b5swGqEUoi7m5q09pP3H?= =?us-ascii?q?uf4ZXKERAeUZXrUkY47xJ6va3VYjEh54PI0n1hKbO7vSLY29IoGuQl0A2tcM1D?= =?us-ascii?q?P6OBDgPyFNcaB8e2Iuwwh1epdg4EPPxV9KMsJcOpauaJ1bWkPOZlkzOql2JH75?= =?us-ascii?q?5h0kiU7SpzVvbI34oZw/GfxgaHTDn8jE2mssDshYBJfioSHmy4ySnqAY5efKty?= =?us-ascii?q?cZwNCWiwP8293s9+iIL1W35E6F6jAEsL2cGzdhqWc1zywxdQ1V8MrHy5hyS41S?= =?us-ascii?q?d7kywsrqaF2yzO2evifgIdOmFXXGlikUvsIY+sgtAcXUioawwpmwW+5Uvh3adU?= =?us-ascii?q?ur5/L27JTUdPZSj2IHloUrGsubqaf85P9JQovD1JUOS9fV+aVrn9owEA3yz/H2?= =?us-ascii?q?tewzY7dz6xt5X9nhx6jniSLGx0rHbDfsFw3xjf7sTGRfFNxjoGWDV4iT7PC1i4?= =?us-ascii?q?Ptmp5smUm47Ysu+gU2KhV5tTcTTkzI6bryu7/WxqARu+n/+vgd3rCw463jHn19?= =?us-ascii?q?NyTyXHsA78YpX316S9Ke9nZE5oBFv468VkAIFxjowwhZ8L1HgBm5Wa4WEHnX30?= =?us-ascii?q?MdVB1qL0dGANSiITw97J/Ajl31VuLnGXyIL/TXWQ2chhaMe8YmMN3CIy8dxKBL?= =?us-ascii?q?2T7Lxekit/ukC4oh7JYfhhgjcdzuMj6GYAjOEUvAoi0D2dDaoUHUlEIyPsjQ+F?= =?us-ascii?q?782lrKpJfmavaqK81FF5ndC8FrGNvh9TWHj+epc4Ei9/8N9zMFTS333v8ovkYs?= =?us-ascii?q?XfbcoPth2IlBfNl/ZVKJQsmfcRmypnP3/yvX0/x+49kxNuwYmwvJKbJGV14KK5?= =?us-ascii?q?HhlYOyX7Z8wJ/DHtkaFensON0oChAJpuBzILXIHyQvKwCjISsvbnOBiSHz0gsH?= =?us-ascii?q?ubHqDfHQCH4kd8s33PC4yrN22QJHQByNVtXh2dJEhBjwAIQDU1hIQ2GxusxMP/?= =?us-ascii?q?bEd5/Swe6UTgqhRS0O5oMQfwUnvHrgeydjg0UISfLAZR7gxa6UfVK9KR4f9oHy?= =?us-ascii?q?5C+J2hsAuNKneAagtSEW4JX1aIB1f5Prmh/dPA6fSXBvKiL/vSZrWDsepeV+2S?= =?us-ascii?q?ypK3yotr5DiMNsSVPnl5E/071EtDXXZjFMTfhzoPSjYYlybXY86cvhe89TV9rt?= =?us-ascii?q?qj//TzRALv+YyPBqNKMdpx4B+5n6GDN++MhCZ+MjtY140DymHWx7QF214SkS5u?= =?us-ascii?q?fSG3EbscrS7NUL7QmqhPAhEAcCx/M89I76Mn3glRIs7XkMj12aBkgfIvEFdKS1?= =?us-ascii?q?jhmsCvZcwXLGCwL0/IBUaRNLSbPj3H2c/2brmgSb1Li+VUsQe8uTGBE0/sJj6D?= =?us-ascii?q?jSXmVwizMeFQiyGWJAdRuICychZqD2juV8/pZQOgP992lzI2x6c4hnTQNW4TKT?= =?us-ascii?q?J8aV9CrqWM7SNEhfVyA3ZO7nV/IumahSmU9O7YKo4IvvttByR7jeNa4HAhxLtS?= =?us-ascii?q?4yBIXvt1mDHdrtR2uVGpjvGPyiZ7UBpJsjtLmIWLvUB4NaXD8ZlBWGjL/BQW4m?= =?us-ascii?q?WKDBQFudhlB8bztKBXz9jAiLj8KCxe897O+8sTGdTUItqdMHU9KRrpBCLUDAwd?= =?us-ascii?q?QD6pNWHeh1RdkPaW9n2Uspg1tIPhmJ8PSr9HTlw6COkWCkN/HNwNOJ13RC8rka?= =?us-ascii?q?aHjM4U4nqztBrRRcVevp/ZTf+SBPLvKDiXjbZaexsI3bP4LYMWNoLlwUBibEd1?= =?us-ascii?q?nJjSEUrKQd9NujFhbhMzoEhV9nhxUHc820b+ZwOu538TDuK0kQQwigtlYuQt9S?= =?us-ascii?q?3g41EpKVrWvCEwilU+mc35gTCNdz78NL2wUp9NCyXqrUcxKI/0QwZuYAKpnExk?= =?us-ascii?q?LirLR7Vfj7t4b2Bklg/dtYFJGfFCUa1OeAUQyu2PZ/U0zVRcrT2qylJA5evDD5?= =?us-ascii?q?ttiRUlcZqtr39bwQ1scsQ1JavKKKpO1FhQibqEvjW02eAp3A8eO0EN/XuPdyES?= =?us-ascii?q?pkwIN6QpJzGz8+N28wyCgTxDeWYXV/U0vv1q61k9O+WczyPgybJDLF6+N/CHJa?= =?us-ascii?q?ODp2fAjdKIQk831k4Qk0lF+qJ23tklc0uVUEAi17SRFxIUNcbYLgFVdcVS/mDJ?= =?us-ascii?q?fSmSqeXN3Y51P4KlG+DzU+COsKcUgkS5HAcmBIkD8sMBHpyw307CNsfnMKQJyR?= =?us-ascii?q?Mz6wT3PF+FFuhGeAqXkDcbpMGy1IN33YhYJjEaHWV9MSW2663KqQ8rgPuMRsw5?= =?us-ascii?q?bm0cXoQaKnI8QNe6lDJBv3RcEDm31foUxxKG7z/9uivfEiHzb99jZfeSYhNsDs?= =?us-ascii?q?u59C4k/Ki3k1HX9IzSJ2/nNdh4vN/A9/8arY6dC/xIVbl9r1vcm45ASnOxTWHP?= =?us-ascii?q?F8W4KILtZIkyc9P0EG26XUalizM1VcvxO8ytLqeQiwHyWYlUqJWb3CwkNcKlGT?= =?us-ascii?q?EeBhZwp+UH5K1iYA0OeIc0bgDzuAQ/LaO/Jh2U0tK0Q2aiMTFWVeVQzf2mZ7xL?= =?us-ascii?q?yCohdvW6yH0hTp4mz+m39koNRIoSgB/H2PitfZVTXy/oF3NBfAXPoDY2mHJ6Nu?= =?us-ascii?q?Yu2Os/xg3HsUUEOTCRaONpcHBEv807BV6KO3V5EHA4R1iHgofY/g6sxaod/zVD?= =?us-ascii?q?kNZQ0O1Ftnf+vpveYDKjWKyrtZvVvDA6bdgjuaFxN5LsIteevpPEgjPfVIXQsh?= =?us-ascii?q?GCUCOiGftWgMRfICJZQPlNmGEqI88GtJFA6UUvSMgxOaZDCK42prClcTBkFzId?= =?us-ascii?q?zTcFV4Oc2zwPmuK81KHAlheTbpsiLB0EsJNNgtYGXS95eCUeq7OnV4XRim+LV3?= =?us-ascii?q?MLLB0V7QtS+AIKjpVwcfz94IrUUJ9MzCZbrOhuUivWEJlk7Vj7R3qXgVj5SfWh?= =?us-ascii?q?j/em0RhUzP3yztkRQAR/BlRFx+ZKiksoL6l6K6gWvo7WrDCIcV31vGfzx+u6Pl?= =?us-ascii?q?lQydbZd1rgDIXbs2r8VzcT+XwQRYBUz3HeGo4ekw1jaKYkvF9MOpypel7i5zw4?= =?us-ascii?q?wIRkB6W4Vceux1s+sXYKWyKqHMFbB+Fgrl3XRCVvY4q3p5X9J5VSXmhQ9YWdq1?= =?us-ascii?q?hDikViKSq5xodHJs5Q/DEMRCBPriuZvNSsUs1Pw8h2D4UDIt1noXfyBLtEOISN?= =?us-ascii?q?o30xorHvyHjZ9C4nvVin2jqzALG3T/hF/2IABwolPWKepVczD+E06Gfd7kjNsk?= =?us-ascii?q?xo/+dcHrWPkVh+ryt8Hp9UAjZEzmyqL1N2THZaqepaM7jVf9ZaQ/YseR+lIwY+?= =?us-ascii?q?GuI+30yV4UF0mm/0bDd8tgRG5yzQXRQ4WCcOj7jxnj0er92oNiUBS5JUdzkhaT?= =?us-ascii?q?nKKx6DkyBNoBlfc11qW4weAttd4bEUw5Zb/srYRkawMiwFWBtiNhwm3vZBiUFD?= =?us-ascii?q?t1iXdj7HAQqua/nPrgV9fd2No86xMPT54ABHh5v/sOAj66UMXWCpmRG2TNDFqI?= =?us-ascii?q?/8q8eKuVeQe6f+L+28e2XOTDzWgRC3n7ckAIHA/zLPPwpDN5l61X0kbID9CW7R?= =?us-ascii?q?IxtJOb8UKlFGVaB+ddVGuPpVZ9FleKYO/a9iGA6HSgnoGIy1o/lMNkzTSijGLy?= =?us-ascii?q?Wd7uy/ppre7b7HRuj6YcyM3HLHTLhpPpph7Dn7BrPq0ZNf+kXq2/di7EV6SUPc?= =?us-ascii?q?PyCGttThKRsB5NO+eUv6op0pATTWDY9ykHX3wEFAedAXQyq3/5sG055Z9Gz/Se?= =?us-ascii?q?Rj0kj0quFS8adr6ZUv6bBz1ci0PbvSKehdsUJ/BBiUAh5n9pQrAGh6XWxRY+kR?= =?us-ascii?q?KPnLfasDlsDut/r3F7EL5x2J5uxZc8XIK1vGmsmlBTGWUQZEkxsZqT4GMguc0O?= =?us-ascii?q?aIm6l1Scm5ouj53lgi40OkIh4Hy7Bt4pyE+rGTqe/SYBbQwqIIWq/wRsP8tr4s?= =?us-ascii?q?oV+d5eU4lL4SfWx4exGoH/IZVsED3Wfg0aArzSU3HsPYA73g+eBMV3QlnjLhgZ?= =?us-ascii?q?9xBVMWFe0IHbCT54RRgn84m/DFNt0Raq1Cnn2PFRukH7IZx36k9TaYIG5/gh7U?= =?us-ascii?q?yxHwW2Sz7F3ooiBkXSvA1dDjklBaVrOvH0ddQzKpOVNksDOIJAfottv3uaEu4U?= =?us-ascii?q?EzLGPltMyClHGgOLNREM3zPtqcLjcopFgPlp0+WsSv2ZwHGdq6ONoR8XB/YeHE?= =?us-ascii?q?5Gy3iCJBuLlIh5bA7c6J4PnXGmOgj6KCobWX2D9Y0mQ4vU046t24Lf7O5saKQv?= =?us-ascii?q?qy2GYTTid/pxPBUASoqrzftF0bJUuL31rVl4MQI9FZx3441lv86+Q5R9Iz7gpe?= =?us-ascii?q?HJ7aZ/wevTDzJCf0wVGHbtIvTCaezydYHlL7EFl/Aqg823v8vNnXmnfU+l0oQJ?= =?us-ascii?q?RwdkP8iBxvFYo4NV4i6FgZwyoECwgNagqXDLK2CkT/K4sLS0wDZQ6A3Ligdac9?= =?us-ascii?q?xVdzza+35O/Pcex8ALIANvlHgQ6UgldbBpIWvLYaQLJ9Z19S6q7XqRL/C4j8Rf?= =?us-ascii?q?Tmk2Q/NeGtSMBA7c8Zr2ci4hq4Rxe45pdM8bAbiIyPdq5DZpTMp95z70Nm5T4J?= =?us-ascii?q?ayxMjwNyjxenXuAGpOHs+MLXsJy25eayTKwtXfkY9wAoB2RiiJv9mEwsodPN2O?= =?us-ascii?q?hAUYDalYP/8ARJI36LponayQV8JvQSJIKrZrpg8G8HJycGLXIUIdWWc+U84zNq?= =?us-ascii?q?MDjL4lxCBcUMZc8XPMXTgg1Uj0zpV6tV9sXFBl+ZBYBzd9or72rs0jw194UzUv?= =?us-ascii?q?r44j+sOZ/f901NP+9EjCh0m9LNuPMVweHLBCYK7neXbRl1wiWfy5iCEPvw8uCM?= =?us-ascii?q?x8vSV1wYBCI2VJ1dJDWa8wy9WuW1jInpUh+T6sLrgpI+c0KQRnqrkKsZsqZMFf?= =?us-ascii?q?NAhTj63zhfEID1nPGVs9u35WtJt11HDpx87RnYF6VeJJl7Pwr3ltWzTEhmGiT/?= =?us-ascii?q?YN3UdgYpuOeOx+cM/f9xN03laI8fPxIL1rP66X1OTgd0T772pFmZV/oLZNR6UP?= =?us-ascii?q?PEsmxV6YV4Jq8NIledqpLqrjNTpVE4GgApbqE/riBAeknIggJVR77+uKQchQsE?= =?us-ascii?q?Td55pUhMFHq/OGI64DrGW7pajK2VCPEO6TWTSaoOU0R0PS9kRRO6xolucaOznf?= =?us-ascii?q?9bqmNGgj99oP8y3jx6RRu8vDbhp74M2T08+7G3qjEBtWZDTuqAjyfCEU9Dw+gS?= =?us-ascii?q?jacAF3bi7kSxYHwCbIvx47lnIt/t9Ys77HQ8ZhUjeTMJXeK6ByH2kayIHpSFsM?= =?us-ascii?q?hAix6VpMXOcbizIDAJObsjzxLjW2Nw0hPanBZv7GsLXiug48E5K4mnPsYl3CWo?= =?us-ascii?q?E3DBdFkQ+qNJrNfxtVkTQesublNhxH9s0tKJRy0KQMzPFX04jg0jaWVDa5JM9w?= =?us-ascii?q?MVF7MvgjaTpalG/wcUYDjOHoSi4InQkt/C2WMhQtdy2mLWuqqFi4sk0HJ7n9N0?= =?us-ascii?q?7zaOt2oJeu3ZUs9sB33z2ZlFyez6efqhqOcHSJFpyL65Sv8NLtGj+Xeq2JVtQk?= =?us-ascii?q?KkyKweH0C4MOAf2LjWSCKlSWyEWeSRbWeAhTE5MlT95ROwNF04dN9Kr1MhMuvF?= =?us-ascii?q?npNckAnhXq1vSyWIoV/U1ncjMf8bdw0qpIenYRIFQ/ALa+iaO+cu3OU0CEEQYH?= =?us-ascii?q?/RASt2F+i2vEapnIh6PXVg/Er7bf3p8gDnK9uSBgIEHJXbrpFr//y6QXiNOXh6?= =?us-ascii?q?zB19JEN07fvQF0wttu9AdJachd3QiM5n3u4FdvdtNyo9t8UNmoJi74mbzsOKcR?= =?us-ascii?q?DXzpbvKtDZuP+YA+fQz04yYGFVTqIZYR/p54U9JtM5WafcHbhevRsHHqU6XZoh?= =?us-ascii?q?N3vx9KFzMQNzfQ7RZKiujsnsuO2LeoNep2XK4VIoMCfcpxoDx+SvTQx1apClm3?= =?us-ascii?q?T/LZMrSzJfsdJtEBpmHYpIG8MGtQanBYCbmL3ow+O2rmdBnqdetav2F+CPz9my?= =?us-ascii?q?wp9wQ4kf4EuHITLcLLdkj14jjemohPrElJ7rBpWmMfENUeVgCkvCcKXHBc3rKD?= =?us-ascii?q?eJINj9YGZA+ruR0fR+SBrHNw7jWK/TnyS/OeQs2k47w5F2eOfJhGgm5qrWyfPp?= =?us-ascii?q?bGFSuymnoGTMP5IZ51vPU7+NFylIQOaIpT42VZYcapH5oaJfadE=3D?= X-IPAS-Result: =?us-ascii?q?A2BPAgBVM6Fa/wHyM5BeGQEBAQEBAQEBAQEBAQcBAQEBAYN?= =?us-ascii?q?NA2ZvKINQixGNBIICexuBUJJZghIlA4UKAkWCRSE2FgECAQEBAQEBAgFqJ4I4J?= =?us-ascii?q?IJIAwMBAhcBCAQZAQE3AQIDCQEBIQMCIgQCAgMBQQoIBgEMBgIBAQGEfAMVA58?= =?us-ascii?q?MiyZtgWw6gwEBAQWBaYI9A4E6ghUIF3eEJ4E1eYM8KYJOghGDX4JwgmKIGAeFV?= =?us-ascii?q?HVFiyYJhkmKGHWIOYU6i0WHLiUKJ4FSTSMVOoJDCYIZDxyCHFaLZgEBAQ?= Received: from tarius.tycho.ncsc.mil ([144.51.242.1]) by emsm-gh1-uea11.NCSC.MIL with ESMTP; 08 Mar 2018 13:01:57 +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 w28D1twB014722; Thu, 8 Mar 2018 08:01:56 -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 w281rLuY106864 for ; Wed, 7 Mar 2018 20:53:21 -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 w281rOBj030434 for ; Wed, 7 Mar 2018 20:53:24 -0500 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A1AKAQCHlqBalywYGNZeHAEBAQQBAQoBA?= =?us-ascii?q?YNNaXAog1SLGI0IgVAyexuBUJR5JYUVAkWCRSE3FQECAQEBAQEBAhMBAQEBAQY?= =?us-ascii?q?YBoV6AwMaAQgEGQEBNwEPIgMCJgICRQoIBgEMBgIBAYR/AxUDnnCLJm6BbTqDA?= =?us-ascii?q?QEBBYFqgjsDgTqCFQgXeIQjgTV5gz0pgk6CEYNfgnKCYoggB4VZdUaLMAmGVIo?= =?us-ascii?q?kd4hHhUOLSoc7NIF0TSMVOoJDCYIZDxAMghxWjAUBAQE?= X-IPAS-Result: =?us-ascii?q?A1AKAQCHlqBalywYGNZeHAEBAQQBAQoBAYNNaXAog1SLGI0?= =?us-ascii?q?IgVAyexuBUJR5JYUVAkWCRSE3FQECAQEBAQEBAhMBAQEBAQYYBoV6AwMaAQgEG?= =?us-ascii?q?QEBNwEPIgMCJgICRQoIBgEMBgIBAYR/AxUDnnCLJm6BbTqDAQEBBYFqgjsDgTq?= =?us-ascii?q?CFQgXeIQjgTV5gz0pgk6CEYNfgnKCYoggB4VZdUaLMAmGVIokd4hHhUOLSoc7N?= =?us-ascii?q?IF0TSMVOoJDCYIZDxAMghxWjAUBAQE?= X-IronPort-AV: E=Sophos;i="5.47,438,1515474000"; d="scan'208";a="219229" Received: from emsm-gh1-uea10.ncsc.mil ([214.29.60.34]) by goalie.tycho.ncsc.mil with ESMTP; 07 Mar 2018 20:53:22 -0500 IronPort-PHdr: =?us-ascii?q?9a23=3AMD9HQBOWsdEpU5GuBvgl6mtUPXoX/o7sNwtQ0KIM?= =?us-ascii?q?zox0IvX4rarrMEGX3/hxlliBBdydt6ofzbqN+Pu/EUU7or+5+EgYd5JNUxJXwe?= =?us-ascii?q?43pCcHRPC/NEvgMfTxZDY7FskRHHVs/nW8LFQHUJ2mPw6arXK99yMdFQviPgRp?= =?us-ascii?q?OOv1BpTSj8Oq3Oyu5pHfeQpFiCazbL9oLxi7owrdu8cUjIB/Nqs/1xzFr2dSde?= =?us-ascii?q?9L321oP1WTnxj95se04pFu9jlbtuwi+cBdT6j0Zrw0QrNEAjsoNWA1/9DrugLY?= =?us-ascii?q?TQST/HscU34ZnQRODgPY8Rz1RJbxsi/9tupgxCmXOND9QL4oVTi+6apgVQTlgz?= =?us-ascii?q?kbOTEn7G7Xi9RwjKNFrxKnuxx/2JPfbIWMOPZjYq/RYdYWSGxGUclTTSNBAoS8?= =?us-ascii?q?b4wWA+YYIetVoYjwq0YXoReiGAWnGefjxiFUinPz26AxzuYvHhzc3AE4AtwArn?= =?us-ascii?q?rUotX2OqkcX++6w6vHwinMYf5NxTfw6pLFfgw9rfyCX799d9fax0k1FwPCi1Wd?= =?us-ascii?q?sZLoMCmO1usTs2mQ8vduWv6vi2E9tgFxrDyvydk2ioLUgY8a1krL9T5nz4c1Pt?= =?us-ascii?q?C4U1J0Yd6+H5tNuSGaM5V5Qtk7T250oik20KEJuZm+fCUTzpks2h3Ra+SffoSW?= =?us-ascii?q?/x7uW/ydLSl3iX5/Zr6yiAy+/Eevx+HkV8S50UxGojdEn9TCrHwByhje5tWdRv?= =?us-ascii?q?dg/kqs1jCC3B3J5O5eO0A7j6/bJoYhwrEukpoTtlzOESHolUvviqGbeFsp9PK0?= =?us-ascii?q?5uj7Y7jqvIGTOJFxigHlPaQigMm/Dv45MggKRWSb/OW81Ln78U34RrVFkOE2n7?= =?us-ascii?q?HHvJzHKskXvLC1DgBP3oo95BuzFTir3dsAkXkCNl1FeRaHj4bzO1HJJfD1Feuw?= =?us-ascii?q?jE63kDh1x/HLJabhDYnNLnfZjbfhc7J95FBGyAYq0d9Q/YhYBa0GIPL2QkPxrs?= =?us-ascii?q?DXDgclMwyoxObqEM592Z0aWWKOBK+ZLazTvESU5uMvP+aMZIgVtCz7K/g+/fHi?= =?us-ascii?q?l3A5mVgDffrh4ZxCTEudVqBiIkOEcT/3j9wcC2YWr087S+D3jFCqTzFefTCxUr?= =?us-ascii?q?g66zV9D5ipW8OLZImojafJ+SChBJxNLjRED1eWC3bzX4ONXvoNLiWILZkyvCYD?= =?us-ascii?q?UO2KQpQsxFmVvw/z1rRjI/CcriYRrp/y/MN+5+TOmxU/73l/BoKW1GTbHDI8pX?= =?us-ascii?q?8BWzJjhPM3mkd60FrWlPggjg=3D=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0D1AAA8l6BalywYGNZeHAEBAQQBAQoBA?= =?us-ascii?q?YNNaXAog1SLGI0IgVAyexuBUJR5JYUVAkWCRSE3FQECAQEBAQEBAgESAQEBAQE?= =?us-ascii?q?GGAZWgjgkgkgDAxoBCAQZAQE3AQ8iAwImAgJFCggGAQwGAgEBhH8DFQOecIsmb?= =?us-ascii?q?oFtOoMBAQEFgWqCOwOBOoIVCBd4hCOBNXmDPSmCToIRg1+CcoJiiCAHhVl1Ros?= =?us-ascii?q?wCYZUiiR3iEeFQ4tKhzs0gXRNIxU6gkMJghkPEAyCHFaMBQEBAQ?= X-IPAS-Result: =?us-ascii?q?A0D1AAA8l6BalywYGNZeHAEBAQQBAQoBAYNNaXAog1SLGI0?= =?us-ascii?q?IgVAyexuBUJR5JYUVAkWCRSE3FQECAQEBAQEBAgESAQEBAQEGGAZWgjgkgkgDA?= =?us-ascii?q?xoBCAQZAQE3AQ8iAwImAgJFCggGAQwGAgEBhH8DFQOecIsmboFtOoMBAQEFgWq?= =?us-ascii?q?COwOBOoIVCBd4hCOBNXmDPSmCToIRg1+CcoJiiCAHhVl1RoswCYZUiiR3iEeFQ?= =?us-ascii?q?4tKhzs0gXRNIxU6gkMJghkPEAyCHFaMBQEBAQ?= X-IronPort-AV: E=Sophos;i="5.47,438,1515456000"; d="scan'208";a="9474829" X-IronPort-Outbreak-Status: No, level 0, Unknown - Unknown Received: from ucol3cpa06.eemsg.mail.mil ([214.24.24.44]) by EMSM-GH1-UEA10.NCSC.MIL with ESMTP; 08 Mar 2018 01:53:21 +0000 X-EEMSG-check-005: 0 X-EEMSG-check-006: 000-001;aaf769a0-fb22-4bf4-aec3-ca7d06dea661 Authentication-Results: ucol19pa13.eemsg.mail.mil; dkim=pass (signature verified) header.i=@yahoo.com X-EEMSG-check-008: 577852955|UCOL19PA13_EEMSG_MP11.csd.disa.mil X-EEMSG-SBRS: 3.5 X-EEMSG-ORIG-IP: 66.163.191.154 X-EEMSG-check-002: true X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0ByAABrlKBah5q/o0JeGwEBAQEDAQEBCQEBAYQ2cCiDVIsYjlgyexuBUJR5JYUVAkWCRSE3FQECAQEBAQEBAhMBAQEIDQkIKC6FJAMDGgEIBBkBATcBDyIDAiYCAkUKCAYBDAYCAQGEfwMVnnCLJm6BbTqDAQEBBYFqgjsDgTqCFQgXeIQjgTWENimCToIRg1+CcoJiiCAHhVl1RoswCYZUiiR3iEeFQ4tKhzs0gXRNIxU6gkMJghkPEAyCHB83jAUBAQE X-IPAS-Result: A0ByAABrlKBah5q/o0JeGwEBAQEDAQEBCQEBAYQ2cCiDVIsYjlgyexuBUJR5JYUVAkWCRSE3FQECAQEBAQEBAhMBAQEIDQkIKC6FJAMDGgEIBBkBATcBDyIDAiYCAkUKCAYBDAYCAQGEfwMVnnCLJm6BbTqDAQEBBYFqgjsDgTqCFQgXeIQjgTWENimCToIRg1+CcoJiiCAHhVl1RoswCYZUiiR3iEeFQ4tKhzs0gXRNIxU6gkMJghkPEAyCHB83jAUBAQE Received: from sonic304-28.consmr.mail.ne1.yahoo.com ([66.163.191.154]) by ucol19pa13.eemsg.mail.mil with ESMTP; 08 Mar 2018 01:53:18 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1520473998; bh=vYDDE5/B3NqEiHf2WGK9gESmNSpOiUj/Um5ZbSqiFG8=; h=Subject:To:Cc:References:From:Date:In-Reply-To:From:Subject; b=qhpqeedqA2guft4kDvy0HF9I71XG6lt/LusnHd8zm1SI3tUcnNWYen64DMdx+DgX5g3aKgpA3cG8fqX8AliEZJ+7wvzVpJ3Hv7gymG/WnNOeWZy2/FAo9THYm8qKaGEiAqY1l0H6DOn456dHhDBNke+3UhgcxZem1nJkeZefolpWxrRYQ9LzTWqryE8CejLLY4cKZIPkpWCCroea9q/H4BRbsvp1WFJo2074nntTyEQiNnhFXPkAC8peimPe83hXCmbgrbIU4MN+pXmkJV6MFWWR4VbeRvkbJiFLRsQcSdp1Xl2nSdQhb19o/AXj1Z1T2b/N5cJjmfw28K4eUfTu2g== X-YMail-OSG: blkds0AVM1m9VO1ZMfMmTDr_0IKy9GbYGDL1BMDjx57ocEi4WDyz9QoNQ1cv0.M uWaaIGs_KaF8CtY_4RaBC8AGu5meXci2pZ.F_RWK3bBDEz0itDGnknmQ_Pv2dq.Yn4mPd8KpbYdO UUMyqYec5t_FdHw5KQPe3o4L.tTEmFmwwiw9HuZg_7bNraxxBOLL6gpQ.3bSnMfdRnrV06NQR9u3 256zgVgwt80sa38irx.wnsbqUHJfsy7pu9gQB7idOOCSLE9zhyAfgaH9yjaQj4puquPYeYn8xKw4 1LD07.o_mg2HMEzR7GbqZqwSg614XcCtHjfiODSR1phgSWFpKv1i_KfftW9ajSaRBDcSgZmiSudr Yvzrdga.pjMCvoMbp8b1pGomHFWp2ApDuwGcyoperzm.wHosdFFrt0WfV3Tm6Dp1pvBKZu727zNf jWfmA4BxBq0.msk40QdjSWkZ4hbUjqvfl1AldDKHeo27aakI4OEc1i2Dk7tywrVmcXGkuk6jVwTg wGe2OsyZq9qY6SP.j8li4XtmG3rFDbjb3EG3PT8DdkYj2SSHyypa2ZT82yYIR5Lpf Received: from sonic.gate.mail.ne1.yahoo.com by sonic304.consmr.mail.ne1.yahoo.com with HTTP; Thu, 8 Mar 2018 01:53:18 +0000 Received: from smtp232.mail.ne1.yahoo.com (EHLO [192.168.0.104]) ([10.218.253.209]) by smtp416.mail.ne1.yahoo.com (JAMES SMTP Server ) with ESMTPA ID 411150156728ecd633034a64be76a28c; Thu, 08 Mar 2018 01:53:17 +0000 (UTC) To: LSM , James Morris References: X-EEMSG-check-009: 444-444 From: Casey Schaufler Message-ID: <098ce144-c71d-d3bb-c400-2cdf1b8a80bf@schaufler-ca.com> Date: Wed, 7 Mar 2018 17:53:15 -0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 In-Reply-To: Content-Language: en-US X-Mailman-Approved-At: Thu, 08 Mar 2018 08:00:06 -0500 Subject: [PATCH 5/8] LSM: Manage remaining security blobs 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: John Johansen , Tetsuo Handa , SE Linux , Stephen Smalley , SMACK-announce@lists.01.org, Kees Cook Errors-To: selinux-bounces@tycho.nsa.gov Sender: "Selinux" X-Virus-Scanned: ClamAV using ClamSMTP Subject: [PATCH 5/8] LSM: Manage remaining security blobs Move management of the inode, ipc, key, msg_msg, sock and superblock security blobs from the security modules to the infrastructure. Use of the blob pointers is abstracted in the security modules. Signed-off-by: Casey Schaufler --- include/linux/lsm_hooks.h | 8 + security/security.c | 298 ++++++++++++++++++++++++++++++-- security/selinux/hooks.c | 333 +++++++++++------------------------ security/selinux/include/objsec.h | 65 ++++++- security/selinux/netlabel.c | 15 +- security/selinux/selinuxfs.c | 4 +- security/selinux/ss/services.c | 3 +- security/smack/smack.h | 61 ++++++- security/smack/smack_lsm.c | 353 +++++++++++--------------------------- security/smack/smack_netfilter.c | 8 +- 10 files changed, 631 insertions(+), 517 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index da09168e4daa..03f036ab7b59 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1975,6 +1975,12 @@ struct security_hook_list { struct lsm_blob_sizes { int lbs_cred; int lbs_file; + int lbs_inode; + int lbs_ipc; + int lbs_key; + int lbs_msg_msg; + int lbs_sock; + int lbs_superblock; int lbs_task; }; @@ -2038,9 +2044,11 @@ static inline void loadpin_add_hooks(void) { }; #endif extern int lsm_cred_alloc(struct cred *cred, gfp_t gfp); +extern int lsm_inode_alloc(struct inode *inode); #ifdef CONFIG_SECURITY void lsm_early_cred(struct cred *cred); +void lsm_early_inode(struct inode *inode); #endif #endif /* ! __LINUX_LSM_HOOKS_H */ diff --git a/security/security.c b/security/security.c index 8d6738f384fa..4ca49b5074f8 100644 --- a/security/security.c +++ b/security/security.c @@ -28,7 +28,9 @@ #include #include #include +#include #include +#include #define MAX_LSM_EVM_XATTR 2 @@ -39,6 +41,7 @@ struct security_hook_heads security_hook_heads __lsm_ro_after_init; static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain); static struct kmem_cache *lsm_file_cache; +static struct kmem_cache *lsm_inode_cache; char *lsm_names; static struct lsm_blob_sizes blob_sizes; @@ -92,6 +95,10 @@ int __init security_init(void) lsm_file_cache = kmem_cache_create("lsm_file_cache", blob_sizes.lbs_file, 0, SLAB_PANIC, NULL); + if (blob_sizes.lbs_inode) + lsm_inode_cache = kmem_cache_create("lsm_inode_cache", + blob_sizes.lbs_inode, 0, + SLAB_PANIC, NULL); /* * The second call to a module specific init function * adds hooks to the hook lists and does any other early @@ -102,8 +109,16 @@ int __init security_init(void) #ifdef CONFIG_SECURITY_LSM_DEBUG pr_info("LSM: cred blob size = %d\n", blob_sizes.lbs_cred); pr_info("LSM: file blob size = %d\n", blob_sizes.lbs_file); + pr_info("LSM: inode blob size = %d\n", blob_sizes.lbs_inode); + pr_info("LSM: ipc blob size = %d\n", blob_sizes.lbs_ipc); +#ifdef CONFIG_KEYS + pr_info("LSM: key blob size = %d\n", blob_sizes.lbs_key); +#endif /* CONFIG_KEYS */ + pr_info("LSM: msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg); + pr_info("LSM: sock blob size = %d\n", blob_sizes.lbs_sock); + pr_info("LSM: superblock blob size = %d\n", blob_sizes.lbs_superblock); pr_info("LSM: task blob size = %d\n", blob_sizes.lbs_task); -#endif +#endif /* CONFIG_SECURITY_LSM_DEBUG */ return 0; } @@ -278,7 +293,19 @@ void __init security_add_blobs(struct lsm_blob_sizes *needed) { lsm_set_size(&needed->lbs_cred, &blob_sizes.lbs_cred); lsm_set_size(&needed->lbs_file, &blob_sizes.lbs_file); + lsm_set_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc); + lsm_set_size(&needed->lbs_key, &blob_sizes.lbs_key); + lsm_set_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg); + lsm_set_size(&needed->lbs_sock, &blob_sizes.lbs_sock); + lsm_set_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock); lsm_set_size(&needed->lbs_task, &blob_sizes.lbs_task); + /* + * The inode blob gets an rcu_head in addition to + * what the modules might need. + */ + if (needed->lbs_inode && blob_sizes.lbs_inode == 0) + blob_sizes.lbs_inode = sizeof(struct rcu_head); + lsm_set_size(&needed->lbs_inode, &blob_sizes.lbs_inode); } /** @@ -323,6 +350,154 @@ int lsm_task_alloc(struct task_struct *task) return 0; } +/** + * lsm_inode_alloc - allocate a composite inode blob + * @inode: the inode that needs a blob + * + * Allocate the inode blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_inode_alloc(struct inode *inode) +{ + if (!lsm_inode_cache) { + inode->i_security = NULL; + return 0; + } + + inode->i_security = kmem_cache_zalloc(lsm_inode_cache, GFP_KERNEL); + if (inode->i_security == NULL) + return -ENOMEM; + return 0; +} + +/** + * lsm_early_inode - during initialization allocate a composite inode blob + * @inode: the inode that needs a blob + * + * Allocate the inode blob for all the modules if it's not already there + */ +void lsm_early_inode(struct inode *inode) +{ + int rc; + + if (inode == NULL) + panic("%s: NULL inode.\n", __func__); + if (inode->i_security != NULL) + return; + rc = lsm_inode_alloc(inode); + if (rc) + panic("%s: Early inode alloc failed.\n", __func__); +} + +/** + * lsm_ipc_alloc - allocate a composite ipc blob + * @kip: the ipc that needs a blob + * + * Allocate the ipc blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_ipc_alloc(struct kern_ipc_perm *kip) +{ + if (blob_sizes.lbs_ipc == 0) { + kip->security = NULL; + return 0; + } + + kip->security = kzalloc(blob_sizes.lbs_ipc, GFP_KERNEL); + if (kip->security == NULL) + return -ENOMEM; + return 0; +} + +#ifdef CONFIG_KEYS +/** + * lsm_key_alloc - allocate a composite key blob + * @key: the key that needs a blob + * + * Allocate the key blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_key_alloc(struct key *key) +{ + if (blob_sizes.lbs_key == 0) { + key->security = NULL; + return 0; + } + + key->security = kzalloc(blob_sizes.lbs_key, GFP_KERNEL); + if (key->security == NULL) + return -ENOMEM; + return 0; +} +#endif /* CONFIG_KEYS */ + +/** + * lsm_msg_msg_alloc - allocate a composite msg_msg blob + * @mp: the msg_msg that needs a blob + * + * Allocate the ipc blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_msg_msg_alloc(struct msg_msg *mp) +{ + if (blob_sizes.lbs_msg_msg == 0) { + mp->security = NULL; + return 0; + } + + mp->security = kzalloc(blob_sizes.lbs_msg_msg, GFP_KERNEL); + if (mp->security == NULL) + return -ENOMEM; + return 0; +} + +/** + * lsm_sock_alloc - allocate a composite sock blob + * @sock: the sock that needs a blob + * @priority: allocation mode + * + * Allocate the sock blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_sock_alloc(struct sock *sock, gfp_t priority) +{ + if (blob_sizes.lbs_sock == 0) { + sock->sk_security = NULL; + return 0; + } + + sock->sk_security = kzalloc(blob_sizes.lbs_sock, priority); + if (sock->sk_security == NULL) + return -ENOMEM; + return 0; +} + +/** + * lsm_superblock_alloc - allocate a composite superblock blob + * @sb: the superblock that needs a blob + * + * Allocate the superblock blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_superblock_alloc(struct super_block *sb) +{ + if (blob_sizes.lbs_superblock == 0) { + sb->s_security = NULL; + return 0; + } + + sb->s_security = kzalloc(blob_sizes.lbs_superblock, GFP_KERNEL); + if (sb->s_security == NULL) + return -ENOMEM; + return 0; +} + /* * Hook list operation macros. * @@ -490,12 +665,21 @@ void security_bprm_committed_creds(struct linux_binprm *bprm) int security_sb_alloc(struct super_block *sb) { - return call_int_hook(sb_alloc_security, 0, sb); + int rc = lsm_superblock_alloc(sb); + + if (unlikely(rc)) + return rc; + rc = call_int_hook(sb_alloc_security, 0, sb); + if (unlikely(rc)) + security_sb_free(sb); + return rc; } void security_sb_free(struct super_block *sb) { call_void_hook(sb_free_security, sb); + kfree(sb->s_security); + sb->s_security = NULL; } int security_sb_copy_data(char *orig, char *copy) @@ -569,14 +753,40 @@ EXPORT_SYMBOL(security_sb_parse_opts_str); int security_inode_alloc(struct inode *inode) { - inode->i_security = NULL; - return call_int_hook(inode_alloc_security, 0, inode); + int rc = lsm_inode_alloc(inode); + + if (unlikely(rc)) + return rc; + rc = call_int_hook(inode_alloc_security, 0, inode); + if (unlikely(rc)) + security_inode_free(inode); + return rc; +} + +static void inode_free_by_rcu(struct rcu_head *head) +{ + /* + * The rcu head is at the start of the inode blob + */ + kmem_cache_free(lsm_inode_cache, head); } void security_inode_free(struct inode *inode) { integrity_inode_free(inode); call_void_hook(inode_free_security, inode); + /* + * The inode may still be referenced in a path walk and + * a call to security_inode_permission() can be made + * after inode_free_security() is called. Ideally, the VFS + * wouldn't do this, but fixing that is a much harder + * job. For now, simply free the i_security via RCU, and + * leave the current inode->i_security pointer intact. + * The inode will be freed after the RCU grace period too. + */ + if (inode->i_security) + call_rcu((struct rcu_head *)inode->i_security, + inode_free_by_rcu); } int security_dentry_init_security(struct dentry *dentry, int mode, @@ -1008,7 +1218,7 @@ int security_file_alloc(struct file *file) { int rc = lsm_file_alloc(file); - if (rc) + if (unlikely(rc)) return rc; rc = call_int_hook(file_alloc_security, 0, file); if (unlikely(rc)) @@ -1131,7 +1341,7 @@ int security_task_alloc(struct task_struct *task, unsigned long clone_flags) { int rc = lsm_task_alloc(task); - if (rc) + if (unlikely(rc)) return rc; rc = call_int_hook(task_alloc, 0, task, clone_flags); if (unlikely(rc)) @@ -1151,7 +1361,7 @@ int security_cred_alloc_blank(struct cred *cred, gfp_t gfp) { int rc = lsm_cred_alloc(cred, gfp); - if (rc) + if (unlikely(rc)) return rc; rc = call_int_hook(cred_alloc_blank, 0, cred, gfp); @@ -1172,7 +1382,7 @@ int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp) { int rc = lsm_cred_alloc(new, gfp); - if (rc) + if (unlikely(rc)) return rc; rc = call_int_hook(cred_prepare, 0, new, old, gfp); @@ -1336,22 +1546,42 @@ void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) int security_msg_msg_alloc(struct msg_msg *msg) { - return call_int_hook(msg_msg_alloc_security, 0, msg); + int rc = lsm_msg_msg_alloc(msg); + + if (unlikely(rc)) + return rc; + rc = call_int_hook(msg_msg_alloc_security, 0, msg); + if (unlikely(rc)) + security_msg_msg_free(msg); + return rc; } void security_msg_msg_free(struct msg_msg *msg) { call_void_hook(msg_msg_free_security, msg); + kfree(msg->security); + msg->security = NULL; } int security_msg_queue_alloc(struct msg_queue *msq) { - return call_int_hook(msg_queue_alloc_security, 0, msq); + int rc = lsm_ipc_alloc(&msq->q_perm); + + if (unlikely(rc)) + return rc; + rc = call_int_hook(msg_queue_alloc_security, 0, msq); + if (unlikely(rc)) + security_msg_queue_free(msq); + return rc; } void security_msg_queue_free(struct msg_queue *msq) { + struct kern_ipc_perm *kip = &msq->q_perm; + call_void_hook(msg_queue_free_security, msq); + kfree(kip->security); + kip->security = NULL; } int security_msg_queue_associate(struct msg_queue *msq, int msqflg) @@ -1378,12 +1608,23 @@ int security_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, int security_shm_alloc(struct shmid_kernel *shp) { - return call_int_hook(shm_alloc_security, 0, shp); + int rc = lsm_ipc_alloc(&shp->shm_perm); + + if (unlikely(rc)) + return rc; + rc = call_int_hook(shm_alloc_security, 0, shp); + if (unlikely(rc)) + security_shm_free(shp); + return rc; } void security_shm_free(struct shmid_kernel *shp) { + struct kern_ipc_perm *kip = &shp->shm_perm; + call_void_hook(shm_free_security, shp); + kfree(kip->security); + kip->security = NULL; } int security_shm_associate(struct shmid_kernel *shp, int shmflg) @@ -1403,12 +1644,23 @@ int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmfl int security_sem_alloc(struct sem_array *sma) { - return call_int_hook(sem_alloc_security, 0, sma); + int rc = lsm_ipc_alloc(&sma->sem_perm); + + if (unlikely(rc)) + return rc; + rc = call_int_hook(sem_alloc_security, 0, sma); + if (unlikely(rc)) + security_sem_free(sma); + return rc; } void security_sem_free(struct sem_array *sma) { + struct kern_ipc_perm *kip = &sma->sem_perm; + call_void_hook(sem_free_security, sma); + kfree(kip->security); + kip->security = NULL; } int security_sem_associate(struct sem_array *sma, int semflg) @@ -1620,12 +1872,21 @@ EXPORT_SYMBOL(security_socket_getpeersec_dgram); int security_sk_alloc(struct sock *sk, int family, gfp_t priority) { - return call_int_hook(sk_alloc_security, 0, sk, family, priority); + int rc = lsm_sock_alloc(sk, priority); + + if (unlikely(rc)) + return rc; + rc = call_int_hook(sk_alloc_security, 0, sk, family, priority); + if (unlikely(rc)) + security_sk_free(sk); + return rc; } void security_sk_free(struct sock *sk) { call_void_hook(sk_free_security, sk); + kfree(sk->sk_security); + sk->sk_security = NULL; } void security_sk_clone(const struct sock *sk, struct sock *newsk) @@ -1855,12 +2116,21 @@ EXPORT_SYMBOL(security_skb_classify_flow); int security_key_alloc(struct key *key, const struct cred *cred, unsigned long flags) { - return call_int_hook(key_alloc, 0, key, cred, flags); + int rc = lsm_key_alloc(key); + + if (unlikely(rc)) + return rc; + rc = call_int_hook(key_alloc, 0, key, cred, flags); + if (unlikely(rc)) + security_key_free(key); + return rc; } void security_key_free(struct key *key) { call_void_hook(key_free, key); + kfree(key->security); + key->security = NULL; } int security_key_permission(key_ref_t key_ref, diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index ed01d18d0924..cb51b66c483b 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -129,8 +129,6 @@ __setup("selinux=", selinux_enabled_setup); int selinux_enabled = 1; #endif -static struct kmem_cache *sel_inode_cache; - /** * selinux_secmark_enabled - Check to see if SECMARK is currently enabled * @@ -224,13 +222,9 @@ static inline u32 task_sid(const struct task_struct *task) static int inode_alloc_security(struct inode *inode) { - struct inode_security_struct *isec; + struct inode_security_struct *isec = selinux_inode(inode); u32 sid = current_sid(); - isec = kmem_cache_zalloc(sel_inode_cache, GFP_NOFS); - if (!isec) - return -ENOMEM; - spin_lock_init(&isec->lock); INIT_LIST_HEAD(&isec->list); isec->inode = inode; @@ -238,7 +232,6 @@ static int inode_alloc_security(struct inode *inode) isec->sclass = SECCLASS_FILE; isec->task_sid = sid; isec->initialized = LABEL_INVALID; - inode->i_security = isec; return 0; } @@ -256,7 +249,7 @@ static int __inode_security_revalidate(struct inode *inode, struct dentry *opt_dentry, bool may_sleep) { - struct inode_security_struct *isec = inode->i_security; + struct inode_security_struct *isec = selinux_inode(inode); might_sleep_if(may_sleep); @@ -276,7 +269,7 @@ static int __inode_security_revalidate(struct inode *inode, static struct inode_security_struct *inode_security_novalidate(struct inode *inode) { - return inode->i_security; + return selinux_inode(inode); } static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu) @@ -286,7 +279,7 @@ static struct inode_security_struct *inode_security_rcu(struct inode *inode, boo error = __inode_security_revalidate(inode, NULL, !rcu); if (error) return ERR_PTR(error); - return inode->i_security; + return selinux_inode(inode); } /* @@ -295,14 +288,14 @@ static struct inode_security_struct *inode_security_rcu(struct inode *inode, boo static struct inode_security_struct *inode_security(struct inode *inode) { __inode_security_revalidate(inode, NULL, true); - return inode->i_security; + return selinux_inode(inode); } static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry) { struct inode *inode = d_backing_inode(dentry); - return inode->i_security; + return selinux_inode(inode); } /* @@ -313,21 +306,14 @@ static struct inode_security_struct *backing_inode_security(struct dentry *dentr struct inode *inode = d_backing_inode(dentry); __inode_security_revalidate(inode, dentry, true); - return inode->i_security; -} - -static void inode_free_rcu(struct rcu_head *head) -{ - struct inode_security_struct *isec; - - isec = container_of(head, struct inode_security_struct, rcu); - kmem_cache_free(sel_inode_cache, isec); + return selinux_inode(inode); } static void inode_free_security(struct inode *inode) { - struct inode_security_struct *isec = inode->i_security; - struct superblock_security_struct *sbsec = inode->i_sb->s_security; + struct inode_security_struct *isec = selinux_inode(inode); + struct superblock_security_struct *sbsec = + selinux_superblock(inode->i_sb); /* * As not all inode security structures are in a list, we check for @@ -344,17 +330,6 @@ static void inode_free_security(struct inode *inode) list_del_init(&isec->list); spin_unlock(&sbsec->isec_lock); } - - /* - * The inode may still be referenced in a path walk and - * a call to selinux_inode_permission() can be made - * after inode_free_security() is called. Ideally, the VFS - * wouldn't do this, but fixing that is a much harder - * job. For now, simply free the i_security via RCU, and - * leave the current inode->i_security pointer intact. - * The inode will be freed after the RCU grace period too. - */ - call_rcu(&isec->rcu, inode_free_rcu); } static int file_alloc_security(struct file *file) @@ -370,11 +345,7 @@ static int file_alloc_security(struct file *file) static int superblock_alloc_security(struct super_block *sb) { - struct superblock_security_struct *sbsec; - - sbsec = kzalloc(sizeof(struct superblock_security_struct), GFP_KERNEL); - if (!sbsec) - return -ENOMEM; + struct superblock_security_struct *sbsec = selinux_superblock(sb); mutex_init(&sbsec->lock); INIT_LIST_HEAD(&sbsec->isec_head); @@ -383,18 +354,10 @@ static int superblock_alloc_security(struct super_block *sb) sbsec->sid = SECINITSID_UNLABELED; sbsec->def_sid = SECINITSID_FILE; sbsec->mntpoint_sid = SECINITSID_UNLABELED; - sb->s_security = sbsec; return 0; } -static void superblock_free_security(struct super_block *sb) -{ - struct superblock_security_struct *sbsec = sb->s_security; - sb->s_security = NULL; - kfree(sbsec); -} - static inline int inode_doinit(struct inode *inode) { return inode_doinit_with_dentry(inode, NULL); @@ -458,7 +421,7 @@ static int may_context_mount_inode_relabel(u32 sid, static int selinux_is_sblabel_mnt(struct super_block *sb) { - struct superblock_security_struct *sbsec = sb->s_security; + struct superblock_security_struct *sbsec = selinux_superblock(sb); return sbsec->behavior == SECURITY_FS_USE_XATTR || sbsec->behavior == SECURITY_FS_USE_TRANS || @@ -477,7 +440,7 @@ static int selinux_is_sblabel_mnt(struct super_block *sb) static int sb_finish_set_opts(struct super_block *sb) { - struct superblock_security_struct *sbsec = sb->s_security; + struct superblock_security_struct *sbsec = selinux_superblock(sb); struct dentry *root = sb->s_root; struct inode *root_inode = d_backing_inode(root); int rc = 0; @@ -560,7 +523,7 @@ static int selinux_get_mnt_opts(const struct super_block *sb, struct security_mnt_opts *opts) { int rc = 0, i; - struct superblock_security_struct *sbsec = sb->s_security; + struct superblock_security_struct *sbsec = selinux_superblock(sb); char *context = NULL; u32 len; char tmp; @@ -623,7 +586,8 @@ static int selinux_get_mnt_opts(const struct super_block *sb, } if (sbsec->flags & ROOTCONTEXT_MNT) { struct dentry *root = sbsec->sb->s_root; - struct inode_security_struct *isec = backing_inode_security(root); + struct inode_security_struct *isec = + backing_inode_security(root); rc = security_sid_to_context(isec->sid, &context, &len); if (rc) @@ -676,7 +640,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, { const struct cred *cred = current_cred(); int rc = 0, i; - struct superblock_security_struct *sbsec = sb->s_security; + struct superblock_security_struct *sbsec = selinux_superblock(sb); const char *name = sb->s_type->name; struct dentry *root = sbsec->sb->s_root; struct inode_security_struct *root_isec; @@ -927,8 +891,8 @@ static int selinux_set_mnt_opts(struct super_block *sb, static int selinux_cmp_sb_context(const struct super_block *oldsb, const struct super_block *newsb) { - struct superblock_security_struct *old = oldsb->s_security; - struct superblock_security_struct *new = newsb->s_security; + struct superblock_security_struct *old = selinux_superblock(oldsb); + struct superblock_security_struct *new = selinux_superblock(newsb); char oldflags = old->flags & SE_MNTMASK; char newflags = new->flags & SE_MNTMASK; @@ -960,8 +924,9 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb, unsigned long *set_kern_flags) { int rc = 0; - const struct superblock_security_struct *oldsbsec = oldsb->s_security; - struct superblock_security_struct *newsbsec = newsb->s_security; + const struct superblock_security_struct *oldsbsec = + selinux_superblock(oldsb); + struct superblock_security_struct *newsbsec = selinux_superblock(newsb); int set_fscontext = (oldsbsec->flags & FSCONTEXT_MNT); int set_context = (oldsbsec->flags & CONTEXT_MNT); @@ -1014,14 +979,17 @@ static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb, if (!set_fscontext) newsbsec->sid = sid; if (!set_rootcontext) { - struct inode_security_struct *newisec = backing_inode_security(newsb->s_root); + struct inode_security_struct *newisec = + backing_inode_security(newsb->s_root); newisec->sid = sid; } newsbsec->mntpoint_sid = sid; } if (set_rootcontext) { - const struct inode_security_struct *oldisec = backing_inode_security(oldsb->s_root); - struct inode_security_struct *newisec = backing_inode_security(newsb->s_root); + const struct inode_security_struct *oldisec = + backing_inode_security(oldsb->s_root); + struct inode_security_struct *newisec = + backing_inode_security(newsb->s_root); newisec->sid = oldisec->sid; } @@ -1465,7 +1433,7 @@ static int selinux_genfs_get_sid(struct dentry *dentry, static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry) { struct superblock_security_struct *sbsec = NULL; - struct inode_security_struct *isec = inode->i_security; + struct inode_security_struct *isec = selinux_inode(inode); u32 task_sid, sid = 0; u16 sclass; struct dentry *dentry; @@ -1484,7 +1452,7 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent if (isec->sclass == SECCLASS_FILE) isec->sclass = inode_mode_to_security_class(inode->i_mode); - sbsec = inode->i_sb->s_security; + sbsec = selinux_superblock(inode->i_sb); if (!(sbsec->flags & SE_SBINITIALIZED)) { /* Defer initialization until selinux_complete_init, after the initial policy is loaded and the security @@ -1750,7 +1718,7 @@ static int inode_has_perm(const struct cred *cred, return 0; sid = cred_sid(cred); - isec = inode->i_security; + isec = selinux_inode(inode); return avc_has_perm(sid, isec->sid, isec->sclass, perms, adp); } @@ -1857,7 +1825,8 @@ selinux_determine_inode_label(const struct task_security_struct *tsec, const struct qstr *name, u16 tclass, u32 *_new_isid) { - const struct superblock_security_struct *sbsec = dir->i_sb->s_security; + const struct superblock_security_struct *sbsec = + selinux_superblock(dir->i_sb); if ((sbsec->flags & SE_SBINITIALIZED) && (sbsec->behavior == SECURITY_FS_USE_MNTPOINT)) { @@ -1887,7 +1856,7 @@ static int may_create(struct inode *dir, int rc; dsec = inode_security(dir); - sbsec = dir->i_sb->s_security; + sbsec = selinux_superblock(dir->i_sb); sid = tsec->sid; @@ -2026,7 +1995,7 @@ static int superblock_has_perm(const struct cred *cred, struct superblock_security_struct *sbsec; u32 sid = cred_sid(cred); - sbsec = sb->s_security; + sbsec = selinux_superblock(sb); return avc_has_perm(sid, sbsec->sid, SECCLASS_FILESYSTEM, perms, ad); } @@ -2631,11 +2600,6 @@ static int selinux_sb_alloc_security(struct super_block *sb) return superblock_alloc_security(sb); } -static void selinux_sb_free_security(struct super_block *sb) -{ - superblock_free_security(sb); -} - static inline int match_prefix(char *prefix, int plen, char *option, int olen) { if (plen > olen) @@ -2732,7 +2696,7 @@ static int selinux_sb_remount(struct super_block *sb, void *data) int rc, i, *flags; struct security_mnt_opts opts; char *secdata, **mount_options; - struct superblock_security_struct *sbsec = sb->s_security; + struct superblock_security_struct *sbsec = selinux_superblock(sb); if (!(sbsec->flags & SE_SBINITIALIZED)) return 0; @@ -2923,7 +2887,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, int rc; char *context; - sbsec = dir->i_sb->s_security; + sbsec = selinux_superblock(dir->i_sb); newsid = tsec->create_sid; @@ -2936,7 +2900,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, /* Possibly defer initialization to selinux_complete_init. */ if (sbsec->flags & SE_SBINITIALIZED) { - struct inode_security_struct *isec = inode->i_security; + struct inode_security_struct *isec = selinux_inode(inode); isec->sclass = inode_mode_to_security_class(inode->i_mode); isec->sid = newsid; isec->initialized = LABEL_INITIALIZED; @@ -3034,7 +2998,7 @@ static noinline int audit_inode_permission(struct inode *inode, unsigned flags) { struct common_audit_data ad; - struct inode_security_struct *isec = inode->i_security; + struct inode_security_struct *isec = selinux_inode(inode); int rc; ad.type = LSM_AUDIT_DATA_INODE; @@ -3156,7 +3120,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, return dentry_has_perm(current_cred(), dentry, FILE__SETATTR); } - sbsec = inode->i_sb->s_security; + sbsec = selinux_superblock(inode->i_sb); if (!(sbsec->flags & SBLABEL_MNT)) return -EOPNOTSUPP; @@ -3998,7 +3962,7 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info, static void selinux_task_to_inode(struct task_struct *p, struct inode *inode) { - struct inode_security_struct *isec = inode->i_security; + struct inode_security_struct *isec = selinux_inode(inode); u32 sid = task_sid(p); spin_lock(&isec->lock); @@ -4284,7 +4248,7 @@ static int socket_sockcreate_sid(const struct task_security_struct *tsec, static int sock_has_perm(struct sock *sk, u32 perms) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct common_audit_data ad; struct lsm_network_audit net = {0,}; @@ -4339,7 +4303,7 @@ static int selinux_socket_post_create(struct socket *sock, int family, isec->initialized = LABEL_INITIALIZED; if (sock->sk) { - sksec = sock->sk->sk_security; + sksec = selinux_sock(sock->sk); sksec->sclass = sclass; sksec->sid = sid; err = selinux_netlbl_socket_post_create(sock->sk, family); @@ -4370,7 +4334,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in family = sk->sk_family; if (family == PF_INET || family == PF_INET6) { char *addrp; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct common_audit_data ad; struct lsm_network_audit net = {0,}; struct sockaddr_in *addr4 = NULL; @@ -4463,7 +4427,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen) { struct sock *sk = sock->sk; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); int err; err = sock_has_perm(sk, SOCKET__CONNECT); @@ -4595,9 +4559,9 @@ static int selinux_socket_unix_stream_connect(struct sock *sock, struct sock *other, struct sock *newsk) { - struct sk_security_struct *sksec_sock = sock->sk_security; - struct sk_security_struct *sksec_other = other->sk_security; - struct sk_security_struct *sksec_new = newsk->sk_security; + struct sk_security_struct *sksec_sock = selinux_sock(sock); + struct sk_security_struct *sksec_other = selinux_sock(other); + struct sk_security_struct *sksec_new = selinux_sock(newsk); struct common_audit_data ad; struct lsm_network_audit net = {0,}; int err; @@ -4628,8 +4592,8 @@ static int selinux_socket_unix_stream_connect(struct sock *sock, static int selinux_socket_unix_may_send(struct socket *sock, struct socket *other) { - struct sk_security_struct *ssec = sock->sk->sk_security; - struct sk_security_struct *osec = other->sk->sk_security; + struct sk_security_struct *ssec = selinux_sock(sock->sk); + struct sk_security_struct *osec = selinux_sock(other->sk); struct common_audit_data ad; struct lsm_network_audit net = {0,}; @@ -4668,7 +4632,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, u16 family) { int err = 0; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); u32 sk_sid = sksec->sid; struct common_audit_data ad; struct lsm_network_audit net = {0,}; @@ -4700,7 +4664,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) { int err; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); u16 family = sk->sk_family; u32 sk_sid = sksec->sid; struct common_audit_data ad; @@ -4766,13 +4730,15 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) return err; } -static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval, - int __user *optlen, unsigned len) +static int selinux_socket_getpeersec_stream(struct socket *sock, + __user char *optval, + __user int *optlen, + unsigned int len) { int err = 0; char *scontext; u32 scontext_len; - struct sk_security_struct *sksec = sock->sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sock->sk); u32 peer_sid = SECSID_NULL; if (sksec->sclass == SECCLASS_UNIX_STREAM_SOCKET || @@ -4830,34 +4796,27 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff * static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority) { - struct sk_security_struct *sksec; - - sksec = kzalloc(sizeof(*sksec), priority); - if (!sksec) - return -ENOMEM; + struct sk_security_struct *sksec = selinux_sock(sk); sksec->peer_sid = SECINITSID_UNLABELED; sksec->sid = SECINITSID_UNLABELED; sksec->sclass = SECCLASS_SOCKET; selinux_netlbl_sk_security_reset(sksec); - sk->sk_security = sksec; return 0; } static void selinux_sk_free_security(struct sock *sk) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); - sk->sk_security = NULL; selinux_netlbl_sk_security_free(sksec); - kfree(sksec); } static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) { - struct sk_security_struct *sksec = sk->sk_security; - struct sk_security_struct *newsksec = newsk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); + struct sk_security_struct *newsksec = selinux_sock(newsk); newsksec->sid = sksec->sid; newsksec->peer_sid = sksec->peer_sid; @@ -4871,7 +4830,7 @@ static void selinux_sk_getsecid(struct sock *sk, u32 *secid) if (!sk) *secid = SECINITSID_ANY_SOCKET; else { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); *secid = sksec->sid; } @@ -4881,7 +4840,7 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent) { struct inode_security_struct *isec = inode_security_novalidate(SOCK_INODE(parent)); - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); if (sk->sk_family == PF_INET || sk->sk_family == PF_INET6 || sk->sk_family == PF_UNIX) @@ -4892,7 +4851,7 @@ static void selinux_sock_graft(struct sock *sk, struct socket *parent) static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, struct request_sock *req) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); int err; u16 family = req->rsk_ops->family; u32 connsid; @@ -4913,7 +4872,7 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, static void selinux_inet_csk_clone(struct sock *newsk, const struct request_sock *req) { - struct sk_security_struct *newsksec = newsk->sk_security; + struct sk_security_struct *newsksec = selinux_sock(newsk); newsksec->sid = req->secid; newsksec->peer_sid = req->peer_secid; @@ -4930,7 +4889,7 @@ static void selinux_inet_csk_clone(struct sock *newsk, static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb) { u16 family = sk->sk_family; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); /* handle mapped IPv4 packets arriving via IPv6 sockets */ if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP)) @@ -5010,7 +4969,7 @@ static int selinux_tun_dev_attach_queue(void *security) static int selinux_tun_dev_attach(struct sock *sk, void *security) { struct tun_security_struct *tunsec = security; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); /* we don't currently perform any NetLabel based labeling here and it * isn't clear that we would want to do so anyway; while we could apply @@ -5049,7 +5008,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) int err = 0; u32 perm; struct nlmsghdr *nlh; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); if (skb->len < NLMSG_HDRLEN) { err = -EINVAL; @@ -5188,7 +5147,7 @@ static unsigned int selinux_ip_output(struct sk_buff *skb, return NF_ACCEPT; /* standard practice, label using the parent socket */ - sksec = sk->sk_security; + sksec = selinux_sock(sk); sid = sksec->sid; } else sid = SECINITSID_KERNEL; @@ -5227,7 +5186,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, if (sk == NULL) return NF_ACCEPT; - sksec = sk->sk_security; + sksec = selinux_sock(sk); ad.type = LSM_AUDIT_DATA_NET; ad.u.net = &net; @@ -5318,7 +5277,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, u32 skb_sid; struct sk_security_struct *sksec; - sksec = sk->sk_security; + sksec = selinux_sock(sk); if (selinux_skb_peerlbl_sid(skb, family, &skb_sid)) return NF_DROP; /* At this point, if the returned skb peerlbl is SECSID_NULL @@ -5347,7 +5306,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, } else { /* Locally generated packet, fetch the security label from the * associated socket. */ - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); peer_sid = sksec->sid; secmark_perm = PACKET__SEND; } @@ -5407,51 +5366,22 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) return selinux_nlmsg_perm(sk, skb); } -static int ipc_alloc_security(struct kern_ipc_perm *perm, - u16 sclass) +static void ipc_init_security(struct ipc_security_struct *isec, u16 sclass) { - struct ipc_security_struct *isec; - - isec = kzalloc(sizeof(struct ipc_security_struct), GFP_KERNEL); - if (!isec) - return -ENOMEM; - isec->sclass = sclass; isec->sid = current_sid(); - perm->security = isec; - - return 0; -} - -static void ipc_free_security(struct kern_ipc_perm *perm) -{ - struct ipc_security_struct *isec = perm->security; - perm->security = NULL; - kfree(isec); } static int msg_msg_alloc_security(struct msg_msg *msg) { struct msg_security_struct *msec; - msec = kzalloc(sizeof(struct msg_security_struct), GFP_KERNEL); - if (!msec) - return -ENOMEM; - + msec = selinux_msg_msg(msg); msec->sid = SECINITSID_UNLABELED; - msg->security = msec; return 0; } -static void msg_msg_free_security(struct msg_msg *msg) -{ - struct msg_security_struct *msec = msg->security; - - msg->security = NULL; - kfree(msec); -} - static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, u32 perms) { @@ -5459,7 +5389,7 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, struct common_audit_data ad; u32 sid = current_sid(); - isec = ipc_perms->security; + isec = selinux_ipc(ipc_perms); ad.type = LSM_AUDIT_DATA_IPC; ad.u.ipc_id = ipc_perms->key; @@ -5472,11 +5402,6 @@ static int selinux_msg_msg_alloc_security(struct msg_msg *msg) return msg_msg_alloc_security(msg); } -static void selinux_msg_msg_free_security(struct msg_msg *msg) -{ - msg_msg_free_security(msg); -} - /* message queue security operations */ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) { @@ -5485,27 +5410,15 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) u32 sid = current_sid(); int rc; - rc = ipc_alloc_security(&msq->q_perm, SECCLASS_MSGQ); - if (rc) - return rc; - - isec = msq->q_perm.security; + isec = selinux_ipc(&msq->q_perm); + ipc_init_security(isec, SECCLASS_MSGQ); ad.type = LSM_AUDIT_DATA_IPC; ad.u.ipc_id = msq->q_perm.key; rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, MSGQ__CREATE, &ad); - if (rc) { - ipc_free_security(&msq->q_perm); - return rc; - } - return 0; -} - -static void selinux_msg_queue_free_security(struct msg_queue *msq) -{ - ipc_free_security(&msq->q_perm); + return rc; } static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg) @@ -5514,7 +5427,7 @@ static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg) struct common_audit_data ad; u32 sid = current_sid(); - isec = msq->q_perm.security; + isec = selinux_ipc(&msq->q_perm); ad.type = LSM_AUDIT_DATA_IPC; ad.u.ipc_id = msq->q_perm.key; @@ -5560,8 +5473,8 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, u32 sid = current_sid(); int rc; - isec = msq->q_perm.security; - msec = msg->security; + isec = selinux_ipc(&msq->q_perm); + msec = selinux_msg_msg(msg); /* * First time through, need to assign label to the message @@ -5605,8 +5518,8 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, u32 sid = task_sid(target); int rc; - isec = msq->q_perm.security; - msec = msg->security; + isec = selinux_ipc(&msq->q_perm); + msec = selinux_msg_msg(msg); ad.type = LSM_AUDIT_DATA_IPC; ad.u.ipc_id = msq->q_perm.key; @@ -5627,27 +5540,15 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp) u32 sid = current_sid(); int rc; - rc = ipc_alloc_security(&shp->shm_perm, SECCLASS_SHM); - if (rc) - return rc; - - isec = shp->shm_perm.security; + isec = selinux_ipc(&shp->shm_perm); + ipc_init_security(isec, SECCLASS_SHM); ad.type = LSM_AUDIT_DATA_IPC; ad.u.ipc_id = shp->shm_perm.key; rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, SHM__CREATE, &ad); - if (rc) { - ipc_free_security(&shp->shm_perm); - return rc; - } - return 0; -} - -static void selinux_shm_free_security(struct shmid_kernel *shp) -{ - ipc_free_security(&shp->shm_perm); + return rc; } static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg) @@ -5656,7 +5557,7 @@ static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg) struct common_audit_data ad; u32 sid = current_sid(); - isec = shp->shm_perm.security; + isec = selinux_ipc(&shp->shm_perm); ad.type = LSM_AUDIT_DATA_IPC; ad.u.ipc_id = shp->shm_perm.key; @@ -5720,27 +5621,15 @@ static int selinux_sem_alloc_security(struct sem_array *sma) u32 sid = current_sid(); int rc; - rc = ipc_alloc_security(&sma->sem_perm, SECCLASS_SEM); - if (rc) - return rc; - - isec = sma->sem_perm.security; + isec = selinux_ipc(&sma->sem_perm); + ipc_init_security(isec, SECCLASS_SEM); ad.type = LSM_AUDIT_DATA_IPC; ad.u.ipc_id = sma->sem_perm.key; rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, SEM__CREATE, &ad); - if (rc) { - ipc_free_security(&sma->sem_perm); - return rc; - } - return 0; -} - -static void selinux_sem_free_security(struct sem_array *sma) -{ - ipc_free_security(&sma->sem_perm); + return rc; } static int selinux_sem_associate(struct sem_array *sma, int semflg) @@ -5749,7 +5638,7 @@ static int selinux_sem_associate(struct sem_array *sma, int semflg) struct common_audit_data ad; u32 sid = current_sid(); - isec = sma->sem_perm.security; + isec = selinux_ipc(&sma->sem_perm); ad.type = LSM_AUDIT_DATA_IPC; ad.u.ipc_id = sma->sem_perm.key; @@ -5832,7 +5721,7 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) { - struct ipc_security_struct *isec = ipcp->security; + struct ipc_security_struct *isec = selinux_ipc(ipcp); *secid = isec->sid; } @@ -6042,7 +5931,7 @@ static void selinux_release_secctx(char *secdata, u32 seclen) static void selinux_inode_invalidate_secctx(struct inode *inode) { - struct inode_security_struct *isec = inode->i_security; + struct inode_security_struct *isec = selinux_inode(inode); spin_lock(&isec->lock); isec->initialized = LABEL_INVALID; @@ -6081,11 +5970,7 @@ static int selinux_key_alloc(struct key *k, const struct cred *cred, unsigned long flags) { const struct task_security_struct *tsec; - struct key_security_struct *ksec; - - ksec = kzalloc(sizeof(struct key_security_struct), GFP_KERNEL); - if (!ksec) - return -ENOMEM; + struct key_security_struct *ksec = selinux_key(k); tsec = selinux_cred(cred); if (tsec->keycreate_sid) @@ -6093,18 +5978,9 @@ static int selinux_key_alloc(struct key *k, const struct cred *cred, else ksec->sid = tsec->sid; - k->security = ksec; return 0; } -static void selinux_key_free(struct key *k) -{ - struct key_security_struct *ksec = k->security; - - k->security = NULL; - kfree(ksec); -} - static int selinux_key_permission(key_ref_t key_ref, const struct cred *cred, unsigned perm) @@ -6122,14 +5998,14 @@ static int selinux_key_permission(key_ref_t key_ref, sid = cred_sid(cred); key = key_ref_to_ptr(key_ref); - ksec = key->security; + ksec = selinux_key(key); return avc_has_perm(sid, ksec->sid, SECCLASS_KEY, perm, NULL); } static int selinux_key_getsecurity(struct key *key, char **_buffer) { - struct key_security_struct *ksec = key->security; + struct key_security_struct *ksec = selinux_key(key); char *context = NULL; unsigned len; int rc; @@ -6342,6 +6218,14 @@ static void selinux_bpf_prog_free(struct bpf_prog_aux *aux) struct lsm_blob_sizes selinux_blob_sizes = { .lbs_cred = sizeof(struct task_security_struct), .lbs_file = sizeof(struct file_security_struct), + .lbs_inode = sizeof(struct inode_security_struct), + .lbs_ipc = sizeof(struct ipc_security_struct), +#ifdef CONFIG_KEYS + .lbs_key = sizeof(struct key_security_struct), +#endif /* CONFIG_KEYS */ + .lbs_msg_msg = sizeof(struct msg_security_struct), + .lbs_sock = sizeof(struct sk_security_struct), + .lbs_superblock = sizeof(struct superblock_security_struct), }; static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { @@ -6367,7 +6251,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(bprm_committed_creds, selinux_bprm_committed_creds), LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), - LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), LSM_HOOK_INIT(sb_copy_data, selinux_sb_copy_data), LSM_HOOK_INIT(sb_remount, selinux_sb_remount), LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount), @@ -6450,24 +6333,20 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ipc_getsecid, selinux_ipc_getsecid), LSM_HOOK_INIT(msg_msg_alloc_security, selinux_msg_msg_alloc_security), - LSM_HOOK_INIT(msg_msg_free_security, selinux_msg_msg_free_security), LSM_HOOK_INIT(msg_queue_alloc_security, selinux_msg_queue_alloc_security), - LSM_HOOK_INIT(msg_queue_free_security, selinux_msg_queue_free_security), LSM_HOOK_INIT(msg_queue_associate, selinux_msg_queue_associate), LSM_HOOK_INIT(msg_queue_msgctl, selinux_msg_queue_msgctl), LSM_HOOK_INIT(msg_queue_msgsnd, selinux_msg_queue_msgsnd), LSM_HOOK_INIT(msg_queue_msgrcv, selinux_msg_queue_msgrcv), LSM_HOOK_INIT(shm_alloc_security, selinux_shm_alloc_security), - LSM_HOOK_INIT(shm_free_security, selinux_shm_free_security), LSM_HOOK_INIT(shm_associate, selinux_shm_associate), LSM_HOOK_INIT(shm_shmctl, selinux_shm_shmctl), LSM_HOOK_INIT(shm_shmat, selinux_shm_shmat), LSM_HOOK_INIT(sem_alloc_security, selinux_sem_alloc_security), - LSM_HOOK_INIT(sem_free_security, selinux_sem_free_security), LSM_HOOK_INIT(sem_associate, selinux_sem_associate), LSM_HOOK_INIT(sem_semctl, selinux_sem_semctl), LSM_HOOK_INIT(sem_semop, selinux_sem_semop), @@ -6549,7 +6428,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { #ifdef CONFIG_KEYS LSM_HOOK_INIT(key_alloc, selinux_key_alloc), - LSM_HOOK_INIT(key_free, selinux_key_free), LSM_HOOK_INIT(key_permission, selinux_key_permission), LSM_HOOK_INIT(key_getsecurity, selinux_key_getsecurity), #endif @@ -6599,9 +6477,6 @@ static __init int selinux_init(void) default_noexec = !(VM_DATA_DEFAULT_FLAGS & VM_EXEC); - sel_inode_cache = kmem_cache_create("selinux_inode_security", - sizeof(struct inode_security_struct), - 0, SLAB_PANIC, NULL); avc_init(); security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux"); diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 8117051eef41..56b9428ac934 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -59,10 +59,7 @@ enum label_initialized { struct inode_security_struct { struct inode *inode; /* back pointer to inode object */ - union { - struct list_head list; /* list of inode_security_struct */ - struct rcu_head rcu; /* for freeing the inode_security_struct */ - }; + struct list_head list; /* list of inode_security_struct */ u32 task_sid; /* SID of creating task */ u32 sid; /* SID of this object */ u16 sclass; /* security class of this object */ @@ -170,4 +167,64 @@ static inline struct file_security_struct *selinux_file(const struct file *file) return file->f_security; } +static inline struct inode_security_struct *selinux_inode( + const struct inode *inode) +{ +#ifdef CONFIG_SECURITY_STACKING + return inode->i_security + selinux_blob_sizes.lbs_inode; +#else + return inode->i_security; +#endif +} + +static inline struct superblock_security_struct *selinux_superblock( + const struct super_block *superblock) +{ +#ifdef CONFIG_SECURITY_STACKING + return superblock->s_security + selinux_blob_sizes.lbs_superblock; +#else + return superblock->s_security; +#endif +} + +static inline struct msg_security_struct *selinux_msg_msg( + const struct msg_msg *msg_msg) +{ +#ifdef CONFIG_SECURITY_STACKING + return msg_msg->security + selinux_blob_sizes.lbs_msg_msg; +#else + return msg_msg->security; +#endif +} + +static inline struct ipc_security_struct *selinux_ipc( + const struct kern_ipc_perm *ipc) +{ +#ifdef CONFIG_SECURITY_STACKING + return ipc->security + selinux_blob_sizes.lbs_ipc; +#else + return ipc->security; +#endif +} + +#ifdef CONFIG_KEYS +static inline struct key_security_struct *selinux_key(const struct key *key) +{ +#ifdef CONFIG_SECURITY_STACKING + return key->security + selinux_blob_sizes.lbs_key; +#else + return key->security; +#endif +} +#endif /* CONFIG_KEYS */ + +static inline struct sk_security_struct *selinux_sock(const struct sock *sock) +{ +#ifdef CONFIG_SECURITY_STACKING + return sock->sk_security + selinux_blob_sizes.lbs_sock; +#else + return sock->sk_security; +#endif +} + #endif /* _SELINUX_OBJSEC_H_ */ diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 2c297b995b16..338b14842d49 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -81,7 +82,7 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb, static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr(struct sock *sk) { int rc; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct netlbl_lsm_secattr *secattr; if (sksec->nlbl_secattr != NULL) @@ -113,7 +114,7 @@ static struct netlbl_lsm_secattr *selinux_netlbl_sock_getattr( const struct sock *sk, u32 sid) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct netlbl_lsm_secattr *secattr = sksec->nlbl_secattr; if (secattr == NULL) @@ -248,7 +249,7 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb, * being labeled by it's parent socket, if it is just exit */ sk = skb_to_full_sk(skb); if (sk != NULL) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); if (sksec->nlbl_state != NLBL_REQSKB) return 0; secattr = selinux_netlbl_sock_getattr(sk, sid); @@ -310,7 +311,7 @@ int selinux_netlbl_inet_conn_request(struct request_sock *req, u16 family) */ void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family) { - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); if (family == PF_INET) sksec->nlbl_state = NLBL_LABELED; @@ -331,7 +332,7 @@ void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family) int selinux_netlbl_socket_post_create(struct sock *sk, u16 family) { int rc; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct netlbl_lsm_secattr *secattr; if (family != PF_INET && family != PF_INET6) @@ -445,7 +446,7 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, { int rc = 0; struct sock *sk = sock->sk; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct netlbl_lsm_secattr secattr; if (selinux_netlbl_option(level, optname) && @@ -481,7 +482,7 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, int selinux_netlbl_socket_connect(struct sock *sk, struct sockaddr *addr) { int rc; - struct sk_security_struct *sksec = sk->sk_security; + struct sk_security_struct *sksec = selinux_sock(sk); struct netlbl_lsm_secattr *secattr; if (sksec->nlbl_state != NLBL_REQSKB && diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 855a13053a81..1b4bed79101e 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -1300,7 +1300,7 @@ static int sel_make_bools(void) if (len >= PAGE_SIZE) goto out; - isec = (struct inode_security_struct *)inode->i_security; + isec = (struct inode_security_struct *)selinux_inode(inode); ret = security_genfs_sid("selinuxfs", page, SECCLASS_FILE, &sid); if (ret) { pr_warn_ratelimited("SELinux: no sid found, defaulting to security isid for %s\n", @@ -1841,7 +1841,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) goto err; inode->i_ino = ++sel_last_ino; - isec = (struct inode_security_struct *)inode->i_security; + isec = (struct inode_security_struct *)selinux_inode(inode); isec->sid = SECINITSID_DEVNULL; isec->sclass = SECCLASS_CHR_FILE; isec->initialized = LABEL_INITIALIZED; diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 8900ea5cbabf..13118a9a2513 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include "flask.h" @@ -2664,7 +2665,7 @@ int security_fs_use(struct super_block *sb) { int rc = 0; struct ocontext *c; - struct superblock_security_struct *sbsec = sb->s_security; + struct superblock_security_struct *sbsec = selinux_superblock(sb); const char *fstype = sb->s_type->name; read_lock(&policy_rwlock); diff --git a/security/smack/smack.h b/security/smack/smack.h index 043525a52e94..d2df0af9e5b5 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -367,12 +367,69 @@ static inline struct smack_known **smack_file(const struct file *file) return file->f_security; } +static inline struct inode_smack *smack_inode(const struct inode *inode) +{ +#ifdef CONFIG_SECURITY_STACKING + return inode->i_security + smack_blob_sizes.lbs_inode; +#else + return inode->i_security; +#endif +} + +static inline struct socket_smack *smack_sock(const struct sock *sock) +{ +#ifdef CONFIG_SECURITY_STACKING + return sock->sk_security + smack_blob_sizes.lbs_sock; +#else + return sock->sk_security; +#endif +} + +static inline struct superblock_smack *smack_superblock( + const struct super_block *superblock) +{ +#ifdef CONFIG_SECURITY_STACKING + return superblock->s_security + smack_blob_sizes.lbs_superblock; +#else + return superblock->s_security; +#endif +} + +static inline struct smack_known **smack_msg_msg(const struct msg_msg *msg) +{ +#ifdef CONFIG_SECURITY_STACKING + return msg->security + smack_blob_sizes.lbs_msg_msg; +#else + return msg->security; +#endif +} + +static inline struct smack_known **smack_ipc(const struct kern_ipc_perm *ipc) +{ +#ifdef CONFIG_SECURITY_STACKING + return ipc->security + smack_blob_sizes.lbs_ipc; +#else + return ipc->security; +#endif +} + +#ifdef CONFIG_KEYS +static inline struct smack_known **smack_key(const struct key *key) +{ +#ifdef CONFIG_SECURITY_STACKING + return key->security + smack_blob_sizes.lbs_key; +#else + return key->security; +#endif +} +#endif /* CONFIG_KEYS */ + /* * Is the directory transmuting? */ static inline int smk_inode_transmutable(const struct inode *isp) { - struct inode_smack *sip = isp->i_security; + struct inode_smack *sip = smack_inode(isp); return (sip->smk_flags & SMK_INODE_TRANSMUTE) != 0; } @@ -381,7 +438,7 @@ static inline int smk_inode_transmutable(const struct inode *isp) */ static inline struct smack_known *smk_of_inode(const struct inode *isp) { - struct inode_smack *sip = isp->i_security; + struct inode_smack *sip = smack_inode(isp); return sip->smk_inode; } diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 1bffbab2e765..5197c7bf7f63 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -165,7 +165,7 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc) static int smk_bu_inode(struct inode *inode, int mode, int rc) { struct task_smack *tsp = smack_cred(current_cred()); - struct inode_smack *isp = inode->i_security; + struct inode_smack *isp = smack_inode(inode); char acc[SMK_NUM_ACCESS_TYPE + 1]; if (isp->smk_flags & SMK_INODE_IMPURE) @@ -197,7 +197,7 @@ static int smk_bu_file(struct file *file, int mode, int rc) struct task_smack *tsp = smack_cred(current_cred()); struct smack_known *sskp = tsp->smk_task; struct inode *inode = file_inode(file); - struct inode_smack *isp = inode->i_security; + struct inode_smack *isp = smack_inode(inode); char acc[SMK_NUM_ACCESS_TYPE + 1]; if (isp->smk_flags & SMK_INODE_IMPURE) @@ -227,7 +227,7 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file, struct task_smack *tsp = smack_cred(cred); struct smack_known *sskp = tsp->smk_task; struct inode *inode = file_inode(file); - struct inode_smack *isp = inode->i_security; + struct inode_smack *isp = smack_inode(inode); char acc[SMK_NUM_ACCESS_TYPE + 1]; if (isp->smk_flags & SMK_INODE_IMPURE) @@ -287,24 +287,18 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip, } /** - * new_inode_smack - allocate an inode security blob + * init_inode_smack - initialize an inode security blob + * @isp: the blob to initialize * @skp: a pointer to the Smack label entry to use in the blob * - * Returns the new blob or NULL if there's no memory available */ -static struct inode_smack *new_inode_smack(struct smack_known *skp) +static void init_inode_smack(struct inode *inode, struct smack_known *skp) { - struct inode_smack *isp; - - isp = kmem_cache_zalloc(smack_inode_cache, GFP_NOFS); - if (isp == NULL) - return NULL; + struct inode_smack *isp = smack_inode(inode); isp->smk_inode = skp; isp->smk_flags = 0; mutex_init(&isp->smk_lock); - - return isp; } /** @@ -525,12 +519,7 @@ static int smack_syslog(int typefrom_file) */ static int smack_sb_alloc_security(struct super_block *sb) { - struct superblock_smack *sbsp; - - sbsp = kzalloc(sizeof(struct superblock_smack), GFP_KERNEL); - - if (sbsp == NULL) - return -ENOMEM; + struct superblock_smack *sbsp = smack_superblock(sb); sbsp->smk_root = &smack_known_floor; sbsp->smk_default = &smack_known_floor; @@ -539,22 +528,10 @@ static int smack_sb_alloc_security(struct super_block *sb) /* * SMK_SB_INITIALIZED will be zero from kzalloc. */ - sb->s_security = sbsp; return 0; } -/** - * smack_sb_free_security - free a superblock blob - * @sb: the superblock getting the blob - * - */ -static void smack_sb_free_security(struct super_block *sb) -{ - kfree(sb->s_security); - sb->s_security = NULL; -} - /** * smack_sb_copy_data - copy mount options data for processing * @orig: where to start @@ -745,7 +722,7 @@ static int smack_set_mnt_opts(struct super_block *sb, { struct dentry *root = sb->s_root; struct inode *inode = d_backing_inode(root); - struct superblock_smack *sp = sb->s_security; + struct superblock_smack *sp = smack_superblock(sb); struct inode_smack *isp; struct smack_known *skp; int i; @@ -823,17 +800,13 @@ static int smack_set_mnt_opts(struct super_block *sb, /* * Initialize the root inode. */ - isp = inode->i_security; - if (isp == NULL) { - isp = new_inode_smack(sp->smk_root); - if (isp == NULL) - return -ENOMEM; - inode->i_security = isp; - } else - isp->smk_inode = sp->smk_root; + lsm_early_inode(inode); + init_inode_smack(inode, sp->smk_root); - if (transmute) + if (transmute) { + isp = smack_inode(inode); isp->smk_flags |= SMK_INODE_TRANSMUTE; + } return 0; } @@ -878,7 +851,7 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) */ static int smack_sb_statfs(struct dentry *dentry) { - struct superblock_smack *sbp = dentry->d_sb->s_security; + struct superblock_smack *sbp = smack_superblock(dentry->d_sb); int rc; struct smk_audit_info ad; @@ -911,11 +884,11 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm) if (bprm->called_set_creds) return 0; - isp = inode->i_security; + isp = smack_inode(inode); if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task) return 0; - sbsp = inode->i_sb->s_security; + sbsp = smack_superblock(inode->i_sb); if ((sbsp->smk_flags & SMK_SB_UNTRUSTED) && isp->smk_task != sbsp->smk_root) return 0; @@ -962,48 +935,10 @@ static int smack_inode_alloc_security(struct inode *inode) { struct smack_known *skp = smk_of_current(); - inode->i_security = new_inode_smack(skp); - if (inode->i_security == NULL) - return -ENOMEM; + init_inode_smack(inode, skp); return 0; } -/** - * smack_inode_free_rcu - Free inode_smack blob from cache - * @head: the rcu_head for getting inode_smack pointer - * - * Call back function called from call_rcu() to free - * the i_security blob pointer in inode - */ -static void smack_inode_free_rcu(struct rcu_head *head) -{ - struct inode_smack *issp; - - issp = container_of(head, struct inode_smack, smk_rcu); - kmem_cache_free(smack_inode_cache, issp); -} - -/** - * smack_inode_free_security - free an inode blob using call_rcu() - * @inode: the inode with a blob - * - * Clears the blob pointer in inode using RCU - */ -static void smack_inode_free_security(struct inode *inode) -{ - struct inode_smack *issp = inode->i_security; - - /* - * The inode may still be referenced in a path walk and - * a call to smack_inode_permission() can be made - * after smack_inode_free_security() is called. - * To avoid race condition free the i_security via RCU - * and leave the current inode->i_security pointer intact. - * The inode will be freed after the RCU grace period too. - */ - call_rcu(&issp->smk_rcu, smack_inode_free_rcu); -} - /** * smack_inode_init_security - copy out the smack from an inode * @inode: the newly created inode @@ -1019,7 +954,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, const struct qstr *qstr, const char **name, void **value, size_t *len) { - struct inode_smack *issp = inode->i_security; + struct inode_smack *issp = smack_inode(inode); struct smack_known *skp = smk_of_current(); struct smack_known *isp = smk_of_inode(inode); struct smack_known *dsp = smk_of_inode(dir); @@ -1204,7 +1139,7 @@ static int smack_inode_rename(struct inode *old_inode, */ static int smack_inode_permission(struct inode *inode, int mask) { - struct superblock_smack *sbsp = inode->i_sb->s_security; + struct superblock_smack *sbsp = smack_superblock(inode->i_sb); struct smk_audit_info ad; int no_block = mask & MAY_NOT_BLOCK; int rc; @@ -1357,7 +1292,7 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { struct smack_known *skp; - struct inode_smack *isp = d_backing_inode(dentry)->i_security; + struct inode_smack *isp = smack_inode(d_backing_inode(dentry)); if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { isp->smk_flags |= SMK_INODE_TRANSMUTE; @@ -1438,7 +1373,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) if (rc != 0) return rc; - isp = d_backing_inode(dentry)->i_security; + isp = smack_inode(d_backing_inode(dentry)); /* * Don't do anything special for these. * XATTR_NAME_SMACKIPIN @@ -1446,7 +1381,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) */ if (strcmp(name, XATTR_NAME_SMACK) == 0) { struct super_block *sbp = dentry->d_sb; - struct superblock_smack *sbsp = sbp->s_security; + struct superblock_smack *sbsp = smack_superblock(sbp); isp->smk_inode = sbsp->smk_default; } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) @@ -1492,7 +1427,7 @@ static int smack_inode_getsecurity(struct inode *inode, if (sock == NULL || sock->sk == NULL) return -EOPNOTSUPP; - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); if (strcmp(name, XATTR_SMACK_IPIN) == 0) isp = ssp->smk_in; @@ -1536,7 +1471,7 @@ static int smack_inode_listsecurity(struct inode *inode, char *buffer, */ static void smack_inode_getsecid(struct inode *inode, u32 *secid) { - struct inode_smack *isp = inode->i_security; + struct inode_smack *isp = smack_inode(inode); *secid = isp->smk_inode->smk_secid; } @@ -1713,10 +1648,10 @@ static int smack_mmap_file(struct file *file, if (unlikely(IS_PRIVATE(file_inode(file)))) return 0; - isp = file_inode(file)->i_security; + isp = smack_inode(file_inode(file)); if (isp->smk_mmap == NULL) return 0; - sbsp = file_inode(file)->i_sb->s_security; + sbsp = smack_superblock(file_inode(file)->i_sb); if (sbsp->smk_flags & SMK_SB_UNTRUSTED && isp->smk_mmap != sbsp->smk_root) return -EACCES; @@ -1869,7 +1804,7 @@ static int smack_file_receive(struct file *file) if (inode->i_sb->s_magic == SOCKFS_MAGIC) { sock = SOCKET_I(inode); - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); tsp = smack_cred(current_cred()); /* * If the receiving process can't write to the @@ -2038,7 +1973,7 @@ static int smack_kernel_act_as(struct cred *new, u32 secid) static int smack_kernel_create_files_as(struct cred *new, struct inode *inode) { - struct inode_smack *isp = inode->i_security; + struct inode_smack *isp = smack_inode(inode); struct task_smack *tsp = smack_cred(new); tsp->smk_forked = isp->smk_inode; @@ -2238,7 +2173,7 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, */ static void smack_task_to_inode(struct task_struct *p, struct inode *inode) { - struct inode_smack *isp = inode->i_security; + struct inode_smack *isp = smack_inode(inode); struct smack_known *skp = smk_of_task_struct(p); isp->smk_inode = skp; @@ -2261,11 +2196,7 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode) static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) { struct smack_known *skp = smk_of_current(); - struct socket_smack *ssp; - - ssp = kzalloc(sizeof(struct socket_smack), gfp_flags); - if (ssp == NULL) - return -ENOMEM; + struct socket_smack *ssp = smack_sock(sk); /* * Sockets created by kernel threads receive web label. @@ -2279,11 +2210,10 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) } ssp->smk_packet = NULL; - sk->sk_security = ssp; - return 0; } +#ifdef SMACK_IPV6_PORT_LABELING /** * smack_sk_free_security - Free a socket blob * @sk: the socket @@ -2292,7 +2222,6 @@ static int smack_sk_alloc_security(struct sock *sk, int family, gfp_t gfp_flags) */ static void smack_sk_free_security(struct sock *sk) { -#ifdef SMACK_IPV6_PORT_LABELING struct smk_port_label *spp; if (sk->sk_family == PF_INET6) { @@ -2305,9 +2234,8 @@ static void smack_sk_free_security(struct sock *sk) } rcu_read_unlock(); } -#endif - kfree(sk->sk_security); } +#endif /** * smack_ipv4host_label - check host based restrictions @@ -2425,7 +2353,7 @@ static struct smack_known *smack_ipv6host_label(struct sockaddr_in6 *sip) static int smack_netlabel(struct sock *sk, int labeled) { struct smack_known *skp; - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); int rc = 0; /* @@ -2470,7 +2398,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) int rc; int sk_lbl; struct smack_known *hkp; - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct smk_audit_info ad; rcu_read_lock(); @@ -2546,7 +2474,7 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address) { struct sock *sk = sock->sk; struct sockaddr_in6 *addr6; - struct socket_smack *ssp = sock->sk->sk_security; + struct socket_smack *ssp = smack_sock(sock->sk); struct smk_port_label *spp; unsigned short port = 0; @@ -2633,7 +2561,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, int act) { struct smk_port_label *spp; - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct smack_known *skp = NULL; unsigned short port; struct smack_known *object; @@ -2700,7 +2628,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags) { struct smack_known *skp; - struct inode_smack *nsp = inode->i_security; + struct inode_smack *nsp = smack_inode(inode); struct socket_smack *ssp; struct socket *sock; int rc = 0; @@ -2727,7 +2655,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, if (sock == NULL || sock->sk == NULL) return -EOPNOTSUPP; - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); if (strcmp(name, XATTR_SMACK_IPIN) == 0) ssp->smk_in = skp; @@ -2775,7 +2703,7 @@ static int smack_socket_post_create(struct socket *sock, int family, * Sockets created by kernel threads receive web label. */ if (unlikely(current->flags & PF_KTHREAD)) { - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); ssp->smk_in = &smack_known_web; ssp->smk_out = &smack_known_web; } @@ -2834,7 +2762,7 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, return 0; #ifdef SMACK_IPV6_SECMARK_LABELING - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); #endif switch (sock->sk->sk_family) { @@ -2888,34 +2816,12 @@ static int smack_flags_to_may(int flags) */ static int smack_msg_msg_alloc_security(struct msg_msg *msg) { - struct smack_known *skp = smk_of_current(); + struct smack_known **blob = smack_msg_msg(msg); - msg->security = skp; + *blob = smk_of_current(); return 0; } -/** - * smack_msg_msg_free_security - Clear the security blob for msg_msg - * @msg: the object - * - * Clears the blob pointer - */ -static void smack_msg_msg_free_security(struct msg_msg *msg) -{ - msg->security = NULL; -} - -/** - * smack_of_shm - the smack pointer for the shm - * @shp: the object - * - * Returns a pointer to the smack value - */ -static struct smack_known *smack_of_shm(struct shmid_kernel *shp) -{ - return (struct smack_known *)shp->shm_perm.security; -} - /** * smack_shm_alloc_security - Set the security blob for shm * @shp: the object @@ -2924,26 +2830,12 @@ static struct smack_known *smack_of_shm(struct shmid_kernel *shp) */ static int smack_shm_alloc_security(struct shmid_kernel *shp) { - struct kern_ipc_perm *isp = &shp->shm_perm; - struct smack_known *skp = smk_of_current(); + struct smack_known **blob = smack_ipc(&shp->shm_perm); - isp->security = skp; + *blob = smk_of_current(); return 0; } -/** - * smack_shm_free_security - Clear the security blob for shm - * @shp: the object - * - * Clears the blob pointer - */ -static void smack_shm_free_security(struct shmid_kernel *shp) -{ - struct kern_ipc_perm *isp = &shp->shm_perm; - - isp->security = NULL; -} - /** * smk_curacc_shm : check if current has access on shm * @shp : the object @@ -2953,7 +2845,8 @@ static void smack_shm_free_security(struct shmid_kernel *shp) */ static int smk_curacc_shm(struct shmid_kernel *shp, int access) { - struct smack_known *ssp = smack_of_shm(shp); + struct smack_known **blob = smack_ipc(&shp->shm_perm); + struct smack_known *ssp = *blob; struct smk_audit_info ad; int rc; @@ -3032,17 +2925,6 @@ static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, return smk_curacc_shm(shp, may); } -/** - * smack_of_sem - the smack pointer for the sem - * @sma: the object - * - * Returns a pointer to the smack value - */ -static struct smack_known *smack_of_sem(struct sem_array *sma) -{ - return (struct smack_known *)sma->sem_perm.security; -} - /** * smack_sem_alloc_security - Set the security blob for sem * @sma: the object @@ -3051,26 +2933,12 @@ static struct smack_known *smack_of_sem(struct sem_array *sma) */ static int smack_sem_alloc_security(struct sem_array *sma) { - struct kern_ipc_perm *isp = &sma->sem_perm; - struct smack_known *skp = smk_of_current(); + struct smack_known **blob = smack_ipc(&sma->sem_perm); - isp->security = skp; + *blob = smk_of_current(); return 0; } -/** - * smack_sem_free_security - Clear the security blob for sem - * @sma: the object - * - * Clears the blob pointer - */ -static void smack_sem_free_security(struct sem_array *sma) -{ - struct kern_ipc_perm *isp = &sma->sem_perm; - - isp->security = NULL; -} - /** * smk_curacc_sem : check if current has access on sem * @sma : the object @@ -3080,7 +2948,8 @@ static void smack_sem_free_security(struct sem_array *sma) */ static int smk_curacc_sem(struct sem_array *sma, int access) { - struct smack_known *ssp = smack_of_sem(sma); + struct smack_known **blob = smack_ipc(&sma->sem_perm); + struct smack_known *ssp = *blob; struct smk_audit_info ad; int rc; @@ -3166,44 +3035,19 @@ static int smack_sem_semop(struct sem_array *sma, struct sembuf *sops, } /** - * smack_msg_alloc_security - Set the security blob for msg + * smack_msg_queue_alloc_security - Set the security blob for msg * @msq: the object * * Returns 0 */ static int smack_msg_queue_alloc_security(struct msg_queue *msq) { - struct kern_ipc_perm *kisp = &msq->q_perm; - struct smack_known *skp = smk_of_current(); + struct smack_known **blob = smack_ipc(&msq->q_perm); - kisp->security = skp; + *blob = smk_of_current(); return 0; } -/** - * smack_msg_free_security - Clear the security blob for msg - * @msq: the object - * - * Clears the blob pointer - */ -static void smack_msg_queue_free_security(struct msg_queue *msq) -{ - struct kern_ipc_perm *kisp = &msq->q_perm; - - kisp->security = NULL; -} - -/** - * smack_of_msq - the smack pointer for the msq - * @msq: the object - * - * Returns a pointer to the smack label entry - */ -static struct smack_known *smack_of_msq(struct msg_queue *msq) -{ - return (struct smack_known *)msq->q_perm.security; -} - /** * smk_curacc_msq : helper to check if current has access on msq * @msq : the msq @@ -3213,7 +3057,8 @@ static struct smack_known *smack_of_msq(struct msg_queue *msq) */ static int smk_curacc_msq(struct msg_queue *msq, int access) { - struct smack_known *msp = smack_of_msq(msq); + struct smack_known **blob = smack_ipc(&msq->q_perm); + struct smack_known *msp = *blob; struct smk_audit_info ad; int rc; @@ -3316,7 +3161,8 @@ static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, */ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) { - struct smack_known *iskp = ipp->security; + struct smack_known **blob = smack_ipc(ipp); + struct smack_known *iskp = *blob; int may = smack_flags_to_may(flag); struct smk_audit_info ad; int rc; @@ -3337,7 +3183,8 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) */ static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid) { - struct smack_known *iskp = ipp->security; + struct smack_known **blob = smack_ipc(ipp); + struct smack_known *iskp = *blob; *secid = iskp->smk_secid; } @@ -3365,7 +3212,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) if (inode == NULL) return; - isp = inode->i_security; + isp = smack_inode(inode); mutex_lock(&isp->smk_lock); /* @@ -3376,7 +3223,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) goto unlockandout; sbp = inode->i_sb; - sbsp = sbp->s_security; + sbsp = smack_superblock(sbp); /* * We're going to use the superblock default label * if there's no label on the file. @@ -3670,9 +3517,9 @@ static int smack_unix_stream_connect(struct sock *sock, { struct smack_known *skp; struct smack_known *okp; - struct socket_smack *ssp = sock->sk_security; - struct socket_smack *osp = other->sk_security; - struct socket_smack *nsp = newsk->sk_security; + struct socket_smack *ssp = smack_sock(sock); + struct socket_smack *osp = smack_sock(other); + struct socket_smack *nsp = smack_sock(newsk); struct smk_audit_info ad; int rc = 0; #ifdef CONFIG_AUDIT @@ -3718,8 +3565,8 @@ static int smack_unix_stream_connect(struct sock *sock, */ static int smack_unix_may_send(struct socket *sock, struct socket *other) { - struct socket_smack *ssp = sock->sk->sk_security; - struct socket_smack *osp = other->sk->sk_security; + struct socket_smack *ssp = smack_sock(sock->sk); + struct socket_smack *osp = smack_sock(other->sk); struct smk_audit_info ad; int rc; @@ -3756,7 +3603,7 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; #endif #ifdef SMACK_IPV6_SECMARK_LABELING - struct socket_smack *ssp = sock->sk->sk_security; + struct socket_smack *ssp = smack_sock(sock->sk); struct smack_known *rsp; #endif int rc = 0; @@ -3920,7 +3767,7 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) { struct netlbl_lsm_secattr secattr; - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct smack_known *skp = NULL; int rc = 0; struct smk_audit_info ad; @@ -4029,7 +3876,7 @@ static int smack_socket_getpeersec_stream(struct socket *sock, int slen = 1; int rc = 0; - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); if (ssp->smk_packet != NULL) { rcp = ssp->smk_packet->smk_known; slen = strlen(rcp) + 1; @@ -4079,7 +3926,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, switch (family) { case PF_UNIX: - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); s = ssp->smk_out->smk_secid; break; case PF_INET: @@ -4092,7 +3939,7 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, * Translate what netlabel gave us. */ if (sock != NULL && sock->sk != NULL) - ssp = sock->sk->sk_security; + ssp = smack_sock(sock->sk); netlbl_secattr_init(&secattr); rc = netlbl_skbuff_getattr(skb, family, &secattr); if (rc == 0) { @@ -4130,7 +3977,7 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent) (sk->sk_family != PF_INET && sk->sk_family != PF_INET6)) return; - ssp = sk->sk_security; + ssp = smack_sock(sk); ssp->smk_in = skp; ssp->smk_out = skp; /* cssp->smk_packet is already set in smack_inet_csk_clone() */ @@ -4150,7 +3997,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, { u16 family = sk->sk_family; struct smack_known *skp; - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct netlbl_lsm_secattr secattr; struct sockaddr_in addr; struct iphdr *hdr; @@ -4249,7 +4096,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, static void smack_inet_csk_clone(struct sock *sk, const struct request_sock *req) { - struct socket_smack *ssp = sk->sk_security; + struct socket_smack *ssp = smack_sock(sk); struct smack_known *skp; if (req->peer_secid != 0) { @@ -4281,23 +4128,13 @@ static void smack_inet_csk_clone(struct sock *sk, static int smack_key_alloc(struct key *key, const struct cred *cred, unsigned long flags) { + struct smack_known **blob = smack_key(key); struct smack_known *skp = smk_of_task(smack_cred(cred)); - key->security = skp; + *blob = skp; return 0; } -/** - * smack_key_free - Clear the key security blob - * @key: the object - * - * Clear the blob pointer - */ -static void smack_key_free(struct key *key) -{ - key->security = NULL; -} - /** * smack_key_permission - Smack access on a key * @key_ref: gets to the object @@ -4310,6 +4147,8 @@ static void smack_key_free(struct key *key) static int smack_key_permission(key_ref_t key_ref, const struct cred *cred, unsigned perm) { + struct smack_known **blob; + struct smack_known *skp; struct key *keyp; struct smk_audit_info ad; struct smack_known *tkp = smk_of_task(smack_cred(cred)); @@ -4323,7 +4162,9 @@ static int smack_key_permission(key_ref_t key_ref, * If the key hasn't been initialized give it access so that * it may do so. */ - if (keyp->security == NULL) + blob = smack_key(keyp); + skp = *blob; + if (skp == NULL) return 0; /* * This should not occur @@ -4343,8 +4184,8 @@ static int smack_key_permission(key_ref_t key_ref, request = MAY_READ; if (perm & (KEY_NEED_WRITE | KEY_NEED_LINK | KEY_NEED_SETATTR)) request = MAY_WRITE; - rc = smk_access(tkp, keyp->security, request, &ad); - rc = smk_bu_note("key access", tkp, keyp->security, request, rc); + rc = smk_access(tkp, skp, request, &ad); + rc = smk_bu_note("key access", tkp, skp, request, rc); return rc; } @@ -4359,11 +4200,12 @@ static int smack_key_permission(key_ref_t key_ref, */ static int smack_key_getsecurity(struct key *key, char **_buffer) { - struct smack_known *skp = key->security; + struct smack_known **blob = smack_key(key); + struct smack_known *skp = *blob; size_t length; char *copy; - if (key->security == NULL) { + if (skp == NULL) { *_buffer = NULL; return 0; } @@ -4588,7 +4430,7 @@ static int smack_inode_copy_up(struct dentry *dentry, struct cred **new) /* * Get label from overlay inode and set it in create_sid */ - isp = d_inode(dentry->d_parent)->i_security; + isp = smack_inode(d_inode(dentry->d_parent)); skp = isp->smk_inode; tsp->smk_task = skp; *new = new_creds; @@ -4625,7 +4467,7 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode, /* * the attribute of the containing directory */ - isp = d_inode(dentry->d_parent)->i_security; + isp = smack_inode(d_inode(dentry->d_parent)); if (isp->smk_flags & SMK_INODE_TRANSMUTE) { rcu_read_lock(); @@ -4648,6 +4490,14 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode, struct lsm_blob_sizes smack_blob_sizes = { .lbs_cred = sizeof(struct task_smack), .lbs_file = sizeof(struct smack_known *), + .lbs_inode = sizeof(struct inode_smack), + .lbs_ipc = sizeof(struct smack_known *), +#ifdef CONFIG_KEYS + .lbs_key = sizeof(struct smack_known *), +#endif /* CONFIG_KEYS */ + .lbs_msg_msg = sizeof(struct smack_known *), + .lbs_sock = sizeof(struct socket_smack), + .lbs_superblock = sizeof(struct superblock_smack), }; static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { @@ -4656,7 +4506,6 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(syslog, smack_syslog), LSM_HOOK_INIT(sb_alloc_security, smack_sb_alloc_security), - LSM_HOOK_INIT(sb_free_security, smack_sb_free_security), LSM_HOOK_INIT(sb_copy_data, smack_sb_copy_data), LSM_HOOK_INIT(sb_kern_mount, smack_sb_kern_mount), LSM_HOOK_INIT(sb_statfs, smack_sb_statfs), @@ -4666,7 +4515,6 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(bprm_set_creds, smack_bprm_set_creds), LSM_HOOK_INIT(inode_alloc_security, smack_inode_alloc_security), - LSM_HOOK_INIT(inode_free_security, smack_inode_free_security), LSM_HOOK_INIT(inode_init_security, smack_inode_init_security), LSM_HOOK_INIT(inode_link, smack_inode_link), LSM_HOOK_INIT(inode_unlink, smack_inode_unlink), @@ -4719,23 +4567,19 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ipc_getsecid, smack_ipc_getsecid), LSM_HOOK_INIT(msg_msg_alloc_security, smack_msg_msg_alloc_security), - LSM_HOOK_INIT(msg_msg_free_security, smack_msg_msg_free_security), LSM_HOOK_INIT(msg_queue_alloc_security, smack_msg_queue_alloc_security), - LSM_HOOK_INIT(msg_queue_free_security, smack_msg_queue_free_security), LSM_HOOK_INIT(msg_queue_associate, smack_msg_queue_associate), LSM_HOOK_INIT(msg_queue_msgctl, smack_msg_queue_msgctl), LSM_HOOK_INIT(msg_queue_msgsnd, smack_msg_queue_msgsnd), LSM_HOOK_INIT(msg_queue_msgrcv, smack_msg_queue_msgrcv), LSM_HOOK_INIT(shm_alloc_security, smack_shm_alloc_security), - LSM_HOOK_INIT(shm_free_security, smack_shm_free_security), LSM_HOOK_INIT(shm_associate, smack_shm_associate), LSM_HOOK_INIT(shm_shmctl, smack_shm_shmctl), LSM_HOOK_INIT(shm_shmat, smack_shm_shmat), LSM_HOOK_INIT(sem_alloc_security, smack_sem_alloc_security), - LSM_HOOK_INIT(sem_free_security, smack_sem_free_security), LSM_HOOK_INIT(sem_associate, smack_sem_associate), LSM_HOOK_INIT(sem_semctl, smack_sem_semctl), LSM_HOOK_INIT(sem_semop, smack_sem_semop), @@ -4758,7 +4602,9 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(socket_getpeersec_stream, smack_socket_getpeersec_stream), LSM_HOOK_INIT(socket_getpeersec_dgram, smack_socket_getpeersec_dgram), LSM_HOOK_INIT(sk_alloc_security, smack_sk_alloc_security), +#ifdef SMACK_IPV6_PORT_LABELING LSM_HOOK_INIT(sk_free_security, smack_sk_free_security), +#endif LSM_HOOK_INIT(sock_graft, smack_sock_graft), LSM_HOOK_INIT(inet_conn_request, smack_inet_conn_request), LSM_HOOK_INIT(inet_csk_clone, smack_inet_csk_clone), @@ -4766,7 +4612,6 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { /* key management security hooks */ #ifdef CONFIG_KEYS LSM_HOOK_INIT(key_alloc, smack_key_alloc), - LSM_HOOK_INIT(key_free, smack_key_free), LSM_HOOK_INIT(key_permission, smack_key_permission), LSM_HOOK_INIT(key_getsecurity, smack_key_getsecurity), #endif /* CONFIG_KEYS */ diff --git a/security/smack/smack_netfilter.c b/security/smack/smack_netfilter.c index e36d17835d4f..701a1cc1bdcc 100644 --- a/security/smack/smack_netfilter.c +++ b/security/smack/smack_netfilter.c @@ -31,8 +31,8 @@ static unsigned int smack_ipv6_output(void *priv, struct socket_smack *ssp; struct smack_known *skp; - if (sk && sk->sk_security) { - ssp = sk->sk_security; + if (sk && smack_sock(sk)) { + ssp = smack_sock(sk); skp = ssp->smk_out; skb->secmark = skp->smk_secid; } @@ -49,8 +49,8 @@ static unsigned int smack_ipv4_output(void *priv, struct socket_smack *ssp; struct smack_known *skp; - if (sk && sk->sk_security) { - ssp = sk->sk_security; + if (sk && smack_sock(sk)) { + ssp = smack_sock(sk); skp = ssp->smk_out; skb->secmark = skp->smk_secid; }