// SPDX-License-Identifier: GPL-2.0-only
/*
 * Functions to manage eBPF programs attached to cgroups
 *
 * Copyright (c) 2016 Daniel Mack
 */

#include <linux/kernel.h>
#include <linux/atomic.h>
#include <linux/cgroup.h>
#include <linux/filter.h>
#include <linux/slab.h>
#include <linux/sysctl.h>
#include <linux/string.h>
#include <linux/bpf.h>
#include <linux/bpf-cgroup.h>
#include <linux/bpf_lsm.h>
#include <linux/bpf_verifier.h>
#include <net/sock.h>
#include <net/bpf_sk_storage.h>

#include "../cgroup/cgroup-internal.h"

DEFINE_STATIC_KEY_ARRAY_FALSE(cgroup_bpf_enabled_key, MAX_CGROUP_BPF_ATTACH_TYPE);
EXPORT_SYMBOL(cgroup_bpf_enabled_key);

/*
 * cgroup bpf destruction makes heavy use of work items and there can be a lot
 * of concurrent destructions.  Use a separate workqueue so that cgroup bpf
 * destruction work items don't end up filling up max_active of system_wq
 * which may lead to deadlock.
 */
static struct workqueue_struct *cgroup_bpf_destroy_wq;

static int __init cgroup_bpf_wq_init(void)
{
	cgroup_bpf_destroy_wq = alloc_workqueue("cgroup_bpf_destroy", 0, 1);
	if (!cgroup_bpf_destroy_wq)
		panic("Failed to alloc workqueue for cgroup bpf destroy.\n");
	return 0;
}
core_initcall(cgroup_bpf_wq_init);

static int cgroup_bpf_lifetime_notify(struct notifier_block *nb,
				      unsigned long action, void *data);

static struct notifier_block cgroup_bpf_lifetime_nb = {
	.notifier_call = cgroup_bpf_lifetime_notify,
};

void __init cgroup_bpf_lifetime_notifier_init(void)
{
	BUG_ON(blocking_notifier_chain_register(&cgroup_lifetime_notifier,
						&cgroup_bpf_lifetime_nb));
}

/* __always_inline is necessary to prevent indirect call through run_prog
 * function pointer.
 */
static __always_inline int
bpf_prog_run_array_cg(const struct cgroup_bpf *cgrp,
		      enum cgroup_bpf_attach_type atype,
		      const void *ctx, bpf_prog_run_fn run_prog,
		      int retval, u32 *ret_flags)
{
	const struct bpf_prog_array_item *item;
	const struct bpf_prog *prog;
	const struct bpf_prog_array *array;
	struct bpf_run_ctx *old_run_ctx;
	struct bpf_cg_run_ctx run_ctx;
	u32 func_ret;

	run_ctx.retval = retval;
	migrate_disable();
	rcu_read_lock();
	array = rcu_dereference(cgrp->effective[atype]);
	item = &array->items[0];
	old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx);
	while ((prog = READ_ONCE(item->prog))) {
		run_ctx.prog_item = item;
		func_ret = run_prog(prog, ctx);
		if (ret_flags) {
			*(ret_flags) |= (func_ret >> 1);
			func_ret &= 1;
		}
		if (!func_ret && !IS_ERR_VALUE((long)run_ctx.retval))
			run_ctx.retval = -EPERM;
		item++;
	}
	bpf_reset_run_ctx(old_run_ctx);
	rcu_read_unlock();
	migrate_enable();
	return run_ctx.retval;
}

unsigned int __cgroup_bpf_run_lsm_sock(const void *ctx,
				       const struct bpf_insn *insn)
{
	const struct bpf_prog *shim_prog;
	struct sock *sk;
	struct cgroup *cgrp;
	int ret = 0;
	u64 *args;

	args = (u64 *)ctx;
	sk = (void *)(unsigned long)args[0];
	/*shim_prog = container_of(insn, struct bpf_prog, insnsi);*/
	shim_prog = (const struct bpf_prog *)((void *)insn - offsetof(struct bpf_prog, insnsi));

	cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
	if (likely(cgrp))
		ret = bpf_prog_run_array_cg(&cgrp->bpf,
					    shim_prog->aux->cgroup_atype,
					    ctx, bpf_prog_run, 0, NULL);
	return ret;
}

unsigned int __cgroup_bpf_run_lsm_socket(const void *ctx,
					 const struct bpf_insn *insn)
{
	const struct bpf_prog *shim_prog;
	struct socket *sock;
	struct cgroup *cgrp;
	int ret = 0;
	u64 *args;

	args = (u64 *)ctx;
	sock = (void *)(unsigned long)args[0];
	/*shim_prog = container_of(insn, struct bpf_prog, insnsi);*/
	shim_prog = (const struct bpf_prog *)((void *)insn - offsetof(struct bpf_prog, insnsi));

	cgrp = sock_cgroup_ptr(&sock->sk->sk_cgrp_data);
	if (likely(cgrp))
		ret = bpf_prog_run_array_cg(&cgrp->bpf,
					    shim_prog->aux->cgroup_atype,
					    ctx, bpf_prog_run, 0, NULL);
	return ret;
}

unsigned int __cgroup_bpf_run_lsm_current(const void *ctx,
					  const struct bpf_insn *insn)
{
	const struct bpf_prog *shim_prog;
	struct cgroup *cgrp;
	int ret = 0;

	/*shim_prog = container_of(insn, struct bpf_prog, insnsi);*/
	shim_prog = (const struct bpf_prog *)((void *)insn - offsetof(struct bpf_prog, insnsi));

	/* We rely on trampoline's __bpf_prog_enter_lsm_cgroup to grab RCU read lock. */
	cgrp = task_dfl_cgroup(current);
	if (likely(cgrp))
		ret = bpf_prog_run_array_cg(&cgrp->bpf,
					    shim_prog->aux->cgroup_atype,
					    ctx, bpf_prog_run, 0, NULL);
	return ret;
}

#ifdef CONFIG_BPF_LSM
struct cgroup_lsm_atype {
	u32 attach_btf_id;
	int refcnt;
};

static struct cgroup_lsm_atype cgroup_lsm_atype[CGROUP_LSM_NUM];

static enum cgroup_bpf_attach_type
bpf_cgroup_atype_find(enum bpf_attach_type attach_type, u32 attach_btf_id)
{
	int i;

	lockdep_assert_held(&cgroup_mutex);

	if (attach_type != BPF_LSM_CGROUP)
		return to_cgroup_bpf_attach_type(attach_type);

	for (i = 0; i < ARRAY_SIZE(cgroup_lsm_atype); i++)
		if (cgroup_lsm_atype[i].attach_btf_id == attach_btf_id)
			return CGROUP_LSM_START + i;

	for (i = 0; i < ARRAY_SIZE(cgroup_lsm_atype); i++)
		if (cgroup_lsm_atype[i].attach_btf_id == 0)
			return CGROUP_LSM_START + i;

	return -E2BIG;

}

void bpf_cgroup_atype_get(u32 attach_btf_id, int cgroup_atype)
{
	int i = cgroup_atype - CGROUP_LSM_START;

	lockdep_assert_held(&cgroup_mutex);

	WARN_ON_ONCE(cgroup_lsm_atype[i].attach_btf_id &&
		     cgroup_lsm_atype[i].attach_btf_id != attach_btf_id);

	cgroup_lsm_atype[i].attach_btf_id = attach_btf_id;
	cgroup_lsm_atype[i].refcnt++;
}

void bpf_cgroup_atype_put(int cgroup_atype)
{
	int i = cgroup_atype - CGROUP_LSM_START;

	cgroup_lock();
	if (--cgroup_lsm_atype[i].refcnt <= 0)
		cgroup_lsm_atype[i].attach_btf_id = 0;
	WARN_ON_ONCE(cgroup_lsm_atype[i].refcnt < 0);
	cgroup_unlock();
}
#else
static enum cgroup_bpf_attach_type
bpf_cgroup_atype_find(enum bpf_attach_type attach_type, u32 attach_btf_id)
{
	if (attach_type != BPF_LSM_CGROUP)
		return to_cgroup_bpf_attach_type(attach_type);
	return -EOPNOTSUPP;
}
#endif /* CONFIG_BPF_LSM */

static void cgroup_bpf_offline(struct cgroup *cgrp)
{
	cgroup_get(cgrp);
	percpu_ref_kill(&cgrp->bpf.refcnt);
}

static void bpf_cgroup_storages_free(struct bpf_cgroup_storage *storages[])
{
	enum bpf_cgroup_storage_type stype;

	for_each_cgroup_storage_type(stype)
		bpf_cgroup_storage_free(storages[stype]);
}

static int bpf_cgroup_storages_alloc(struct bpf_cgroup_storage *storages[],
				     struct bpf_cgroup_storage *new_storages[],
				     enum bpf_attach_type type,
				     struct bpf_prog *prog,
				     struct cgroup *cgrp)
{
	enum bpf_cgroup_storage_type stype;
	struct bpf_cgroup_storage_key key;
	struct bpf_map *map;

	key.cgroup_inode_id = cgroup_id(cgrp);
	key.attach_type = type;

	for_each_cgroup_storage_type(stype) {
		map = prog->aux->cgroup_storage[stype];
		if (!map)
			continue;

		storages[stype] = cgroup_storage_lookup((void *)map, &key, false);
		if (storages[stype])
			continue;

		storages[stype] = bpf_cgroup_storage_alloc(prog, stype);
		if (IS_ERR(storages[stype])) {
			bpf_cgroup_storages_free(new_storages);
			return -ENOMEM;
		}

		new_storages[stype] = storages[stype];
	}

	return 0;
}

static void bpf_cgroup_storages_assign(struct bpf_cgroup_storage *dst[],
				       struct bpf_cgroup_storage *src[])
{
	enum bpf_cgroup_storage_type stype;

	for_each_cgroup_storage_type(stype)
		dst[stype] = src[stype];
}

static void bpf_cgroup_storages_link(struct bpf_cgroup_storage *storages[],
				     struct cgroup *cgrp,
				     enum bpf_attach_type attach_type)
{
	enum bpf_cgroup_storage_type stype;

	for_each_cgroup_storage_type(stype)
		bpf_cgroup_storage_link(storages[stype], cgrp, attach_type);
}

/* Called when bpf_cgroup_link is auto-detached from dying cgroup.
 * It drops cgroup and bpf_prog refcounts, and marks bpf_link as defunct. It
 * doesn't free link memory, which will eventually be done by bpf_link's
 * release() callback, when its last FD is closed.
 */
static void bpf_cgroup_link_auto_detach(struct bpf_cgroup_link *link)
{
	cgroup_put(link->cgroup);
	link->cgroup = NULL;
}

/**
 * cgroup_bpf_release() - put references of all bpf programs and
 *                        release all cgroup bpf data
 * @work: work structure embedded into the cgroup to modify
 */
static void cgroup_bpf_release(struct work_struct *work)
{
	struct cgroup *p, *cgrp = container_of(work, struct cgroup,
					       bpf.release_work);
	struct bpf_prog_array *old_array;
	struct list_head *storages = &cgrp->bpf.storages;
	struct bpf_cgroup_storage *storage, *stmp;

	unsigned int atype;

	cgroup_lock();

	for (atype = 0; atype < ARRAY_SIZE(cgrp->bpf.progs); atype++) {
		struct hlist_head *progs = &cgrp->bpf.progs[atype];
		struct bpf_prog_list *pl;
		struct hlist_node *pltmp;

		hlist_for_each_entry_safe(pl, pltmp, progs, node) {
			hlist_del(&pl->node);
			if (pl->prog) {
				if (pl->prog->expected_attach_type == BPF_LSM_CGROUP)
					bpf_trampoline_unlink_cgroup_shim(pl->prog);
				bpf_prog_put(pl->prog);
			}
			if (pl->link) {
				if (pl->link->link.prog->expected_attach_type == BPF_LSM_CGROUP)
					bpf_trampoline_unlink_cgroup_shim(pl->link->link.prog);
				bpf_cgroup_link_auto_detach(pl->link);
			}
			kfree(pl);
			static_branch_dec(&cgroup_bpf_enabled_key[atype]);
		}
		old_array = rcu_dereference_protected(
				cgrp->bpf.effective[atype],
				lockdep_is_held(&cgroup_mutex));
		bpf_prog_array_free(old_array);
	}

	list_for_each_entry_safe(storage, stmp, storages, list_cg) {
		bpf_cgroup_storage_unlink(storage);
		bpf_cgroup_storage_free(storage);
	}

	cgroup_unlock();

	for (p = cgroup_parent(cgrp); p; p = cgroup_parent(p))
		cgroup_bpf_put(p);

	percpu_ref_exit(&cgrp->bpf.refcnt);
	cgroup_put(cgrp);
}

/**
 * cgroup_bpf_release_fn() - callback used to schedule releasing
 *                           of bpf cgroup data
 * @ref: percpu ref counter structure
 */
static void cgroup_bpf_release_fn(struct percpu_ref *ref)
{
	struct cgroup *cgrp = container_of(ref, struct cgroup, bpf.refcnt);

	INIT_WORK(&cgrp->bpf.release_work, cgroup_bpf_release);
	queue_work(cgroup_bpf_destroy_wq, &cgrp->bpf.release_work);
}

/* Get underlying bpf_prog of bpf_prog_list entry, regardless if it's through
 * link or direct prog.
 */
static struct bpf_prog *prog_list_prog(struct bpf_prog_list *pl)
{
	if (pl->prog)
		return pl->prog;
	if (pl->link)
		return pl->link->link.prog;
	return NULL;
}

/* count number of elements in the list.
 * it's slow but the list cannot be long
 */
static u32 prog_list_length(struct hlist_head *head, int *preorder_cnt)
{
	struct bpf_prog_list *pl;
	u32 cnt = 0;

	hlist_for_each_entry(pl, head, node) {
		if (!prog_list_prog(pl))
			continue;
		if (preorder_cnt && (pl->flags & BPF_F_PREORDER))
			(*preorder_cnt)++;
		cnt++;
	}
	return cnt;
}

/* if parent has non-overridable prog attached,
 * disallow attaching new programs to the descendent cgroup.
 * if parent has overridable or multi-prog, allow attaching
 */
static bool hierarchy_allows_attach(struct cgroup *cgrp,
				    enum cgroup_bpf_attach_type atype)
{
	struct cgroup *p;

	p = cgroup_parent(cgrp);
	if (!p)
		return true;
	do {
		u32 flags = p->bpf.flags[atype];
		u32 cnt;

		if (flags & BPF_F_ALLOW_MULTI)
			return true;
		cnt = prog_list_length(&p->bpf.progs[atype], NULL);
		WARN_ON_ONCE(cnt > 1);
		if (cnt == 1)
			return !!(flags & BPF_F_ALLOW_OVERRIDE);
		p = cgroup_parent(p);
	} while (p);
	return true;
}

/* compute a chain of effective programs for a given cgroup:
 * start from the list of programs in this cgroup and add
 * all parent programs.
 * Note that parent's F_ALLOW_OVERRIDE-type program is yielding
 * to programs in this cgroup
 */
static int compute_effective_progs(struct cgroup *cgrp,
				   enum cgroup_bpf_attach_type atype,
				   struct bpf_prog_array **array)
{
	struct bpf_prog_array_item *item;
	struct bpf_prog_array *progs;
	struct bpf_prog_list *pl;
	struct cgroup *p = cgrp;
	int i, j, cnt = 0, preorder_cnt = 0, fstart, bstart, init_bstart;

	/* count number of effective programs by walking parents */
	do {
		if (cnt == 0 || (p->bpf.flags[atype] & BPF_F_ALLOW_MULTI))
			cnt += prog_list_length(&p->bpf.progs[atype], &preorder_cnt);
		p = cgroup_parent(p);
	} while (p);

	progs = bpf_prog_array_alloc(cnt, GFP_KERNEL);
	if (!progs)
		return -ENOMEM;

	/* populate the array with effective progs */
	cnt = 0;
	p = cgrp;
	fstart = preorder_cnt;
	bstart = preorder_cnt - 1;
	do {
		if (cnt > 0 && !(p->bpf.flags[atype] & BPF_F_ALLOW_MULTI))
			continue;

		init_bstart = bstart;
		hlist_for_each_entry(pl, &p->bpf.progs[atype], node) {
			if (!prog_list_prog(pl))
				continue;

			if (pl->flags & BPF_F_PREORDER) {
				item = &progs->items[bstart];
				bstart--;
			} else {
				item = &progs->items[fstart];
				fstart++;
			}
			item->prog = prog_list_prog(pl);
			bpf_cgroup_storages_assign(item->cgroup_storage,
						   pl->storage);
			cnt++;
		}

		/* reverse pre-ordering progs at this cgroup level */
		for (i = bstart + 1, j = init_bstart; i < j; i++, j--)
			swap(progs->items[i], progs->items[j]);

	} while ((p = cgroup_parent(p)));

	*array = progs;
	return 0;
}

static void activate_effective_progs(struct cgroup *cgrp,
				     enum cgroup_bpf_attach_type atype,
				     struct bpf_prog_array *old_array)
{
	old_array = rcu_replace_pointer(cgrp->bpf.effective[atype], old_array,
					lockdep_is_held(&cgroup_mutex));
	/* free prog array after grace period, since __cgroup_bpf_run_*()
	 * might be still walking the array
	 */
	bpf_prog_array_free(old_array);
}

/**
 * cgroup_bpf_inherit() - inherit effective programs from parent
 * @cgrp: the cgroup to modify
 */
static int cgroup_bpf_inherit(struct cgroup *cgrp)
{
/* has to use marco instead of const int, since compiler thinks
 * that array below is variable length
 */
#define	NR ARRAY_SIZE(cgrp->bpf.effective)
	struct bpf_prog_array *arrays[NR] = {};
	struct cgroup *p;
	int ret, i;

	ret = percpu_ref_init(&cgrp->bpf.refcnt, cgroup_bpf_release_fn, 0,
			      GFP_KERNEL);
	if (ret)
		return ret;

	for (p = cgroup_parent(cgrp); p; p = cgroup_parent(p))
		cgroup_bpf_get(p);

	for (i = 0; i < NR; i++)
		INIT_HLIST_HEAD(&cgrp->bpf.progs[i]);

	INIT_LIST_HEAD(&cgrp->bpf.storages);

	for (i = 0; i < NR; i++)
		if (compute_effective_progs(cgrp, i, &arrays[i]))
			goto cleanup;

	for (i = 0; i < NR; i++)
		activate_effective_progs(cgrp, i, arrays[i]);

	return 0;
cleanup:
	for (i = 0; i < NR; i++)
		bpf_prog_array_free(arrays[i]);

	for (p = cgroup_parent(cgrp); p; p = cgroup_parent(p))
		cgroup_bpf_put(p);

	percpu_ref_exit(&cgrp->bpf.refcnt);

	return -ENOMEM;
}

static int cgroup_bpf_lifetime_notify(struct notifier_block *nb,
				      unsigned long action, void *data)
{
	struct cgroup *cgrp = data;
	int ret = 0;

	if (cgrp->root != &cgrp_dfl_root)
		return NOTIFY_OK;

	switch (action) {
	case CGROUP_LIFETIME_ONLINE:
		ret = cgroup_bpf_inherit(cgrp);
		break;
	case CGROUP_LIFETIME_OFFLINE:
		cgroup_bpf_offline(cgrp);
		break;
	}

	return notifier_from_errno(ret);
}

static int update_effective_progs(struct cgroup *cgrp,
				  enum cgroup_bpf_attach_type atype)
{
	struct cgroup_subsys_state *css;
	int err;

	/* allocate and recompute effective prog arrays */
	css_for_each_descendant_pre(css, &cgrp->self) {
		struct cgroup *desc = container_of(css, struct cgroup, self);

		if (percpu_ref_is_zero(&desc->bpf.refcnt))
			continue;

		err = compute_effective_progs(desc, atype, &desc->bpf.inactive);
		if (err)
			goto cleanup;
	}

	/* all allocations were successful. Activate all prog arrays */
	css_for_each_descendant_pre(css, &cgrp->self) {
		struct cgroup *desc = container_of(css, struct cgroup, self);

		if (percpu_ref_is_zero(&desc->bpf.refcnt)) {
			if (unlikely(desc->bpf.inactive)) {
				bpf_prog_array_free(desc->bpf.inactive);
				desc->bpf.inactive = NULL;
			}
			continue;
		}

		activate_effective_progs(desc, atype, desc->bpf.inactive);
		desc->bpf.inactive = NULL;
	}

	return 0;

cleanup:
	/* oom while computing effective. Free all computed effective arrays
	 * since they were not activated
	 */
	css_for_each_descendant_pre(css, &cgrp->self) {
		struct cgroup *desc = container_of(css, struct cgroup, self);

		bpf_prog_array_free(desc->bpf.inactive);
		desc->bpf.inactive = NULL;
	}

	return err;
}

#define BPF_CGROUP_MAX_PROGS 64

static struct bpf_prog_list *find_attach_entry(struct hlist_head *progs,
					       struct bpf_prog *prog,
					       struct bpf_cgroup_link *link,
					       struct bpf_prog *replace_prog,
					       bool allow_multi)
{
	struct bpf_prog_list *pl;

	/* single-attach case */
	if (!allow_multi) {
		if (hlist_empty(progs))
			return NULL;
		return hlist_entry(progs->first, typeof(*pl), node);
	}

	hlist_for_each_entry(pl, progs, node) {
		if (prog && pl->prog == prog && prog != replace_prog)
			/* disallow attaching the same prog twice */
			return ERR_PTR(-EINVAL);
		if (link && pl->link == link)
			/* disallow attaching the same link twice */
			return ERR_PTR(-EINVAL);
	}

	/* direct prog multi-attach w/ replacement case */
	if (replace_prog) {
		hlist_for_each_entry(pl, progs, node) {
			if (pl->prog == replace_prog)
				/* a match found */
				return pl;
		}
		/* prog to replace not found for cgroup */
		return ERR_PTR(-ENOENT);
	}

	return NULL;
}

/**
 * __cgroup_bpf_attach() - Attach the program or the link to a cgroup, and
 *                         propagate the change to descendants
 * @cgrp: The cgroup which descendants to traverse
 * @prog: A program to attach
 * @link: A link to attach
 * @replace_prog: Previously attached program to replace if BPF_F_REPLACE is set
 * @type: Type of attach operation
 * @flags: Option flags
 *
 * Exactly one of @prog or @link can be non-null.
 * Must be called with cgroup_mutex held.
 */
static int __cgroup_bpf_attach(struct cgroup *cgrp,
			       struct bpf_prog *prog, struct bpf_prog *replace_prog,
			       struct bpf_cgroup_link *link,
			       enum bpf_attach_type type, u32 flags)
{
	u32 saved_flags = (flags & (BPF_F_ALLOW_OVERRIDE | BPF_F_ALLOW_MULTI));
	struct bpf_prog *old_prog = NULL;
	struct bpf_cgroup_storage *storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
	struct bpf_cgroup_storage *new_storage[MAX_BPF_CGROUP_STORAGE_TYPE] = {};
	struct bpf_prog *new_prog = prog ? : link->link.prog;
	enum cgroup_bpf_attach_type atype;
	struct bpf_prog_list *pl;
	struct hlist_head *progs;
	int err;

	if (((flags & BPF_F_ALLOW_OVERRIDE) && (flags & BPF_F_ALLOW_MULTI)) ||
	    ((flags & BPF_F_REPLACE) && !(flags & BPF_F_ALLOW_MULTI)))
		/* invalid combination */
		return -EINVAL;
	if (link && (prog || replace_prog))
		/* only either link or prog/replace_prog can be specified */
		return -EINVAL;
	if (!!replace_prog != !!(flags & BPF_F_REPLACE))
		/* replace_prog implies BPF_F_REPLACE, and vice versa */
		return -EINVAL;

	atype = bpf_cgroup_atype_find(type, new_prog->aux->attach_btf_id);
	if (atype < 0)
		return -EINVAL;

	progs = &cgrp->bpf.progs[atype];

	if (!hierarchy_allows_attach(cgrp, atype))
		return -EPERM;

	if (!hlist_empty(progs) && cgrp->bpf.flags[atype] != saved_flags)
		/* Disallow attaching non-overridable on top
		 * of existing overridable in this cgroup.
		 * Disallow attaching multi-prog if overridable or none
		 */
		return -EPERM;

	if (prog_list_length(progs, NULL) >= BPF_CGROUP_MAX_PROGS)
		return -E2BIG;

	pl = find_attach_entry(progs, prog, link, replace_prog,
			       flags & BPF_F_ALLOW_MULTI);
	if (IS_ERR(pl))
		return PTR_ERR(pl);

	if (bpf_cgroup_storages_alloc(storage, new_storage, type,
				      prog ? : link->link.prog, cgrp))
		return -ENOMEM;

	if (pl) {
		old_prog = pl->prog;
	} else {
		struct hlist_node *last = NULL;

		pl = kmalloc(sizeof(*pl), GFP_KERNEL);
		if (!pl) {
			bpf_cgroup_storages_free(new_storage);
			return -ENOMEM;
		}
		if (hlist_empty(progs))
			hlist_add_head(&pl->node, progs);
		else
			hlist_for_each(last, progs) {
				if (last->next)
					continue;
				hlist_add_behind(&pl->node, last);
				break;
			}
	}

	pl->prog = prog;
	pl->link = link;
	pl->flags = flags;
	bpf_cgroup_storages_assign(pl->storage, storage);
	cgrp->bpf.flags[atype] = saved_flags;

	if (type == BPF_LSM_CGROUP) {
		err = bpf_trampoline_link_cgroup_shim(new_prog, atype);
		if (err)
			goto cleanup;
	}

	err = update_effective_progs(cgrp, atype);
	if (err)
		goto cleanup_trampoline;

	if (old_prog) {
		if (type == BPF_LSM_CGROUP)
			bpf_trampoline_unlink_cgroup_shim(old_prog);
		bpf_prog_put(old_prog);
	} else {
		static_branch_inc(&cgroup_bpf_enabled_key[atype]);
	}
	bpf_cgroup_storages_link(new_storage, cgrp, type);
	return 0;

cleanup_trampoline:
	if (type == BPF_LSM_CGROUP)
		bpf_trampoline_unlink_cgroup_shim(new_prog);

cleanup:
	if (old_prog) {
		pl->prog = old_prog;
		pl->link = NULL;
	}
	bpf_cgroup_storages_free(new_storage);
	if (!old_prog) {
		hlist_del(&pl->node);
		kfree(pl);
	}
	return err;
}

static int cgroup_bpf_attach(struct cgroup *cgrp,
			     struct bpf_prog *prog, struct bpf_prog *replace_prog,
			     struct bpf_cgroup_link *link,
			     enum bpf_attach_type type,
			     u32 flags)
{
	int ret;

	cgroup_lock();
	ret = __cgroup_bpf_attach(cgrp, prog, replace_prog, link, type, flags);
	cgroup_unlock();
	return ret;
}

/* Swap updated BPF program for given link in effective program arrays across
 * all descendant cgroups. This function is guaranteed to succeed.
 */
static void replace_effective_prog(struct cgroup *cgrp,
				   enum cgroup_bpf_attach_type atype,
				   struct bpf_cgroup_link *link)
{
	struct bpf_prog_array_item *item;
	struct cgroup_subsys_state *css;
	struct bpf_prog_array *progs;
	struct bpf_prog_list *pl;
	struct hlist_head *head;
	struct cgroup *cg;
	int pos;

	css_for_each_descendant_pre(css, &cgrp->self) {
		struct cgroup *desc = container_of(css, struct cgroup, self);

		if (percpu_ref_is_zero(&desc->bpf.refcnt))
			continue;

		/* find position of link in effective progs array */
		for (pos = 0, cg = desc; cg; cg = cgroup_parent(cg)) {
			if (pos && !(cg->bpf.flags[atype] & BPF_F_ALLOW_MULTI))
				continue;

			head = &cg->bpf.progs[atype];
			hlist_for_each_entry(pl, head, node) {
				if (!prog_list_prog(pl))
					continue;
				if (pl->link == link)
					goto found;
				pos++;
			}
		}
found:
		BUG_ON(!cg);
		progs = rcu_dereference_protected(
				desc->bpf.effective[atype],
				lockdep_is_held(&cgroup_mutex));
		item = &progs->items[pos];
		WRITE_ONCE(item->prog, link->link.prog);
	}
}

/**
 * __cgroup_bpf_replace() - Replace link's program and propagate the change
 *                          to descendants
 * @cgrp: The cgroup which descendants to traverse
 * @link: A link for which to replace BPF program
 * @new_prog: &struct bpf_prog for the target BPF program with its refcnt
 *            incremented
 *
 * Must be called with cgroup_mutex held.
 */
static int __cgroup_bpf_replace(struct cgroup *cgrp,
				struct bpf_cgroup_link *link,
				struct bpf_prog *new_prog)
{
	enum cgroup_bpf_attach_type atype;
	struct bpf_prog *old_prog;
	struct bpf_prog_list *pl;
	struct hlist_head *progs;
	bool found = false;

	atype = bpf_cgroup_atype_find(link->type, new_prog->aux->attach_btf_id);
	if (atype < 0)
		return -EINVAL;

	progs = &cgrp->bpf.progs[atype];

	if (link->link.prog->type != new_prog->type)
		return -EINVAL;

	hlist_for_each_entry(pl, progs, node) {
		if (pl->link == link) {
			found = true;
			break;
		}
	}
	if (!found)
		return -ENOENT;

	old_prog = xchg(&link->link.prog, new_prog);
	replace_effective_prog(cgrp, atype, link);
	bpf_prog_put(old_prog);
	return 0;
}

static int cgroup_bpf_replace(struct bpf_link *link, struct bpf_prog *new_prog,
			      struct bpf_prog *old_prog)
{
	struct bpf_cgroup_link *cg_link;
	int ret;

	cg_link = container_of(link, struct bpf_cgroup_link, link);

	cgroup_lock();
	/* link might have been auto-released by dying cgroup, so fail */
	if (!cg_link->cgroup) {
		ret = -ENOLINK;
		goto out_unlock;
	}
	if (old_prog && link->prog != old_prog) {
		ret = -EPERM;
		goto out_unlock;
	}
	ret = __cgroup_bpf_replace(cg_link->cgroup, cg_link, new_prog);
out_unlock:
	cgroup_unlock();
	return ret;
}

static struct bpf_prog_list *find_detach_entry(struct hlist_head *progs,
					       struct bpf_prog *prog,
					       struct bpf_cgroup_link *link,
					       bool allow_multi)
{
	struct bpf_prog_list *pl;

	if (!allow_multi) {
		if (hlist_empty(progs))
			/* report error when trying to detach and nothing is attached */
			return ERR_PTR(-ENOENT);

		/* to maintain backward compatibility NONE and OVERRIDE cgroups
		 * allow detaching with invalid FD (prog==NULL) in legacy mode
		 */
		return hlist_entry(progs->first, typeof(*pl), node);
	}

	if (!prog && !link)
		/* to detach MULTI prog the user has to specify valid FD
		 * of the program or link to be detached
		 */
		return ERR_PTR(-EINVAL);

	/* find the prog or link and detach it */
	hlist_for_each_entry(pl, progs, node) {
		if (pl->prog == prog && pl->link == link)
			return pl;
	}
	return ERR_PTR(-ENOENT);
}

/**
 * purge_effective_progs() - After compute_effective_progs fails to alloc new
 *                           cgrp->bpf.inactive table we can recover by
 *                           recomputing the array in place.
 *
 * @cgrp: The cgroup which descendants to travers
 * @prog: A program to detach or NULL
 * @link: A link to detach or NULL
 * @atype: Type of detach operation
 */
static void purge_effective_progs(struct cgroup *cgrp, struct bpf_prog *prog,
				  struct bpf_cgroup_link *link,
				  enum cgroup_bpf_attach_type atype)
{
	struct cgroup_subsys_state *css;
	struct bpf_prog_array *progs;
	struct bpf_prog_list *pl;
	struct hlist_head *head;
	struct cgroup *cg;
	int pos;

	/* recompute effective prog array in place */
	css_for_each_descendant_pre(css, &cgrp->self) {
		struct cgroup *desc = container_of(css, struct cgroup, self);

		if (percpu_ref_is_zero(&desc->bpf.refcnt))
			continue;

		/* find position of link or prog in effective progs array */
		for (pos = 0, cg = desc; cg; cg = cgroup_parent(cg)) {
			if (pos && !(cg->bpf.flags[atype] & BPF_F_ALLOW_MULTI))
				continue;

			head = &cg->bpf.progs[atype];
			hlist_for_each_entry(pl, head, node) {
				if (!prog_list_prog(pl))
					continue;
				if (pl->prog == prog && pl->link == link)
					goto found;
				pos++;
			}
		}

		/* no link or prog match, skip the cgroup of this layer */
		continue;
found:
		progs = rcu_dereference_protected(
				desc->bpf.effective[atype],
				lockdep_is_held(&cgroup_mutex));

		/* Remove the program from the array */
		WARN_ONCE(bpf_prog_array_delete_safe_at(progs, pos),
			  "Failed to purge a prog from array at index %d", pos);
	}
}

/**
 * __cgroup_bpf_detach() - Detach the program or link from a cgroup, and
 *                         propagate the change to descendants
 * @cgrp: The cgroup which descendants to traverse
 * @prog: A program to detach or NULL
 * @link: A link to detach or NULL
 * @type: Type of detach operation
 *
 * At most one of @prog or @link can be non-NULL.
 * Must be called with cgroup_mutex held.
 */
static int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
			       struct bpf_cgroup_link *link, enum bpf_attach_type type)
{
	enum cgroup_bpf_attach_type atype;
	struct bpf_prog *old_prog;
	struct bpf_prog_list *pl;
	struct hlist_head *progs;
	u32 attach_btf_id = 0;
	u32 flags;

	if (prog)
		attach_btf_id = prog->aux->attach_btf_id;
	if (link)
		attach_btf_id = link->link.prog->aux->attach_btf_id;

	atype = bpf_cgroup_atype_find(type, attach_btf_id);
	if (atype < 0)
		return -EINVAL;

	progs = &cgrp->bpf.progs[atype];
	flags = cgrp->bpf.flags[atype];

	if (prog && link)
		/* only one of prog or link can be specified */
		return -EINVAL;

	pl = find_detach_entry(progs, prog, link, flags & BPF_F_ALLOW_MULTI);
	if (IS_ERR(pl))
		return PTR_ERR(pl);

	/* mark it deleted, so it's ignored while recomputing effective */
	old_prog = pl->prog;
	pl->prog = NULL;
	pl->link = NULL;

	if (update_effective_progs(cgrp, atype)) {
		/* if update effective array failed replace the prog with a dummy prog*/
		pl->prog = old_prog;
		pl->link = link;
		purge_effective_progs(cgrp, old_prog, link, atype);
	}

	/* now can actually delete it from this cgroup list */
	hlist_del(&pl->node);

	kfree(pl);
	if (hlist_empty(progs))
		/* last program was detached, reset flags to zero */
		cgrp->bpf.flags[atype] = 0;
	if (old_prog) {
		if (type == BPF_LSM_CGROUP)
			bpf_trampoline_unlink_cgroup_shim(old_prog);
		bpf_prog_put(old_prog);
	}
	static_branch_dec(&cgroup_bpf_enabled_key[atype]);
	return 0;
}

static int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
			     enum bpf_attach_type type)
{
	int ret;

	cgroup_lock();
	ret = __cgroup_bpf_detach(cgrp, prog, NULL, type);
	cgroup_unlock();
	return ret;
}

/* Must be called with cgroup_mutex held to avoid races. */
static int __cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
			      union bpf_attr __user *uattr)
{
	__u32 __user *prog_attach_flags = u64_to_user_ptr(attr->query.prog_attach_flags);
	bool effective_query = attr->query.query_flags & BPF_F_QUERY_EFFECTIVE;
	__u32 __user *prog_ids = u64_to_user_ptr(attr->query.prog_ids);
	enum bpf_attach_type type = attr->query.attach_type;
	enum cgroup_bpf_attach_type from_atype, to_atype;
	enum cgroup_bpf_attach_type atype;
	struct bpf_prog_array *effective;
	int cnt, ret = 0, i;
	int total_cnt = 0;
	u32 flags;

	if (effective_query && prog_attach_flags)
		return -EINVAL;

	if (type == BPF_LSM_CGROUP) {
		if (!effective_query && attr->query.prog_cnt &&
		    prog_ids && !prog_attach_flags)
			return -EINVAL;

		from_atype = CGROUP_LSM_START;
		to_atype = CGROUP_LSM_END;
		flags = 0;
	} else {
		from_atype = to_cgroup_bpf_attach_type(type);
		if (from_atype < 0)
			return -EINVAL;
		to_atype = from_atype;
		flags = cgrp->bpf.flags[from_atype];
	}

	for (atype = from_atype; atype <= to_atype; atype++) {
		if (effective_query) {
			effective = rcu_dereference_protected(cgrp->bpf.effective[atype],
							      lockdep_is_held(&cgroup_mutex));
			total_cnt += bpf_prog_array_length(effective);
		} else {
			total_cnt += prog_list_length(&cgrp->bpf.progs[atype], NULL);
		}
	}

	/* always output uattr->query.attach_flags as 0 during effective query */
	flags = effective_query ? 0 : flags;
	if (copy_to_user(&uattr->query.attach_flags, &flags, sizeof(flags)))
		return -EFAULT;
	if (copy_to_user(&uattr->query.prog_cnt, &total_cnt, sizeof(total_cnt)))
		return -EFAULT;
	if (attr->query.prog_cnt == 0 || !prog_ids || !total_cnt)
		/* return early if user requested only program count + flags */
		return 0;

	if (attr->query.prog_cnt < total_cnt) {
		total_cnt = attr->query.prog_cnt;
		ret = -ENOSPC;
	}

	for (atype = from_atype; atype <= to_atype && total_cnt; atype++) {
		if (effective_query) {
			effective = rcu_dereference_protected(cgrp->bpf.effective[atype],
							      lockdep_is_held(&cgroup_mutex));
			cnt = min_t(int, bpf_prog_array_length(effective), total_cnt);
			ret = bpf_prog_array_copy_to_user(effective, prog_ids, cnt);
		} else {
			struct hlist_head *progs;
			struct bpf_prog_list *pl;
			struct bpf_prog *prog;
			u32 id;

			progs = &cgrp->bpf.progs[atype];
			cnt = min_t(int, prog_list_length(progs, NULL), total_cnt);
			i = 0;
			hlist_for_each_entry(pl, progs, node) {
				prog = prog_list_prog(pl);
				id = prog->aux->id;
				if (copy_to_user(prog_ids + i, &id, sizeof(id)))
					return -EFAULT;
				if (++i == cnt)
					break;
			}

			if (prog_attach_flags) {
				flags = cgrp->bpf.flags[atype];

				for (i = 0; i < cnt; i++)
					if (copy_to_user(prog_attach_flags + i,
							 &flags, sizeof(flags)))
						return -EFAULT;
				prog_attach_flags += cnt;
			}
		}

		prog_ids += cnt;
		total_cnt -= cnt;
	}
	return ret;
}

static int cgroup_bpf_query(struct cgroup *cgrp, const union bpf_attr *attr,
			    union bpf_attr __user *uattr)
{
	int ret;

	cgroup_lock();
	ret = __cgroup_bpf_query(cgrp, attr, uattr);
	cgroup_unlock();
	return ret;
}

int cgroup_bpf_prog_attach(const union bpf_attr *attr,
			   enum bpf_prog_type ptype, struct bpf_prog *prog)
{
	struct bpf_prog *replace_prog = NULL;
	struct cgroup *cgrp;
	int ret;

	cgrp = cgroup_get_from_fd(attr->target_fd);
	if (IS_ERR(cgrp))
		return PTR_ERR(cgrp);

	if ((attr->attach_flags & BPF_F_ALLOW_MULTI) &&
	    (attr->attach_flags & BPF_F_REPLACE)) {
		replace_prog = bpf_prog_get_type(attr->replace_bpf_fd, ptype);
		if (IS_ERR(replace_prog)) {
			cgroup_put(cgrp);
			return PTR_ERR(replace_prog);
		}
	}

	ret = cgroup_bpf_attach(cgrp, prog, replace_prog, NULL,
				attr->attach_type, attr->attach_flags);

	if (replace_prog)
		bpf_prog_put(replace_prog);
	cgroup_put(cgrp);
	return ret;
}

int cgroup_bpf_prog_detach(const union bpf_attr *attr, enum bpf_prog_type ptype)
{
	struct bpf_prog *prog;
	struct cgroup *cgrp;
	int ret;

	cgrp = cgroup_get_from_fd(attr->target_fd);
	if (IS_ERR(cgrp))
		return PTR_ERR(cgrp);

	prog = bpf_prog_get_type(attr->attach_bpf_fd, ptype);
	if (IS_ERR(prog))
		prog = NULL;

	ret = cgroup_bpf_detach(cgrp, prog, attr->attach_type);
	if (prog)
		bpf_prog_put(prog);

	cgroup_put(cgrp);
	return ret;
}

static void bpf_cgroup_link_release(struct bpf_link *link)
{
	struct bpf_cgroup_link *cg_link =
		container_of(link, struct bpf_cgroup_link, link);
	struct cgroup *cg;

	/* link might have been auto-detached by dying cgroup already,
	 * in that case our work is done here
	 */
	if (!cg_link->cgroup)
		return;

	cgroup_lock();

	/* re-check cgroup under lock again */
	if (!cg_link->cgroup) {
		cgroup_unlock();
		return;
	}

	WARN_ON(__cgroup_bpf_detach(cg_link->cgroup, NULL, cg_link,
				    cg_link->type));
	if (cg_link->type == BPF_LSM_CGROUP)
		bpf_trampoline_unlink_cgroup_shim(cg_link->link.prog);

	cg = cg_link->cgroup;
	cg_link->cgroup = NULL;

	cgroup_unlock();

	cgroup_put(cg);
}

static void bpf_cgroup_link_dealloc(struct bpf_link *link)
{
	struct bpf_cgroup_link *cg_link =
		container_of(link, struct bpf_cgroup_link, link);

	kfree(cg_link);
}

static int bpf_cgroup_link_detach(struct bpf_link *link)
{
	bpf_cgroup_link_release(link);

	return 0;
}

static void bpf_cgroup_link_show_fdinfo(const struct bpf_link *link,
					struct seq_file *seq)
{
	struct bpf_cgroup_link *cg_link =
		container_of(link, struct bpf_cgroup_link, link);
	u64 cg_id = 0;

	cgroup_lock();
	if (cg_link->cgroup)
		cg_id = cgroup_id(cg_link->cgroup);
	cgroup_unlock();

	seq_printf(seq,
		   "cgroup_id:\t%llu\n"
		   "attach_type:\t%d\n",
		   cg_id,
		   cg_link->type);
}

static int bpf_cgroup_link_fill_link_info(const struct bpf_link *link,
					  struct bpf_link_info *info)
{
	struct bpf_cgroup_link *cg_link =
		container_of(link, struct bpf_cgroup_link, link);
	u64 cg_id = 0;

	cgroup_lock();
	if (cg_link->cgroup)
		cg_id = cgroup_id(cg_link->cgroup);
	cgroup_unlock();

	info->cgroup.cgroup_id = cg_id;
	info->cgroup.attach_type = cg_link->type;
	return 0;
}

static const struct bpf_link_ops bpf_cgroup_link_lops = {
	.release = bpf_cgroup_link_release,
	.dealloc = bpf_cgroup_link_dealloc,
	.detach = bpf_cgroup_link_detach,
	.update_prog = cgroup_bpf_replace,
	.show_fdinfo = bpf_cgroup_link_show_fdinfo,
	.fill_link_info = bpf_cgroup_link_fill_link_info,
};

int cgroup_bpf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
{
	struct bpf_link_primer link_primer;
	struct bpf_cgroup_link *link;
	struct cgroup *cgrp;
	int err;

	if (attr->link_create.flags)
		return -EINVAL;

	cgrp = cgroup_get_from_fd(attr->link_create.target_fd);
	if (IS_ERR(cgrp))
		return PTR_ERR(cgrp);

	link = kzalloc(sizeof(*link), GFP_USER);
	if (!link) {
		err = -ENOMEM;
		goto out_put_cgroup;
	}
	bpf_link_init(&link->link, BPF_LINK_TYPE_CGROUP, &bpf_cgroup_link_lops,
		      prog);
	link->cgroup = cgrp;
	link->type = attr->link_create.attach_type;

	err = bpf_link_prime(&link->link, &link_primer);
	if (err) {
		kfree(link);
		goto out_put_cgroup;
	}

	err = cgroup_bpf_attach(cgrp, NULL, NULL, link,
				link->type, BPF_F_ALLOW_MULTI);
	if (err) {
		bpf_link_cleanup(&link_primer);
		goto out_put_cgroup;
	}

	return bpf_link_settle(&link_primer);

out_put_cgroup:
	cgroup_put(cgrp);
	return err;
}

int cgroup_bpf_prog_query(const union bpf_attr *attr,
			  union bpf_attr __user *uattr)
{
	struct cgroup *cgrp;
	int ret;

	cgrp = cgroup_get_from_fd(attr->query.target_fd);
	if (IS_ERR(cgrp))
		return PTR_ERR(cgrp);

	ret = cgroup_bpf_query(cgrp, attr, uattr);

	cgroup_put(cgrp);
	return ret;
}

/**
 * __cgroup_bpf_run_filter_skb() - Run a program for packet filtering
 * @sk: The socket sending or receiving traffic
 * @skb: The skb that is being sent or received
 * @atype: The type of program to be executed
 *
 * If no socket is passed, or the socket is not of type INET or INET6,
 * this function does nothing and returns 0.
 *
 * The program type passed in via @type must be suitable for network
 * filtering. No further check is performed to assert that.
 *
 * For egress packets, this function can return:
 *   NET_XMIT_SUCCESS    (0)	- continue with packet output
 *   NET_XMIT_DROP       (1)	- drop packet and notify TCP to call cwr
 *   NET_XMIT_CN         (2)	- continue with packet output and notify TCP
 *				  to call cwr
 *   -err			- drop packet
 *
 * For ingress packets, this function will return -EPERM if any
 * attached program was found and if it returned != 1 during execution.
 * Otherwise 0 is returned.
 */
int __cgroup_bpf_run_filter_skb(struct sock *sk,
				struct sk_buff *skb,
				enum cgroup_bpf_attach_type atype)
{
	unsigned int offset = -skb_network_offset(skb);
	struct sock *save_sk;
	void *saved_data_end;
	struct cgroup *cgrp;
	int ret;

	if (sk->sk_family != AF_INET && sk->sk_family != AF_INET6)
		return 0;

	cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
	save_sk = skb->sk;
	skb->sk = sk;
	__skb_push(skb, offset);

	/* compute pointers for the bpf prog */
	bpf_compute_and_save_data_end(skb, &saved_data_end);

	if (atype == CGROUP_INET_EGRESS) {
		u32 flags = 0;
		bool cn;

		ret = bpf_prog_run_array_cg(&cgrp->bpf, atype, skb,
					    __bpf_prog_run_save_cb, 0, &flags);

		/* Return values of CGROUP EGRESS BPF programs are:
		 *   0: drop packet
		 *   1: keep packet
		 *   2: drop packet and cn
		 *   3: keep packet and cn
		 *
		 * The returned value is then converted to one of the NET_XMIT
		 * or an error code that is then interpreted as drop packet
		 * (and no cn):
		 *   0: NET_XMIT_SUCCESS  skb should be transmitted
		 *   1: NET_XMIT_DROP     skb should be dropped and cn
		 *   2: NET_XMIT_CN       skb should be transmitted and cn
		 *   3: -err              skb should be dropped
		 */

		cn = flags & BPF_RET_SET_CN;
		if (ret && !IS_ERR_VALUE((long)ret))
			ret = -EFAULT;
		if (!ret)
			ret = (cn ? NET_XMIT_CN : NET_XMIT_SUCCESS);
		else
			ret = (cn ? NET_XMIT_DROP : ret);
	} else {
		ret = bpf_prog_run_array_cg(&cgrp->bpf, atype,
					    skb, __bpf_prog_run_save_cb, 0,
					    NULL);
		if (ret && !IS_ERR_VALUE((long)ret))
			ret = -EFAULT;
	}
	bpf_restore_data_end(skb, saved_data_end);
	__skb_pull(skb, offset);
	skb->sk = save_sk;

	return ret;
}
EXPORT_SYMBOL(__cgroup_bpf_run_filter_skb);

/**
 * __cgroup_bpf_run_filter_sk() - Run a program on a sock
 * @sk: sock structure to manipulate
 * @atype: The type of program to be executed
 *
 * socket is passed is expected to be of type INET or INET6.
 *
 * The program type passed in via @type must be suitable for sock
 * filtering. No further check is performed to assert that.
 *
 * This function will return %-EPERM if any if an attached program was found
 * and if it returned != 1 during execution. In all other cases, 0 is returned.
 */
int __cgroup_bpf_run_filter_sk(struct sock *sk,
			       enum cgroup_bpf_attach_type atype)
{
	struct cgroup *cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);

	return bpf_prog_run_array_cg(&cgrp->bpf, atype, sk, bpf_prog_run, 0,
				     NULL);
}
EXPORT_SYMBOL(__cgroup_bpf_run_filter_sk);

/**
 * __cgroup_bpf_run_filter_sock_addr() - Run a program on a sock and
 *                                       provided by user sockaddr
 * @sk: sock struct that will use sockaddr
 * @uaddr: sockaddr struct provided by user
 * @uaddrlen: Pointer to the size of the sockaddr struct provided by user. It is
 *            read-only for AF_INET[6] uaddr but can be modified for AF_UNIX
 *            uaddr.
 * @atype: The type of program to be executed
 * @t_ctx: Pointer to attach type specific context
 * @flags: Pointer to u32 which contains higher bits of BPF program
 *         return value (OR'ed together).
 *
 * socket is expected to be of type INET, INET6 or UNIX.
 *
 * This function will return %-EPERM if an attached program is found and
 * returned value != 1 during execution. In all other cases, 0 is returned.
 */
int __cgroup_bpf_run_filter_sock_addr(struct sock *sk,
				      struct sockaddr *uaddr,
				      int *uaddrlen,
				      enum cgroup_bpf_attach_type atype,
				      void *t_ctx,
				      u32 *flags)
{
	struct bpf_sock_addr_kern ctx = {
		.sk = sk,
		.uaddr = uaddr,
		.t_ctx = t_ctx,
	};
	struct sockaddr_storage unspec;
	struct cgroup *cgrp;
	int ret;

	/* Check socket family since not all sockets represent network
	 * endpoint (e.g. AF_UNIX).
	 */
	if (sk->sk_family != AF_INET && sk->sk_family != AF_INET6 &&
	    sk->sk_family != AF_UNIX)
		return 0;

	if (!ctx.uaddr) {
		memset(&unspec, 0, sizeof(unspec));
		ctx.uaddr = (struct sockaddr *)&unspec;
		ctx.uaddrlen = 0;
	} else {
		ctx.uaddrlen = *uaddrlen;
	}

	cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
	ret = bpf_prog_run_array_cg(&cgrp->bpf, atype, &ctx, bpf_prog_run,
				    0, flags);

	if (!ret && uaddr)
		*uaddrlen = ctx.uaddrlen;

	return ret;
}
EXPORT_SYMBOL(__cgroup_bpf_run_filter_sock_addr);

/**
 * __cgroup_bpf_run_filter_sock_ops() - Run a program on a sock
 * @sk: socket to get cgroup from
 * @sock_ops: bpf_sock_ops_kern struct to pass to program. Contains
 * sk with connection information (IP addresses, etc.) May not contain
 * cgroup info if it is a req sock.
 * @atype: The type of program to be executed
 *
 * socket passed is expected to be of type INET or INET6.
 *
 * The program type passed in via @type must be suitable for sock_ops
 * filtering. No further check is performed to assert that.
 *
 * This function will return %-EPERM if any if an attached program was found
 * and if it returned != 1 during execution. In all other cases, 0 is returned.
 */
int __cgroup_bpf_run_filter_sock_ops(struct sock *sk,
				     struct bpf_sock_ops_kern *sock_ops,
				     enum cgroup_bpf_attach_type atype)
{
	struct cgroup *cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);

	return bpf_prog_run_array_cg(&cgrp->bpf, atype, sock_ops, bpf_prog_run,
				     0, NULL);
}
EXPORT_SYMBOL(__cgroup_bpf_run_filter_sock_ops);

int __cgroup_bpf_check_dev_permission(short dev_type, u32 major, u32 minor,
				      short access, enum cgroup_bpf_attach_type atype)
{
	struct cgroup *cgrp;
	struct bpf_cgroup_dev_ctx ctx = {
		.access_type = (access << 16) | dev_type,
		.major = major,
		.minor = minor,
	};
	int ret;

	rcu_read_lock();
	cgrp = task_dfl_cgroup(current);
	ret = bpf_prog_run_array_cg(&cgrp->bpf, atype, &ctx, bpf_prog_run, 0,
				    NULL);
	rcu_read_unlock();

	return ret;
}

BPF_CALL_2(bpf_get_local_storage, struct bpf_map *, map, u64, flags)
{
	/* flags argument is not used now,
	 * but provides an ability to extend the API.
	 * verifier checks that its value is correct.
	 */
	enum bpf_cgroup_storage_type stype = cgroup_storage_type(map);
	struct bpf_cgroup_storage *storage;
	struct bpf_cg_run_ctx *ctx;
	void *ptr;

	/* get current cgroup storage from BPF run context */
	ctx = container_of(current->bpf_ctx, struct bpf_cg_run_ctx, run_ctx);
	storage = ctx->prog_item->cgroup_storage[stype];

	if (stype == BPF_CGROUP_STORAGE_SHARED)
		ptr = &READ_ONCE(storage->buf)->data[0];
	else
		ptr = this_cpu_ptr(storage->percpu_buf);

	return (unsigned long)ptr;
}

const struct bpf_func_proto bpf_get_local_storage_proto = {
	.func		= bpf_get_local_storage,
	.gpl_only	= false,
	.ret_type	= RET_PTR_TO_MAP_VALUE,
	.arg1_type	= ARG_CONST_MAP_PTR,
	.arg2_type	= ARG_ANYTHING,
};

BPF_CALL_0(bpf_get_retval)
{
	struct bpf_cg_run_ctx *ctx =
		container_of(current->bpf_ctx, struct bpf_cg_run_ctx, run_ctx);

	return ctx->retval;
}

const struct bpf_func_proto bpf_get_retval_proto = {
	.func		= bpf_get_retval,
	.gpl_only	= false,
	.ret_type	= RET_INTEGER,
};

BPF_CALL_1(bpf_set_retval, int, retval)
{
	struct bpf_cg_run_ctx *ctx =
		container_of(current->bpf_ctx, struct bpf_cg_run_ctx, run_ctx);

	ctx->retval = retval;
	return 0;
}

const struct bpf_func_proto bpf_set_retval_proto = {
	.func		= bpf_set_retval,
	.gpl_only	= false,
	.ret_type	= RET_INTEGER,
	.arg1_type	= ARG_ANYTHING,
};

static const struct bpf_func_proto *
cgroup_dev_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
	const struct bpf_func_proto *func_proto;

	func_proto = cgroup_common_func_proto(func_id, prog);
	if (func_proto)
		return func_proto;

	switch (func_id) {
	case BPF_FUNC_perf_event_output:
		return &bpf_event_output_data_proto;
	default:
		return bpf_base_func_proto(func_id, prog);
	}
}

static bool cgroup_dev_is_valid_access(int off, int size,
				       enum bpf_access_type type,
				       const struct bpf_prog *prog,
				       struct bpf_insn_access_aux *info)
{
	const int size_default = sizeof(__u32);

	if (type == BPF_WRITE)
		return false;

	if (off < 0 || off + size > sizeof(struct bpf_cgroup_dev_ctx))
		return false;
	/* The verifier guarantees that size > 0. */
	if (off % size != 0)
		return false;

	switch (off) {
	case bpf_ctx_range(struct bpf_cgroup_dev_ctx, access_type):
		bpf_ctx_record_field_size(info, size_default);
		if (!bpf_ctx_narrow_access_ok(off, size, size_default))
			return false;
		break;
	default:
		if (size != size_default)
			return false;
	}

	return true;
}

const struct bpf_prog_ops cg_dev_prog_ops = {
};

const struct bpf_verifier_ops cg_dev_verifier_ops = {
	.get_func_proto		= cgroup_dev_func_proto,
	.is_valid_access	= cgroup_dev_is_valid_access,
};

/**
 * __cgroup_bpf_run_filter_sysctl - Run a program on sysctl
 *
 * @head: sysctl table header
 * @table: sysctl table
 * @write: sysctl is being read (= 0) or written (= 1)
 * @buf: pointer to buffer (in and out)
 * @pcount: value-result argument: value is size of buffer pointed to by @buf,
 *	result is size of @new_buf if program set new value, initial value
 *	otherwise
 * @ppos: value-result argument: value is position at which read from or write
 *	to sysctl is happening, result is new position if program overrode it,
 *	initial value otherwise
 * @atype: type of program to be executed
 *
 * Program is run when sysctl is being accessed, either read or written, and
 * can allow or deny such access.
 *
 * This function will return %-EPERM if an attached program is found and
 * returned value != 1 during execution. In all other cases 0 is returned.
 */
int __cgroup_bpf_run_filter_sysctl(struct ctl_table_header *head,
				   const struct ctl_table *table, int write,
				   char **buf, size_t *pcount, loff_t *ppos,
				   enum cgroup_bpf_attach_type atype)
{
	struct bpf_sysctl_kern ctx = {
		.head = head,
		.table = table,
		.write = write,
		.ppos = ppos,
		.cur_val = NULL,
		.cur_len = PAGE_SIZE,
		.new_val = NULL,
		.new_len = 0,
		.new_updated = 0,
	};
	struct cgroup *cgrp;
	loff_t pos = 0;
	int ret;

	ctx.cur_val = kmalloc_track_caller(ctx.cur_len, GFP_KERNEL);
	if (!ctx.cur_val ||
	    table->proc_handler(table, 0, ctx.cur_val, &ctx.cur_len, &pos)) {
		/* Let BPF program decide how to proceed. */
		ctx.cur_len = 0;
	}

	if (write && *buf && *pcount) {
		/* BPF program should be able to override new value with a
		 * buffer bigger than provided by user.
		 */
		ctx.new_val = kmalloc_track_caller(PAGE_SIZE, GFP_KERNEL);
		ctx.new_len = min_t(size_t, PAGE_SIZE, *pcount);
		if (ctx.new_val) {
			memcpy(ctx.new_val, *buf, ctx.new_len);
		} else {
			/* Let BPF program decide how to proceed. */
			ctx.new_len = 0;
		}
	}

	rcu_read_lock();
	cgrp = task_dfl_cgroup(current);
	ret = bpf_prog_run_array_cg(&cgrp->bpf, atype, &ctx, bpf_prog_run, 0,
				    NULL);
	rcu_read_unlock();

	kfree(ctx.cur_val);

	if (ret == 1 && ctx.new_updated) {
		kfree(*buf);
		*buf = ctx.new_val;
		*pcount = ctx.new_len;
	} else {
		kfree(ctx.new_val);
	}

	return ret;
}

#ifdef CONFIG_NET
static int sockopt_alloc_buf(struct bpf_sockopt_kern *ctx, int max_optlen,
			     struct bpf_sockopt_buf *buf)
{
	if (unlikely(max_optlen < 0))
		return -EINVAL;

	if (unlikely(max_optlen > PAGE_SIZE)) {
		/* We don't expose optvals that are greater than PAGE_SIZE
		 * to the BPF program.
		 */
		max_optlen = PAGE_SIZE;
	}

	if (max_optlen <= sizeof(buf->data)) {
		/* When the optval fits into BPF_SOCKOPT_KERN_BUF_SIZE
		 * bytes avoid the cost of kzalloc.
		 */
		ctx->optval = buf->data;
		ctx->optval_end = ctx->optval + max_optlen;
		return max_optlen;
	}

	ctx->optval = kzalloc(max_optlen, GFP_USER);
	if (!ctx->optval)
		return -ENOMEM;

	ctx->optval_end = ctx->optval + max_optlen;

	return max_optlen;
}

static void sockopt_free_buf(struct bpf_sockopt_kern *ctx,
			     struct bpf_sockopt_buf *buf)
{
	if (ctx->optval == buf->data)
		return;
	kfree(ctx->optval);
}

static bool sockopt_buf_allocated(struct bpf_sockopt_kern *ctx,
				  struct bpf_sockopt_buf *buf)
{
	return ctx->optval != buf->data;
}

int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level,
				       int *optname, sockptr_t optval,
				       int *optlen, char **kernel_optval)
{
	struct cgroup *cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
	struct bpf_sockopt_buf buf = {};
	struct bpf_sockopt_kern ctx = {
		.sk = sk,
		.level = *level,
		.optname = *optname,
	};
	int ret, max_optlen;

	/* Allocate a bit more than the initial user buffer for
	 * BPF program. The canonical use case is overriding
	 * TCP_CONGESTION(nv) to TCP_CONGESTION(cubic).
	 */
	max_optlen = max_t(int, 16, *optlen);
	max_optlen = sockopt_alloc_buf(&ctx, max_optlen, &buf);
	if (max_optlen < 0)
		return max_optlen;

	ctx.optlen = *optlen;

	if (copy_from_sockptr(ctx.optval, optval,
			      min(*optlen, max_optlen))) {
		ret = -EFAULT;
		goto out;
	}

	lock_sock(sk);
	ret = bpf_prog_run_array_cg(&cgrp->bpf, CGROUP_SETSOCKOPT,
				    &ctx, bpf_prog_run, 0, NULL);
	release_sock(sk);

	if (ret)
		goto out;

	if (ctx.optlen == -1) {
		/* optlen set to -1, bypass kernel */
		ret = 1;
	} else if (ctx.optlen > max_optlen || ctx.optlen < -1) {
		/* optlen is out of bounds */
		if (*optlen > PAGE_SIZE && ctx.optlen >= 0) {
			pr_info_once("bpf setsockopt: ignoring program buffer with optlen=%d (max_optlen=%d)\n",
				     ctx.optlen, max_optlen);
			ret = 0;
			goto out;
		}
		ret = -EFAULT;
	} else {
		/* optlen within bounds, run kernel handler */
		ret = 0;

		/* export any potential modifications */
		*level = ctx.level;
		*optname = ctx.optname;

		/* optlen == 0 from BPF indicates that we should
		 * use original userspace data.
		 */
		if (ctx.optlen != 0) {
			*optlen = ctx.optlen;
			/* We've used bpf_sockopt_kern->buf as an intermediary
			 * storage, but the BPF program indicates that we need
			 * to pass this data to the kernel setsockopt handler.
			 * No way to export on-stack buf, have to allocate a
			 * new buffer.
			 */
			if (!sockopt_buf_allocated(&ctx, &buf)) {
				void *p = kmalloc(ctx.optlen, GFP_USER);

				if (!p) {
					ret = -ENOMEM;
					goto out;
				}
				memcpy(p, ctx.optval, ctx.optlen);
				*kernel_optval = p;
			} else {
				*kernel_optval = ctx.optval;
			}
			/* export and don't free sockopt buf */
			return 0;
		}
	}

out:
	sockopt_free_buf(&ctx, &buf);
	return ret;
}

int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
				       int optname, sockptr_t optval,
				       sockptr_t optlen, int max_optlen,
				       int retval)
{
	struct cgroup *cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
	struct bpf_sockopt_buf buf = {};
	struct bpf_sockopt_kern ctx = {
		.sk = sk,
		.level = level,
		.optname = optname,
		.current_task = current,
	};
	int orig_optlen;
	int ret;

	orig_optlen = max_optlen;
	ctx.optlen = max_optlen;
	max_optlen = sockopt_alloc_buf(&ctx, max_optlen, &buf);
	if (max_optlen < 0)
		return max_optlen;

	if (!retval) {
		/* If kernel getsockopt finished successfully,
		 * copy whatever was returned to the user back
		 * into our temporary buffer. Set optlen to the
		 * one that kernel returned as well to let
		 * BPF programs inspect the value.
		 */
		if (copy_from_sockptr(&ctx.optlen, optlen,
				      sizeof(ctx.optlen))) {
			ret = -EFAULT;
			goto out;
		}

		if (ctx.optlen < 0) {
			ret = -EFAULT;
			goto out;
		}
		orig_optlen = ctx.optlen;

		if (copy_from_sockptr(ctx.optval, optval,
				      min(ctx.optlen, max_optlen))) {
			ret = -EFAULT;
			goto out;
		}
	}

	lock_sock(sk);
	ret = bpf_prog_run_array_cg(&cgrp->bpf, CGROUP_GETSOCKOPT,
				    &ctx, bpf_prog_run, retval, NULL);
	release_sock(sk);

	if (ret < 0)
		goto out;

	if (!sockptr_is_null(optval) &&
	    (ctx.optlen > max_optlen || ctx.optlen < 0)) {
		if (orig_optlen > PAGE_SIZE && ctx.optlen >= 0) {
			pr_info_once("bpf getsockopt: ignoring program buffer with optlen=%d (max_optlen=%d)\n",
				     ctx.optlen, max_optlen);
			ret = retval;
			goto out;
		}
		ret = -EFAULT;
		goto out;
	}

	if (ctx.optlen != 0) {
		if (!sockptr_is_null(optval) &&
		    copy_to_sockptr(optval, ctx.optval, ctx.optlen)) {
			ret = -EFAULT;
			goto out;
		}
		if (copy_to_sockptr(optlen, &ctx.optlen, sizeof(ctx.optlen))) {
			ret = -EFAULT;
			goto out;
		}
	}

out:
	sockopt_free_buf(&ctx, &buf);
	return ret;
}

int __cgroup_bpf_run_filter_getsockopt_kern(struct sock *sk, int level,
					    int optname, void *optval,
					    int *optlen, int retval)
{
	struct cgroup *cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data);
	struct bpf_sockopt_kern ctx = {
		.sk = sk,
		.level = level,
		.optname = optname,
		.optlen = *optlen,
		.optval = optval,
		.optval_end = optval + *optlen,
		.current_task = current,
	};
	int ret;

	/* Note that __cgroup_bpf_run_filter_getsockopt doesn't copy
	 * user data back into BPF buffer when reval != 0. This is
	 * done as an optimization to avoid extra copy, assuming
	 * kernel won't populate the data in case of an error.
	 * Here we always pass the data and memset() should
	 * be called if that data shouldn't be "exported".
	 */

	ret = bpf_prog_run_array_cg(&cgrp->bpf, CGROUP_GETSOCKOPT,
				    &ctx, bpf_prog_run, retval, NULL);
	if (ret < 0)
		return ret;

	if (ctx.optlen > *optlen)
		return -EFAULT;

	/* BPF programs can shrink the buffer, export the modifications.
	 */
	if (ctx.optlen != 0)
		*optlen = ctx.optlen;

	return ret;
}
#endif

static ssize_t sysctl_cpy_dir(const struct ctl_dir *dir, char **bufp,
			      size_t *lenp)
{
	ssize_t tmp_ret = 0, ret;

	if (dir->header.parent) {
		tmp_ret = sysctl_cpy_dir(dir->header.parent, bufp, lenp);
		if (tmp_ret < 0)
			return tmp_ret;
	}

	ret = strscpy(*bufp, dir->header.ctl_table[0].procname, *lenp);
	if (ret < 0)
		return ret;
	*bufp += ret;
	*lenp -= ret;
	ret += tmp_ret;

	/* Avoid leading slash. */
	if (!ret)
		return ret;

	tmp_ret = strscpy(*bufp, "/", *lenp);
	if (tmp_ret < 0)
		return tmp_ret;
	*bufp += tmp_ret;
	*lenp -= tmp_ret;

	return ret + tmp_ret;
}

BPF_CALL_4(bpf_sysctl_get_name, struct bpf_sysctl_kern *, ctx, char *, buf,
	   size_t, buf_len, u64, flags)
{
	ssize_t tmp_ret = 0, ret;

	if (!buf)
		return -EINVAL;

	if (!(flags & BPF_F_SYSCTL_BASE_NAME)) {
		if (!ctx->head)
			return -EINVAL;
		tmp_ret = sysctl_cpy_dir(ctx->head->parent, &buf, &buf_len);
		if (tmp_ret < 0)
			return tmp_ret;
	}

	ret = strscpy(buf, ctx->table->procname, buf_len);

	return ret < 0 ? ret : tmp_ret + ret;
}

static const struct bpf_func_proto bpf_sysctl_get_name_proto = {
	.func		= bpf_sysctl_get_name,
	.gpl_only	= false,
	.ret_type	= RET_INTEGER,
	.arg1_type	= ARG_PTR_TO_CTX,
	.arg2_type	= ARG_PTR_TO_MEM | MEM_WRITE,
	.arg3_type	= ARG_CONST_SIZE,
	.arg4_type	= ARG_ANYTHING,
};

static int copy_sysctl_value(char *dst, size_t dst_len, char *src,
			     size_t src_len)
{
	if (!dst)
		return -EINVAL;

	if (!dst_len)
		return -E2BIG;

	if (!src || !src_len) {
		memset(dst, 0, dst_len);
		return -EINVAL;
	}

	memcpy(dst, src, min(dst_len, src_len));

	if (dst_len > src_len) {
		memset(dst + src_len, '\0', dst_len - src_len);
		return src_len;
	}

	dst[dst_len - 1] = '\0';

	return -E2BIG;
}

BPF_CALL_3(bpf_sysctl_get_current_value, struct bpf_sysctl_kern *, ctx,
	   char *, buf, size_t, buf_len)
{
	return copy_sysctl_value(buf, buf_len, ctx->cur_val, ctx->cur_len);
}

static const struct bpf_func_proto bpf_sysctl_get_current_value_proto = {
	.func		= bpf_sysctl_get_current_value,
	.gpl_only	= false,
	.ret_type	= RET_INTEGER,
	.arg1_type	= ARG_PTR_TO_CTX,
	.arg2_type	= ARG_PTR_TO_UNINIT_MEM,
	.arg3_type	= ARG_CONST_SIZE,
};

BPF_CALL_3(bpf_sysctl_get_new_value, struct bpf_sysctl_kern *, ctx, char *, buf,
	   size_t, buf_len)
{
	if (!ctx->write) {
		if (buf && buf_len)
			memset(buf, '\0', buf_len);
		return -EINVAL;
	}
	return copy_sysctl_value(buf, buf_len, ctx->new_val, ctx->new_len);
}

static const struct bpf_func_proto bpf_sysctl_get_new_value_proto = {
	.func		= bpf_sysctl_get_new_value,
	.gpl_only	= false,
	.ret_type	= RET_INTEGER,
	.arg1_type	= ARG_PTR_TO_CTX,
	.arg2_type	= ARG_PTR_TO_UNINIT_MEM,
	.arg3_type	= ARG_CONST_SIZE,
};

BPF_CALL_3(bpf_sysctl_set_new_value, struct bpf_sysctl_kern *, ctx,
	   const char *, buf, size_t, buf_len)
{
	if (!ctx->write || !ctx->new_val || !ctx->new_len || !buf || !buf_len)
		return -EINVAL;

	if (buf_len > PAGE_SIZE - 1)
		return -E2BIG;

	memcpy(ctx->new_val, buf, buf_len);
	ctx->new_len = buf_len;
	ctx->new_updated = 1;

	return 0;
}

static const struct bpf_func_proto bpf_sysctl_set_new_value_proto = {
	.func		= bpf_sysctl_set_new_value,
	.gpl_only	= false,
	.ret_type	= RET_INTEGER,
	.arg1_type	= ARG_PTR_TO_CTX,
	.arg2_type	= ARG_PTR_TO_MEM | MEM_RDONLY,
	.arg3_type	= ARG_CONST_SIZE,
};

static const struct bpf_func_proto *
sysctl_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
	const struct bpf_func_proto *func_proto;

	func_proto = cgroup_common_func_proto(func_id, prog);
	if (func_proto)
		return func_proto;

	switch (func_id) {
	case BPF_FUNC_sysctl_get_name:
		return &bpf_sysctl_get_name_proto;
	case BPF_FUNC_sysctl_get_current_value:
		return &bpf_sysctl_get_current_value_proto;
	case BPF_FUNC_sysctl_get_new_value:
		return &bpf_sysctl_get_new_value_proto;
	case BPF_FUNC_sysctl_set_new_value:
		return &bpf_sysctl_set_new_value_proto;
	case BPF_FUNC_ktime_get_coarse_ns:
		return &bpf_ktime_get_coarse_ns_proto;
	case BPF_FUNC_perf_event_output:
		return &bpf_event_output_data_proto;
	default:
		return bpf_base_func_proto(func_id, prog);
	}
}

static bool sysctl_is_valid_access(int off, int size, enum bpf_access_type type,
				   const struct bpf_prog *prog,
				   struct bpf_insn_access_aux *info)
{
	const int size_default = sizeof(__u32);

	if (off < 0 || off + size > sizeof(struct bpf_sysctl) || off % size)
		return false;

	switch (off) {
	case bpf_ctx_range(struct bpf_sysctl, write):
		if (type != BPF_READ)
			return false;
		bpf_ctx_record_field_size(info, size_default);
		return bpf_ctx_narrow_access_ok(off, size, size_default);
	case bpf_ctx_range(struct bpf_sysctl, file_pos):
		if (type == BPF_READ) {
			bpf_ctx_record_field_size(info, size_default);
			return bpf_ctx_narrow_access_ok(off, size, size_default);
		} else {
			return size == size_default;
		}
	default:
		return false;
	}
}

static u32 sysctl_convert_ctx_access(enum bpf_access_type type,
				     const struct bpf_insn *si,
				     struct bpf_insn *insn_buf,
				     struct bpf_prog *prog, u32 *target_size)
{
	struct bpf_insn *insn = insn_buf;
	u32 read_size;

	switch (si->off) {
	case offsetof(struct bpf_sysctl, write):
		*insn++ = BPF_LDX_MEM(
			BPF_SIZE(si->code), si->dst_reg, si->src_reg,
			bpf_target_off(struct bpf_sysctl_kern, write,
				       sizeof_field(struct bpf_sysctl_kern,
						    write),
				       target_size));
		break;
	case offsetof(struct bpf_sysctl, file_pos):
		/* ppos is a pointer so it should be accessed via indirect
		 * loads and stores. Also for stores additional temporary
		 * register is used since neither src_reg nor dst_reg can be
		 * overridden.
		 */
		if (type == BPF_WRITE) {
			int treg = BPF_REG_9;

			if (si->src_reg == treg || si->dst_reg == treg)
				--treg;
			if (si->src_reg == treg || si->dst_reg == treg)
				--treg;
			*insn++ = BPF_STX_MEM(
				BPF_DW, si->dst_reg, treg,
				offsetof(struct bpf_sysctl_kern, tmp_reg));
			*insn++ = BPF_LDX_MEM(
				BPF_FIELD_SIZEOF(struct bpf_sysctl_kern, ppos),
				treg, si->dst_reg,
				offsetof(struct bpf_sysctl_kern, ppos));
			*insn++ = BPF_RAW_INSN(
				BPF_CLASS(si->code) | BPF_MEM | BPF_SIZEOF(u32),
				treg, si->src_reg,
				bpf_ctx_narrow_access_offset(
					0, sizeof(u32), sizeof(loff_t)),
				si->imm);
			*insn++ = BPF_LDX_MEM(
				BPF_DW, treg, si->dst_reg,
				offsetof(struct bpf_sysctl_kern, tmp_reg));
		} else {
			*insn++ = BPF_LDX_MEM(
				BPF_FIELD_SIZEOF(struct bpf_sysctl_kern, ppos),
				si->dst_reg, si->src_reg,
				offsetof(struct bpf_sysctl_kern, ppos));
			read_size = bpf_size_to_bytes(BPF_SIZE(si->code));
			*insn++ = BPF_LDX_MEM(
				BPF_SIZE(si->code), si->dst_reg, si->dst_reg,
				bpf_ctx_narrow_access_offset(
					0, read_size, sizeof(loff_t)));
		}
		*target_size = sizeof(u32);
		break;
	}

	return insn - insn_buf;
}

const struct bpf_verifier_ops cg_sysctl_verifier_ops = {
	.get_func_proto		= sysctl_func_proto,
	.is_valid_access	= sysctl_is_valid_access,
	.convert_ctx_access	= sysctl_convert_ctx_access,
};

const struct bpf_prog_ops cg_sysctl_prog_ops = {
};

#ifdef CONFIG_NET
BPF_CALL_1(bpf_get_netns_cookie_sockopt, struct bpf_sockopt_kern *, ctx)
{
	const struct net *net = ctx ? sock_net(ctx->sk) : &init_net;

	return net->net_cookie;
}

static const struct bpf_func_proto bpf_get_netns_cookie_sockopt_proto = {
	.func		= bpf_get_netns_cookie_sockopt,
	.gpl_only	= false,
	.ret_type	= RET_INTEGER,
	.arg1_type	= ARG_PTR_TO_CTX_OR_NULL,
};
#endif

static const struct bpf_func_proto *
cg_sockopt_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
	const struct bpf_func_proto *func_proto;

	func_proto = cgroup_common_func_proto(func_id, prog);
	if (func_proto)
		return func_proto;

	switch (func_id) {
#ifdef CONFIG_NET
	case BPF_FUNC_get_netns_cookie:
		return &bpf_get_netns_cookie_sockopt_proto;
	case BPF_FUNC_sk_storage_get:
		return &bpf_sk_storage_get_proto;
	case BPF_FUNC_sk_storage_delete:
		return &bpf_sk_storage_delete_proto;
	case BPF_FUNC_setsockopt:
		if (prog->expected_attach_type == BPF_CGROUP_SETSOCKOPT)
			return &bpf_sk_setsockopt_proto;
		return NULL;
	case BPF_FUNC_getsockopt:
		if (prog->expected_attach_type == BPF_CGROUP_SETSOCKOPT)
			return &bpf_sk_getsockopt_proto;
		return NULL;
#endif
#ifdef CONFIG_INET
	case BPF_FUNC_tcp_sock:
		return &bpf_tcp_sock_proto;
#endif
	case BPF_FUNC_perf_event_output:
		return &bpf_event_output_data_proto;
	default:
		return bpf_base_func_proto(func_id, prog);
	}
}

static bool cg_sockopt_is_valid_access(int off, int size,
				       enum bpf_access_type type,
				       const struct bpf_prog *prog,
				       struct bpf_insn_access_aux *info)
{
	const int size_default = sizeof(__u32);

	if (off < 0 || off >= sizeof(struct bpf_sockopt))
		return false;

	if (off % size != 0)
		return false;

	if (type == BPF_WRITE) {
		switch (off) {
		case offsetof(struct bpf_sockopt, retval):
			if (size != size_default)
				return false;
			return prog->expected_attach_type ==
				BPF_CGROUP_GETSOCKOPT;
		case offsetof(struct bpf_sockopt, optname):
			fallthrough;
		case offsetof(struct bpf_sockopt, level):
			if (size != size_default)
				return false;
			return prog->expected_attach_type ==
				BPF_CGROUP_SETSOCKOPT;
		case offsetof(struct bpf_sockopt, optlen):
			return size == size_default;
		default:
			return false;
		}
	}

	switch (off) {
	case bpf_ctx_range_ptr(struct bpf_sockopt, sk):
		if (size != sizeof(__u64))
			return false;
		info->reg_type = PTR_TO_SOCKET;
		break;
	case bpf_ctx_range_ptr(struct bpf_sockopt, optval):
		if (size != sizeof(__u64))
			return false;
		info->reg_type = PTR_TO_PACKET;
		break;
	case bpf_ctx_range_ptr(struct bpf_sockopt, optval_end):
		if (size != sizeof(__u64))
			return false;
		info->reg_type = PTR_TO_PACKET_END;
		break;
	case bpf_ctx_range(struct bpf_sockopt, retval):
		if (size != size_default)
			return false;
		return prog->expected_attach_type == BPF_CGROUP_GETSOCKOPT;
	default:
		if (size != size_default)
			return false;
		break;
	}
	return true;
}

#define CG_SOCKOPT_READ_FIELD(F)					\
	BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_sockopt_kern, F),	\
		    si->dst_reg, si->src_reg,				\
		    offsetof(struct bpf_sockopt_kern, F))

#define CG_SOCKOPT_WRITE_FIELD(F)					\
	BPF_RAW_INSN((BPF_FIELD_SIZEOF(struct bpf_sockopt_kern, F) |	\
		      BPF_MEM | BPF_CLASS(si->code)),			\
		     si->dst_reg, si->src_reg,				\
		     offsetof(struct bpf_sockopt_kern, F),		\
		     si->imm)

static u32 cg_sockopt_convert_ctx_access(enum bpf_access_type type,
					 const struct bpf_insn *si,
					 struct bpf_insn *insn_buf,
					 struct bpf_prog *prog,
					 u32 *target_size)
{
	struct bpf_insn *insn = insn_buf;

	switch (si->off) {
	case offsetof(struct bpf_sockopt, sk):
		*insn++ = CG_SOCKOPT_READ_FIELD(sk);
		break;
	case offsetof(struct bpf_sockopt, level):
		if (type == BPF_WRITE)
			*insn++ = CG_SOCKOPT_WRITE_FIELD(level);
		else
			*insn++ = CG_SOCKOPT_READ_FIELD(level);
		break;
	case offsetof(struct bpf_sockopt, optname):
		if (type == BPF_WRITE)
			*insn++ = CG_SOCKOPT_WRITE_FIELD(optname);
		else
			*insn++ = CG_SOCKOPT_READ_FIELD(optname);
		break;
	case offsetof(struct bpf_sockopt, optlen):
		if (type == BPF_WRITE)
			*insn++ = CG_SOCKOPT_WRITE_FIELD(optlen);
		else
			*insn++ = CG_SOCKOPT_READ_FIELD(optlen);
		break;
	case offsetof(struct bpf_sockopt, retval):
		BUILD_BUG_ON(offsetof(struct bpf_cg_run_ctx, run_ctx) != 0);

		if (type == BPF_WRITE) {
			int treg = BPF_REG_9;

			if (si->src_reg == treg || si->dst_reg == treg)
				--treg;
			if (si->src_reg == treg || si->dst_reg == treg)
				--treg;
			*insn++ = BPF_STX_MEM(BPF_DW, si->dst_reg, treg,
					      offsetof(struct bpf_sockopt_kern, tmp_reg));
			*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_sockopt_kern, current_task),
					      treg, si->dst_reg,
					      offsetof(struct bpf_sockopt_kern, current_task));
			*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct task_struct, bpf_ctx),
					      treg, treg,
					      offsetof(struct task_struct, bpf_ctx));
			*insn++ = BPF_RAW_INSN(BPF_CLASS(si->code) | BPF_MEM |
					       BPF_FIELD_SIZEOF(struct bpf_cg_run_ctx, retval),
					       treg, si->src_reg,
					       offsetof(struct bpf_cg_run_ctx, retval),
					       si->imm);
			*insn++ = BPF_LDX_MEM(BPF_DW, treg, si->dst_reg,
					      offsetof(struct bpf_sockopt_kern, tmp_reg));
		} else {
			*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_sockopt_kern, current_task),
					      si->dst_reg, si->src_reg,
					      offsetof(struct bpf_sockopt_kern, current_task));
			*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct task_struct, bpf_ctx),
					      si->dst_reg, si->dst_reg,
					      offsetof(struct task_struct, bpf_ctx));
			*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct bpf_cg_run_ctx, retval),
					      si->dst_reg, si->dst_reg,
					      offsetof(struct bpf_cg_run_ctx, retval));
		}
		break;
	case offsetof(struct bpf_sockopt, optval):
		*insn++ = CG_SOCKOPT_READ_FIELD(optval);
		break;
	case offsetof(struct bpf_sockopt, optval_end):
		*insn++ = CG_SOCKOPT_READ_FIELD(optval_end);
		break;
	}

	return insn - insn_buf;
}

static int cg_sockopt_get_prologue(struct bpf_insn *insn_buf,
				   bool direct_write,
				   const struct bpf_prog *prog)
{
	/* Nothing to do for sockopt argument. The data is kzalloc'ated.
	 */
	return 0;
}

const struct bpf_verifier_ops cg_sockopt_verifier_ops = {
	.get_func_proto		= cg_sockopt_func_proto,
	.is_valid_access	= cg_sockopt_is_valid_access,
	.convert_ctx_access	= cg_sockopt_convert_ctx_access,
	.gen_prologue		= cg_sockopt_get_prologue,
};

const struct bpf_prog_ops cg_sockopt_prog_ops = {
};

/* Common helpers for cgroup hooks. */
const struct bpf_func_proto *
cgroup_common_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
	switch (func_id) {
	case BPF_FUNC_get_local_storage:
		return &bpf_get_local_storage_proto;
	case BPF_FUNC_get_retval:
		switch (prog->expected_attach_type) {
		case BPF_CGROUP_INET_INGRESS:
		case BPF_CGROUP_INET_EGRESS:
		case BPF_CGROUP_SOCK_OPS:
		case BPF_CGROUP_UDP4_RECVMSG:
		case BPF_CGROUP_UDP6_RECVMSG:
		case BPF_CGROUP_UNIX_RECVMSG:
		case BPF_CGROUP_INET4_GETPEERNAME:
		case BPF_CGROUP_INET6_GETPEERNAME:
		case BPF_CGROUP_UNIX_GETPEERNAME:
		case BPF_CGROUP_INET4_GETSOCKNAME:
		case BPF_CGROUP_INET6_GETSOCKNAME:
		case BPF_CGROUP_UNIX_GETSOCKNAME:
			return NULL;
		default:
			return &bpf_get_retval_proto;
		}
	case BPF_FUNC_set_retval:
		switch (prog->expected_attach_type) {
		case BPF_CGROUP_INET_INGRESS:
		case BPF_CGROUP_INET_EGRESS:
		case BPF_CGROUP_SOCK_OPS:
		case BPF_CGROUP_UDP4_RECVMSG:
		case BPF_CGROUP_UDP6_RECVMSG:
		case BPF_CGROUP_UNIX_RECVMSG:
		case BPF_CGROUP_INET4_GETPEERNAME:
		case BPF_CGROUP_INET6_GETPEERNAME:
		case BPF_CGROUP_UNIX_GETPEERNAME:
		case BPF_CGROUP_INET4_GETSOCKNAME:
		case BPF_CGROUP_INET6_GETSOCKNAME:
		case BPF_CGROUP_UNIX_GETSOCKNAME:
			return NULL;
		default:
			return &bpf_set_retval_proto;
		}
	default:
		return NULL;
	}
}
