3

I made a very simple program in C which writes "Test string" into file named "file.txt":

root@3:~# cat test.c
#include "unistd.h"
#include "string.h"
#include "stdio.h"

main()
{
  FILE *fp;
  int fd;

  fp = fopen("file.txt", "w");
  fd = fileno(fp);
  write(fd, "Test string\n", strlen("Test string\n"));
}
root@3:~#

I created a file named "file.txt" before I execute the test:

root@3:~# ls -l file.txt 
-r-------- 1 root root 0 sept  21 22:28 file.txt
root@3:~#

As seen above, file.txt has only read permissions. However, if I execute the test, the "Test string" is written into "file.txt":

root@3:~# strace ./test
execve("./test", ["./test"], [/* 22 vars */]) = 0
brk(0)                                  = 0x188d000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc03a44e000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=30251, ...}) = 0
mmap(NULL, 30251, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fc03a446000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\357\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1599504, ...}) = 0
mmap(NULL, 3713112, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fc039ea6000
mprotect(0x7fc03a028000, 2093056, PROT_NONE) = 0
mmap(0x7fc03a227000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x181000) = 0x7fc03a227000
mmap(0x7fc03a22c000, 18520, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fc03a22c000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc03a445000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc03a444000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fc03a443000
arch_prctl(ARCH_SET_FS, 0x7fc03a444700) = 0
mprotect(0x7fc03a227000, 16384, PROT_READ) = 0
mprotect(0x7fc03a450000, 4096, PROT_READ) = 0
munmap(0x7fc03a446000, 30251)           = 0
brk(0)                                  = 0x188d000
brk(0x18ae000)                          = 0x18ae000
open("file.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
write(3, "Test string\n", 12)           = 12
exit_group(12)                          = ?
root@3:~# cat file.txt
Test string
root@3:~# 

How can this happen?

6

You are able to write to the file because you are the root user. Consider the following:

> cat file.txt
> ls -al file.txt
-r--------  1 sdanna  staff  0 Sep 21 20:43 file.txt
> ./a.out
Segmentation fault: 11
> sudo ./a.out
> cat file.txt
Test string 

Here ./a.out is your presented program. As you can see, when I run the command as a normal user, I receive a segmentation fault as I try to operate on the null pointer returned by the failed fopen.

If I run the command as root it works fine. The root user can always write to the file unless the file's extended attributes are changed to prevent modification. The path_resolution(7) man page on linux, sums up the situation nicely:

On a traditional UNIX system, the superuser (root, user ID 0) is all- powerful, and bypasses all permissions restrictions when accessing files.

On Linux, superuser privileges are divided into capabilities (see capabilities(7)). Two capabilities are relevant for file permissions checks: CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH. (A process has these capabilities if its fsuid is 0.)

The CAP_DAC_OVERRIDE capability overrides all permission checking, but grants execute permission only when at least one of the file's three execute permission bits is set.

The CAP_DAC_READ_SEARCH capability grants read and search permission on directories, and read permission on ordinary files.

The root user on Linux has both of the required capabilities.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.