|
25 | 25 | #include <linux/kasan.h>
|
26 | 26 | #include <linux/bpf_verifier.h>
|
27 | 27 | #include <linux/uaccess.h>
|
| 28 | +#include <linux/verification.h> |
28 | 29 |
|
29 | 30 | #include "../../lib/kstrtox.h"
|
30 | 31 |
|
@@ -3702,6 +3703,163 @@ __bpf_kfunc int bpf_strstr(const char *s1__ign, const char *s2__ign)
|
3702 | 3703 | {
|
3703 | 3704 | return bpf_strnstr(s1__ign, s2__ign, XATTR_SIZE_MAX);
|
3704 | 3705 | }
|
| 3706 | +#ifdef CONFIG_KEYS |
| 3707 | +/** |
| 3708 | + * bpf_lookup_user_key - lookup a key by its serial |
| 3709 | + * @serial: key handle serial number |
| 3710 | + * @flags: lookup-specific flags |
| 3711 | + * |
| 3712 | + * Search a key with a given *serial* and the provided *flags*. |
| 3713 | + * If found, increment the reference count of the key by one, and |
| 3714 | + * return it in the bpf_key structure. |
| 3715 | + * |
| 3716 | + * The bpf_key structure must be passed to bpf_key_put() when done |
| 3717 | + * with it, so that the key reference count is decremented and the |
| 3718 | + * bpf_key structure is freed. |
| 3719 | + * |
| 3720 | + * Permission checks are deferred to the time the key is used by |
| 3721 | + * one of the available key-specific kfuncs. |
| 3722 | + * |
| 3723 | + * Set *flags* with KEY_LOOKUP_CREATE, to attempt creating a requested |
| 3724 | + * special keyring (e.g. session keyring), if it doesn't yet exist. |
| 3725 | + * Set *flags* with KEY_LOOKUP_PARTIAL, to lookup a key without waiting |
| 3726 | + * for the key construction, and to retrieve uninstantiated keys (keys |
| 3727 | + * without data attached to them). |
| 3728 | + * |
| 3729 | + * Return: a bpf_key pointer with a valid key pointer if the key is found, a |
| 3730 | + * NULL pointer otherwise. |
| 3731 | + */ |
| 3732 | +__bpf_kfunc struct bpf_key *bpf_lookup_user_key(s32 serial, u64 flags) |
| 3733 | +{ |
| 3734 | + key_ref_t key_ref; |
| 3735 | + struct bpf_key *bkey; |
| 3736 | + |
| 3737 | + if (flags & ~KEY_LOOKUP_ALL) |
| 3738 | + return NULL; |
| 3739 | + |
| 3740 | + /* |
| 3741 | + * Permission check is deferred until the key is used, as the |
| 3742 | + * intent of the caller is unknown here. |
| 3743 | + */ |
| 3744 | + key_ref = lookup_user_key(serial, flags, KEY_DEFER_PERM_CHECK); |
| 3745 | + if (IS_ERR(key_ref)) |
| 3746 | + return NULL; |
| 3747 | + |
| 3748 | + bkey = kmalloc(sizeof(*bkey), GFP_KERNEL); |
| 3749 | + if (!bkey) { |
| 3750 | + key_put(key_ref_to_ptr(key_ref)); |
| 3751 | + return NULL; |
| 3752 | + } |
| 3753 | + |
| 3754 | + bkey->key = key_ref_to_ptr(key_ref); |
| 3755 | + bkey->has_ref = true; |
| 3756 | + |
| 3757 | + return bkey; |
| 3758 | +} |
| 3759 | + |
| 3760 | +/** |
| 3761 | + * bpf_lookup_system_key - lookup a key by a system-defined ID |
| 3762 | + * @id: key ID |
| 3763 | + * |
| 3764 | + * Obtain a bpf_key structure with a key pointer set to the passed key ID. |
| 3765 | + * The key pointer is marked as invalid, to prevent bpf_key_put() from |
| 3766 | + * attempting to decrement the key reference count on that pointer. The key |
| 3767 | + * pointer set in such way is currently understood only by |
| 3768 | + * verify_pkcs7_signature(). |
| 3769 | + * |
| 3770 | + * Set *id* to one of the values defined in include/linux/verification.h: |
| 3771 | + * 0 for the primary keyring (immutable keyring of system keys); |
| 3772 | + * VERIFY_USE_SECONDARY_KEYRING for both the primary and secondary keyring |
| 3773 | + * (where keys can be added only if they are vouched for by existing keys |
| 3774 | + * in those keyrings); VERIFY_USE_PLATFORM_KEYRING for the platform |
| 3775 | + * keyring (primarily used by the integrity subsystem to verify a kexec'ed |
| 3776 | + * kerned image and, possibly, the initramfs signature). |
| 3777 | + * |
| 3778 | + * Return: a bpf_key pointer with an invalid key pointer set from the |
| 3779 | + * pre-determined ID on success, a NULL pointer otherwise |
| 3780 | + */ |
| 3781 | +__bpf_kfunc struct bpf_key *bpf_lookup_system_key(u64 id) |
| 3782 | +{ |
| 3783 | + struct bpf_key *bkey; |
| 3784 | + |
| 3785 | + if (system_keyring_id_check(id) < 0) |
| 3786 | + return NULL; |
| 3787 | + |
| 3788 | + bkey = kmalloc(sizeof(*bkey), GFP_ATOMIC); |
| 3789 | + if (!bkey) |
| 3790 | + return NULL; |
| 3791 | + |
| 3792 | + bkey->key = (struct key *)(unsigned long)id; |
| 3793 | + bkey->has_ref = false; |
| 3794 | + |
| 3795 | + return bkey; |
| 3796 | +} |
| 3797 | + |
| 3798 | +/** |
| 3799 | + * bpf_key_put - decrement key reference count if key is valid and free bpf_key |
| 3800 | + * @bkey: bpf_key structure |
| 3801 | + * |
| 3802 | + * Decrement the reference count of the key inside *bkey*, if the pointer |
| 3803 | + * is valid, and free *bkey*. |
| 3804 | + */ |
| 3805 | +__bpf_kfunc void bpf_key_put(struct bpf_key *bkey) |
| 3806 | +{ |
| 3807 | + if (bkey->has_ref) |
| 3808 | + key_put(bkey->key); |
| 3809 | + |
| 3810 | + kfree(bkey); |
| 3811 | +} |
| 3812 | + |
| 3813 | +/** |
| 3814 | + * bpf_verify_pkcs7_signature - verify a PKCS#7 signature |
| 3815 | + * @data_p: data to verify |
| 3816 | + * @sig_p: signature of the data |
| 3817 | + * @trusted_keyring: keyring with keys trusted for signature verification |
| 3818 | + * |
| 3819 | + * Verify the PKCS#7 signature *sig_ptr* against the supplied *data_ptr* |
| 3820 | + * with keys in a keyring referenced by *trusted_keyring*. |
| 3821 | + * |
| 3822 | + * Return: 0 on success, a negative value on error. |
| 3823 | + */ |
| 3824 | +__bpf_kfunc int bpf_verify_pkcs7_signature(struct bpf_dynptr *data_p, |
| 3825 | + struct bpf_dynptr *sig_p, |
| 3826 | + struct bpf_key *trusted_keyring) |
| 3827 | +{ |
| 3828 | +#ifdef CONFIG_SYSTEM_DATA_VERIFICATION |
| 3829 | + struct bpf_dynptr_kern *data_ptr = (struct bpf_dynptr_kern *)data_p; |
| 3830 | + struct bpf_dynptr_kern *sig_ptr = (struct bpf_dynptr_kern *)sig_p; |
| 3831 | + const void *data, *sig; |
| 3832 | + u32 data_len, sig_len; |
| 3833 | + int ret; |
| 3834 | + |
| 3835 | + if (trusted_keyring->has_ref) { |
| 3836 | + /* |
| 3837 | + * Do the permission check deferred in bpf_lookup_user_key(). |
| 3838 | + * See bpf_lookup_user_key() for more details. |
| 3839 | + * |
| 3840 | + * A call to key_task_permission() here would be redundant, as |
| 3841 | + * it is already done by keyring_search() called by |
| 3842 | + * find_asymmetric_key(). |
| 3843 | + */ |
| 3844 | + ret = key_validate(trusted_keyring->key); |
| 3845 | + if (ret < 0) |
| 3846 | + return ret; |
| 3847 | + } |
| 3848 | + |
| 3849 | + data_len = __bpf_dynptr_size(data_ptr); |
| 3850 | + data = __bpf_dynptr_data(data_ptr, data_len); |
| 3851 | + sig_len = __bpf_dynptr_size(sig_ptr); |
| 3852 | + sig = __bpf_dynptr_data(sig_ptr, sig_len); |
| 3853 | + |
| 3854 | + return verify_pkcs7_signature(data, data_len, sig, sig_len, |
| 3855 | + trusted_keyring->key, |
| 3856 | + VERIFYING_UNSPECIFIED_SIGNATURE, NULL, |
| 3857 | + NULL); |
| 3858 | +#else |
| 3859 | + return -EOPNOTSUPP; |
| 3860 | +#endif /* CONFIG_SYSTEM_DATA_VERIFICATION */ |
| 3861 | +} |
| 3862 | +#endif /* CONFIG_KEYS */ |
3705 | 3863 |
|
3706 | 3864 | __bpf_kfunc_end_defs();
|
3707 | 3865 |
|
@@ -3743,6 +3901,14 @@ BTF_ID_FLAGS(func, bpf_throw)
|
3743 | 3901 | #ifdef CONFIG_BPF_EVENTS
|
3744 | 3902 | BTF_ID_FLAGS(func, bpf_send_signal_task, KF_TRUSTED_ARGS)
|
3745 | 3903 | #endif
|
| 3904 | +#ifdef CONFIG_KEYS |
| 3905 | +BTF_ID_FLAGS(func, bpf_lookup_user_key, KF_ACQUIRE | KF_RET_NULL | KF_SLEEPABLE) |
| 3906 | +BTF_ID_FLAGS(func, bpf_lookup_system_key, KF_ACQUIRE | KF_RET_NULL) |
| 3907 | +BTF_ID_FLAGS(func, bpf_key_put, KF_RELEASE) |
| 3908 | +#ifdef CONFIG_SYSTEM_DATA_VERIFICATION |
| 3909 | +BTF_ID_FLAGS(func, bpf_verify_pkcs7_signature, KF_SLEEPABLE) |
| 3910 | +#endif |
| 3911 | +#endif |
3746 | 3912 | BTF_KFUNCS_END(generic_btf_ids)
|
3747 | 3913 |
|
3748 | 3914 | static const struct btf_kfunc_id_set generic_kfunc_set = {
|
|
0 commit comments