Search code examples
clinuxfile-permissions

"Sticky bit" is only for directories? I found it could be on files, weird


The samples from web sites says "sticky bit" is for directories, e.g.

$ ll /tmp
drwxrwxrwt 16 root root   4096 1月   2 15:45 ./

We can see the execution permission of /tmp is "t", everyone can execute, but certain directories can be operated only by either "root" or its owner.

So my previous understanding was, this file permission flag is only for directories, but not for files. However, I ran into this problem when I was using "open" function to create a file, I don't specify any file permissions as 3rd parameter, so my program was:

#include<fcntl.h>
#include<unistd.h>
int main()
{
    int f1=open("./mytest_c1.txt",O_CREAT|O_RDWR);
    write(f1,"abc xyz\n",8);
    close(f1);
    return 0;
}

After execution, I got a file like this:

--wxr-x--T 1 x x     8 1月   2 11:38 mytest_c1.txt*

Weird, here's an upper case "T".

  1. How did I generate this "T" flag? I didn't specify anything.
  2. What's the difference from the lower case "t"?

So I continued my experiment, I removed the "write" statement, as to be:

#include<fcntl.h>
#include<unistd.h>
int main()
{
    int f1=open("./mytest_c2.txt",O_CREAT|O_RDWR);
    close(f1);
    return 0;
}

The running result created another file:

-rw---x--T 1 x x     0 1月   2 15:59 mytest_c2.txt*

This time, ever weird-er. The file permission of mytest_c2.txt is different from mytest_c1.txt.

Where does this difference come from? I didn't specify anything in my program!


Solution

  • This is incorrect:

    int f1=open("./mytest_c1.txt",O_CREAT|O_RDWR);
    

    This statement invokes undefined behavior (UB). Whenever you use open(2) with flags that include O_CREAT, you must (as stated in the manpages) specify the file mode. The sticky bits you are seeing are result of something unexpected happening because of UB.

    Now, a few other points that are interesting:

    We can see the execution permission of /tmp is "t", everyone can execute, but certain directories can be operated only by either "root" or its owner.

    That's not wrong, but it's a bit misleading. To be more precise, if a directory has a sticky bit (e.g., /tmp usually does), that means that anyone can create files in that directory, but only the owner (and root, because root can do pretty much anything) can modify or exclude the file, once it has been created.

    Next:

    The samples from web sites says "sticky bit" is for directories, e.g.

    Also, not wrong again, but a bit misleading. Sticky bits can be applied to files, but Linux simply ignores them.