From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mimi Zohar Date: Thu, 17 Aug 2017 15:04:35 +0000 Subject: Re: [PATCH v4 7/7] ima: Support module-style appended signatures for appraisal Message-Id: <1502982275.3172.17.camel@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Type: text/plain; charset="ibm852" Content-Transfer-Encoding: base64 List-Id: References: <20170804220330.30026-1-bauerman@linux.vnet.ibm.com> <20170804220330.30026-8-bauerman@linux.vnet.ibm.com> In-Reply-To: <20170804220330.30026-8-bauerman@linux.vnet.ibm.com> To: Thiago Jung Bauermann , linux-security-module@vger.kernel.org Cc: linux-ima-devel@lists.sourceforge.net, keyrings@vger.kernel.org, linux-crypto@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , David Howells , David Woodhouse , Jessica Yu , Rusty Russell , Herbert Xu , "David S. Miller" , "AKASHI, Takahiro" T24gRnJpLCAyMDE3LTA4LTA0IGF0IDE5OjAzIC0wMzAwLCBUaGlhZ28gSnVuZyBCYXVlcm1hbm4g d3JvdGU6Cj4gVGhpcyBwYXRjaCBpbnRyb2R1Y2VzIHRoZSBtb2RzaWcga2V5d29yZCB0byB0aGUg SU1BIHBvbGljeSBzeW50YXggdG8KPiBzcGVjaWZ5IHRoYXQgYSBnaXZlbiBob29rIHNob3VsZCBl eHBlY3QgdGhlIGZpbGUgdG8gaGF2ZSB0aGUgSU1BIHNpZ25hdHVyZQo+IGFwcGVuZGVkIHRvIGl0 LiBIZXJlIGlzIGhvdyBpdCBjYW4gYmUgdXNlZCBpbiBhIHJ1bGU6Cj4gCj4gYXBwcmFpc2UgZnVu Yz1LRVhFQ19LRVJORUxfQ0hFQ0sgYXBwcmFpc2VfdHlwZT1tb2RzaWd8aW1hc2lnCj4gCj4gV2l0 aCB0aGlzIHJ1bGUsIElNQSB3aWxsIGFjY2VwdCBlaXRoZXIgYW4gYXBwZW5kZWQgc2lnbmF0dXJl IG9yIGEgc2lnbmF0dXJlCj4gc3RvcmVkIGluIHRoZSBleHRlbmRlZCBhdHRyaWJ1dGUuIEluIHRo YXQgY2FzZSwgaXQgd2lsbCBmaXJzdCBjaGVjayB3aGV0aGVyCj4gdGhlcmUgaXMgYW4gYXBwZW5k ZWQgc2lnbmF0dXJlLCBhbmQgaWYgbm90IGl0IHdpbGwgcmVhZCBpdCBmcm9tIHRoZQo+IGV4dGVu ZGVkIGF0dHJpYnV0ZS4KPiAKPiBUaGUgZm9ybWF0IG9mIHRoZSBhcHBlbmRlZCBzaWduYXR1cmUg aXMgdGhlIHNhbWUgdXNlZCBmb3Igc2lnbmVkIGtlcm5lbAo+IG1vZHVsZXMuIFRoaXMgbWVhbnMg dGhhdCB0aGUgZmlsZSBjYW4gYmUgc2lnbmVkIHdpdGggdGhlIHNjcmlwdHMvc2lnbi1maWxlCj4g dG9vbCwgd2l0aCBhIGNvbW1hbmQgbGluZSBzdWNoIGFzIHRoaXM6Cj4gCj4gJCBzaWduLWZpbGUg c2hhMjU2IHByaXZrZXlfaW1hLnBlbSB4NTA5X2ltYS5kZXIgdm1saW51eAo+IAo+IFRoaXMgY29k ZSBvbmx5IHdvcmtzIGZvciBmaWxlcyB0aGF0IGFyZSBoYXNoZWQgZnJvbSBhIG1lbW9yeSBidWZm ZXIsIG5vdAo+IGZvciBmaWxlcyB0aGF0IGFyZSByZWFkIGZyb20gZGlzayBhdCB0aGUgdGltZSBv ZiBoYXNoIGNhbGN1bGF0aW9uLiBJbiBvdGhlcgo+IHdvcmRzLCBvbmx5IGhvb2tzIHRoYXQgdXNl IGtlcm5lbF9yZWFkX2ZpbGUgY2FuIHN1cHBvcnQgYXBwZW5kZWQKPiBzaWduYXR1cmVzLiBUaGlz IG1lYW5zIHRoYXQgb25seSBGSVJNV0FSRV9DSEVDSywgS0VYRUNfS0VSTkVMX0NIRUNLLAo+IEtF WEVDX0lOSVRSQU1GU19DSEVDSyBhbmQgUE9MSUNZX0NIRUNLIGNhbiBiZSBzdXBwb3J0ZWQuCj4g Cj4gVGhpcyBmZWF0dXJlIHdhcnJhbnRzIGEgc2VwYXJhdGUgY29uZmlnIG9wdGlvbiBiZWNhdXNl IGVuYWJsaW5nIGl0IGJyaW5ncwo+IGluIG1hbnkgb3RoZXIgY29uZmlnIG9wdGlvbnMuCj4gCj4g U2lnbmVkLW9mZi1ieTogVGhpYWdvIEp1bmcgQmF1ZXJtYW5uIDxiYXVlcm1hbkBsaW51eC52bmV0 LmlibS5jb20+CgpPdGhlciB0aGFuIHRoZSBhcHBlbmRlZCBzaWduYXR1cmUgbm90IGJlaW5nIHBy b3Blcmx5IGluY2x1ZGVkIGluIHRoZQptZWFzdXJlbWVudCBsaXN0LCB0aGUgcGF0Y2ggc2VlbXMg dG8gYmUgd29ya2luZy4gwqBUaGlzIHBhdGNoIGlzIG9uIHRoZQpyYXRoZXIgbGFyZ2Ugc2l6ZS4g Q291bGQgeW91IGdvIGJhY2sgYW5kIGJyZWFrIHRoaXMgcGF0Y2ggdXAgaW50bwpzbWFsbGVyLCBt b3JlIGNvbmNpc2UgcGF0Y2hlcywgd2l0aCBjbGVhciBwYXRjaCBkZXNjcmlwdGlvbnMgKGVnLgpz ZXBhcmF0ZSBjb2RlIGNsZWFudXAgZnJvbSBjaGFuZ2VzLCBuZXcgcG9saWN5IG9wdGlvbiwgY29k ZSBmb3IKYXBwcmFpc2luZyBhbiBhdHRhY2hlZCBzaWduYXR1cmUsIHN0b3JpbmcgdGhlIGFwcGVu ZGVkIHNpZ25hdHVyZSBpbgp0aGUgbWVhc3VyZW1lbnQgbGlzdCwgZXRjKT8KCnRoYW5rcyEKCk1p bWkKCj4gLS0tCj4gIHNlY3VyaXR5L2ludGVncml0eS9pbWEvS2NvbmZpZyAgICAgICAgICAgIHwg IDEzICsrKwo+ICBzZWN1cml0eS9pbnRlZ3JpdHkvaW1hL01ha2VmaWxlICAgICAgICAgICB8ICAg MSArCj4gIHNlY3VyaXR5L2ludGVncml0eS9pbWEvaW1hLmggICAgICAgICAgICAgIHwgIDcwICsr KysrKysrKysrLQo+ICBzZWN1cml0eS9pbnRlZ3JpdHkvaW1hL2ltYV9hcHByYWlzZS5jICAgICB8 IDE3OCArKysrKysrKysrKysrKysrKysrKysrKysrLS0tLS0KPiAgc2VjdXJpdHkvaW50ZWdyaXR5 L2ltYS9pbWFfbWFpbi5jICAgICAgICAgfCAgIDcgKy0KPiAgc2VjdXJpdHkvaW50ZWdyaXR5L2lt YS9pbWFfbW9kc2lnLmMgICAgICAgfCAxNzggKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr Cj4gIHNlY3VyaXR5L2ludGVncml0eS9pbWEvaW1hX3BvbGljeS5jICAgICAgIHwgIDI2ICsrKy0t Cj4gIHNlY3VyaXR5L2ludGVncml0eS9pbWEvaW1hX3RlbXBsYXRlX2xpYi5jIHwgIDE0ICsrLQo+ ICBzZWN1cml0eS9pbnRlZ3JpdHkvaW50ZWdyaXR5LmggICAgICAgICAgICB8ICAgNCArLQo+ICA5 IGZpbGVzIGNoYW5nZWQsIDQ0MyBpbnNlcnRpb25zKCspLCA0OCBkZWxldGlvbnMoLSkKPiAKPiBk aWZmIC0tZ2l0IGEvc2VjdXJpdHkvaW50ZWdyaXR5L2ltYS9LY29uZmlnIGIvc2VjdXJpdHkvaW50 ZWdyaXR5L2ltYS9LY29uZmlnCj4gaW5kZXggMzVlZjY5MzEyODExLi41NWY3MzRhNjEyNGIgMTAw NjQ0Cj4gLS0tIGEvc2VjdXJpdHkvaW50ZWdyaXR5L2ltYS9LY29uZmlnCj4gKysrIGIvc2VjdXJp dHkvaW50ZWdyaXR5L2ltYS9LY29uZmlnCj4gQEAgLTE2Myw2ICsxNjMsMTkgQEAgY29uZmlnIElN QV9BUFBSQUlTRV9CT09UUEFSQU0KPiAgCSAgVGhpcyBvcHRpb24gZW5hYmxlcyB0aGUgZGlmZmVy ZW50ICJpbWFfYXBwcmFpc2U9IiBtb2Rlcwo+ICAJICAoZWcuIGZpeCwgbG9nKSBmcm9tIHRoZSBi b290IGNvbW1hbmQgbGluZS4KPiAKPiArY29uZmlnIElNQV9BUFBSQUlTRV9NT0RTSUcKPiArCWJv b2wgIlN1cHBvcnQgbW9kdWxlLXN0eWxlIHNpZ25hdHVyZXMgZm9yIGFwcHJhaXNhbCIKPiArCWRl cGVuZHMgb24gSU1BX0FQUFJBSVNFCj4gKwlkZXBlbmRzIG9uIElOVEVHUklUWV9BU1lNTUVUUklD X0tFWVMKPiArCXNlbGVjdCBQS0NTN19NRVNTQUdFX1BBUlNFUgo+ICsJc2VsZWN0IE1PRFVMRV9T SUdfRk9STUFUCj4gKwlkZWZhdWx0IG4KPiArCWhlbHAKPiArCSAgIEFkZHMgc3VwcG9ydCBmb3Ig c2lnbmF0dXJlcyBhcHBlbmRlZCB0byBmaWxlcy4gVGhlIGZvcm1hdCBvZiB0aGUKPiArCSAgIGFw cGVuZGVkIHNpZ25hdHVyZSBpcyB0aGUgc2FtZSB1c2VkIGZvciBzaWduZWQga2VybmVsIG1vZHVs ZXMuCj4gKwkgICBUaGUgbW9kc2lnIGtleXdvcmQgY2FuIGJlIHVzZWQgaW4gdGhlIElNQSBwb2xp Y3kgdG8gYWxsb3cgYSBob29rCj4gKwkgICB0byBhY2NlcHQgc3VjaCBzaWduYXR1cmVzLgo+ICsK PiAgY29uZmlnIElNQV9UUlVTVEVEX0tFWVJJTkcKPiAgCWJvb2wgIlJlcXVpcmUgYWxsIGtleXMg b24gdGhlIC5pbWEga2V5cmluZyBiZSBzaWduZWQgKGRlcHJlY2F0ZWQpIgo+ICAJZGVwZW5kcyBv biBJTUFfQVBQUkFJU0UgJiYgU1lTVEVNX1RSVVNURURfS0VZUklORwo+IGRpZmYgLS1naXQgYS9z ZWN1cml0eS9pbnRlZ3JpdHkvaW1hL01ha2VmaWxlIGIvc2VjdXJpdHkvaW50ZWdyaXR5L2ltYS9N YWtlZmlsZQo+IGluZGV4IDI5ZjE5OGJkZTAyYi4uYzcyMDI2YWNlY2MzIDEwMDY0NAo+IC0tLSBh L3NlY3VyaXR5L2ludGVncml0eS9pbWEvTWFrZWZpbGUKPiArKysgYi9zZWN1cml0eS9pbnRlZ3Jp dHkvaW1hL01ha2VmaWxlCj4gQEAgLTgsNSArOCw2IEBAIG9iai0kKENPTkZJR19JTUEpICs9IGlt YS5vCj4gIGltYS15IDo9IGltYV9mcy5vIGltYV9xdWV1ZS5vIGltYV9pbml0Lm8gaW1hX21haW4u byBpbWFfY3J5cHRvLm8gaW1hX2FwaS5vIFwKPiAgCSBpbWFfcG9saWN5Lm8gaW1hX3RlbXBsYXRl Lm8gaW1hX3RlbXBsYXRlX2xpYi5vCj4gIGltYS0kKENPTkZJR19JTUFfQVBQUkFJU0UpICs9IGlt YV9hcHByYWlzZS5vCj4gK2ltYS0kKENPTkZJR19JTUFfQVBQUkFJU0VfTU9EU0lHKSArPSBpbWFf bW9kc2lnLm8KPiAgaW1hLSQoQ09ORklHX0hBVkVfSU1BX0tFWEVDKSArPSBpbWFfa2V4ZWMubwo+ ICBvYmotJChDT05GSUdfSU1BX0JMQUNLTElTVF9LRVlSSU5HKSArPSBpbWFfbW9rLm8KPiBkaWZm IC0tZ2l0IGEvc2VjdXJpdHkvaW50ZWdyaXR5L2ltYS9pbWEuaCBiL3NlY3VyaXR5L2ludGVncml0 eS9pbWEvaW1hLmgKPiBpbmRleCBkNTJiNDg3YWQyNTkuLjU0OTJhZjJjZDdjNyAxMDA2NDQKPiAt LS0gYS9zZWN1cml0eS9pbnRlZ3JpdHkvaW1hL2ltYS5oCj4gKysrIGIvc2VjdXJpdHkvaW50ZWdy aXR5L2ltYS9pbWEuaAo+IEBAIC0xOTAsNiArMTkwLDggQEAgZW51bSBpbWFfaG9va3Mgewo+ICAJ X19pbWFfaG9va3MoX19pbWFfaG9va19lbnVtaWZ5KQo+ICB9Owo+IAo+ICtleHRlcm4gY29uc3Qg Y2hhciAqY29uc3QgZnVuY190b2tlbnNbXTsKPiArCj4gIC8qIExJTSBBUEkgZnVuY3Rpb24gZGVm aW5pdGlvbnMgKi8KPiAgaW50IGltYV9nZXRfYWN0aW9uKHN0cnVjdCBpbm9kZSAqaW5vZGUsIGlu dCBtYXNrLAo+ICAJCSAgIGVudW0gaW1hX2hvb2tzIGZ1bmMsIGludCAqcGNyKTsKPiBAQCAtMjM2 LDkgKzIzOCwxMCBAQCBpbnQgaW1hX3BvbGljeV9zaG93KHN0cnVjdCBzZXFfZmlsZSAqbSwgdm9p ZCAqdik7Cj4gICNpZmRlZiBDT05GSUdfSU1BX0FQUFJBSVNFCj4gIGludCBpbWFfYXBwcmFpc2Vf bWVhc3VyZW1lbnQoZW51bSBpbWFfaG9va3MgZnVuYywKPiAgCQkJICAgICBzdHJ1Y3QgaW50ZWdy aXR5X2lpbnRfY2FjaGUgKmlpbnQsCj4gLQkJCSAgICAgc3RydWN0IGZpbGUgKmZpbGUsIGNvbnN0 IHVuc2lnbmVkIGNoYXIgKmZpbGVuYW1lLAo+IC0JCQkgICAgIHN0cnVjdCBldm1faW1hX3hhdHRy X2RhdGEgKnhhdHRyX3ZhbHVlLAo+IC0JCQkgICAgIGludCB4YXR0cl9sZW4sIGludCBvcGVuZWQp Owo+ICsJCQkgICAgIHN0cnVjdCBmaWxlICpmaWxlLCBjb25zdCB2b2lkICpidWYsIGxvZmZfdCBz aXplLAo+ICsJCQkgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKmZpbGVuYW1lLAo+ICsJCQkgICAg IHN0cnVjdCBldm1faW1hX3hhdHRyX2RhdGEgKip4YXR0cl92YWx1ZSwKPiArCQkJICAgICBpbnQg KnhhdHRyX2xlbiwgaW50IG9wZW5lZCk7Cj4gIGludCBpbWFfbXVzdF9hcHByYWlzZShzdHJ1Y3Qg aW5vZGUgKmlub2RlLCBpbnQgbWFzaywgZW51bSBpbWFfaG9va3MgZnVuYyk7Cj4gIHZvaWQgaW1h X3VwZGF0ZV94YXR0cihzdHJ1Y3QgaW50ZWdyaXR5X2lpbnRfY2FjaGUgKmlpbnQsIHN0cnVjdCBm aWxlICpmaWxlKTsKPiAgZW51bSBpbnRlZ3JpdHlfc3RhdHVzIGltYV9nZXRfY2FjaGVfc3RhdHVz KHN0cnVjdCBpbnRlZ3JpdHlfaWludF9jYWNoZSAqaWludCwKPiBAQCAtMjQ4LDEzICsyNTEsMjgg QEAgZW51bSBoYXNoX2FsZ28gaW1hX2dldF9oYXNoX2FsZ28oc3RydWN0IGV2bV9pbWFfeGF0dHJf ZGF0YSAqeGF0dHJfdmFsdWUsCj4gIGludCBpbWFfcmVhZF94YXR0cihzdHJ1Y3QgZGVudHJ5ICpk ZW50cnksCj4gIAkJICAgc3RydWN0IGV2bV9pbWFfeGF0dHJfZGF0YSAqKnhhdHRyX3ZhbHVlKTsK PiAKPiArI2lmZGVmIENPTkZJR19JTUFfQVBQUkFJU0VfTU9EU0lHCj4gK2Jvb2wgaW1hX2hvb2tf c3VwcG9ydHNfbW9kc2lnKGVudW0gaW1hX2hvb2tzIGZ1bmMpOwo+ICtpbnQgaW1hX3JlYWRfbW9k c2lnKGVudW0gaW1hX2hvb2tzIGZ1bmMsIGNvbnN0IHZvaWQgKmJ1ZiwgbG9mZl90IGJ1Zl9sZW4s Cj4gKwkJICAgIHN0cnVjdCBldm1faW1hX3hhdHRyX2RhdGEgKip4YXR0cl92YWx1ZSwKPiArCQkg ICAgaW50ICp4YXR0cl9sZW4pOwo+ICtpbnQgaW1hX2dldF9tb2RzaWdfaGFzaChzdHJ1Y3QgZXZt X2ltYV94YXR0cl9kYXRhICpoZHIsIGVudW0gaGFzaF9hbGdvICphbGdvLAo+ICsJCQl2b2lkIGNv bnN0ICoqaGFzaCwgdTggKmxlbik7Cj4gK2ludCBpbWFfbW9kc2lnX3NlcmlhbGl6ZV9kYXRhKHN0 cnVjdCBldm1faW1hX3hhdHRyX2RhdGEgKmhkciwKPiArCQkJICAgICAgc3RydWN0IGV2bV9pbWFf eGF0dHJfZGF0YSAqKmRhdGEsIGludCAqZGF0YV9sZW4pOwo+ICtpbnQgaW1hX21vZHNpZ192ZXJp ZnkoY29uc3QgdW5zaWduZWQgaW50IGtleXJpbmdfaWQsCj4gKwkJICAgICAgc3RydWN0IGV2bV9p bWFfeGF0dHJfZGF0YSAqaGRyKTsKPiArdm9pZCBpbWFfZnJlZV94YXR0cl9kYXRhKHN0cnVjdCBl dm1faW1hX3hhdHRyX2RhdGEgKmhkcik7Cj4gKyNlbmRpZgo+ICsKPiAgI2Vsc2UKPiAgc3RhdGlj IGlubGluZSBpbnQgaW1hX2FwcHJhaXNlX21lYXN1cmVtZW50KGVudW0gaW1hX2hvb2tzIGZ1bmMs Cj4gIAkJCQkJICAgc3RydWN0IGludGVncml0eV9paW50X2NhY2hlICppaW50LAo+IC0JCQkJCSAg IHN0cnVjdCBmaWxlICpmaWxlLAo+ICsJCQkJCSAgIHN0cnVjdCBmaWxlICpmaWxlLCBjb25zdCB2 b2lkICpidWYsCj4gKwkJCQkJICAgbG9mZl90IHNpemUsCj4gIAkJCQkJICAgY29uc3QgdW5zaWdu ZWQgY2hhciAqZmlsZW5hbWUsCj4gLQkJCQkJICAgc3RydWN0IGV2bV9pbWFfeGF0dHJfZGF0YSAq eGF0dHJfdmFsdWUsCj4gLQkJCQkJICAgaW50IHhhdHRyX2xlbiwgaW50IG9wZW5lZCkKPiArCQkJ CQkgICBzdHJ1Y3QgZXZtX2ltYV94YXR0cl9kYXRhICoqeGF0dHJfdmFsdWUsCj4gKwkJCQkJICAg aW50ICp4YXR0cl9sZW4sIGludCBvcGVuZWQpCj4gIHsKPiAgCXJldHVybiBJTlRFR1JJVFlfVU5L Tk9XTjsKPiAgfQo+IEBAIC0yOTEsNiArMzA5LDQ2IEBAIHN0YXRpYyBpbmxpbmUgaW50IGltYV9y ZWFkX3hhdHRyKHN0cnVjdCBkZW50cnkgKmRlbnRyeSwKPiAKPiAgI2VuZGlmIC8qIENPTkZJR19J TUFfQVBQUkFJU0UgKi8KPiAKPiArI2lmbmRlZiBDT05GSUdfSU1BX0FQUFJBSVNFX01PRFNJRwo+ ICtzdGF0aWMgaW5saW5lIGJvb2wgaW1hX2hvb2tfc3VwcG9ydHNfbW9kc2lnKGVudW0gaW1hX2hv b2tzIGZ1bmMpCj4gK3sKPiArCXJldHVybiBmYWxzZTsKPiArfQo+ICsKPiArc3RhdGljIGlubGlu ZSBpbnQgaW1hX3JlYWRfbW9kc2lnKGVudW0gaW1hX2hvb2tzIGZ1bmMsIGNvbnN0IHZvaWQgKmJ1 ZiwKPiArCQkJCSAgbG9mZl90IGJ1Zl9sZW4sCj4gKwkJCQkgIHN0cnVjdCBldm1faW1hX3hhdHRy X2RhdGEgKip4YXR0cl92YWx1ZSwKPiArCQkJCSAgaW50ICp4YXR0cl9sZW4pCj4gK3sKPiArCXJl dHVybiAtRU5PVFNVUFA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbmxpbmUgaW50IGltYV9nZXRfbW9k c2lnX2hhc2goc3RydWN0IGV2bV9pbWFfeGF0dHJfZGF0YSAqaGRyLAo+ICsJCQkJICAgICAgZW51 bSBoYXNoX2FsZ28gKmFsZ28sIHZvaWQgY29uc3QgKipoYXNoLAo+ICsJCQkJICAgICAgdTggKmxl bikKPiArewo+ICsJcmV0dXJuIC1FTk9UU1VQUDsKPiArfQo+ICsKPiArc3RhdGljIGlubGluZSBp bnQgaW1hX21vZHNpZ19zZXJpYWxpemVfZGF0YShzdHJ1Y3QgZXZtX2ltYV94YXR0cl9kYXRhICpo ZHIsCj4gKwkJCQkJICAgIHN0cnVjdCBldm1faW1hX3hhdHRyX2RhdGEgKipkYXRhLAo+ICsJCQkJ CSAgICBpbnQgKmRhdGFfbGVuKQo+ICt7Cj4gKwlyZXR1cm4gLUVOT1RTVVBQOwo+ICt9Cj4gKwo+ ICtzdGF0aWMgaW5saW5lIGludCBpbWFfbW9kc2lnX3ZlcmlmeShjb25zdCB1bnNpZ25lZCBpbnQg a2V5cmluZ19pZCwKPiArCQkJCSAgICBzdHJ1Y3QgZXZtX2ltYV94YXR0cl9kYXRhICpoZHIpCj4g K3sKPiArCXJldHVybiAtRU5PVFNVUFA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbmxpbmUgdm9pZCBp bWFfZnJlZV94YXR0cl9kYXRhKHN0cnVjdCBldm1faW1hX3hhdHRyX2RhdGEgKmhkcikKPiArewo+ ICsJa2ZyZWUoaGRyKTsKPiArfQo+ICsjZW5kaWYKPiArCj4gIC8qIExTTSBiYXNlZCBwb2xpY3kg cnVsZXMgcmVxdWlyZSBhdWRpdCAqLwo+ICAjaWZkZWYgQ09ORklHX0lNQV9MU01fUlVMRVMKPiAK PiBkaWZmIC0tZ2l0IGEvc2VjdXJpdHkvaW50ZWdyaXR5L2ltYS9pbWFfYXBwcmFpc2UuYyBiL3Nl Y3VyaXR5L2ludGVncml0eS9pbWEvaW1hX2FwcHJhaXNlLmMKPiBpbmRleCA4N2QyYjYwMWNmOGUu LjVhMjQ0ZWJjNjFkOSAxMDA2NDQKPiAtLS0gYS9zZWN1cml0eS9pbnRlZ3JpdHkvaW1hL2ltYV9h cHByYWlzZS5jCj4gKysrIGIvc2VjdXJpdHkvaW50ZWdyaXR5L2ltYS9pbWFfYXBwcmFpc2UuYwo+ IEBAIC0xOTAsNiArMTkwLDY0IEBAIGludCBpbWFfcmVhZF94YXR0cihzdHJ1Y3QgZGVudHJ5ICpk ZW50cnksCj4gIAlyZXR1cm4gcmV0Owo+ICB9Cj4gCj4gK3N0YXRpYyB2b2lkIHByb2Nlc3NfeGF0 dHJfZXJyb3IoaW50IHJjLCBzdHJ1Y3QgaW50ZWdyaXR5X2lpbnRfY2FjaGUgKmlpbnQsCj4gKwkJ CQlpbnQgb3BlbmVkLCBjaGFyIGNvbnN0ICoqY2F1c2UsCj4gKwkJCQllbnVtIGludGVncml0eV9z dGF0dXMgKnN0YXR1cykKPiArewo+ICsJaWYgKHJjICYmIHJjICE9IC1FTk9EQVRBKQo+ICsJCXJl dHVybjsKPiArCj4gKwkqY2F1c2UgPSBpaW50LT5mbGFncyAmIElNQV9ESUdTSUdfUkVRVUlSRUQg Pwo+ICsJCSJJTUEtc2lnbmF0dXJlLXJlcXVpcmVkIiA6ICJtaXNzaW5nLWhhc2giOwo+ICsJKnN0 YXR1cyA9IElOVEVHUklUWV9OT0xBQkVMOwo+ICsKPiArCWlmIChvcGVuZWQgJiBGSUxFX0NSRUFU RUQpCj4gKwkJaWludC0+ZmxhZ3MgfD0gSU1BX05FV19GSUxFOwo+ICsKPiArCWlmICgoaWludC0+ ZmxhZ3MgJiBJTUFfTkVXX0ZJTEUpICYmCj4gKwkgICAgIShpaW50LT5mbGFncyAmIElNQV9ESUdT SUdfUkVRVUlSRUQpKQo+ICsJCSpzdGF0dXMgPSBJTlRFR1JJVFlfUEFTUzsKPiArfQo+ICsKPiAr c3RhdGljIGludCBhcHByYWlzZV9tb2RzaWcoc3RydWN0IGludGVncml0eV9paW50X2NhY2hlICpp aW50LAo+ICsJCQkgICBzdHJ1Y3QgZXZtX2ltYV94YXR0cl9kYXRhICp4YXR0cl92YWx1ZSwKPiAr CQkJICAgaW50IHhhdHRyX2xlbikKPiArewo+ICsJZW51bSBoYXNoX2FsZ28gYWxnbzsKPiArCWNv bnN0IHZvaWQgKmRpZ2VzdDsKPiArCXZvaWQgKmJ1ZjsKPiArCWludCByYywgbGVuOwo+ICsJdTgg ZGlnX2xlbjsKPiArCj4gKwlyYyA9IGltYV9tb2RzaWdfdmVyaWZ5KElOVEVHUklUWV9LRVlSSU5H X0lNQSwgeGF0dHJfdmFsdWUpOwo+ICsJaWYgKHJjKQo+ICsJCXJldHVybiByYzsKPiArCj4gKwkv Kgo+ICsJICogVGhlIHNpZ25hdHVyZSBpcyBnb29kLiBOb3cgbGV0J3MgcHV0IHRoZSBzaWcgaGFz aAo+ICsJICogaW50byB0aGUgaWludCBjYWNoZSBzbyB0aGF0IGl0IGdldHMgc3RvcmVkIGluIHRo ZQo+ICsJICogbWVhc3VyZW1lbnQgbGlzdC4KPiArCSAqLwo+ICsKPiArCXJjID0gaW1hX2dldF9t b2RzaWdfaGFzaCh4YXR0cl92YWx1ZSwgJmFsZ28sICZkaWdlc3QsICZkaWdfbGVuKTsKPiArCWlm IChyYykKPiArCQlyZXR1cm4gcmM7Cj4gKwo+ICsJbGVuID0gc2l6ZW9mKGlpbnQtPmltYV9oYXNo KSArIGRpZ19sZW47Cj4gKwlidWYgPSBrcmVhbGxvYyhpaW50LT5pbWFfaGFzaCwgbGVuLCBHRlBf Tk9GUyk7Cj4gKwlpZiAoIWJ1ZikKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCj4gKwlpaW50LT5p bWFfaGFzaCA9IGJ1ZjsKPiArCWlpbnQtPmZsYWdzIHw9IElNQV9ESUdTSUc7Cj4gKwlpaW50LT5p bWFfaGFzaC0+YWxnbyA9IGFsZ287Cj4gKwlpaW50LT5pbWFfaGFzaC0+bGVuZ3RoID0gZGlnX2xl bjsKPiArCj4gKwltZW1jcHkoaWludC0+aW1hX2hhc2gtPmRpZ2VzdCwgZGlnZXN0LCBkaWdfbGVu KTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiAgLyoKPiAgICogaW1hX2FwcHJhaXNlX21l YXN1cmVtZW50IC0gYXBwcmFpc2UgZmlsZSBtZWFzdXJlbWVudAo+ICAgKgo+IEBAIC0yMDAsNDQg KzI1OCw1NSBAQCBpbnQgaW1hX3JlYWRfeGF0dHIoc3RydWN0IGRlbnRyeSAqZGVudHJ5LAo+ICAg Ki8KPiAgaW50IGltYV9hcHByYWlzZV9tZWFzdXJlbWVudChlbnVtIGltYV9ob29rcyBmdW5jLAo+ ICAJCQkgICAgIHN0cnVjdCBpbnRlZ3JpdHlfaWludF9jYWNoZSAqaWludCwKPiAtCQkJICAgICBz dHJ1Y3QgZmlsZSAqZmlsZSwgY29uc3QgdW5zaWduZWQgY2hhciAqZmlsZW5hbWUsCj4gLQkJCSAg ICAgc3RydWN0IGV2bV9pbWFfeGF0dHJfZGF0YSAqeGF0dHJfdmFsdWUsCj4gLQkJCSAgICAgaW50 IHhhdHRyX2xlbiwgaW50IG9wZW5lZCkKPiArCQkJICAgICBzdHJ1Y3QgZmlsZSAqZmlsZSwgY29u c3Qgdm9pZCAqYnVmLCBsb2ZmX3Qgc2l6ZSwKPiArCQkJICAgICBjb25zdCB1bnNpZ25lZCBjaGFy ICpmaWxlbmFtZSwKPiArCQkJICAgICBzdHJ1Y3QgZXZtX2ltYV94YXR0cl9kYXRhICoqeGF0dHJf dmFsdWVfLAo+ICsJCQkgICAgIGludCAqeGF0dHJfbGVuXywgaW50IG9wZW5lZCkKPiAgewo+ICAJ c3RhdGljIGNvbnN0IGNoYXIgb3BbXSA9ICJhcHByYWlzZV9kYXRhIjsKPiAtCWNoYXIgKmNhdXNl ID0gInVua25vd24iOwo+ICsJY29uc3QgY2hhciAqY2F1c2UgPSAidW5rbm93biI7Cj4gIAlzdHJ1 Y3QgZGVudHJ5ICpkZW50cnkgPSBmaWxlX2RlbnRyeShmaWxlKTsKPiAgCXN0cnVjdCBpbm9kZSAq aW5vZGUgPSBkX2JhY2tpbmdfaW5vZGUoZGVudHJ5KTsKPiAgCWVudW0gaW50ZWdyaXR5X3N0YXR1 cyBzdGF0dXMgPSBJTlRFR1JJVFlfVU5LTk9XTjsKPiAtCWludCByYyA9IHhhdHRyX2xlbiwgaGFz aF9zdGFydCA9IDA7Cj4gKwlzdHJ1Y3QgZXZtX2ltYV94YXR0cl9kYXRhICp4YXR0cl92YWx1ZSA9 ICp4YXR0cl92YWx1ZV87Cj4gKwlpbnQgeGF0dHJfbGVuID0gKnhhdHRyX2xlbl8sIHJjID0geGF0 dHJfbGVuLCBoYXNoX3N0YXJ0ID0gMDsKPiArCWJvb2wgYXBwcmFpc2luZ19tb2RzaWcgPSBmYWxz ZTsKPiArCj4gKwlpZiAoaWludC0+ZmxhZ3MgJiBJTUFfTU9EU0lHX0FMTE9XRUQgJiYKPiArCSAg ICAhaW1hX3JlYWRfbW9kc2lnKGZ1bmMsIGJ1Ziwgc2l6ZSwgJnhhdHRyX3ZhbHVlLCAmeGF0dHJf bGVuKSkgewo+ICsJCWFwcHJhaXNpbmdfbW9kc2lnID0gdHJ1ZTsKPiArCQlyYyA9IHhhdHRyX2xl bjsKPiArCX0KPiAKPiAtCWlmICghKGlub2RlLT5pX29wZmxhZ3MgJiBJT1BfWEFUVFIpKQo+ICsJ LyogSWYgbm90IGFwcHJhaXNpbmcgYSBtb2RzaWcsIHdlIG5lZWQgYW4geGF0dHIuICovCj4gKwlp ZiAoIWFwcHJhaXNpbmdfbW9kc2lnICYmICEoaW5vZGUtPmlfb3BmbGFncyAmIElPUF9YQVRUUikp Cj4gIAkJcmV0dXJuIElOVEVHUklUWV9VTktOT1dOOwo+IAo+ICAJaWYgKHJjIDw9IDApIHsKPiAt CQlpZiAocmMgJiYgcmMgIT0gLUVOT0RBVEEpCj4gLQkJCWdvdG8gb3V0Owo+IC0KPiAtCQljYXVz ZSA9IGlpbnQtPmZsYWdzICYgSU1BX0RJR1NJR19SRVFVSVJFRCA/Cj4gLQkJCQkiSU1BLXNpZ25h dHVyZS1yZXF1aXJlZCIgOiAibWlzc2luZy1oYXNoIjsKPiAtCQlzdGF0dXMgPSBJTlRFR1JJVFlf Tk9MQUJFTDsKPiAtCQlpZiAob3BlbmVkICYgRklMRV9DUkVBVEVEKQo+IC0JCQlpaW50LT5mbGFn cyB8PSBJTUFfTkVXX0ZJTEU7Cj4gLQkJaWYgKChpaW50LT5mbGFncyAmIElNQV9ORVdfRklMRSkg JiYKPiAtCQkgICAgIShpaW50LT5mbGFncyAmIElNQV9ESUdTSUdfUkVRVUlSRUQpKQo+IC0JCQlz dGF0dXMgPSBJTlRFR1JJVFlfUEFTUzsKPiArCQlwcm9jZXNzX3hhdHRyX2Vycm9yKHJjLCBpaW50 LCBvcGVuZWQsICZjYXVzZSwgJnN0YXR1cyk7Cj4gIAkJZ290byBvdXQ7Cj4gIAl9Cj4gCj4gLQlz dGF0dXMgPSBldm1fdmVyaWZ5eGF0dHIoZGVudHJ5LCBYQVRUUl9OQU1FX0lNQSwgeGF0dHJfdmFs dWUsIHJjLCBpaW50KTsKPiAtCWlmICgoc3RhdHVzICE9IElOVEVHUklUWV9QQVNTKSAmJiAoc3Rh dHVzICE9IElOVEVHUklUWV9VTktOT1dOKSkgewo+IC0JCWlmICgoc3RhdHVzID0gSU5URUdSSVRZ X05PTEFCRUwpCj4gLQkJICAgIHx8IChzdGF0dXMgPSBJTlRFR1JJVFlfTk9YQVRUUlMpKQo+IC0J CQljYXVzZSA9ICJtaXNzaW5nLUhNQUMiOwo+IC0JCWVsc2UgaWYgKHN0YXR1cyA9IElOVEVHUklU WV9GQUlMKQo+IC0JCQljYXVzZSA9ICJpbnZhbGlkLUhNQUMiOwo+ICsJc3RhdHVzID0gZXZtX3Zl cmlmeXhhdHRyKGRlbnRyeSwgWEFUVFJfTkFNRV9JTUEsIE5VTEwsIDAsIGlpbnQpOwo+ICsJc3dp dGNoIChzdGF0dXMpIHsKPiArCWNhc2UgSU5URUdSSVRZX1BBU1M6Cj4gKwljYXNlIElOVEVHUklU WV9VTktOT1dOOgo+ICsJCWJyZWFrOwo+ICsJY2FzZSBJTlRFR1JJVFlfTk9YQVRUUlM6Cj4gKwkJ LyogTm8gRVZNIHByb3RlY3RlZCB4YXR0cnMuICovCj4gKwkJaWYgKGFwcHJhaXNpbmdfbW9kc2ln KQo+ICsJCQlicmVhazsKPiArCWNhc2UgSU5URUdSSVRZX05PTEFCRUw6Cj4gKwkJLyogTm8gc2Vj dXJpdHkuZXZtIHhhdHRyLiAqLwo+ICsJCWNhdXNlID0gIm1pc3NpbmctSE1BQyI7Cj4gKwkJZ290 byBvdXQ7Cj4gKwljYXNlIElOVEVHUklUWV9GQUlMOgo+ICsJCS8qIEludmFsaWQgSE1BQy9zaWdu YXR1cmUuICovCj4gKwkJY2F1c2UgPSAiaW52YWxpZC1ITUFDIjsKPiAgCQlnb3RvIG91dDsKPiAg CX0KPiArCj4gKyByZXRyeToKPiAgCXN3aXRjaCAoeGF0dHJfdmFsdWUtPnR5cGUpIHsKPiAgCWNh c2UgSU1BX1hBVFRSX0RJR0VTVF9ORzoKPiAgCQkvKiBmaXJzdCBieXRlIGNvbnRhaW5zIGFsZ29y aXRobSBpZCAqLwo+IEBAIC0yODEsNiArMzUwLDU0IEBAIGludCBpbWFfYXBwcmFpc2VfbWVhc3Vy ZW1lbnQoZW51bSBpbWFfaG9va3MgZnVuYywKPiAgCQkJc3RhdHVzID0gSU5URUdSSVRZX1BBU1M7 Cj4gIAkJfQo+ICAJCWJyZWFrOwo+ICsJY2FzZSBJTUFfTU9EU0lHOgo+ICsJCS8qCj4gKwkJICog VG8gYXZvaWQgYmVpbmcgdHJpY2tlZCBpbnRvIGFuIGluZmluaXRlIGxvb3AsIHdlIGRvbid0IGFs bG93Cj4gKwkJICogYSBtb2RzaWcgc3RvcmVkIGluIHRoZSB4YXR0ci4KPiArCQkgKi8KPiArCQlp ZiAoIWFwcHJhaXNpbmdfbW9kc2lnKSB7Cj4gKwkJCXN0YXR1cyA9IElOVEVHUklUWV9VTktOT1dO Owo+ICsJCQljYXVzZSA9ICJ1bmtub3duLWltYS1kYXRhIjsKPiArCQkJYnJlYWs7Cj4gKwkJfQo+ ICsKPiArCQlyYyA9IGFwcHJhaXNlX21vZHNpZyhpaW50LCB4YXR0cl92YWx1ZSwgeGF0dHJfbGVu KTsKPiArCQlpZiAoIXJjKSB7Cj4gKwkJCWtmcmVlKCp4YXR0cl92YWx1ZV8pOwo+ICsJCQkqeGF0 dHJfdmFsdWVfID0geGF0dHJfdmFsdWU7Cj4gKwkJCSp4YXR0cl9sZW5fID0geGF0dHJfbGVuOwo+ ICsKPiArCQkJc3RhdHVzID0gSU5URUdSSVRZX1BBU1M7Cj4gKwkJCWJyZWFrOwo+ICsJCX0KPiAr Cj4gKwkJaW1hX2ZyZWVfeGF0dHJfZGF0YSh4YXR0cl92YWx1ZSk7Cj4gKwo+ICsJCS8qCj4gKwkJ ICogVGhlIGFwcGVuZGVkIHNpZ25hdHVyZSBmYWlsZWQgdmVyaWZpY2F0aW9uLiBMZXQncyBzZWUg aWYKPiArCQkgKiB0aGVyZSdzIGFuIGV4dGVuZGVkIGF0dHJpYnV0ZSB0byBmYWxsIGJhY2sgdG8u Cj4gKwkJICovCj4gKwkJaWYgKGlub2RlLT5pX29wZmxhZ3MgJiBJT1BfWEFUVFIgJiYgKnhhdHRy X2xlbl8gIT0gMCkgewo+ICsJCQl4YXR0cl92YWx1ZSA9ICp4YXR0cl92YWx1ZV87Cj4gKwkJCXhh dHRyX2xlbiA9IHJjID0gKnhhdHRyX2xlbl87Cj4gKwkJCWFwcHJhaXNpbmdfbW9kc2lnID0gZmFs c2U7Cj4gKwo+ICsJCQlpZiAocmMgPD0gMCkgewo+ICsJCQkJcHJvY2Vzc194YXR0cl9lcnJvcihy YywgaWludCwgb3BlbmVkLCAmY2F1c2UsCj4gKwkJCQkJCSAgICAmc3RhdHVzKTsKPiArCQkJCWdv dG8gb3V0Owo+ICsJCQl9Cj4gKwo+ICsJCQlnb3RvIHJldHJ5Owo+ICsJCX0KPiArCj4gKwkJaWYg KHJjID0gLUVPUE5PVFNVUFApCj4gKwkJCXN0YXR1cyA9IElOVEVHUklUWV9VTktOT1dOOwo+ICsJ CWVsc2UgaWYgKHJjKSB7Cj4gKwkJCWNhdXNlID0gImludmFsaWQtc2lnbmF0dXJlIjsKPiArCQkJ c3RhdHVzID0gSU5URUdSSVRZX0ZBSUw7Cj4gKwkJfQo+ICsJCWJyZWFrOwo+ICAJZGVmYXVsdDoK PiAgCQlzdGF0dXMgPSBJTlRFR1JJVFlfVU5LTk9XTjsKPiAgCQljYXVzZSA9ICJ1bmtub3duLWlt YS1kYXRhIjsKPiBAQCAtMjkxLDEzICs0MDgsMTUgQEAgaW50IGltYV9hcHByYWlzZV9tZWFzdXJl bWVudChlbnVtIGltYV9ob29rcyBmdW5jLAo+ICAJaWYgKHN0YXR1cyAhPSBJTlRFR1JJVFlfUEFT Uykgewo+ICAJCWlmICgoaW1hX2FwcHJhaXNlICYgSU1BX0FQUFJBSVNFX0ZJWCkgJiYKPiAgCQkg ICAgKCF4YXR0cl92YWx1ZSB8fAo+IC0JCSAgICAgeGF0dHJfdmFsdWUtPnR5cGUgIT0gRVZNX0lN QV9YQVRUUl9ESUdTSUcpKSB7Cj4gKwkJICAgICAoeGF0dHJfdmFsdWUtPnR5cGUgIT0gRVZNX0lN QV9YQVRUUl9ESUdTSUcgJiYKPiArCQkgICAgICB4YXR0cl92YWx1ZS0+dHlwZSAhPSBJTUFfTU9E U0lHKSkpIHsKPiAgCQkJaWYgKCFpbWFfZml4X3hhdHRyKGRlbnRyeSwgaWludCkpCj4gIAkJCQlz dGF0dXMgPSBJTlRFR1JJVFlfUEFTUzsKPiAgCQl9IGVsc2UgaWYgKChpbm9kZS0+aV9zaXplID0g MCkgJiYKPiAgCQkJICAgKGlpbnQtPmZsYWdzICYgSU1BX05FV19GSUxFKSAmJgo+ICAJCQkgICAo eGF0dHJfdmFsdWUgJiYKPiAtCQkJICAgIHhhdHRyX3ZhbHVlLT50eXBlID0gRVZNX0lNQV9YQVRU Ul9ESUdTSUcpKSB7Cj4gKwkJCSAgICAoeGF0dHJfdmFsdWUtPnR5cGUgPSBFVk1fSU1BX1hBVFRS X0RJR1NJRyB8fAo+ICsJCQkgICAgIHhhdHRyX3ZhbHVlLT50eXBlID0gSU1BX01PRFNJRykpKSB7 Cj4gIAkJCXN0YXR1cyA9IElOVEVHUklUWV9QQVNTOwo+ICAJCX0KPiAgCQlpbnRlZ3JpdHlfYXVk aXRfbXNnKEFVRElUX0lOVEVHUklUWV9EQVRBLCBpbm9kZSwgZmlsZW5hbWUsCj4gQEAgLTM5OCw2 ICs1MTcsNyBAQCBpbnQgaW1hX2lub2RlX3NldHhhdHRyKHN0cnVjdCBkZW50cnkgKmRlbnRyeSwg Y29uc3QgY2hhciAqeGF0dHJfbmFtZSwKPiAgCQkgICAgICAgY29uc3Qgdm9pZCAqeGF0dHJfdmFs dWUsIHNpemVfdCB4YXR0cl92YWx1ZV9sZW4pCj4gIHsKPiAgCWNvbnN0IHN0cnVjdCBldm1faW1h X3hhdHRyX2RhdGEgKnh2YWx1ZSA9IHhhdHRyX3ZhbHVlOwo+ICsJYm9vbCBkaWdzaWc7Cj4gIAlp bnQgcmVzdWx0Owo+IAo+ICAJcmVzdWx0ID0gaW1hX3Byb3RlY3RfeGF0dHIoZGVudHJ5LCB4YXR0 cl9uYW1lLCB4YXR0cl92YWx1ZSwKPiBAQCAtNDA1LDggKzUyNSwxMCBAQCBpbnQgaW1hX2lub2Rl X3NldHhhdHRyKHN0cnVjdCBkZW50cnkgKmRlbnRyeSwgY29uc3QgY2hhciAqeGF0dHJfbmFtZSwK PiAgCWlmIChyZXN1bHQgPSAxKSB7Cj4gIAkJaWYgKCF4YXR0cl92YWx1ZV9sZW4gfHwgKHh2YWx1 ZS0+dHlwZSA+PSBJTUFfWEFUVFJfTEFTVCkpCj4gIAkJCXJldHVybiAtRUlOVkFMOwo+IC0JCWlt YV9yZXNldF9hcHByYWlzZV9mbGFncyhkX2JhY2tpbmdfaW5vZGUoZGVudHJ5KSwKPiAtCQkJICh4 dmFsdWUtPnR5cGUgPSBFVk1fSU1BX1hBVFRSX0RJR1NJRykgPyAxIDogMCk7Cj4gKwo+ICsJCWRp Z3NpZyA9IHh2YWx1ZS0+dHlwZSA9IEVWTV9JTUFfWEFUVFJfRElHU0lHIHx8Cj4gKwkJCQl4dmFs dWUtPnR5cGUgPSBJTUFfTU9EU0lHOwo+ICsJCWltYV9yZXNldF9hcHByYWlzZV9mbGFncyhkX2Jh Y2tpbmdfaW5vZGUoZGVudHJ5KSwgZGlnc2lnKTsKPiAgCQlyZXN1bHQgPSAwOwo+ICAJfQo+ICAJ cmV0dXJuIHJlc3VsdDsKPiBkaWZmIC0tZ2l0IGEvc2VjdXJpdHkvaW50ZWdyaXR5L2ltYS9pbWFf bWFpbi5jIGIvc2VjdXJpdHkvaW50ZWdyaXR5L2ltYS9pbWFfbWFpbi5jCj4gaW5kZXggMGI0ODQ1 ZTcyNDhkLi45M2ZhMjU3YzcxYTcgMTAwNjQ0Cj4gLS0tIGEvc2VjdXJpdHkvaW50ZWdyaXR5L2lt YS9pbWFfbWFpbi5jCj4gKysrIGIvc2VjdXJpdHkvaW50ZWdyaXR5L2ltYS9pbWFfbWFpbi5jCj4g QEAgLTI0NSw4ICsyNDUsOSBAQCBzdGF0aWMgaW50IHByb2Nlc3NfbWVhc3VyZW1lbnQoc3RydWN0 IGZpbGUgKmZpbGUsIGNoYXIgKmJ1ZiwgbG9mZl90IHNpemUsCj4gIAkJcGF0aG5hbWUgPSBpbWFf ZF9wYXRoKCZmaWxlLT5mX3BhdGgsICZwYXRoYnVmLCBmaWxlbmFtZSk7Cj4gCj4gIAlpZiAoYWN0 aW9uICYgSU1BX0FQUFJBSVNFX1NVQk1BU0spCj4gLQkJcmMgPSBpbWFfYXBwcmFpc2VfbWVhc3Vy ZW1lbnQoZnVuYywgaWludCwgZmlsZSwgcGF0aG5hbWUsCj4gLQkJCQkJICAgICAgeGF0dHJfdmFs dWUsIHhhdHRyX2xlbiwgb3BlbmVkKTsKPiArCQlyYyA9IGltYV9hcHByYWlzZV9tZWFzdXJlbWVu dChmdW5jLCBpaW50LCBmaWxlLCBidWYsIHNpemUsCj4gKwkJCQkJICAgICAgcGF0aG5hbWUsICZ4 YXR0cl92YWx1ZSwKPiArCQkJCQkgICAgICAmeGF0dHJfbGVuLCBvcGVuZWQpOwo+ICAJaWYgKGFj dGlvbiAmIElNQV9NRUFTVVJFKQo+ICAJCWltYV9zdG9yZV9tZWFzdXJlbWVudChpaW50LCBmaWxl LCBwYXRobmFtZSwKPiAgCQkJCSAgICAgIHhhdHRyX3ZhbHVlLCB4YXR0cl9sZW4sIHBjcik7Cj4g QEAgLTI1Nyw3ICsyNTgsNyBAQCBzdGF0aWMgaW50IHByb2Nlc3NfbWVhc3VyZW1lbnQoc3RydWN0 IGZpbGUgKmZpbGUsIGNoYXIgKmJ1ZiwgbG9mZl90IHNpemUsCj4gIAlpZiAoKG1hc2sgJiBNQVlf V1JJVEUpICYmIChpaW50LT5mbGFncyAmIElNQV9ESUdTSUcpICYmCj4gIAkgICAgICEoaWludC0+ ZmxhZ3MgJiBJTUFfTkVXX0ZJTEUpKQo+ICAJCXJjID0gLUVBQ0NFUzsKPiAtCWtmcmVlKHhhdHRy X3ZhbHVlKTsKPiArCWltYV9mcmVlX3hhdHRyX2RhdGEoeGF0dHJfdmFsdWUpOwo+ICBvdXRfZnJl ZToKPiAgCWlmIChwYXRoYnVmKQo+ICAJCV9fcHV0bmFtZShwYXRoYnVmKTsKPiBkaWZmIC0tZ2l0 IGEvc2VjdXJpdHkvaW50ZWdyaXR5L2ltYS9pbWFfbW9kc2lnLmMgYi9zZWN1cml0eS9pbnRlZ3Jp dHkvaW1hL2ltYV9tb2RzaWcuYwo+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAw MDAwMDAwLi43OTgzZWRmODQ1MTEKPiAtLS0gL2Rldi9udWxsCj4gKysrIGIvc2VjdXJpdHkvaW50 ZWdyaXR5L2ltYS9pbWFfbW9kc2lnLmMKPiBAQCAtMCwwICsxLDE3OCBAQAo+ICsvKgo+ICsgKiBJ TUEgc3VwcG9ydCBmb3IgYXBwcmFpc2luZyBtb2R1bGUtc3R5bGUgYXBwZW5kZWQgc2lnbmF0dXJl cy4KPiArICoKPiArICogQ29weXJpZ2h0IChDKSAyMDE3ICBJQk0gQ29ycG9yYXRpb24KPiArICoK PiArICogQXV0aG9yOgo+ICsgKiBUaGlhZ28gSnVuZyBCYXVlcm1hbm4gPGJhdWVybWFuQGxpbnV4 LnZuZXQuaWJtLmNvbT4KPiArICoKPiArICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7 IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKPiArICogaXQgdW5kZXIgdGhl IHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkK PiArICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiAodmVyc2lvbiAyIG9mIHRoZSBMaWNl bnNlKS4KPiArICoKPiArICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3Bl IHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCj4gKyAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsg d2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCj4gKyAqIE1FUkNIQU5UQUJJTElU WSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKPiArICogR05V IEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KPiArICovCj4gKwo+ICsj aW5jbHVkZSA8bGludXgvdHlwZXMuaD4KPiArI2luY2x1ZGUgPGxpbnV4L21vZHVsZV9zaWduYXR1 cmUuaD4KPiArI2luY2x1ZGUgPGtleXMvYXN5bW1ldHJpYy10eXBlLmg+Cj4gKyNpbmNsdWRlIDxj cnlwdG8vcGtjczcuaD4KPiArCj4gKyNpbmNsdWRlICJpbWEuaCIKPiArCj4gK3N0cnVjdCBtb2Rz aWdfaGRyIHsKPiArCXVpbnQ4X3QgdHlwZTsJCS8qIFNob3VsZCBiZSBJTUFfTU9EU0lHLiAqLwo+ ICsJY29uc3Qgdm9pZCAqZGF0YTsJLyogUG9pbnRlciB0byBkYXRhIGNvdmVyZWQgYnkgcGtjczdf bXNnLiAqLwo+ICsJc2l6ZV90IGRhdGFfbGVuOwo+ICsJc3RydWN0IHBrY3M3X21lc3NhZ2UgKnBr Y3M3X21zZzsKPiArCWludCByYXdfcGtjczdfbGVuOwo+ICsKPiArCS8qIFRoaXMgd2lsbCBiZSBp biB0aGUgbWVhc3VyZW1lbnQgbGlzdCBpZiByZXF1aXJlZCBieSB0aGUgdGVtcGxhdGUuICovCj4g KwlzdHJ1Y3QgZXZtX2ltYV94YXR0cl9kYXRhIHJhd19wa2NzNzsKPiArfTsKPiArCj4gKy8qKgo+ ICsgKiBpbWFfaG9va19zdXBwb3J0c19tb2RzaWcgLSBjYW4gdGhlIHBvbGljeSBhbGxvdyBtb2Rz aWcgZm9yIHRoaXMgaG9vaz8KPiArICoKPiArICogbW9kc2lnIGlzIG9ubHkgc3VwcG9ydGVkIGJ5 IGhvb2tzIHVzaW5nIGltYV9wb3N0X3JlYWRfZmlsZSwgYmVjYXVzZSBvbmx5IHRoZXkKPiArICog cHJlbG9hZCB0aGUgY29udGVudHMgb2YgdGhlIGZpbGUgaW4gYSBidWZmZXIuIEZJTEVfQ0hFQ0sg ZG9lcyB0aGF0IGluIHNvbWUKPiArICogY2FzZXMsIGJ1dCBub3Qgd2hlbiByZWFjaGVkIGZyb20g dmZzX29wZW4uIFBPTElDWV9DSEVDSyBjYW4gc3VwcG9ydCBpdCwgYnV0Cj4gKyAqIGl0J3Mgbm90 IHVzZWZ1bCBpbiBwcmFjdGljZSBiZWNhdXNlIGl0J3MgYSB0ZXh0IGZpbGUgc28gZGVueS4KPiAr ICovCj4gK2Jvb2wgaW1hX2hvb2tfc3VwcG9ydHNfbW9kc2lnKGVudW0gaW1hX2hvb2tzIGZ1bmMp Cj4gK3sKPiArCXN3aXRjaCAoZnVuYykgewo+ICsJY2FzZSBGSVJNV0FSRV9DSEVDSzoKPiArCWNh c2UgS0VYRUNfS0VSTkVMX0NIRUNLOgo+ICsJY2FzZSBLRVhFQ19JTklUUkFNRlNfQ0hFQ0s6Cj4g KwkJcmV0dXJuIHRydWU7Cj4gKwlkZWZhdWx0Ogo+ICsJCXJldHVybiBmYWxzZTsKPiArCX0KPiAr fQo+ICsKPiAraW50IGltYV9yZWFkX21vZHNpZyhlbnVtIGltYV9ob29rcyBmdW5jLCBjb25zdCB2 b2lkICpidWYsIGxvZmZfdCBidWZfbGVuLAo+ICsJCSAgICBzdHJ1Y3QgZXZtX2ltYV94YXR0cl9k YXRhICoqeGF0dHJfdmFsdWUsCj4gKwkJICAgIGludCAqeGF0dHJfbGVuKQo+ICt7Cj4gKwljb25z dCBzaXplX3QgbWFya2VyX2xlbiA9IHNpemVvZihNT0RVTEVfU0lHX1NUUklORykgLSAxOwo+ICsJ Y29uc3Qgc3RydWN0IG1vZHVsZV9zaWduYXR1cmUgKnNpZzsKPiArCXN0cnVjdCBtb2RzaWdfaGRy ICpoZHI7Cj4gKwlzaXplX3Qgc2lnX2xlbjsKPiArCWNvbnN0IHZvaWQgKnA7Cj4gKwlpbnQgcmM7 Cj4gKwo+ICsJLyoKPiArCSAqIE5vdCBzdXBwb3NlZCB0byBoYXBwZW4uIEhvb2tzIHRoYXQgc3Vw cG9ydCBtb2RzaWcgYXJlCj4gKwkgKiB3aGl0ZWxpc3RlZCB3aGVuIHBhcnNpbmcgdGhlIHBvbGlj eSB1c2luZwo+ICsJICogaW1hX2hvb2tzX3N1cHBvcnRzX21vZHNpZy4KPiArCSAqLwo+ICsJaWYg KCFidWYgfHwgIWJ1Zl9sZW4pIHsKPiArCQlXQVJOX09OQ0UodHJ1ZSwgIiVzIGRvZXNuJ3Qgc3Vw cG9ydCBtb2RzaWdcbiIsCj4gKwkJCSAgZnVuY190b2tlbnNbZnVuY10pOwo+ICsJCXJldHVybiAt RU5PRU5UOwo+ICsJfSBlbHNlIGlmIChidWZfbGVuIDw9IG1hcmtlcl9sZW4gKyBzaXplb2YoKnNp ZykpCj4gKwkJcmV0dXJuIC1FTk9FTlQ7Cj4gKwo+ICsJcCA9IGJ1ZiArIGJ1Zl9sZW4gLSBtYXJr ZXJfbGVuOwo+ICsJaWYgKG1lbWNtcChwLCBNT0RVTEVfU0lHX1NUUklORywgbWFya2VyX2xlbikp Cj4gKwkJcmV0dXJuIC1FTk9FTlQ7Cj4gKwo+ICsJYnVmX2xlbiAtPSBtYXJrZXJfbGVuOwo+ICsJ c2lnID0gKGNvbnN0IHN0cnVjdCBtb2R1bGVfc2lnbmF0dXJlICopIChwIC0gc2l6ZW9mKCpzaWcp KTsKPiArCj4gKwlyYyA9IHZhbGlkYXRlX21vZHVsZV9zaWcoc2lnLCBidWZfbGVuKTsKPiArCWlm IChyYykKPiArCQlyZXR1cm4gcmM7Cj4gKwo+ICsJc2lnX2xlbiA9IGJlMzJfdG9fY3B1KHNpZy0+ c2lnX2xlbik7Cj4gKwlidWZfbGVuIC09IHNpZ19sZW4gKyBzaXplb2YoKnNpZyk7Cj4gKwo+ICsJ aGRyID0ga21hbGxvYyhzaXplb2YoKmhkcikgKyBzaWdfbGVuLCBHRlBfS0VSTkVMKTsKPiArCWlm ICghaGRyKQo+ICsJCXJldHVybiAtRU5PTUVNOwo+ICsKPiArCWhkci0+cGtjczdfbXNnID0gcGtj czdfcGFyc2VfbWVzc2FnZShidWYgKyBidWZfbGVuLCBzaWdfbGVuKTsKPiArCWlmIChJU19FUlIo aGRyLT5wa2NzN19tc2cpKSB7Cj4gKwkJcmMgPSBQVFJfRVJSKGhkci0+cGtjczdfbXNnKTsKPiAr CQlrZnJlZShoZHIpOwo+ICsJCXJldHVybiByYzsKPiArCX0KPiArCj4gKwltZW1jcHkoaGRyLT5y YXdfcGtjczcuZGF0YSwgYnVmICsgYnVmX2xlbiwgc2lnX2xlbik7Cj4gKwloZHItPnJhd19wa2Nz N19sZW4gPSBzaWdfbGVuICsgMTsKPiArCWhkci0+cmF3X3BrY3M3LnR5cGUgPSBJTUFfTU9EU0lH Owo+ICsKPiArCWhkci0+dHlwZSA9IElNQV9NT0RTSUc7Cj4gKwloZHItPmRhdGEgPSBidWY7Cj4g KwloZHItPmRhdGFfbGVuID0gYnVmX2xlbjsKPiArCj4gKwkqeGF0dHJfdmFsdWUgPSAodHlwZW9m KCp4YXR0cl92YWx1ZSkpIGhkcjsKPiArCSp4YXR0cl9sZW4gPSBzaXplb2YoKmhkcik7Cj4gKwo+ ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK2ludCBpbWFfZ2V0X21vZHNpZ19oYXNoKHN0cnVjdCBl dm1faW1hX3hhdHRyX2RhdGEgKmhkciwgZW51bSBoYXNoX2FsZ28gKmFsZ28sCj4gKwkJCXZvaWQg Y29uc3QgKipoYXNoLCB1OCAqbGVuKQo+ICt7Cj4gKwljb25zdCBzdHJ1Y3QgcHVibGljX2tleV9z aWduYXR1cmUgKnBrczsKPiArCXN0cnVjdCBtb2RzaWdfaGRyICptb2RzaWcgPSAodHlwZW9mKG1v ZHNpZykpIGhkcjsKPiArCWludCBpOwo+ICsKPiArCXBrcyA9IHBrY3M3X2dldF9tZXNzYWdlX3Np Zyhtb2RzaWctPnBrY3M3X21zZyk7Cj4gKwlpZiAoIXBrcykKPiArCQlyZXR1cm4gLUVCQURNU0c7 Cj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IEhBU0hfQUxHT19fTEFTVDsgaSsrKQo+ICsJCWlmICgh c3RyY21wKGhhc2hfYWxnb19uYW1lW2ldLCBwa3MtPmhhc2hfYWxnbykpCj4gKwkJCWJyZWFrOwo+ ICsKPiArCSphbGdvID0gaTsKPiArCSpoYXNoID0gcGtzLT5kaWdlc3Q7Cj4gKwkqbGVuID0gcGtz LT5kaWdlc3Rfc2l6ZTsKPiArCj4gKwlyZXR1cm4gMDsKPiArfQo+ICsKPiAraW50IGltYV9tb2Rz aWdfc2VyaWFsaXplX2RhdGEoc3RydWN0IGV2bV9pbWFfeGF0dHJfZGF0YSAqaGRyLAo+ICsJCQkg ICAgICBzdHJ1Y3QgZXZtX2ltYV94YXR0cl9kYXRhICoqZGF0YSwgaW50ICpkYXRhX2xlbikKPiAr ewo+ICsJc3RydWN0IG1vZHNpZ19oZHIgKm1vZHNpZyA9IChzdHJ1Y3QgbW9kc2lnX2hkciAqKSBo ZHI7Cj4gKwo+ICsJKmRhdGEgPSAmbW9kc2lnLT5yYXdfcGtjczc7Cj4gKwkqZGF0YV9sZW4gPSBt b2RzaWctPnJhd19wa2NzN19sZW47Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK2ludCBp bWFfbW9kc2lnX3ZlcmlmeShjb25zdCB1bnNpZ25lZCBpbnQga2V5cmluZ19pZCwKPiArCQkgICAg ICBzdHJ1Y3QgZXZtX2ltYV94YXR0cl9kYXRhICpoZHIpCj4gK3sKPiArCXN0cnVjdCBtb2RzaWdf aGRyICptb2RzaWcgPSAoc3RydWN0IG1vZHNpZ19oZHIgKikgaGRyOwo+ICsJc3RydWN0IGtleSAq dHJ1c3RlZF9rZXlzID0gaW50ZWdyaXR5X2tleXJpbmdfZnJvbV9pZChrZXlyaW5nX2lkKTsKPiAr Cj4gKwlpZiAoSVNfRVJSKHRydXN0ZWRfa2V5cykpCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwo+ ICsJcmV0dXJuIHZlcmlmeV9wa2NzN19tZXNzYWdlX3NpZyhtb2RzaWctPmRhdGEsIG1vZHNpZy0+ ZGF0YV9sZW4sCj4gKwkJCQkJbW9kc2lnLT5wa2NzN19tc2csIHRydXN0ZWRfa2V5cywKPiArCQkJ CQlWRVJJRllJTkdfTU9EVUxFX1NJR05BVFVSRSwgTlVMTCwgTlVMTCk7Cj4gK30KPiArCj4gK3Zv aWQgaW1hX2ZyZWVfeGF0dHJfZGF0YShzdHJ1Y3QgZXZtX2ltYV94YXR0cl9kYXRhICpoZHIpCj4g K3sKPiArCWlmICghaGRyKQo+ICsJCXJldHVybjsKPiArCj4gKwlpZiAoaGRyLT50eXBlID0gSU1B X01PRFNJRykgewo+ICsJCXN0cnVjdCBtb2RzaWdfaGRyICptb2RzaWcgPSAoc3RydWN0IG1vZHNp Z19oZHIgKikgaGRyOwo+ICsKPiArCQlwa2NzN19mcmVlX21lc3NhZ2UobW9kc2lnLT5wa2NzN19t c2cpOwo+ICsJfQo+ICsKPiArCWtmcmVlKGhkcik7Cj4gK30KPiBkaWZmIC0tZ2l0IGEvc2VjdXJp dHkvaW50ZWdyaXR5L2ltYS9pbWFfcG9saWN5LmMgYi9zZWN1cml0eS9pbnRlZ3JpdHkvaW1hL2lt YV9wb2xpY3kuYwo+IGluZGV4IDk1MjA5YTVmODU5NS4uY2IwNTZkMjBlNmU1IDEwMDY0NAo+IC0t LSBhL3NlY3VyaXR5L2ludGVncml0eS9pbWEvaW1hX3BvbGljeS5jCj4gKysrIGIvc2VjdXJpdHkv aW50ZWdyaXR5L2ltYS9pbWFfcG9saWN5LmMKPiBAQCAtODUxLDggKzg1MSwxMiBAQCBzdGF0aWMg aW50IGltYV9wYXJzZV9ydWxlKGNoYXIgKnJ1bGUsIHN0cnVjdCBpbWFfcnVsZV9lbnRyeSAqZW50 cnkpCj4gIAkJCX0KPiAKPiAgCQkJaW1hX2xvZ19zdHJpbmcoYWIsICJhcHByYWlzZV90eXBlIiwg YXJnc1swXS5mcm9tKTsKPiAtCQkJaWYgKChzdHJjbXAoYXJnc1swXS5mcm9tLCAiaW1hc2lnIikp ID0gMCkKPiArCQkJaWYgKHN0cmNtcChhcmdzWzBdLmZyb20sICJpbWFzaWciKSA9IDApCj4gIAkJ CQllbnRyeS0+ZmxhZ3MgfD0gSU1BX0RJR1NJR19SRVFVSVJFRDsKPiArCQkJZWxzZSBpZiAoaW1h X2hvb2tfc3VwcG9ydHNfbW9kc2lnKGVudHJ5LT5mdW5jKSAmJgo+ICsJCQkJIHN0cmNtcChhcmdz WzBdLmZyb20sICJtb2RzaWd8aW1hc2lnIikgPSAwKQo+ICsJCQkJZW50cnktPmZsYWdzIHw9IElN QV9ESUdTSUdfUkVRVUlSRUQKPiArCQkJCQkJfCBJTUFfTU9EU0lHX0FMTE9XRUQ7Cj4gIAkJCWVs c2UKPiAgCQkJCXJlc3VsdCA9IC1FSU5WQUw7Cj4gIAkJCWJyZWFrOwo+IEBAIC05NTgsNiArOTYy LDEyIEBAIHZvaWQgaW1hX2RlbGV0ZV9ydWxlcyh2b2lkKQo+ICAJfQo+ICB9Cj4gCj4gKyNkZWZp bmUgX19pbWFfaG9va19zdHJpbmdpZnkoc3RyKQkoI3N0ciksCj4gKwo+ICtjb25zdCBjaGFyICpj b25zdCBmdW5jX3Rva2Vuc1tdID0gewo+ICsJX19pbWFfaG9va3MoX19pbWFfaG9va19zdHJpbmdp ZnkpCj4gK307Cj4gKwo+ICAjaWZkZWYJQ09ORklHX0lNQV9SRUFEX1BPTElDWQo+ICBlbnVtIHsK PiAgCW1hc2tfZXhlYyA9IDAsIG1hc2tfd3JpdGUsIG1hc2tfcmVhZCwgbWFza19hcHBlbmQKPiBA QCAtOTcwLDEyICs5ODAsNiBAQCBzdGF0aWMgY29uc3QgY2hhciAqY29uc3QgbWFza190b2tlbnNb XSA9IHsKPiAgCSJNQVlfQVBQRU5EIgo+ICB9Owo+IAo+IC0jZGVmaW5lIF9faW1hX2hvb2tfc3Ry aW5naWZ5KHN0cikJKCNzdHIpLAo+IC0KPiAtc3RhdGljIGNvbnN0IGNoYXIgKmNvbnN0IGZ1bmNf dG9rZW5zW10gPSB7Cj4gLQlfX2ltYV9ob29rcyhfX2ltYV9ob29rX3N0cmluZ2lmeSkKPiAtfTsK PiAtCj4gIHZvaWQgKmltYV9wb2xpY3lfc3RhcnQoc3RydWN0IHNlcV9maWxlICptLCBsb2ZmX3Qg KnBvcykKPiAgewo+ICAJbG9mZl90IGwgPSAqcG9zOwo+IEBAIC0xMTM4LDggKzExNDIsMTIgQEAg aW50IGltYV9wb2xpY3lfc2hvdyhzdHJ1Y3Qgc2VxX2ZpbGUgKm0sIHZvaWQgKnYpCj4gIAkJCX0K PiAgCQl9Cj4gIAl9Cj4gLQlpZiAoZW50cnktPmZsYWdzICYgSU1BX0RJR1NJR19SRVFVSVJFRCkK PiAtCQlzZXFfcHV0cyhtLCAiYXBwcmFpc2VfdHlwZT1pbWFzaWcgIik7Cj4gKwlpZiAoZW50cnkt PmZsYWdzICYgSU1BX0RJR1NJR19SRVFVSVJFRCkgewo+ICsJCWlmIChlbnRyeS0+ZmxhZ3MgJiBJ TUFfTU9EU0lHX0FMTE9XRUQpCj4gKwkJCXNlcV9wdXRzKG0sICJhcHByYWlzZV90eXBlPW1vZHNp Z3xpbWFzaWcgIik7Cj4gKwkJZWxzZQo+ICsJCQlzZXFfcHV0cyhtLCAiYXBwcmFpc2VfdHlwZT1p bWFzaWcgIik7Cj4gKwl9Cj4gIAlpZiAoZW50cnktPmZsYWdzICYgSU1BX1BFUk1JVF9ESVJFQ1RJ TykKPiAgCQlzZXFfcHV0cyhtLCAicGVybWl0X2RpcmVjdGlvICIpOwo+ICAJcmN1X3JlYWRfdW5s b2NrKCk7Cj4gZGlmZiAtLWdpdCBhL3NlY3VyaXR5L2ludGVncml0eS9pbWEvaW1hX3RlbXBsYXRl X2xpYi5jIGIvc2VjdXJpdHkvaW50ZWdyaXR5L2ltYS9pbWFfdGVtcGxhdGVfbGliLmMKPiBpbmRl eCAyOGFmNDNmNjM1NzIuLjhjN2ZhNTI2MDRhNSAxMDA2NDQKPiAtLS0gYS9zZWN1cml0eS9pbnRl Z3JpdHkvaW1hL2ltYV90ZW1wbGF0ZV9saWIuYwo+ICsrKyBiL3NlY3VyaXR5L2ludGVncml0eS9p bWEvaW1hX3RlbXBsYXRlX2xpYi5jCj4gQEAgLTM4Myw5ICszODMsMjEgQEAgaW50IGltYV9ldmVu dHNpZ19pbml0KHN0cnVjdCBpbWFfZXZlbnRfZGF0YSAqZXZlbnRfZGF0YSwKPiAgCWludCB4YXR0 cl9sZW4gPSBldmVudF9kYXRhLT54YXR0cl9sZW47Cj4gIAlpbnQgcmMgPSAwOwo+IAo+IC0JaWYg KCgheGF0dHJfdmFsdWUpIHx8ICh4YXR0cl92YWx1ZS0+dHlwZSAhPSBFVk1fSU1BX1hBVFRSX0RJ R1NJRykpCj4gKwlpZiAoIXhhdHRyX3ZhbHVlIHx8ICh4YXR0cl92YWx1ZS0+dHlwZSAhPSBFVk1f SU1BX1hBVFRSX0RJR1NJRyAmJgo+ICsJCQkgICAgIHhhdHRyX3ZhbHVlLT50eXBlICE9IElNQV9N T0RTSUcpKQo+ICAJCWdvdG8gb3V0Owo+IAo+ICsJLyoKPiArCSAqIFRoZSB4YXR0cl92YWx1ZSBm b3IgSU1BX01PRFNJRyBpcyBhIHJ1bnRpbWUgc3RydWN0dXJlIGNvbnRhaW5pbmcKPiArCSAqIHBv aW50ZXJzLiBHZXQgaXRzIHJhdyBkYXRhIGluc3RlYWQuCj4gKwkgKi8KPiArCWlmICh4YXR0cl92 YWx1ZS0+dHlwZSA9IElNQV9NT0RTSUcpIHsKPiArCQlyYyA9IGltYV9tb2RzaWdfc2VyaWFsaXpl X2RhdGEoeGF0dHJfdmFsdWUsICZ4YXR0cl92YWx1ZSwKPiArCQkJCQkgICAgICAgJnhhdHRyX2xl bik7Cj4gKwkJaWYgKHJjKQo+ICsJCQlnb3RvIG91dDsKPiArCX0KPiArCj4gIAlyYyA9IGltYV93 cml0ZV90ZW1wbGF0ZV9maWVsZF9kYXRhKHhhdHRyX3ZhbHVlLCB4YXR0cl9sZW4sIGZtdCwKPiAg CQkJCQkgICBmaWVsZF9kYXRhKTsKPiAgb3V0Ogo+IGRpZmYgLS1naXQgYS9zZWN1cml0eS9pbnRl Z3JpdHkvaW50ZWdyaXR5LmggYi9zZWN1cml0eS9pbnRlZ3JpdHkvaW50ZWdyaXR5LmgKPiBpbmRl eCAxZjhmMWEzMWQ0ODcuLjBiOGI5ZWZhMGQyZSAxMDA2NDQKPiAtLS0gYS9zZWN1cml0eS9pbnRl Z3JpdHkvaW50ZWdyaXR5LmgKPiArKysgYi9zZWN1cml0eS9pbnRlZ3JpdHkvaW50ZWdyaXR5LmgK PiBAQCAtMjgsMTEgKzI4LDEyIEBACj4gCj4gIC8qIGlpbnQgY2FjaGUgZmxhZ3MgKi8KPiAgI2Rl ZmluZSBJTUFfQUNUSU9OX0ZMQUdTCTB4ZmYwMDAwMDAKPiAtI2RlZmluZSBJTUFfQUNUSU9OX1JV TEVfRkxBR1MJMHgwNjAwMDAwMAo+ICsjZGVmaW5lIElNQV9BQ1RJT05fUlVMRV9GTEFHUwkweDE2 MDAwMDAwCj4gICNkZWZpbmUgSU1BX0RJR1NJRwkJMHgwMTAwMDAwMAo+ICAjZGVmaW5lIElNQV9E SUdTSUdfUkVRVUlSRUQJMHgwMjAwMDAwMAo+ICAjZGVmaW5lIElNQV9QRVJNSVRfRElSRUNUSU8J MHgwNDAwMDAwMAo+ICAjZGVmaW5lIElNQV9ORVdfRklMRQkJMHgwODAwMDAwMAo+ICsjZGVmaW5l IElNQV9NT0RTSUdfQUxMT1dFRAkweDEwMDAwMDAwCj4gCj4gICNkZWZpbmUgSU1BX0RPX01BU0sJ CShJTUFfTUVBU1VSRSB8IElNQV9BUFBSQUlTRSB8IElNQV9BVURJVCB8IFwKPiAgCQkJCSBJTUFf QVBQUkFJU0VfU1VCTUFTSykKPiBAQCAtNTgsNiArNTksNyBAQCBlbnVtIGV2bV9pbWFfeGF0dHJf dHlwZSB7Cj4gIAlFVk1fWEFUVFJfSE1BQywKPiAgCUVWTV9JTUFfWEFUVFJfRElHU0lHLAo+ICAJ SU1BX1hBVFRSX0RJR0VTVF9ORywKPiArCUlNQV9NT0RTSUcsCj4gIAlJTUFfWEFUVFJfTEFTVAo+ ICB9Owo+IAoKLS0KVG8gdW5zdWJzY3JpYmUgZnJvbSB0aGlzIGxpc3Q6IHNlbmQgdGhlIGxpbmUg InVuc3Vic2NyaWJlIGtleXJpbmdzIiBpbgp0aGUgYm9keSBvZiBhIG1lc3NhZ2UgdG8gbWFqb3Jk b21vQHZnZXIua2VybmVsLm9yZwpNb3JlIG1ham9yZG9tbyBpbmZvIGF0ICBodHRwOi8vdmdlci5r ZXJuZWwub3JnL21ham9yZG9tby1pbmZvLmh0bWw= From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mimi Zohar Subject: Re: [PATCH v4 7/7] ima: Support module-style appended signatures for appraisal Date: Thu, 17 Aug 2017 11:04:35 -0400 Message-ID: <1502982275.3172.17.camel@linux.vnet.ibm.com> References: <20170804220330.30026-1-bauerman@linux.vnet.ibm.com> <20170804220330.30026-8-bauerman@linux.vnet.ibm.com> Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit Cc: linux-ima-devel@lists.sourceforge.net, keyrings@vger.kernel.org, linux-crypto@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, Dmitry Kasatkin , James Morris , "Serge E. Hallyn" , David Howells , David Woodhouse , Jessica Yu , Rusty Russell , Herbert Xu , "David S. Miller" , "AKASHI, Takahiro" To: Thiago Jung Bauermann , linux-security-module@vger.kernel.org Return-path: In-Reply-To: <20170804220330.30026-8-bauerman@linux.vnet.ibm.com> Sender: owner-linux-security-module@vger.kernel.org List-Id: linux-crypto.vger.kernel.org On Fri, 2017-08-04 at 19:03 -0300, Thiago Jung Bauermann wrote: > This patch introduces the modsig keyword to the IMA policy syntax to > specify that a given hook should expect the file to have the IMA signature > appended to it. Here is how it can be used in a rule: > > appraise func=KEXEC_KERNEL_CHECK appraise_type=modsig|imasig > > With this rule, IMA will accept either an appended signature or a signature > stored in the extended attribute. In that case, it will first check whether > there is an appended signature, and if not it will read it from the > extended attribute. > > The format of the appended signature is the same used for signed kernel > modules. This means that the file can be signed with the scripts/sign-file > tool, with a command line such as this: > > $ sign-file sha256 privkey_ima.pem x509_ima.der vmlinux > > This code only works for files that are hashed from a memory buffer, not > for files that are read from disk at the time of hash calculation. In other > words, only hooks that use kernel_read_file can support appended > signatures. This means that only FIRMWARE_CHECK, KEXEC_KERNEL_CHECK, > KEXEC_INITRAMFS_CHECK and POLICY_CHECK can be supported. > > This feature warrants a separate config option because enabling it brings > in many other config options. > > Signed-off-by: Thiago Jung Bauermann Other than the appended signature not being properly included in the measurement list, the patch seems to be working.  This patch is on the rather large size. Could you go back and break this patch up into smaller, more concise patches, with clear patch descriptions (eg. separate code cleanup from changes, new policy option, code for appraising an attached signature, storing the appended signature in the measurement list, etc)? thanks! Mimi > --- > security/integrity/ima/Kconfig | 13 +++ > security/integrity/ima/Makefile | 1 + > security/integrity/ima/ima.h | 70 +++++++++++- > security/integrity/ima/ima_appraise.c | 178 +++++++++++++++++++++++++----- > security/integrity/ima/ima_main.c | 7 +- > security/integrity/ima/ima_modsig.c | 178 ++++++++++++++++++++++++++++++ > security/integrity/ima/ima_policy.c | 26 +++-- > security/integrity/ima/ima_template_lib.c | 14 ++- > security/integrity/integrity.h | 4 +- > 9 files changed, 443 insertions(+), 48 deletions(-) > > diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig > index 35ef69312811..55f734a6124b 100644 > --- a/security/integrity/ima/Kconfig > +++ b/security/integrity/ima/Kconfig > @@ -163,6 +163,19 @@ config IMA_APPRAISE_BOOTPARAM > This option enables the different "ima_appraise=" modes > (eg. fix, log) from the boot command line. > > +config IMA_APPRAISE_MODSIG > + bool "Support module-style signatures for appraisal" > + depends on IMA_APPRAISE > + depends on INTEGRITY_ASYMMETRIC_KEYS > + select PKCS7_MESSAGE_PARSER > + select MODULE_SIG_FORMAT > + default n > + help > + Adds support for signatures appended to files. The format of the > + appended signature is the same used for signed kernel modules. > + The modsig keyword can be used in the IMA policy to allow a hook > + to accept such signatures. > + > config IMA_TRUSTED_KEYRING > bool "Require all keys on the .ima keyring be signed (deprecated)" > depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING > diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile > index 29f198bde02b..c72026acecc3 100644 > --- a/security/integrity/ima/Makefile > +++ b/security/integrity/ima/Makefile > @@ -8,5 +8,6 @@ obj-$(CONFIG_IMA) += ima.o > ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ > ima_policy.o ima_template.o ima_template_lib.o > ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o > +ima-$(CONFIG_IMA_APPRAISE_MODSIG) += ima_modsig.o > ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o > obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o > diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h > index d52b487ad259..5492af2cd7c7 100644 > --- a/security/integrity/ima/ima.h > +++ b/security/integrity/ima/ima.h > @@ -190,6 +190,8 @@ enum ima_hooks { > __ima_hooks(__ima_hook_enumify) > }; > > +extern const char *const func_tokens[]; > + > /* LIM API function definitions */ > int ima_get_action(struct inode *inode, int mask, > enum ima_hooks func, int *pcr); > @@ -236,9 +238,10 @@ int ima_policy_show(struct seq_file *m, void *v); > #ifdef CONFIG_IMA_APPRAISE > int ima_appraise_measurement(enum ima_hooks func, > struct integrity_iint_cache *iint, > - struct file *file, const unsigned char *filename, > - struct evm_ima_xattr_data *xattr_value, > - int xattr_len, int opened); > + struct file *file, const void *buf, loff_t size, > + const unsigned char *filename, > + struct evm_ima_xattr_data **xattr_value, > + int *xattr_len, int opened); > int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); > void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); > enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, > @@ -248,13 +251,28 @@ enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, > int ima_read_xattr(struct dentry *dentry, > struct evm_ima_xattr_data **xattr_value); > > +#ifdef CONFIG_IMA_APPRAISE_MODSIG > +bool ima_hook_supports_modsig(enum ima_hooks func); > +int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len, > + struct evm_ima_xattr_data **xattr_value, > + int *xattr_len); > +int ima_get_modsig_hash(struct evm_ima_xattr_data *hdr, enum hash_algo *algo, > + void const **hash, u8 *len); > +int ima_modsig_serialize_data(struct evm_ima_xattr_data *hdr, > + struct evm_ima_xattr_data **data, int *data_len); > +int ima_modsig_verify(const unsigned int keyring_id, > + struct evm_ima_xattr_data *hdr); > +void ima_free_xattr_data(struct evm_ima_xattr_data *hdr); > +#endif > + > #else > static inline int ima_appraise_measurement(enum ima_hooks func, > struct integrity_iint_cache *iint, > - struct file *file, > + struct file *file, const void *buf, > + loff_t size, > const unsigned char *filename, > - struct evm_ima_xattr_data *xattr_value, > - int xattr_len, int opened) > + struct evm_ima_xattr_data **xattr_value, > + int *xattr_len, int opened) > { > return INTEGRITY_UNKNOWN; > } > @@ -291,6 +309,46 @@ static inline int ima_read_xattr(struct dentry *dentry, > > #endif /* CONFIG_IMA_APPRAISE */ > > +#ifndef CONFIG_IMA_APPRAISE_MODSIG > +static inline bool ima_hook_supports_modsig(enum ima_hooks func) > +{ > + return false; > +} > + > +static inline int ima_read_modsig(enum ima_hooks func, const void *buf, > + loff_t buf_len, > + struct evm_ima_xattr_data **xattr_value, > + int *xattr_len) > +{ > + return -ENOTSUPP; > +} > + > +static inline int ima_get_modsig_hash(struct evm_ima_xattr_data *hdr, > + enum hash_algo *algo, void const **hash, > + u8 *len) > +{ > + return -ENOTSUPP; > +} > + > +static inline int ima_modsig_serialize_data(struct evm_ima_xattr_data *hdr, > + struct evm_ima_xattr_data **data, > + int *data_len) > +{ > + return -ENOTSUPP; > +} > + > +static inline int ima_modsig_verify(const unsigned int keyring_id, > + struct evm_ima_xattr_data *hdr) > +{ > + return -ENOTSUPP; > +} > + > +static inline void ima_free_xattr_data(struct evm_ima_xattr_data *hdr) > +{ > + kfree(hdr); > +} > +#endif > + > /* LSM based policy rules require audit */ > #ifdef CONFIG_IMA_LSM_RULES > > diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c > index 87d2b601cf8e..5a244ebc61d9 100644 > --- a/security/integrity/ima/ima_appraise.c > +++ b/security/integrity/ima/ima_appraise.c > @@ -190,6 +190,64 @@ int ima_read_xattr(struct dentry *dentry, > return ret; > } > > +static void process_xattr_error(int rc, struct integrity_iint_cache *iint, > + int opened, char const **cause, > + enum integrity_status *status) > +{ > + if (rc && rc != -ENODATA) > + return; > + > + *cause = iint->flags & IMA_DIGSIG_REQUIRED ? > + "IMA-signature-required" : "missing-hash"; > + *status = INTEGRITY_NOLABEL; > + > + if (opened & FILE_CREATED) > + iint->flags |= IMA_NEW_FILE; > + > + if ((iint->flags & IMA_NEW_FILE) && > + !(iint->flags & IMA_DIGSIG_REQUIRED)) > + *status = INTEGRITY_PASS; > +} > + > +static int appraise_modsig(struct integrity_iint_cache *iint, > + struct evm_ima_xattr_data *xattr_value, > + int xattr_len) > +{ > + enum hash_algo algo; > + const void *digest; > + void *buf; > + int rc, len; > + u8 dig_len; > + > + rc = ima_modsig_verify(INTEGRITY_KEYRING_IMA, xattr_value); > + if (rc) > + return rc; > + > + /* > + * The signature is good. Now let's put the sig hash > + * into the iint cache so that it gets stored in the > + * measurement list. > + */ > + > + rc = ima_get_modsig_hash(xattr_value, &algo, &digest, &dig_len); > + if (rc) > + return rc; > + > + len = sizeof(iint->ima_hash) + dig_len; > + buf = krealloc(iint->ima_hash, len, GFP_NOFS); > + if (!buf) > + return -ENOMEM; > + > + iint->ima_hash = buf; > + iint->flags |= IMA_DIGSIG; > + iint->ima_hash->algo = algo; > + iint->ima_hash->length = dig_len; > + > + memcpy(iint->ima_hash->digest, digest, dig_len); > + > + return 0; > +} > + > /* > * ima_appraise_measurement - appraise file measurement > * > @@ -200,44 +258,55 @@ int ima_read_xattr(struct dentry *dentry, > */ > int ima_appraise_measurement(enum ima_hooks func, > struct integrity_iint_cache *iint, > - struct file *file, const unsigned char *filename, > - struct evm_ima_xattr_data *xattr_value, > - int xattr_len, int opened) > + struct file *file, const void *buf, loff_t size, > + const unsigned char *filename, > + struct evm_ima_xattr_data **xattr_value_, > + int *xattr_len_, int opened) > { > static const char op[] = "appraise_data"; > - char *cause = "unknown"; > + const char *cause = "unknown"; > struct dentry *dentry = file_dentry(file); > struct inode *inode = d_backing_inode(dentry); > enum integrity_status status = INTEGRITY_UNKNOWN; > - int rc = xattr_len, hash_start = 0; > + struct evm_ima_xattr_data *xattr_value = *xattr_value_; > + int xattr_len = *xattr_len_, rc = xattr_len, hash_start = 0; > + bool appraising_modsig = false; > + > + if (iint->flags & IMA_MODSIG_ALLOWED && > + !ima_read_modsig(func, buf, size, &xattr_value, &xattr_len)) { > + appraising_modsig = true; > + rc = xattr_len; > + } > > - if (!(inode->i_opflags & IOP_XATTR)) > + /* If not appraising a modsig, we need an xattr. */ > + if (!appraising_modsig && !(inode->i_opflags & IOP_XATTR)) > return INTEGRITY_UNKNOWN; > > if (rc <= 0) { > - if (rc && rc != -ENODATA) > - goto out; > - > - cause = iint->flags & IMA_DIGSIG_REQUIRED ? > - "IMA-signature-required" : "missing-hash"; > - status = INTEGRITY_NOLABEL; > - if (opened & FILE_CREATED) > - iint->flags |= IMA_NEW_FILE; > - if ((iint->flags & IMA_NEW_FILE) && > - !(iint->flags & IMA_DIGSIG_REQUIRED)) > - status = INTEGRITY_PASS; > + process_xattr_error(rc, iint, opened, &cause, &status); > goto out; > } > > - status = evm_verifyxattr(dentry, XATTR_NAME_IMA, xattr_value, rc, iint); > - if ((status != INTEGRITY_PASS) && (status != INTEGRITY_UNKNOWN)) { > - if ((status == INTEGRITY_NOLABEL) > - || (status == INTEGRITY_NOXATTRS)) > - cause = "missing-HMAC"; > - else if (status == INTEGRITY_FAIL) > - cause = "invalid-HMAC"; > + status = evm_verifyxattr(dentry, XATTR_NAME_IMA, NULL, 0, iint); > + switch (status) { > + case INTEGRITY_PASS: > + case INTEGRITY_UNKNOWN: > + break; > + case INTEGRITY_NOXATTRS: > + /* No EVM protected xattrs. */ > + if (appraising_modsig) > + break; > + case INTEGRITY_NOLABEL: > + /* No security.evm xattr. */ > + cause = "missing-HMAC"; > + goto out; > + case INTEGRITY_FAIL: > + /* Invalid HMAC/signature. */ > + cause = "invalid-HMAC"; > goto out; > } > + > + retry: > switch (xattr_value->type) { > case IMA_XATTR_DIGEST_NG: > /* first byte contains algorithm id */ > @@ -281,6 +350,54 @@ int ima_appraise_measurement(enum ima_hooks func, > status = INTEGRITY_PASS; > } > break; > + case IMA_MODSIG: > + /* > + * To avoid being tricked into an infinite loop, we don't allow > + * a modsig stored in the xattr. > + */ > + if (!appraising_modsig) { > + status = INTEGRITY_UNKNOWN; > + cause = "unknown-ima-data"; > + break; > + } > + > + rc = appraise_modsig(iint, xattr_value, xattr_len); > + if (!rc) { > + kfree(*xattr_value_); > + *xattr_value_ = xattr_value; > + *xattr_len_ = xattr_len; > + > + status = INTEGRITY_PASS; > + break; > + } > + > + ima_free_xattr_data(xattr_value); > + > + /* > + * The appended signature failed verification. Let's see if > + * there's an extended attribute to fall back to. > + */ > + if (inode->i_opflags & IOP_XATTR && *xattr_len_ != 0) { > + xattr_value = *xattr_value_; > + xattr_len = rc = *xattr_len_; > + appraising_modsig = false; > + > + if (rc <= 0) { > + process_xattr_error(rc, iint, opened, &cause, > + &status); > + goto out; > + } > + > + goto retry; > + } > + > + if (rc == -EOPNOTSUPP) > + status = INTEGRITY_UNKNOWN; > + else if (rc) { > + cause = "invalid-signature"; > + status = INTEGRITY_FAIL; > + } > + break; > default: > status = INTEGRITY_UNKNOWN; > cause = "unknown-ima-data"; > @@ -291,13 +408,15 @@ int ima_appraise_measurement(enum ima_hooks func, > if (status != INTEGRITY_PASS) { > if ((ima_appraise & IMA_APPRAISE_FIX) && > (!xattr_value || > - xattr_value->type != EVM_IMA_XATTR_DIGSIG)) { > + (xattr_value->type != EVM_IMA_XATTR_DIGSIG && > + xattr_value->type != IMA_MODSIG))) { > if (!ima_fix_xattr(dentry, iint)) > status = INTEGRITY_PASS; > } else if ((inode->i_size == 0) && > (iint->flags & IMA_NEW_FILE) && > (xattr_value && > - xattr_value->type == EVM_IMA_XATTR_DIGSIG)) { > + (xattr_value->type == EVM_IMA_XATTR_DIGSIG || > + xattr_value->type == IMA_MODSIG))) { > status = INTEGRITY_PASS; > } > integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename, > @@ -398,6 +517,7 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name, > const void *xattr_value, size_t xattr_value_len) > { > const struct evm_ima_xattr_data *xvalue = xattr_value; > + bool digsig; > int result; > > result = ima_protect_xattr(dentry, xattr_name, xattr_value, > @@ -405,8 +525,10 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name, > if (result == 1) { > if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST)) > return -EINVAL; > - ima_reset_appraise_flags(d_backing_inode(dentry), > - (xvalue->type == EVM_IMA_XATTR_DIGSIG) ? 1 : 0); > + > + digsig = xvalue->type == EVM_IMA_XATTR_DIGSIG || > + xvalue->type == IMA_MODSIG; > + ima_reset_appraise_flags(d_backing_inode(dentry), digsig); > result = 0; > } > return result; > diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c > index 0b4845e7248d..93fa257c71a7 100644 > --- a/security/integrity/ima/ima_main.c > +++ b/security/integrity/ima/ima_main.c > @@ -245,8 +245,9 @@ static int process_measurement(struct file *file, char *buf, loff_t size, > pathname = ima_d_path(&file->f_path, &pathbuf, filename); > > if (action & IMA_APPRAISE_SUBMASK) > - rc = ima_appraise_measurement(func, iint, file, pathname, > - xattr_value, xattr_len, opened); > + rc = ima_appraise_measurement(func, iint, file, buf, size, > + pathname, &xattr_value, > + &xattr_len, opened); > if (action & IMA_MEASURE) > ima_store_measurement(iint, file, pathname, > xattr_value, xattr_len, pcr); > @@ -257,7 +258,7 @@ static int process_measurement(struct file *file, char *buf, loff_t size, > if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG) && > !(iint->flags & IMA_NEW_FILE)) > rc = -EACCES; > - kfree(xattr_value); > + ima_free_xattr_data(xattr_value); > out_free: > if (pathbuf) > __putname(pathbuf); > diff --git a/security/integrity/ima/ima_modsig.c b/security/integrity/ima/ima_modsig.c > new file mode 100644 > index 000000000000..7983edf84511 > --- /dev/null > +++ b/security/integrity/ima/ima_modsig.c > @@ -0,0 +1,178 @@ > +/* > + * IMA support for appraising module-style appended signatures. > + * > + * Copyright (C) 2017 IBM Corporation > + * > + * Author: > + * Thiago Jung Bauermann > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation (version 2 of the License). > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include > +#include > +#include > +#include > + > +#include "ima.h" > + > +struct modsig_hdr { > + uint8_t type; /* Should be IMA_MODSIG. */ > + const void *data; /* Pointer to data covered by pkcs7_msg. */ > + size_t data_len; > + struct pkcs7_message *pkcs7_msg; > + int raw_pkcs7_len; > + > + /* This will be in the measurement list if required by the template. */ > + struct evm_ima_xattr_data raw_pkcs7; > +}; > + > +/** > + * ima_hook_supports_modsig - can the policy allow modsig for this hook? > + * > + * modsig is only supported by hooks using ima_post_read_file, because only they > + * preload the contents of the file in a buffer. FILE_CHECK does that in some > + * cases, but not when reached from vfs_open. POLICY_CHECK can support it, but > + * it's not useful in practice because it's a text file so deny. > + */ > +bool ima_hook_supports_modsig(enum ima_hooks func) > +{ > + switch (func) { > + case FIRMWARE_CHECK: > + case KEXEC_KERNEL_CHECK: > + case KEXEC_INITRAMFS_CHECK: > + return true; > + default: > + return false; > + } > +} > + > +int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len, > + struct evm_ima_xattr_data **xattr_value, > + int *xattr_len) > +{ > + const size_t marker_len = sizeof(MODULE_SIG_STRING) - 1; > + const struct module_signature *sig; > + struct modsig_hdr *hdr; > + size_t sig_len; > + const void *p; > + int rc; > + > + /* > + * Not supposed to happen. Hooks that support modsig are > + * whitelisted when parsing the policy using > + * ima_hooks_supports_modsig. > + */ > + if (!buf || !buf_len) { > + WARN_ONCE(true, "%s doesn't support modsig\n", > + func_tokens[func]); > + return -ENOENT; > + } else if (buf_len <= marker_len + sizeof(*sig)) > + return -ENOENT; > + > + p = buf + buf_len - marker_len; > + if (memcmp(p, MODULE_SIG_STRING, marker_len)) > + return -ENOENT; > + > + buf_len -= marker_len; > + sig = (const struct module_signature *) (p - sizeof(*sig)); > + > + rc = validate_module_sig(sig, buf_len); > + if (rc) > + return rc; > + > + sig_len = be32_to_cpu(sig->sig_len); > + buf_len -= sig_len + sizeof(*sig); > + > + hdr = kmalloc(sizeof(*hdr) + sig_len, GFP_KERNEL); > + if (!hdr) > + return -ENOMEM; > + > + hdr->pkcs7_msg = pkcs7_parse_message(buf + buf_len, sig_len); > + if (IS_ERR(hdr->pkcs7_msg)) { > + rc = PTR_ERR(hdr->pkcs7_msg); > + kfree(hdr); > + return rc; > + } > + > + memcpy(hdr->raw_pkcs7.data, buf + buf_len, sig_len); > + hdr->raw_pkcs7_len = sig_len + 1; > + hdr->raw_pkcs7.type = IMA_MODSIG; > + > + hdr->type = IMA_MODSIG; > + hdr->data = buf; > + hdr->data_len = buf_len; > + > + *xattr_value = (typeof(*xattr_value)) hdr; > + *xattr_len = sizeof(*hdr); > + > + return 0; > +} > + > +int ima_get_modsig_hash(struct evm_ima_xattr_data *hdr, enum hash_algo *algo, > + void const **hash, u8 *len) > +{ > + const struct public_key_signature *pks; > + struct modsig_hdr *modsig = (typeof(modsig)) hdr; > + int i; > + > + pks = pkcs7_get_message_sig(modsig->pkcs7_msg); > + if (!pks) > + return -EBADMSG; > + > + for (i = 0; i < HASH_ALGO__LAST; i++) > + if (!strcmp(hash_algo_name[i], pks->hash_algo)) > + break; > + > + *algo = i; > + *hash = pks->digest; > + *len = pks->digest_size; > + > + return 0; > +} > + > +int ima_modsig_serialize_data(struct evm_ima_xattr_data *hdr, > + struct evm_ima_xattr_data **data, int *data_len) > +{ > + struct modsig_hdr *modsig = (struct modsig_hdr *) hdr; > + > + *data = &modsig->raw_pkcs7; > + *data_len = modsig->raw_pkcs7_len; > + > + return 0; > +} > + > +int ima_modsig_verify(const unsigned int keyring_id, > + struct evm_ima_xattr_data *hdr) > +{ > + struct modsig_hdr *modsig = (struct modsig_hdr *) hdr; > + struct key *trusted_keys = integrity_keyring_from_id(keyring_id); > + > + if (IS_ERR(trusted_keys)) > + return -EINVAL; > + > + return verify_pkcs7_message_sig(modsig->data, modsig->data_len, > + modsig->pkcs7_msg, trusted_keys, > + VERIFYING_MODULE_SIGNATURE, NULL, NULL); > +} > + > +void ima_free_xattr_data(struct evm_ima_xattr_data *hdr) > +{ > + if (!hdr) > + return; > + > + if (hdr->type == IMA_MODSIG) { > + struct modsig_hdr *modsig = (struct modsig_hdr *) hdr; > + > + pkcs7_free_message(modsig->pkcs7_msg); > + } > + > + kfree(hdr); > +} > diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c > index 95209a5f8595..cb056d20e6e5 100644 > --- a/security/integrity/ima/ima_policy.c > +++ b/security/integrity/ima/ima_policy.c > @@ -851,8 +851,12 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) > } > > ima_log_string(ab, "appraise_type", args[0].from); > - if ((strcmp(args[0].from, "imasig")) == 0) > + if (strcmp(args[0].from, "imasig") == 0) > entry->flags |= IMA_DIGSIG_REQUIRED; > + else if (ima_hook_supports_modsig(entry->func) && > + strcmp(args[0].from, "modsig|imasig") == 0) > + entry->flags |= IMA_DIGSIG_REQUIRED > + | IMA_MODSIG_ALLOWED; > else > result = -EINVAL; > break; > @@ -958,6 +962,12 @@ void ima_delete_rules(void) > } > } > > +#define __ima_hook_stringify(str) (#str), > + > +const char *const func_tokens[] = { > + __ima_hooks(__ima_hook_stringify) > +}; > + > #ifdef CONFIG_IMA_READ_POLICY > enum { > mask_exec = 0, mask_write, mask_read, mask_append > @@ -970,12 +980,6 @@ static const char *const mask_tokens[] = { > "MAY_APPEND" > }; > > -#define __ima_hook_stringify(str) (#str), > - > -static const char *const func_tokens[] = { > - __ima_hooks(__ima_hook_stringify) > -}; > - > void *ima_policy_start(struct seq_file *m, loff_t *pos) > { > loff_t l = *pos; > @@ -1138,8 +1142,12 @@ int ima_policy_show(struct seq_file *m, void *v) > } > } > } > - if (entry->flags & IMA_DIGSIG_REQUIRED) > - seq_puts(m, "appraise_type=imasig "); > + if (entry->flags & IMA_DIGSIG_REQUIRED) { > + if (entry->flags & IMA_MODSIG_ALLOWED) > + seq_puts(m, "appraise_type=modsig|imasig "); > + else > + seq_puts(m, "appraise_type=imasig "); > + } > if (entry->flags & IMA_PERMIT_DIRECTIO) > seq_puts(m, "permit_directio "); > rcu_read_unlock(); > diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c > index 28af43f63572..8c7fa52604a5 100644 > --- a/security/integrity/ima/ima_template_lib.c > +++ b/security/integrity/ima/ima_template_lib.c > @@ -383,9 +383,21 @@ int ima_eventsig_init(struct ima_event_data *event_data, > int xattr_len = event_data->xattr_len; > int rc = 0; > > - if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG)) > + if (!xattr_value || (xattr_value->type != EVM_IMA_XATTR_DIGSIG && > + xattr_value->type != IMA_MODSIG)) > goto out; > > + /* > + * The xattr_value for IMA_MODSIG is a runtime structure containing > + * pointers. Get its raw data instead. > + */ > + if (xattr_value->type == IMA_MODSIG) { > + rc = ima_modsig_serialize_data(xattr_value, &xattr_value, > + &xattr_len); > + if (rc) > + goto out; > + } > + > rc = ima_write_template_field_data(xattr_value, xattr_len, fmt, > field_data); > out: > diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h > index 1f8f1a31d487..0b8b9efa0d2e 100644 > --- a/security/integrity/integrity.h > +++ b/security/integrity/integrity.h > @@ -28,11 +28,12 @@ > > /* iint cache flags */ > #define IMA_ACTION_FLAGS 0xff000000 > -#define IMA_ACTION_RULE_FLAGS 0x06000000 > +#define IMA_ACTION_RULE_FLAGS 0x16000000 > #define IMA_DIGSIG 0x01000000 > #define IMA_DIGSIG_REQUIRED 0x02000000 > #define IMA_PERMIT_DIRECTIO 0x04000000 > #define IMA_NEW_FILE 0x08000000 > +#define IMA_MODSIG_ALLOWED 0x10000000 > > #define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \ > IMA_APPRAISE_SUBMASK) > @@ -58,6 +59,7 @@ enum evm_ima_xattr_type { > EVM_XATTR_HMAC, > EVM_IMA_XATTR_DIGSIG, > IMA_XATTR_DIGEST_NG, > + IMA_MODSIG, > IMA_XATTR_LAST > }; > From mboxrd@z Thu Jan 1 00:00:00 1970 From: zohar@linux.vnet.ibm.com (Mimi Zohar) Date: Thu, 17 Aug 2017 11:04:35 -0400 Subject: [PATCH v4 7/7] ima: Support module-style appended signatures for appraisal In-Reply-To: <20170804220330.30026-8-bauerman@linux.vnet.ibm.com> References: <20170804220330.30026-1-bauerman@linux.vnet.ibm.com> <20170804220330.30026-8-bauerman@linux.vnet.ibm.com> Message-ID: <1502982275.3172.17.camel@linux.vnet.ibm.com> To: linux-security-module@vger.kernel.org List-Id: linux-security-module.vger.kernel.org On Fri, 2017-08-04 at 19:03 -0300, Thiago Jung Bauermann wrote: > This patch introduces the modsig keyword to the IMA policy syntax to > specify that a given hook should expect the file to have the IMA signature > appended to it. Here is how it can be used in a rule: > > appraise func=KEXEC_KERNEL_CHECK appraise_type=modsig|imasig > > With this rule, IMA will accept either an appended signature or a signature > stored in the extended attribute. In that case, it will first check whether > there is an appended signature, and if not it will read it from the > extended attribute. > > The format of the appended signature is the same used for signed kernel > modules. This means that the file can be signed with the scripts/sign-file > tool, with a command line such as this: > > $ sign-file sha256 privkey_ima.pem x509_ima.der vmlinux > > This code only works for files that are hashed from a memory buffer, not > for files that are read from disk at the time of hash calculation. In other > words, only hooks that use kernel_read_file can support appended > signatures. This means that only FIRMWARE_CHECK, KEXEC_KERNEL_CHECK, > KEXEC_INITRAMFS_CHECK and POLICY_CHECK can be supported. > > This feature warrants a separate config option because enabling it brings > in many other config options. > > Signed-off-by: Thiago Jung Bauermann Other than the appended signature not being properly included in the measurement list, the patch seems to be working. ?This patch is on the rather large size. Could you go back and break this patch up into smaller, more concise patches, with clear patch descriptions (eg. separate code cleanup from changes, new policy option, code for appraising an attached signature, storing the appended signature in the measurement list, etc)? thanks! Mimi > --- > security/integrity/ima/Kconfig | 13 +++ > security/integrity/ima/Makefile | 1 + > security/integrity/ima/ima.h | 70 +++++++++++- > security/integrity/ima/ima_appraise.c | 178 +++++++++++++++++++++++++----- > security/integrity/ima/ima_main.c | 7 +- > security/integrity/ima/ima_modsig.c | 178 ++++++++++++++++++++++++++++++ > security/integrity/ima/ima_policy.c | 26 +++-- > security/integrity/ima/ima_template_lib.c | 14 ++- > security/integrity/integrity.h | 4 +- > 9 files changed, 443 insertions(+), 48 deletions(-) > > diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig > index 35ef69312811..55f734a6124b 100644 > --- a/security/integrity/ima/Kconfig > +++ b/security/integrity/ima/Kconfig > @@ -163,6 +163,19 @@ config IMA_APPRAISE_BOOTPARAM > This option enables the different "ima_appraise=" modes > (eg. fix, log) from the boot command line. > > +config IMA_APPRAISE_MODSIG > + bool "Support module-style signatures for appraisal" > + depends on IMA_APPRAISE > + depends on INTEGRITY_ASYMMETRIC_KEYS > + select PKCS7_MESSAGE_PARSER > + select MODULE_SIG_FORMAT > + default n > + help > + Adds support for signatures appended to files. The format of the > + appended signature is the same used for signed kernel modules. > + The modsig keyword can be used in the IMA policy to allow a hook > + to accept such signatures. > + > config IMA_TRUSTED_KEYRING > bool "Require all keys on the .ima keyring be signed (deprecated)" > depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING > diff --git a/security/integrity/ima/Makefile b/security/integrity/ima/Makefile > index 29f198bde02b..c72026acecc3 100644 > --- a/security/integrity/ima/Makefile > +++ b/security/integrity/ima/Makefile > @@ -8,5 +8,6 @@ obj-$(CONFIG_IMA) += ima.o > ima-y := ima_fs.o ima_queue.o ima_init.o ima_main.o ima_crypto.o ima_api.o \ > ima_policy.o ima_template.o ima_template_lib.o > ima-$(CONFIG_IMA_APPRAISE) += ima_appraise.o > +ima-$(CONFIG_IMA_APPRAISE_MODSIG) += ima_modsig.o > ima-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o > obj-$(CONFIG_IMA_BLACKLIST_KEYRING) += ima_mok.o > diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h > index d52b487ad259..5492af2cd7c7 100644 > --- a/security/integrity/ima/ima.h > +++ b/security/integrity/ima/ima.h > @@ -190,6 +190,8 @@ enum ima_hooks { > __ima_hooks(__ima_hook_enumify) > }; > > +extern const char *const func_tokens[]; > + > /* LIM API function definitions */ > int ima_get_action(struct inode *inode, int mask, > enum ima_hooks func, int *pcr); > @@ -236,9 +238,10 @@ int ima_policy_show(struct seq_file *m, void *v); > #ifdef CONFIG_IMA_APPRAISE > int ima_appraise_measurement(enum ima_hooks func, > struct integrity_iint_cache *iint, > - struct file *file, const unsigned char *filename, > - struct evm_ima_xattr_data *xattr_value, > - int xattr_len, int opened); > + struct file *file, const void *buf, loff_t size, > + const unsigned char *filename, > + struct evm_ima_xattr_data **xattr_value, > + int *xattr_len, int opened); > int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); > void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); > enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, > @@ -248,13 +251,28 @@ enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, > int ima_read_xattr(struct dentry *dentry, > struct evm_ima_xattr_data **xattr_value); > > +#ifdef CONFIG_IMA_APPRAISE_MODSIG > +bool ima_hook_supports_modsig(enum ima_hooks func); > +int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len, > + struct evm_ima_xattr_data **xattr_value, > + int *xattr_len); > +int ima_get_modsig_hash(struct evm_ima_xattr_data *hdr, enum hash_algo *algo, > + void const **hash, u8 *len); > +int ima_modsig_serialize_data(struct evm_ima_xattr_data *hdr, > + struct evm_ima_xattr_data **data, int *data_len); > +int ima_modsig_verify(const unsigned int keyring_id, > + struct evm_ima_xattr_data *hdr); > +void ima_free_xattr_data(struct evm_ima_xattr_data *hdr); > +#endif > + > #else > static inline int ima_appraise_measurement(enum ima_hooks func, > struct integrity_iint_cache *iint, > - struct file *file, > + struct file *file, const void *buf, > + loff_t size, > const unsigned char *filename, > - struct evm_ima_xattr_data *xattr_value, > - int xattr_len, int opened) > + struct evm_ima_xattr_data **xattr_value, > + int *xattr_len, int opened) > { > return INTEGRITY_UNKNOWN; > } > @@ -291,6 +309,46 @@ static inline int ima_read_xattr(struct dentry *dentry, > > #endif /* CONFIG_IMA_APPRAISE */ > > +#ifndef CONFIG_IMA_APPRAISE_MODSIG > +static inline bool ima_hook_supports_modsig(enum ima_hooks func) > +{ > + return false; > +} > + > +static inline int ima_read_modsig(enum ima_hooks func, const void *buf, > + loff_t buf_len, > + struct evm_ima_xattr_data **xattr_value, > + int *xattr_len) > +{ > + return -ENOTSUPP; > +} > + > +static inline int ima_get_modsig_hash(struct evm_ima_xattr_data *hdr, > + enum hash_algo *algo, void const **hash, > + u8 *len) > +{ > + return -ENOTSUPP; > +} > + > +static inline int ima_modsig_serialize_data(struct evm_ima_xattr_data *hdr, > + struct evm_ima_xattr_data **data, > + int *data_len) > +{ > + return -ENOTSUPP; > +} > + > +static inline int ima_modsig_verify(const unsigned int keyring_id, > + struct evm_ima_xattr_data *hdr) > +{ > + return -ENOTSUPP; > +} > + > +static inline void ima_free_xattr_data(struct evm_ima_xattr_data *hdr) > +{ > + kfree(hdr); > +} > +#endif > + > /* LSM based policy rules require audit */ > #ifdef CONFIG_IMA_LSM_RULES > > diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c > index 87d2b601cf8e..5a244ebc61d9 100644 > --- a/security/integrity/ima/ima_appraise.c > +++ b/security/integrity/ima/ima_appraise.c > @@ -190,6 +190,64 @@ int ima_read_xattr(struct dentry *dentry, > return ret; > } > > +static void process_xattr_error(int rc, struct integrity_iint_cache *iint, > + int opened, char const **cause, > + enum integrity_status *status) > +{ > + if (rc && rc != -ENODATA) > + return; > + > + *cause = iint->flags & IMA_DIGSIG_REQUIRED ? > + "IMA-signature-required" : "missing-hash"; > + *status = INTEGRITY_NOLABEL; > + > + if (opened & FILE_CREATED) > + iint->flags |= IMA_NEW_FILE; > + > + if ((iint->flags & IMA_NEW_FILE) && > + !(iint->flags & IMA_DIGSIG_REQUIRED)) > + *status = INTEGRITY_PASS; > +} > + > +static int appraise_modsig(struct integrity_iint_cache *iint, > + struct evm_ima_xattr_data *xattr_value, > + int xattr_len) > +{ > + enum hash_algo algo; > + const void *digest; > + void *buf; > + int rc, len; > + u8 dig_len; > + > + rc = ima_modsig_verify(INTEGRITY_KEYRING_IMA, xattr_value); > + if (rc) > + return rc; > + > + /* > + * The signature is good. Now let's put the sig hash > + * into the iint cache so that it gets stored in the > + * measurement list. > + */ > + > + rc = ima_get_modsig_hash(xattr_value, &algo, &digest, &dig_len); > + if (rc) > + return rc; > + > + len = sizeof(iint->ima_hash) + dig_len; > + buf = krealloc(iint->ima_hash, len, GFP_NOFS); > + if (!buf) > + return -ENOMEM; > + > + iint->ima_hash = buf; > + iint->flags |= IMA_DIGSIG; > + iint->ima_hash->algo = algo; > + iint->ima_hash->length = dig_len; > + > + memcpy(iint->ima_hash->digest, digest, dig_len); > + > + return 0; > +} > + > /* > * ima_appraise_measurement - appraise file measurement > * > @@ -200,44 +258,55 @@ int ima_read_xattr(struct dentry *dentry, > */ > int ima_appraise_measurement(enum ima_hooks func, > struct integrity_iint_cache *iint, > - struct file *file, const unsigned char *filename, > - struct evm_ima_xattr_data *xattr_value, > - int xattr_len, int opened) > + struct file *file, const void *buf, loff_t size, > + const unsigned char *filename, > + struct evm_ima_xattr_data **xattr_value_, > + int *xattr_len_, int opened) > { > static const char op[] = "appraise_data"; > - char *cause = "unknown"; > + const char *cause = "unknown"; > struct dentry *dentry = file_dentry(file); > struct inode *inode = d_backing_inode(dentry); > enum integrity_status status = INTEGRITY_UNKNOWN; > - int rc = xattr_len, hash_start = 0; > + struct evm_ima_xattr_data *xattr_value = *xattr_value_; > + int xattr_len = *xattr_len_, rc = xattr_len, hash_start = 0; > + bool appraising_modsig = false; > + > + if (iint->flags & IMA_MODSIG_ALLOWED && > + !ima_read_modsig(func, buf, size, &xattr_value, &xattr_len)) { > + appraising_modsig = true; > + rc = xattr_len; > + } > > - if (!(inode->i_opflags & IOP_XATTR)) > + /* If not appraising a modsig, we need an xattr. */ > + if (!appraising_modsig && !(inode->i_opflags & IOP_XATTR)) > return INTEGRITY_UNKNOWN; > > if (rc <= 0) { > - if (rc && rc != -ENODATA) > - goto out; > - > - cause = iint->flags & IMA_DIGSIG_REQUIRED ? > - "IMA-signature-required" : "missing-hash"; > - status = INTEGRITY_NOLABEL; > - if (opened & FILE_CREATED) > - iint->flags |= IMA_NEW_FILE; > - if ((iint->flags & IMA_NEW_FILE) && > - !(iint->flags & IMA_DIGSIG_REQUIRED)) > - status = INTEGRITY_PASS; > + process_xattr_error(rc, iint, opened, &cause, &status); > goto out; > } > > - status = evm_verifyxattr(dentry, XATTR_NAME_IMA, xattr_value, rc, iint); > - if ((status != INTEGRITY_PASS) && (status != INTEGRITY_UNKNOWN)) { > - if ((status == INTEGRITY_NOLABEL) > - || (status == INTEGRITY_NOXATTRS)) > - cause = "missing-HMAC"; > - else if (status == INTEGRITY_FAIL) > - cause = "invalid-HMAC"; > + status = evm_verifyxattr(dentry, XATTR_NAME_IMA, NULL, 0, iint); > + switch (status) { > + case INTEGRITY_PASS: > + case INTEGRITY_UNKNOWN: > + break; > + case INTEGRITY_NOXATTRS: > + /* No EVM protected xattrs. */ > + if (appraising_modsig) > + break; > + case INTEGRITY_NOLABEL: > + /* No security.evm xattr. */ > + cause = "missing-HMAC"; > + goto out; > + case INTEGRITY_FAIL: > + /* Invalid HMAC/signature. */ > + cause = "invalid-HMAC"; > goto out; > } > + > + retry: > switch (xattr_value->type) { > case IMA_XATTR_DIGEST_NG: > /* first byte contains algorithm id */ > @@ -281,6 +350,54 @@ int ima_appraise_measurement(enum ima_hooks func, > status = INTEGRITY_PASS; > } > break; > + case IMA_MODSIG: > + /* > + * To avoid being tricked into an infinite loop, we don't allow > + * a modsig stored in the xattr. > + */ > + if (!appraising_modsig) { > + status = INTEGRITY_UNKNOWN; > + cause = "unknown-ima-data"; > + break; > + } > + > + rc = appraise_modsig(iint, xattr_value, xattr_len); > + if (!rc) { > + kfree(*xattr_value_); > + *xattr_value_ = xattr_value; > + *xattr_len_ = xattr_len; > + > + status = INTEGRITY_PASS; > + break; > + } > + > + ima_free_xattr_data(xattr_value); > + > + /* > + * The appended signature failed verification. Let's see if > + * there's an extended attribute to fall back to. > + */ > + if (inode->i_opflags & IOP_XATTR && *xattr_len_ != 0) { > + xattr_value = *xattr_value_; > + xattr_len = rc = *xattr_len_; > + appraising_modsig = false; > + > + if (rc <= 0) { > + process_xattr_error(rc, iint, opened, &cause, > + &status); > + goto out; > + } > + > + goto retry; > + } > + > + if (rc == -EOPNOTSUPP) > + status = INTEGRITY_UNKNOWN; > + else if (rc) { > + cause = "invalid-signature"; > + status = INTEGRITY_FAIL; > + } > + break; > default: > status = INTEGRITY_UNKNOWN; > cause = "unknown-ima-data"; > @@ -291,13 +408,15 @@ int ima_appraise_measurement(enum ima_hooks func, > if (status != INTEGRITY_PASS) { > if ((ima_appraise & IMA_APPRAISE_FIX) && > (!xattr_value || > - xattr_value->type != EVM_IMA_XATTR_DIGSIG)) { > + (xattr_value->type != EVM_IMA_XATTR_DIGSIG && > + xattr_value->type != IMA_MODSIG))) { > if (!ima_fix_xattr(dentry, iint)) > status = INTEGRITY_PASS; > } else if ((inode->i_size == 0) && > (iint->flags & IMA_NEW_FILE) && > (xattr_value && > - xattr_value->type == EVM_IMA_XATTR_DIGSIG)) { > + (xattr_value->type == EVM_IMA_XATTR_DIGSIG || > + xattr_value->type == IMA_MODSIG))) { > status = INTEGRITY_PASS; > } > integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename, > @@ -398,6 +517,7 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name, > const void *xattr_value, size_t xattr_value_len) > { > const struct evm_ima_xattr_data *xvalue = xattr_value; > + bool digsig; > int result; > > result = ima_protect_xattr(dentry, xattr_name, xattr_value, > @@ -405,8 +525,10 @@ int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name, > if (result == 1) { > if (!xattr_value_len || (xvalue->type >= IMA_XATTR_LAST)) > return -EINVAL; > - ima_reset_appraise_flags(d_backing_inode(dentry), > - (xvalue->type == EVM_IMA_XATTR_DIGSIG) ? 1 : 0); > + > + digsig = xvalue->type == EVM_IMA_XATTR_DIGSIG || > + xvalue->type == IMA_MODSIG; > + ima_reset_appraise_flags(d_backing_inode(dentry), digsig); > result = 0; > } > return result; > diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c > index 0b4845e7248d..93fa257c71a7 100644 > --- a/security/integrity/ima/ima_main.c > +++ b/security/integrity/ima/ima_main.c > @@ -245,8 +245,9 @@ static int process_measurement(struct file *file, char *buf, loff_t size, > pathname = ima_d_path(&file->f_path, &pathbuf, filename); > > if (action & IMA_APPRAISE_SUBMASK) > - rc = ima_appraise_measurement(func, iint, file, pathname, > - xattr_value, xattr_len, opened); > + rc = ima_appraise_measurement(func, iint, file, buf, size, > + pathname, &xattr_value, > + &xattr_len, opened); > if (action & IMA_MEASURE) > ima_store_measurement(iint, file, pathname, > xattr_value, xattr_len, pcr); > @@ -257,7 +258,7 @@ static int process_measurement(struct file *file, char *buf, loff_t size, > if ((mask & MAY_WRITE) && (iint->flags & IMA_DIGSIG) && > !(iint->flags & IMA_NEW_FILE)) > rc = -EACCES; > - kfree(xattr_value); > + ima_free_xattr_data(xattr_value); > out_free: > if (pathbuf) > __putname(pathbuf); > diff --git a/security/integrity/ima/ima_modsig.c b/security/integrity/ima/ima_modsig.c > new file mode 100644 > index 000000000000..7983edf84511 > --- /dev/null > +++ b/security/integrity/ima/ima_modsig.c > @@ -0,0 +1,178 @@ > +/* > + * IMA support for appraising module-style appended signatures. > + * > + * Copyright (C) 2017 IBM Corporation > + * > + * Author: > + * Thiago Jung Bauermann > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation (version 2 of the License). > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include > +#include > +#include > +#include > + > +#include "ima.h" > + > +struct modsig_hdr { > + uint8_t type; /* Should be IMA_MODSIG. */ > + const void *data; /* Pointer to data covered by pkcs7_msg. */ > + size_t data_len; > + struct pkcs7_message *pkcs7_msg; > + int raw_pkcs7_len; > + > + /* This will be in the measurement list if required by the template. */ > + struct evm_ima_xattr_data raw_pkcs7; > +}; > + > +/** > + * ima_hook_supports_modsig - can the policy allow modsig for this hook? > + * > + * modsig is only supported by hooks using ima_post_read_file, because only they > + * preload the contents of the file in a buffer. FILE_CHECK does that in some > + * cases, but not when reached from vfs_open. POLICY_CHECK can support it, but > + * it's not useful in practice because it's a text file so deny. > + */ > +bool ima_hook_supports_modsig(enum ima_hooks func) > +{ > + switch (func) { > + case FIRMWARE_CHECK: > + case KEXEC_KERNEL_CHECK: > + case KEXEC_INITRAMFS_CHECK: > + return true; > + default: > + return false; > + } > +} > + > +int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len, > + struct evm_ima_xattr_data **xattr_value, > + int *xattr_len) > +{ > + const size_t marker_len = sizeof(MODULE_SIG_STRING) - 1; > + const struct module_signature *sig; > + struct modsig_hdr *hdr; > + size_t sig_len; > + const void *p; > + int rc; > + > + /* > + * Not supposed to happen. Hooks that support modsig are > + * whitelisted when parsing the policy using > + * ima_hooks_supports_modsig. > + */ > + if (!buf || !buf_len) { > + WARN_ONCE(true, "%s doesn't support modsig\n", > + func_tokens[func]); > + return -ENOENT; > + } else if (buf_len <= marker_len + sizeof(*sig)) > + return -ENOENT; > + > + p = buf + buf_len - marker_len; > + if (memcmp(p, MODULE_SIG_STRING, marker_len)) > + return -ENOENT; > + > + buf_len -= marker_len; > + sig = (const struct module_signature *) (p - sizeof(*sig)); > + > + rc = validate_module_sig(sig, buf_len); > + if (rc) > + return rc; > + > + sig_len = be32_to_cpu(sig->sig_len); > + buf_len -= sig_len + sizeof(*sig); > + > + hdr = kmalloc(sizeof(*hdr) + sig_len, GFP_KERNEL); > + if (!hdr) > + return -ENOMEM; > + > + hdr->pkcs7_msg = pkcs7_parse_message(buf + buf_len, sig_len); > + if (IS_ERR(hdr->pkcs7_msg)) { > + rc = PTR_ERR(hdr->pkcs7_msg); > + kfree(hdr); > + return rc; > + } > + > + memcpy(hdr->raw_pkcs7.data, buf + buf_len, sig_len); > + hdr->raw_pkcs7_len = sig_len + 1; > + hdr->raw_pkcs7.type = IMA_MODSIG; > + > + hdr->type = IMA_MODSIG; > + hdr->data = buf; > + hdr->data_len = buf_len; > + > + *xattr_value = (typeof(*xattr_value)) hdr; > + *xattr_len = sizeof(*hdr); > + > + return 0; > +} > + > +int ima_get_modsig_hash(struct evm_ima_xattr_data *hdr, enum hash_algo *algo, > + void const **hash, u8 *len) > +{ > + const struct public_key_signature *pks; > + struct modsig_hdr *modsig = (typeof(modsig)) hdr; > + int i; > + > + pks = pkcs7_get_message_sig(modsig->pkcs7_msg); > + if (!pks) > + return -EBADMSG; > + > + for (i = 0; i < HASH_ALGO__LAST; i++) > + if (!strcmp(hash_algo_name[i], pks->hash_algo)) > + break; > + > + *algo = i; > + *hash = pks->digest; > + *len = pks->digest_size; > + > + return 0; > +} > + > +int ima_modsig_serialize_data(struct evm_ima_xattr_data *hdr, > + struct evm_ima_xattr_data **data, int *data_len) > +{ > + struct modsig_hdr *modsig = (struct modsig_hdr *) hdr; > + > + *data = &modsig->raw_pkcs7; > + *data_len = modsig->raw_pkcs7_len; > + > + return 0; > +} > + > +int ima_modsig_verify(const unsigned int keyring_id, > + struct evm_ima_xattr_data *hdr) > +{ > + struct modsig_hdr *modsig = (struct modsig_hdr *) hdr; > + struct key *trusted_keys = integrity_keyring_from_id(keyring_id); > + > + if (IS_ERR(trusted_keys)) > + return -EINVAL; > + > + return verify_pkcs7_message_sig(modsig->data, modsig->data_len, > + modsig->pkcs7_msg, trusted_keys, > + VERIFYING_MODULE_SIGNATURE, NULL, NULL); > +} > + > +void ima_free_xattr_data(struct evm_ima_xattr_data *hdr) > +{ > + if (!hdr) > + return; > + > + if (hdr->type == IMA_MODSIG) { > + struct modsig_hdr *modsig = (struct modsig_hdr *) hdr; > + > + pkcs7_free_message(modsig->pkcs7_msg); > + } > + > + kfree(hdr); > +} > diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c > index 95209a5f8595..cb056d20e6e5 100644 > --- a/security/integrity/ima/ima_policy.c > +++ b/security/integrity/ima/ima_policy.c > @@ -851,8 +851,12 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) > } > > ima_log_string(ab, "appraise_type", args[0].from); > - if ((strcmp(args[0].from, "imasig")) == 0) > + if (strcmp(args[0].from, "imasig") == 0) > entry->flags |= IMA_DIGSIG_REQUIRED; > + else if (ima_hook_supports_modsig(entry->func) && > + strcmp(args[0].from, "modsig|imasig") == 0) > + entry->flags |= IMA_DIGSIG_REQUIRED > + | IMA_MODSIG_ALLOWED; > else > result = -EINVAL; > break; > @@ -958,6 +962,12 @@ void ima_delete_rules(void) > } > } > > +#define __ima_hook_stringify(str) (#str), > + > +const char *const func_tokens[] = { > + __ima_hooks(__ima_hook_stringify) > +}; > + > #ifdef CONFIG_IMA_READ_POLICY > enum { > mask_exec = 0, mask_write, mask_read, mask_append > @@ -970,12 +980,6 @@ static const char *const mask_tokens[] = { > "MAY_APPEND" > }; > > -#define __ima_hook_stringify(str) (#str), > - > -static const char *const func_tokens[] = { > - __ima_hooks(__ima_hook_stringify) > -}; > - > void *ima_policy_start(struct seq_file *m, loff_t *pos) > { > loff_t l = *pos; > @@ -1138,8 +1142,12 @@ int ima_policy_show(struct seq_file *m, void *v) > } > } > } > - if (entry->flags & IMA_DIGSIG_REQUIRED) > - seq_puts(m, "appraise_type=imasig "); > + if (entry->flags & IMA_DIGSIG_REQUIRED) { > + if (entry->flags & IMA_MODSIG_ALLOWED) > + seq_puts(m, "appraise_type=modsig|imasig "); > + else > + seq_puts(m, "appraise_type=imasig "); > + } > if (entry->flags & IMA_PERMIT_DIRECTIO) > seq_puts(m, "permit_directio "); > rcu_read_unlock(); > diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c > index 28af43f63572..8c7fa52604a5 100644 > --- a/security/integrity/ima/ima_template_lib.c > +++ b/security/integrity/ima/ima_template_lib.c > @@ -383,9 +383,21 @@ int ima_eventsig_init(struct ima_event_data *event_data, > int xattr_len = event_data->xattr_len; > int rc = 0; > > - if ((!xattr_value) || (xattr_value->type != EVM_IMA_XATTR_DIGSIG)) > + if (!xattr_value || (xattr_value->type != EVM_IMA_XATTR_DIGSIG && > + xattr_value->type != IMA_MODSIG)) > goto out; > > + /* > + * The xattr_value for IMA_MODSIG is a runtime structure containing > + * pointers. Get its raw data instead. > + */ > + if (xattr_value->type == IMA_MODSIG) { > + rc = ima_modsig_serialize_data(xattr_value, &xattr_value, > + &xattr_len); > + if (rc) > + goto out; > + } > + > rc = ima_write_template_field_data(xattr_value, xattr_len, fmt, > field_data); > out: > diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h > index 1f8f1a31d487..0b8b9efa0d2e 100644 > --- a/security/integrity/integrity.h > +++ b/security/integrity/integrity.h > @@ -28,11 +28,12 @@ > > /* iint cache flags */ > #define IMA_ACTION_FLAGS 0xff000000 > -#define IMA_ACTION_RULE_FLAGS 0x06000000 > +#define IMA_ACTION_RULE_FLAGS 0x16000000 > #define IMA_DIGSIG 0x01000000 > #define IMA_DIGSIG_REQUIRED 0x02000000 > #define IMA_PERMIT_DIRECTIO 0x04000000 > #define IMA_NEW_FILE 0x08000000 > +#define IMA_MODSIG_ALLOWED 0x10000000 > > #define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \ > IMA_APPRAISE_SUBMASK) > @@ -58,6 +59,7 @@ enum evm_ima_xattr_type { > EVM_XATTR_HMAC, > EVM_IMA_XATTR_DIGSIG, > IMA_XATTR_DIGEST_NG, > + IMA_MODSIG, > IMA_XATTR_LAST > }; > -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo at vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html