1. 13
  1. 3

    Great article. “Kernels should emphasize mechanism not policy. The problem is that currently there’s no mechanism for enforcing any policy (on filenames).” Since it’s a security issue, I would be thrilled if Linux added a way to enforce policy on the use of malicious filenames, and I would definitely configure my systems to use this new feature.

    1. 1

      I just looked at my own toy library for dealing with paths to check which things I reject … and I found this.

      The internet is really a small place. :-)

    2. 3

      when globbing/scanning, have the libraries prefix “./” to any filename beginning with “-”

      That’s not sound advice. If you’re passing an untrusted pathname to a shell command, you’d still be vulnerable to parameter and process expansion. Better to bypass the shell and call execve() directly.

      1. 1

        Not every technical document begins with multiple quotations, I don’t know if that’s a good thing.

        I once impressed a coworker by telling them how to rm a file beginning with a hyphen (I had just read about it 2 weeks previously).

        1. 2

          That was an interview question we used for a while. One guy said his preferred method was to cd up and nuke the whole directory.

          1. 2

            (This is a rewritten version of my original reply, as I cannot any longer edit it).

            One guy said his preferred method was to cd up and nuke the whole directory.

            Wow.

            The method I learned, and used when helping my coworker, was the -- option to rm.

            Nowadays rm seems to detect this and gives a help text:

            $ rm -testfile
            rm: invalid option -- 't'
            Try 'rm ./-testfile' to remove the file '-testfile'.
            Try 'rm --help' for more information.
            

            This option is included in this article https://kb.iu.edu/d/abao, which is high up on the search result for “linux remove file starting with dash”.

            Then there’s this “creative” solution:

            There are some characters that you cannot remove using any of the above methods, such as forward slashes, interpreted by Unix as directory separators. To remove a file with such meta-characters, you may have to FTP into the account containing the file from a separate account and enter the command:

            mdel

            You will be asked if you really wish to delete each file in the directory. Be sure to answer n (for no) for each file except the file containing the difficult character that you wish to delete.

            1. [Comment removed by author]

              1. 3

                That knowledge base article makes me a sad panda.

                There are some characters that you cannot remove using any of the above methods, such as forward slashes, interpreted by Unix as directory separators.

                Yes, slashes are directory separators at the filesystem level. If a filename contains one, you have a corrupted filesystem, and no system call can help you.

                you may have to FTP into the account containing the file from a separate account

                Why a separate account? Users probably only have a single account. This suggestion may be informed by a discomfort with recursion (which crops up other places, too).

                You will be asked if you really wish to delete each file in the directory. Be sure to answer n (for no) for each file except the file containing the difficult character that you wish to delete.

                Using this tip, you have (n - 1) opportunities to irrevocably delete a file you meant to keep. May as well cut FTP out of the loop and just run rm -i *. Better yet, run rm -i *foobar* to target just the one file.

                1. 2

                  There is a much easier way to handle filenames starting with dashes: just use a double dash (–) as the last parameter to the command, before the filename. This double dash signals ‘end of options’ and makes it possible to handle filenames containing dashes. Here’s an example:

                  frank@yetunde:~/testdir$ ls
                  frank@yetunde:~/testdir$ # notice the directory is empty
                  frank@yetunde:~/testdir$ touch -testfile # this will not work...
                  touch: invalid date format ‘estfile’
                  frank@yetunde:~/testdir$ touch -- -testfile # this DOES work
                  frank@yetunde:~/testdir$ ls
                  -testfile
                  frank@yetunde:~/testdir$ # notice the directory now 
                                             contains a file named -testfile
                  frank@yetunde:~/testdir$ rm -testfile # this, again, will not work
                  rm: invalid option -- 't'
                  Try 'rm ./-testfile' to remove the file '-testfile'.
                  Try 'rm --help' for more information.
                  frank@yetunde:~/testdir$ rm -- -testfile # ...while this DOES work
                  frank@yetunde:~/testdir$ ls
                  frank@yetunde:~/testdir$ # and the directory is empty again...
                  
                  1. 1

                    Thanks! I actually mentioned the double-dash option in my comment. Perhaps it wasn’t clear.

                    1. 1

                      It wasn’t to me because I read over it…

                      1. 1

                        I have rewritten my comment and deleted the original one you replied to. Thanks again for expanding on this.

                  2. 1

                    What magic system call is ftpd using to remove files that rm cannot?

                    1. 0

                      mdel just deletes all files, with a prompt. Answer “no” to the files you want to keep…

                    2. 1

                      My approach to deleting files with control characters and glob characters has always been to use

                      ls -i

                      and

                      find -inum $inode_goes_here -delete

                      or

                      -exec rm {} +

                      or

                      | xargs rm

                      But most often -delete.