Re: [PATCH] Fix "fuser" command to properly deal with an invalid argument

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

 



On 2023/04/07 10:37, HAGIO KAZUHITO(萩尾 一仁) wrote:
> On 2023/04/06 16:54, lijiang wrote:
>> On Thu, Apr 6, 2023 at 11:03 AM HAGIO KAZUHITO(萩尾 一仁) <k-hagio-ab@xxxxxxx>
>> wrote:
>>
>>> On 2023/04/04 18:37, Lianbo Jiang wrote:
>>>> The man page of the "fuser" command suggests that the argument can be a
>>>> full pathname or inode address. However, the "fuser" command accepts an
>>>> invalid argument and prints a bogus result as below:
>>>>
>>>>      crash> fuser x
>>>>       PID         TASK        COMM             USAGE
>>>>      100507  ffff9914431f4c80  "packagekitd"    fd
>>>>      100508  ffff991574e59980  "gmain"          fd
>>>>      100509  ffff9914431f3300  "gdbus"          fd
>>>>      102020  ffff991574400000  "sshd"           fd
>>>>      102043  ffff991441d19980  "sshd"           fd
>>>>
>>>> The current fuser command has no checking mechanism to determine if an
>>>> argument is valid or not. Lets add it to handle such cases.
>>>>
>>>> In addition, the fuser can also accept the dentry and file address, for
>>>> example:
>>>>
>>>>      crash> files -d ffff894d826e7240
>>>>           DENTRY           INODE           SUPERBLK     TYPE PATH
>>>>      ffff894d826e7240 ffff894d805b7520 ffff894d80ce5000 REG
>>> /root/proc/kcore
>>>>      crash> fuser ffff894d826e7240
>>>>       PID         TASK        COMM             USAGE
>>>>      1237273  ffff89502ddf0000  "crash"          fd
>>>>      1237280  ffff895079cb0000  "gdb worker"     fd
>>>>      1237281  ffff894f9a124000  "gdb worker"     fd
>>>>      1237282  ffff895017a28000  "gdb worker"     fd
>>>>      1237283  ffff894d89c40000  "gdb worker"     fd
>>>>      ...
>>>>
>>>> Essentially, the fuser command still calls the vm(vm_area_dump())
>>>> and files(open_files_dump()) commands(see foreach()) to achieve
>>>> this goal. So the man page needs to be updated, and there is no
>>>> functional change.
>>>>
>>>> With the patch:
>>>>      crash> fuser -n x
>>>>      fuser: invalid file name: x
>>>>      crash> fuser -p x
>>>>      fuser: invalid virtual address: x
>>>>
>>>>      crash> fuser -p 0xffff894d826e7240
>>>>       PID         TASK        COMM             USAGE
>>>>      1237273  ffff89502ddf0000  "crash"          fd
>>>>      1237280  ffff895079cb0000  "gdb worker"     fd
>>>>      1237281  ffff894f9a124000  "gdb worker"     fd
>>>>      1237282  ffff895017a28000  "gdb worker"     fd
>>>>      1237283  ffff894d89c40000  "gdb worker"     fd
>>>>      ...
>>>
>>> Sorry, but I don't understand why you chose this big interface change,
>>>
>>
>> The initial intent is to make a distinction between an address and a
>> string(file name), so that we can easily check if the argument is valid.
> 
> Yes, I see your intent.  but I thought that the check itself would be
> not so hard, for example, something like this.
> 
>       ulong spec_addr;
>       spec_addr = htol(spec_string, RETURN_ON_ERROR|QUIET, NULL);
>       if ((spec_addr == BADADDR || !IS_KVADDR(spec_addr)) &&
>           spec_string[0] != '/')
>               error(FATAL, "invalid argument: %s\n", args[optind]);
> 
>>
>>
>>
>>> that requires an option, doesn't accept multiple args and has the -f
>>
>>
>> The displaying result of multiple args looks not very clear(confused). This
>> was replaced with a single arg in the patch, but it still can get similar
>> results by running the fuser command repeatedly, and looks cleaner.
> 
> um, this is a detail, not the point I meant, but I agree that multiple
> args may be not so useful.  so we may change it to not accept multiple
> args, but if we do so, at least it needs a discussion separately and a
> description about it in the commit log.
> 
>>
>>
>>> option that does not look useful to me.  Who wants the vm_flags search?
>>>
>>>
>> Agree with you. But I cannot prevent this situation because someone is
>> using it like this. :-) For example:
>>
>> crash> vm -f 8000075
>> 8000075: (READ|EXEC|MAYREAD|MAYWRITE|MAYEXEC|CAN_NONLINEAR)
>> crash> fuser 8000075
>>    PID         TASK        COMM             USAGE
>>       1  ffff894d80270000  "systemd"        mmap
>>     548  ffff894d8789c000  "systemd-journa  mmap
>>     561  ffff894d841bc000  "systemd-udevd"  mmap
>>     685  ffff894d819b8000  "systemd-oomd"   mmap
>>     686  ffff894d885a0000  "systemd-resolv  mmap
>>     687  ffff894d871cc000  "systemd-userdb  mmap
>>     688  ffff894d841b4000  "auditd"         mmap
>>     689  ffff894d85810000  "auditd"         mmap
>>     713  ffff894d84e04000  "avahi-daemon"   mmap
>>     714  ffff894d84e08000  "bluetoothd"     mmap
>>     717  ffff894d84e0c000  "mcelog"         mmap
>>     718  ffff894d84060000  "polkitd"        mmap
>>     719  ffff894d8c174000  "power-profiles  mmap
>>     720  ffff894da2084000  "rtkit-daemon"   mmap
>>     723  ffff894da2088000  "accounts-daemo  mmap
>>     724  ffff894da208c000  "switcheroo-con  mmap
>>     726  ffff894d86c40000  "systemd-logind  mmap
>>     728  ffff894d8719c000  "systemd-machin  mmap
>> ...
> 
> Isn't this prevented by the check above?
> 
>>
>>
>>> (Personally I think that the user that runs "fuser x" knows what they
>>> did, so it prints some but they will just ignore the result.  It does
>>
>>
>> Agree, but that is an ideal situation.
>>
>>
>>> not look so bad to me in the first place..  but ok, there may be some
>>> confusion with valid addresses.)
>>>
>>> Can't we handle it better like this?
>>>
>>> (1) add some check for arg
>>>          if arg is not KVADDR || arg does not starts with '/'
>>>             error out
>>>
>>>
>> Tried it. But actually the current fuser command still can accept a single
>> file name(without full pathname arg) as below:
> 
> sorry, (1) was a wrong condition.  I meant the above check in this
> email.  The fuser command uses strstr() to search targets, so it may
> need some trick to match paths exactly, though.
> 
>> crash> fuser crash
>>    PID         TASK        COMM             USAGE
>>    2760  ffff894ef2204000  "bash"           cwd
>>    5772  ffff894d80d34000  "bash"           cwd
>> 153672  ffff8952abd14000  "bash"           cwd
>> 270976  ffff89534e500000  "bash"           cwd
>> 482087  ffff894e1660c000  "bash"           cwd
>> 580499  ffff89518a160000  "vim"            cwd
>> ...
>>
>> For example:
>> [1] fuser x
>> [2] fuser 0
>> [3] fuser 00
>> [4] fuser CHR
>> [5] fuser CWD
>> [6] fuser ROOT
>> [7] fuser root
>> ...
>>
>> (2) add a supplementary description that it can be used for dentry or filp.

This might be not good...

The "vm" command in the "fuser" additionally prints the inode of files
for "USAGE" output, but does not print dentry and etc.:

       VMA           START       END     FLAGS FILE
ffff90194db51de8 561b62898000 561b628be000 8000875 ffff900d4d239ac8 /usr/bin/less
ffff90194db50ae0 561b62abd000 561b62abe000 8100871 ffff900d4d239ac8 /usr/bin/less
ffff901877eb43a0 561b62abe000 561b62ac2000 8100873 ffff900d4d239ac8 /usr/bin/less
                                                    ^^^^^^^^^^^^^^^^

So the "fuser" outputs with an inode and dentry are different:

crash-dev> files 3426630
PID: 3426630  TASK: ffff9017ce46b080  CPU: 0    COMMAND: "less"  <<-- $ less /usr/bin/less :-)
ROOT: /    CWD: /root
  FD       FILE            DENTRY           INODE       TYPE PATH
   0 ffff9011fabd9400 ffff901119214cc0 ffff900bbda8faf0 CHR  /dev/pts/1
   1 ffff9011fabd9400 ffff901119214cc0 ffff900bbda8faf0 CHR  /dev/pts/1
   2 ffff9011fabd9400 ffff901119214cc0 ffff900bbda8faf0 CHR  /dev/pts/1
   3 ffff90194dbeea00 ffff900b47875a40 ffff901abe07aa70 CHR  /dev/tty
   4 ffff90194dbeee00 ffff901a3699a780 ffff900d4d239ac8 REG  /usr/bin/less

crash-dev> fuser ffff900d4d239ac8 <<-- inode
  PID         TASK        COMM             USAGE
3426630  ffff9017ce46b080  "less"           fd mmap  <<-- there is mmap.
...
crash-dev> fuser ffff901a3699a780 <<-- dentry
  PID         TASK        COMM             USAGE
3426630  ffff9017ce46b080  "less"           fd       <<-- no mmap.


So the fuser does expect that arguments are inodes or full paths.

So if we write a supplementary note,

"This command does not expect arguments other than inodes or full paths.
If others specified, it prints a false output."

this might be close to the real?

Thanks,
Kazu


>>>
>>>
>> Good idea, partially updated to the man page.
>>
>> In addition, the fuser command can also accept the following address args:
>>
>> [1] struct inode address
>> [2] struct dentry address
>> [3] struct file address
>> [4] struct vm_area_struct(VMA) address
>> [5] struct vm_area_struct.vm_start value
>> [6] struct vm_area_struct.vm_end value
>> [7] struct vm_area_struct.vm_flags value
>> ...
> 
> Some of these also can be prevented by the IS_KVADDR check?
> 
>>
>> I don't think that the help text must explain perfectly how it works.
>>> Introducing a strange interface to satisfy it is giving priority to a
>>> less important thing, I think.
>>>
>>>
>> That depends on how you think about it. From the perspective of users and
>> testing, the above cases seem reasonable. And It's not easy to cover these
>> cases without the interface changes.
> 
> sorry, I lacked words..
> The current "fuser" command just uses strstr() to search for targets.
> It's true that it's kind of a rough search and some unexpected values
> can be detected.  The vm_flags is an example.  The "fuser" is to search
> for inodes originally and so far there is no requirement to search for
> vm_flags.  So it's strange to introduce that option, just because the
> current fuser command detects vm_flags.
> 
>> But anyway, adding documents to prevent unusual usage is the easiest
>> solution. Any thoughts?
> 
> It might be good to add a description about the fuser's behavior, too.
> This is a rough one though:
> The "fuser" command almost just does strstr() for "files" and "vm"
> output and its output can contain some errors or noises, and kind of a
> rough search.  So it's better for users to check each task's detail
> output for sure with the "files" and "vm" commands.
> 
> Thanks,
> Kazu
> --
> Crash-utility mailing list
> Crash-utility@xxxxxxxxxx
> https://listman.redhat.com/mailman/listinfo/crash-utility
> Contribution Guidelines: https://github.com/crash-utility/crash/wiki
--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://listman.redhat.com/mailman/listinfo/crash-utility
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux