2

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!

giusti
  • 3,156
  • 3
  • 29
  • 44
Troskyvs
  • 7,537
  • 7
  • 47
  • 115

2 Answers2

4

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.

Community
  • 1
  • 1
giusti
  • 3,156
  • 3
  • 29
  • 44
1

Difference: That denotes sticky bit and in the t version execute bit is set and in T execute bit is unset.

Reason: Linux inherits permission from parent directory (If you set an ACL on a directory, only the files inside that directory inherit the ACL. If you create a subdirectory, it does not get the parent ACL unless the ACL is set to recurse) so in this case the folder in which the file is ...for that sticky bit is set. That's why newly created file inherits it.

For my case ACL is set to recurse. For OP's case too that is set to recurse otherwise it won't inherit parent's the ACL of parent.

user2736738
  • 30,591
  • 5
  • 42
  • 56
  • *Linux inherits permission from parent directory so in this case the folder in which the file is ...for that sticky bit is set.*: I'm not so sure. I ran OP's code, and it didn't set the sticky bit. – giusti Jan 03 '17 at 02:54
  • @giusti.: It did for me...just checked. – user2736738 Jan 03 '17 at 02:57
  • Interesting... I removed the created file and ran OP's code again. Got different results. Some times I get the sticky bit, sometimes I don't. I wonder if there's something wrong with OP's code. – giusti Jan 03 '17 at 03:04
  • 1
    As expected [undefined behavior](http://stackoverflow.com/a/584455/782570)! If `O_CREAT` is used, then a mode must also be supplied. – giusti Jan 03 '17 at 03:10