brintos

brintos / linux-shallow public Read only

0
0
Text · 2.1 KiB · 1af2415 Raw
90 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/* A pointer that can point to either kernel or userspace memory. */3#ifndef _LINUX_BPFPTR_H4#define _LINUX_BPFPTR_H5 6#include <linux/mm.h>7#include <linux/sockptr.h>8 9typedef sockptr_t bpfptr_t;10 11static inline bool bpfptr_is_kernel(bpfptr_t bpfptr)12{13	return bpfptr.is_kernel;14}15 16static inline bpfptr_t KERNEL_BPFPTR(void *p)17{18	return (bpfptr_t) { .kernel = p, .is_kernel = true };19}20 21static inline bpfptr_t USER_BPFPTR(void __user *p)22{23	return (bpfptr_t) { .user = p };24}25 26static inline bpfptr_t make_bpfptr(u64 addr, bool is_kernel)27{28	if (is_kernel)29		return KERNEL_BPFPTR((void*) (uintptr_t) addr);30	else31		return USER_BPFPTR(u64_to_user_ptr(addr));32}33 34static inline bool bpfptr_is_null(bpfptr_t bpfptr)35{36	if (bpfptr_is_kernel(bpfptr))37		return !bpfptr.kernel;38	return !bpfptr.user;39}40 41static inline void bpfptr_add(bpfptr_t *bpfptr, size_t val)42{43	if (bpfptr_is_kernel(*bpfptr))44		bpfptr->kernel += val;45	else46		bpfptr->user += val;47}48 49static inline int copy_from_bpfptr_offset(void *dst, bpfptr_t src,50					  size_t offset, size_t size)51{52	if (!bpfptr_is_kernel(src))53		return copy_from_user(dst, src.user + offset, size);54	return copy_from_kernel_nofault(dst, src.kernel + offset, size);55}56 57static inline int copy_from_bpfptr(void *dst, bpfptr_t src, size_t size)58{59	return copy_from_bpfptr_offset(dst, src, 0, size);60}61 62static inline int copy_to_bpfptr_offset(bpfptr_t dst, size_t offset,63					const void *src, size_t size)64{65	return copy_to_sockptr_offset((sockptr_t) dst, offset, src, size);66}67 68static inline void *kvmemdup_bpfptr_noprof(bpfptr_t src, size_t len)69{70	void *p = kvmalloc_noprof(len, GFP_USER | __GFP_NOWARN);71 72	if (!p)73		return ERR_PTR(-ENOMEM);74	if (copy_from_bpfptr(p, src, len)) {75		kvfree(p);76		return ERR_PTR(-EFAULT);77	}78	return p;79}80#define kvmemdup_bpfptr(...)	alloc_hooks(kvmemdup_bpfptr_noprof(__VA_ARGS__))81 82static inline long strncpy_from_bpfptr(char *dst, bpfptr_t src, size_t count)83{84	if (bpfptr_is_kernel(src))85		return strncpy_from_kernel_nofault(dst, src.kernel, count);86	return strncpy_from_user(dst, src.user, count);87}88 89#endif /* _LINUX_BPFPTR_H */90