Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sinkap/1d213d17fb82a5e8ffdc3f320ec37d79 to your computer and use it in GitHub Desktop.
Save sinkap/1d213d17fb82a5e8ffdc3f320ec37d79 to your computer and use it in GitHub Desktop.
diff --git a/include/linux/bpf_lsm.h b/include/linux/bpf_lsm.h
index af74712af585..2499ff451857 100644
--- a/include/linux/bpf_lsm.h
+++ b/include/linux/bpf_lsm.h
@@ -17,9 +17,23 @@
#include <linux/lsm_hook_defs.h>
#undef LSM_HOOK
+struct bpf_lsm_storage {
+ struct bpf_local_storage __rcu *storage;
+};
+
+extern struct lsm_blob_sizes bpf_lsm_blob_sizes;
+
int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog,
const struct bpf_prog *prog);
+static inline struct bpf_lsm_storage *bpf_inode_storage(const struct inode *inode)
+{
+ if (unlikely(!inode->i_security))
+ return NULL;
+
+ return inode->i_security + bpf_lsm_blob_sizes.lbs_inode;
+}
+
#else /* !CONFIG_BPF_LSM */
static inline int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog,
diff --git a/kernel/bpf/bpf_local_storage.c b/kernel/bpf/bpf_local_storage.c
index 01dd8eb751da..3e12c1eaea58 100644
--- a/kernel/bpf/bpf_local_storage.c
+++ b/kernel/bpf/bpf_local_storage.c
@@ -13,6 +13,7 @@
#include <net/sock.h>
#include <uapi/linux/sock_diag.h>
#include <uapi/linux/btf.h>
+#include <linux/bpf_lsm.h>
static atomic_t cache_idx;
@@ -170,6 +171,7 @@ static struct bpf_local_storage_elem *sk_selem_alloc(
static void __unlink_local_storage(struct bpf_local_storage *local_storage,
bool uncharge_omem)
{
+ struct bpf_lsm_storage *bls;
struct inode *inode;
struct sock *sk;
@@ -186,8 +188,11 @@ static void __unlink_local_storage(struct bpf_local_storage *local_storage,
break;
case BPF_LOCAL_STORAGE_INODE:
inode = local_storage->inode;
- /* After this RCU_INIT, sk may be freed and cannot be used */
- RCU_INIT_POINTER(inode->inode_bpf_storage, NULL);
+ bls = bpf_inode_storage(inode);
+ if (!bls)
+ return;
+
+ RCU_INIT_POINTER(bls->storage, NULL);
local_storage->inode = NULL;
break;
}
@@ -356,8 +361,13 @@ static struct bpf_local_storage_data *inode_storage_lookup(
{
struct bpf_local_storage *inode_storage;
struct bpf_local_storage_map *smap;
+ struct bpf_lsm_storage *bls;
- inode_storage = rcu_dereference(inode->inode_bpf_storage);
+ bls = bpf_inode_storage(inode);
+ if (!bls)
+ return ERR_PTR(-ENOENT);
+
+ inode_storage = rcu_dereference(bls->storage);
if (!inode_storage)
return NULL;
@@ -465,9 +475,14 @@ static int inode_storage_alloc(struct inode *inode,
struct bpf_local_storage_map *smap,
struct bpf_local_storage_elem *first_selem)
{
+ struct bpf_lsm_storage *bls;
struct bpf_local_storage *curr;
int err;
+ bls = bpf_inode_storage(inode);
+ if (!bls)
+ return -EINVAL;
+
curr = bpf_local_storage_alloc(smap);
if (!curr)
return -ENOMEM;
@@ -479,7 +494,7 @@ static int inode_storage_alloc(struct inode *inode,
selem_link_map(smap, first_selem);
err = publish_local_storage(first_selem,
- (struct bpf_local_storage **)&inode->inode_bpf_storage, curr);
+ (struct bpf_local_storage **)&bls->storage, curr);
if (err) {
kfree(curr);
return err;
@@ -524,6 +539,7 @@ static struct bpf_local_storage_data *local_storage_update(
struct bpf_local_storage *local_storage;
struct bpf_local_storage_map *smap;
enum bpf_local_storage_type stype;
+ struct bpf_lsm_storage * bls;
struct inode *inode;
struct sock *sk;
int err;
@@ -545,7 +561,8 @@ static struct bpf_local_storage_data *local_storage_update(
break;
case BPF_LOCAL_STORAGE_INODE:
inode = owner;
- local_storage = rcu_dereference(inode->inode_bpf_storage);
+ bls = bpf_inode_storage(inode);
+ local_storage = rcu_dereference(bls->storage);
break;
}
@@ -742,10 +759,15 @@ void bpf_inode_storage_free(struct inode *inode)
struct bpf_local_storage_elem *selem;
struct bpf_local_storage *local_storage;
bool free_inode_storage = false;
+ struct bpf_lsm_storage *bls;
struct hlist_node *n;
rcu_read_lock();
- local_storage = rcu_dereference(inode->inode_bpf_storage);
+ bls = bpf_inode_storage(inode);
+ if (!bls)
+ return;
+
+ local_storage = rcu_dereference(bls->storage);
if (!local_storage) {
rcu_read_unlock();
return;
diff --git a/security/bpf/hooks.c b/security/bpf/hooks.c
index 32d32d485451..153f54c92e1c 100644
--- a/security/bpf/hooks.c
+++ b/security/bpf/hooks.c
@@ -3,14 +3,18 @@
/*
* Copyright (C) 2020 Google LLC.
*/
+#include <linux/bpf_local_storage.h>
#include <linux/lsm_hooks.h>
#include <linux/bpf_lsm.h>
+
+
static struct security_hook_list bpf_lsm_hooks[] __lsm_ro_after_init = {
#define LSM_HOOK(RET, DEFAULT, NAME, ...) \
LSM_HOOK_INIT(NAME, bpf_lsm_##NAME),
#include <linux/lsm_hook_defs.h>
#undef LSM_HOOK
+ LSM_HOOK_INIT(inode_free_security, bpf_inode_storage_free),
};
static int __init bpf_lsm_init(void)
@@ -20,7 +24,12 @@ static int __init bpf_lsm_init(void)
return 0;
}
+struct lsm_blob_sizes bpf_lsm_blob_sizes __lsm_ro_after_init = {
+ .lbs_inode = sizeof(struct bpf_lsm_storage),
+};
+
DEFINE_LSM(bpf) = {
.name = "bpf",
.init = bpf_lsm_init,
+ .blobs = &bpf_lsm_blob_sizes
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment