@@ -140,17 +140,18 @@ static void __bpf_selem_unlink_storage(struct bpf_local_storage_elem *selem){structbpf_local_storage*local_storage;boolfree_local_storage=false;+unsignedlongflags;if(unlikely(!selem_linked_to_storage(selem)))/* selem has already been unlinked from sk */return;local_storage=rcu_dereference(selem->local_storage);-raw_spin_lock_bh(&local_storage->lock);+raw_spin_lock_irqsave(&local_storage->lock,flags);
It will be useful to have a few words in commit message on this change
for future reference purpose.
Please also remove the in_irq() check from bpf_sk_storage.c
to avoid confusion in the future. It probably should
be in a separate patch.
[ ... ]
If exit_creds() is traced by a bpf and this bpf is doing
bpf_task_storage_get(..., BPF_LOCAL_STORAGE_GET_F_CREATE),
new task storage will be created after bpf_task_storage_free().
I recalled there was an earlier discussion with KP and KP mentioned
BPF_LSM will not be called with a task that is going away.
It seems enabling bpf task storage in bpf tracing will break
this assumption and needs to be addressed?
@@ -140,17 +140,18 @@ static void __bpf_selem_unlink_storage(struct bpf_local_storage_elem *selem){structbpf_local_storage*local_storage;boolfree_local_storage=false;+unsignedlongflags;if(unlikely(!selem_linked_to_storage(selem)))/* selem has already been unlinked from sk */return;local_storage=rcu_dereference(selem->local_storage);-raw_spin_lock_bh(&local_storage->lock);+raw_spin_lock_irqsave(&local_storage->lock,flags);
It will be useful to have a few words in commit message on this change
for future reference purpose.
Please also remove the in_irq() check from bpf_sk_storage.c
to avoid confusion in the future. It probably should
be in a separate patch.
[ ... ]
If exit_creds() is traced by a bpf and this bpf is doing
bpf_task_storage_get(..., BPF_LOCAL_STORAGE_GET_F_CREATE),
new task storage will be created after bpf_task_storage_free().
I recalled there was an earlier discussion with KP and KP mentioned
BPF_LSM will not be called with a task that is going away.
It seems enabling bpf task storage in bpf tracing will break
this assumption and needs to be addressed?
For tracing programs, I think we will need an allow list where
task local storage can be used.
@@ -140,17 +140,18 @@ static void __bpf_selem_unlink_storage(struct bpf_local_storage_elem *selem){structbpf_local_storage*local_storage;boolfree_local_storage=false;+unsignedlongflags;if(unlikely(!selem_linked_to_storage(selem)))/* selem has already been unlinked from sk */return;local_storage=rcu_dereference(selem->local_storage);-raw_spin_lock_bh(&local_storage->lock);+raw_spin_lock_irqsave(&local_storage->lock,flags);
It will be useful to have a few words in commit message on this change
for future reference purpose.
Please also remove the in_irq() check from bpf_sk_storage.c
to avoid confusion in the future. It probably should
be in a separate patch.
[ ... ]
If exit_creds() is traced by a bpf and this bpf is doing
bpf_task_storage_get(..., BPF_LOCAL_STORAGE_GET_F_CREATE),
new task storage will be created after bpf_task_storage_free().
I recalled there was an earlier discussion with KP and KP mentioned
BPF_LSM will not be called with a task that is going away.
It seems enabling bpf task storage in bpf tracing will break
this assumption and needs to be addressed?
For tracing programs, I think we will need an allow list where
task local storage can be used.
Instead of whitelist, can refcount_inc_not_zero(&tsk->usage) be used?
{
struct bpf_local_storage *local_storage;
bool free_local_storage = false;
+ unsigned long flags;
if (unlikely(!selem_linked_to_storage(selem)))
/* selem has already been unlinked from sk */
return;
local_storage = rcu_dereference(selem->local_storage);
- raw_spin_lock_bh(&local_storage->lock);
+ raw_spin_lock_irqsave(&local_storage->lock, flags);
It will be useful to have a few words in commit message on this change
for future reference purpose.
Please also remove the in_irq() check from bpf_sk_storage.c
to avoid confusion in the future. It probably should
be in a separate patch.
[ ... ]
If exit_creds() is traced by a bpf and this bpf is doing
bpf_task_storage_get(..., BPF_LOCAL_STORAGE_GET_F_CREATE),
new task storage will be created after bpf_task_storage_free().
I recalled there was an earlier discussion with KP and KP mentioned
BPF_LSM will not be called with a task that is going away.
It seems enabling bpf task storage in bpf tracing will break
this assumption and needs to be addressed?
For tracing programs, I think we will need an allow list where
task local storage can be used.
Instead of whitelist, can refcount_inc_not_zero(&tsk->usage) be used?
I think we can put refcount_inc_not_zero() in bpf_task_storage_get, like:
{
struct bpf_local_storage *local_storage;
bool free_local_storage = false;
+ unsigned long flags;
if (unlikely(!selem_linked_to_storage(selem)))
/* selem has already been unlinked from sk */
return;
local_storage = rcu_dereference(selem->local_storage);
- raw_spin_lock_bh(&local_storage->lock);
+ raw_spin_lock_irqsave(&local_storage->lock, flags);
It will be useful to have a few words in commit message on this change
for future reference purpose.
Please also remove the in_irq() check from bpf_sk_storage.c
to avoid confusion in the future. It probably should
be in a separate patch.
Do you mean we allow bpf_sk_storage_get_tracing() and
bpf_sk_storage_delete_tracing() in irq context? Like
{
struct bpf_local_storage *local_storage;
bool free_local_storage = false;
+ unsigned long flags;
if (unlikely(!selem_linked_to_storage(selem)))
/* selem has already been unlinked from sk */
return;
local_storage = rcu_dereference(selem->local_storage);
- raw_spin_lock_bh(&local_storage->lock);
+ raw_spin_lock_irqsave(&local_storage->lock, flags);
It will be useful to have a few words in commit message on this change
for future reference purpose.
Please also remove the in_irq() check from bpf_sk_storage.c
to avoid confusion in the future. It probably should
be in a separate patch.
[ ... ]
If exit_creds() is traced by a bpf and this bpf is doing
bpf_task_storage_get(..., BPF_LOCAL_STORAGE_GET_F_CREATE),
new task storage will be created after bpf_task_storage_free().
I recalled there was an earlier discussion with KP and KP mentioned
BPF_LSM will not be called with a task that is going away.
It seems enabling bpf task storage in bpf tracing will break
this assumption and needs to be addressed?
For tracing programs, I think we will need an allow list where
task local storage can be used.
Instead of whitelist, can refcount_inc_not_zero(&tsk->usage) be used?
I think we can put refcount_inc_not_zero() in bpf_task_storage_get, like:
If exit_creds() is traced by a bpf and this bpf is doing
bpf_task_storage_get(..., BPF_LOCAL_STORAGE_GET_F_CREATE),
new task storage will be created after bpf_task_storage_free().
I recalled there was an earlier discussion with KP and KP mentioned
BPF_LSM will not be called with a task that is going away.
It seems enabling bpf task storage in bpf tracing will break
this assumption and needs to be addressed?
For tracing programs, I think we will need an allow list where
task local storage can be used.
Instead of whitelist, can refcount_inc_not_zero(&tsk->usage) be used?
I think we can put refcount_inc_not_zero() in bpf_task_storage_get, like:
I may be missing something but shouldn't bpf_storage be an __rcu
member like we have for sk_bpf_storage?
#ifdef CONFIG_BPF_SYSCALL
struct bpf_local_storage __rcu *sk_bpf_storage;
#endif
{
struct bpf_local_storage *local_storage;
bool free_local_storage = false;
+ unsigned long flags;
if (unlikely(!selem_linked_to_storage(selem)))
/* selem has already been unlinked from sk */
return;
local_storage = rcu_dereference(selem->local_storage);
- raw_spin_lock_bh(&local_storage->lock);
+ raw_spin_lock_irqsave(&local_storage->lock, flags);
It will be useful to have a few words in commit message on this change
for future reference purpose.
Please also remove the in_irq() check from bpf_sk_storage.c
to avoid confusion in the future. It probably should
be in a separate patch.
Do you mean we allow bpf_sk_storage_get_tracing() and
bpf_sk_storage_delete_tracing() in irq context? Like
Right.
However, after another thought, may be lets skip that for now
till a use case comes up and a test can be written.
If exit_creds() is traced by a bpf and this bpf is doing
bpf_task_storage_get(..., BPF_LOCAL_STORAGE_GET_F_CREATE),
new task storage will be created after bpf_task_storage_free().
I recalled there was an earlier discussion with KP and KP mentioned
BPF_LSM will not be called with a task that is going away.
It seems enabling bpf task storage in bpf tracing will break
this assumption and needs to be addressed?
For tracing programs, I think we will need an allow list where
task local storage can be used.
Instead of whitelist, can refcount_inc_not_zero(&tsk->usage) be used?
I think we can put refcount_inc_not_zero() in bpf_task_storage_get, like:
If exit_creds() is traced by a bpf and this bpf is doing
bpf_task_storage_get(..., BPF_LOCAL_STORAGE_GET_F_CREATE),
new task storage will be created after bpf_task_storage_free().
I recalled there was an earlier discussion with KP and KP mentioned
BPF_LSM will not be called with a task that is going away.
It seems enabling bpf task storage in bpf tracing will break
this assumption and needs to be addressed?
For tracing programs, I think we will need an allow list where
task local storage can be used.
Instead of whitelist, can refcount_inc_not_zero(&tsk->usage) be used?
I think we can put refcount_inc_not_zero() in bpf_task_storage_get, like:
If exit_creds() is traced by a bpf and this bpf is doing
bpf_task_storage_get(..., BPF_LOCAL_STORAGE_GET_F_CREATE),
new task storage will be created after bpf_task_storage_free().
I recalled there was an earlier discussion with KP and KP mentioned
BPF_LSM will not be called with a task that is going away.
It seems enabling bpf task storage in bpf tracing will break
this assumption and needs to be addressed?
For tracing programs, I think we will need an allow list where
task local storage can be used.
Instead of whitelist, can refcount_inc_not_zero(&tsk->usage) be used?
I think we can put refcount_inc_not_zero() in bpf_task_storage_get, like:
@@ -216,6 +216,10 @@ BPF_CALL_4(bpf_task_storage_get, struct bpf_map *, map, struct task_struct *,*byanRCUread-sidecriticalsection.*/if(flags&BPF_LOCAL_STORAGE_GET_F_CREATE){+/* the task_struct is being freed, fail over*/+if(!refcount_read(&task->usage))+return-EBUSY;
This may not work? Even we check here and task->usage is not 0, it could still become 0 immediately after the above refcount_read, right?
We call bpf_task_storage_get() with "task" that has valid BTF, so "task"
should not go away during the BPF program? Whatever mechanism that
triggers the BPF program should either hold a reference to task (usage > 0)
or be the only one owning it (usage == 0, in __put_task_struct). Did I miss
anything?
Thanks,
Song
If exit_creds() is traced by a bpf and this bpf is doing
bpf_task_storage_get(..., BPF_LOCAL_STORAGE_GET_F_CREATE),
new task storage will be created after bpf_task_storage_free().
I recalled there was an earlier discussion with KP and KP mentioned
BPF_LSM will not be called with a task that is going away.
It seems enabling bpf task storage in bpf tracing will break
this assumption and needs to be addressed?
For tracing programs, I think we will need an allow list where
task local storage can be used.
Instead of whitelist, can refcount_inc_not_zero(&tsk->usage) be used?
I think we can put refcount_inc_not_zero() in bpf_task_storage_get, like:
@@ -216,6 +216,10 @@ BPF_CALL_4(bpf_task_storage_get, struct bpf_map *, map, struct task_struct *,*byanRCUread-sidecriticalsection.*/if(flags&BPF_LOCAL_STORAGE_GET_F_CREATE){+/* the task_struct is being freed, fail over*/+if(!refcount_read(&task->usage))+return-EBUSY;
This may not work? Even we check here and task->usage is not 0, it could still become 0 immediately after the above refcount_read, right?
We call bpf_task_storage_get() with "task" that has valid BTF, so "task"
should not go away during the BPF program? Whatever mechanism that
Oh, right. this is true. Otherwise, we cannot use task ptr in the helper.
triggers the BPF program should either hold a reference to task (usage > 0)
or be the only one owning it (usage == 0, in __put_task_struct). Did I miss
anything?
Sorry. I think you are right. Not sure lsm requirement. There are two
more possible ways to check task is exiting which happens before
__put_task_struct():
. check task->exit_state
. check task->flags & PF_EXITING (used in bpf_trace.c)
Not sure which condition is the correct one to check.