Re: [PATCH bpf-next] bpf: Pass map file to .map_update_batch directly

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 11/8/2022 2:34 PM, Yonghong Song wrote:
>
>
> On 11/7/22 4:53 PM, Hou Tao wrote:
>> Hi,
>>
>> On 11/8/2022 8:08 AM, Yonghong Song wrote:
>>>
>>>
>>> On 11/6/22 11:55 PM, Hou Tao wrote:
>>>> From: Hou Tao <houtao1@xxxxxxxxxx>
>>>>
>>>> Currently generic_map_update_batch() will get map file from
>>>> attr->batch.map_fd and pass it to bpf_map_update_value(). The problem is
>>>> map_fd may have been closed or reopened as a different file type and
>>>> generic_map_update_batch() doesn't check the validity of map_fd.
>>>>
>>>> It doesn't incur any problem as for now, because only
>>>> BPF_MAP_TYPE_PERF_EVENT_ARRAY uses the passed map file and it doesn't
>>>> support batch update operation. But it is better to fix the potential
>>>> use of an invalid map file.
>>>
>>> I think we don't have problem here. The reason is in bpf_map_do_batch()
>>> we have
>>>      f = fdget(ufd);
>>>      ...
>>>      BPF_DO_BATCH(map->ops->map_update_batch);
>>>      fdput(f)
>>>
>>> So the original ufd is still valid during map->ops->map_update_batch
>>> which eventually may call generic_map_update_batch() which tries to
>>> do fdget(ufd) again.
>> The previous fdget() only guarantees the liveness of struct file. If the map fd
>> is closed by another thread concurrently, the fd will released by pick_file() as
>> show below:
>>
>> static struct file *pick_file(struct files_struct *files, unsigned fd)
>> {
>>          struct fdtable *fdt = files_fdtable(files);
>>          struct file *file;
>>
>>          file = fdt->fd[fd];
>>          if (file) {
>>                  rcu_assign_pointer(fdt->fd[fd], NULL);
>>                  __put_unused_fd(files, fd);
>>          }
>>          return file;
>> }
>>
>> So the second fdget(udf) may return a NULL file or a different file.
>
> Okay. Thanks for explanation. It would be great if you can describe
> the above reasoning clearly in the commit message since this is
> where the bug exists.
Will do in v2.
>
> Not sure why BPF_MAP_TYPE_PERF_EVENT_ARRAY matters here. Or you just
> show BPF_MAP_TYPE_PERF_EVENT_ARRAY does not have a problem. If this
> is the case, there is no need to mention it in the commit message.
I am trying to say that BPF_MAP_TYPE_PERF_EVENT_ARRAY  doesn't have a problem
now, but if we add batch update to it, it will have the problem, because only
BPF_MAP_TYPE_PERF_EVENT_ARRAY uses the passed map_file in .map_fd_get_ptr(). I
will remove the words from the commit message.
>
>>
>>>
>>> Did I miss anything here?
>>>
>>>>
>>>> Checking the validity of map file returned from fdget() in
>>>> generic_map_update_batch() can not fix the problem, because the returned
>>>> map file may be different with map file got in bpf_map_do_batch() due to
>>>> the reopening of fd, so just passing the map file directly to
>>>> .map_update_batch() in bpf_map_do_batch().
>>>>
>>>> Signed-off-by: Hou Tao <houtao1@xxxxxxxxxx>
> [...]




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux