Skip to content

Commit 27672f0

Browse files
sinkapborkmann
authored andcommitted
bpf: Add a BPF helper for getting the IMA hash of an inode
Provide a wrapper function to get the IMA hash of an inode. This helper is useful in fingerprinting files (e.g executables on execution) and using these fingerprints in detections like an executable unlinking itself. Since the ima_inode_hash can sleep, it's only allowed for sleepable LSM hooks. Signed-off-by: KP Singh <kpsingh@google.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Yonghong Song <yhs@fb.com> Link: https://lore.kernel.org/bpf/20201124151210.1081188-3-kpsingh@chromium.org
1 parent 403319b commit 27672f0

4 files changed

Lines changed: 50 additions & 0 deletions

File tree

include/uapi/linux/bpf.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3807,6 +3807,16 @@ union bpf_attr {
38073807
* See: **clock_gettime**\ (**CLOCK_MONOTONIC_COARSE**)
38083808
* Return
38093809
* Current *ktime*.
3810+
*
3811+
* long bpf_ima_inode_hash(struct inode *inode, void *dst, u32 size)
3812+
* Description
3813+
* Returns the stored IMA hash of the *inode* (if it's avaialable).
3814+
* If the hash is larger than *size*, then only *size*
3815+
* bytes will be copied to *dst*
3816+
* Return
3817+
* The **hash_algo** is returned on success,
3818+
* **-EOPNOTSUP** if IMA is disabled or **-EINVAL** if
3819+
* invalid arguments are passed.
38103820
*/
38113821
#define __BPF_FUNC_MAPPER(FN) \
38123822
FN(unspec), \
@@ -3970,6 +3980,7 @@ union bpf_attr {
39703980
FN(get_current_task_btf), \
39713981
FN(bprm_opts_set), \
39723982
FN(ktime_get_coarse_ns), \
3983+
FN(ima_inode_hash), \
39733984
/* */
39743985

39753986
/* integer value in 'imm' field of BPF_CALL instruction selects which helper

kernel/bpf/bpf_lsm.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <net/bpf_sk_storage.h>
1616
#include <linux/bpf_local_storage.h>
1717
#include <linux/btf_ids.h>
18+
#include <linux/ima.h>
1819

1920
/* For every LSM hook that allows attachment of BPF programs, declare a nop
2021
* function where a BPF program can be attached.
@@ -75,6 +76,29 @@ const static struct bpf_func_proto bpf_bprm_opts_set_proto = {
7576
.arg2_type = ARG_ANYTHING,
7677
};
7778

79+
BPF_CALL_3(bpf_ima_inode_hash, struct inode *, inode, void *, dst, u32, size)
80+
{
81+
return ima_inode_hash(inode, dst, size);
82+
}
83+
84+
static bool bpf_ima_inode_hash_allowed(const struct bpf_prog *prog)
85+
{
86+
return bpf_lsm_is_sleepable_hook(prog->aux->attach_btf_id);
87+
}
88+
89+
BTF_ID_LIST_SINGLE(bpf_ima_inode_hash_btf_ids, struct, inode)
90+
91+
const static struct bpf_func_proto bpf_ima_inode_hash_proto = {
92+
.func = bpf_ima_inode_hash,
93+
.gpl_only = false,
94+
.ret_type = RET_INTEGER,
95+
.arg1_type = ARG_PTR_TO_BTF_ID,
96+
.arg1_btf_id = &bpf_ima_inode_hash_btf_ids[0],
97+
.arg2_type = ARG_PTR_TO_UNINIT_MEM,
98+
.arg3_type = ARG_CONST_SIZE,
99+
.allowed = bpf_ima_inode_hash_allowed,
100+
};
101+
78102
static const struct bpf_func_proto *
79103
bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
80104
{
@@ -97,6 +121,8 @@ bpf_lsm_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
97121
return &bpf_task_storage_delete_proto;
98122
case BPF_FUNC_bprm_opts_set:
99123
return &bpf_bprm_opts_set_proto;
124+
case BPF_FUNC_ima_inode_hash:
125+
return prog->aux->sleepable ? &bpf_ima_inode_hash_proto : NULL;
100126
default:
101127
return tracing_prog_func_proto(func_id, prog);
102128
}

scripts/bpf_helpers_doc.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ class PrinterHelpers(Printer):
436436
'struct xdp_md',
437437
'struct path',
438438
'struct btf_ptr',
439+
'struct inode',
439440
]
440441
known_types = {
441442
'...',
@@ -480,6 +481,7 @@ class PrinterHelpers(Printer):
480481
'struct task_struct',
481482
'struct path',
482483
'struct btf_ptr',
484+
'struct inode',
483485
}
484486
mapped_types = {
485487
'u8': '__u8',

tools/include/uapi/linux/bpf.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3807,6 +3807,16 @@ union bpf_attr {
38073807
* See: **clock_gettime**\ (**CLOCK_MONOTONIC_COARSE**)
38083808
* Return
38093809
* Current *ktime*.
3810+
*
3811+
* long bpf_ima_inode_hash(struct inode *inode, void *dst, u32 size)
3812+
* Description
3813+
* Returns the stored IMA hash of the *inode* (if it's avaialable).
3814+
* If the hash is larger than *size*, then only *size*
3815+
* bytes will be copied to *dst*
3816+
* Return
3817+
* The **hash_algo** is returned on success,
3818+
* **-EOPNOTSUP** if IMA is disabled or **-EINVAL** if
3819+
* invalid arguments are passed.
38103820
*/
38113821
#define __BPF_FUNC_MAPPER(FN) \
38123822
FN(unspec), \
@@ -3970,6 +3980,7 @@ union bpf_attr {
39703980
FN(get_current_task_btf), \
39713981
FN(bprm_opts_set), \
39723982
FN(ktime_get_coarse_ns), \
3983+
FN(ima_inode_hash), \
39733984
/* */
39743985

39753986
/* integer value in 'imm' field of BPF_CALL instruction selects which helper

0 commit comments

Comments
 (0)