Apart from usual read, write, and execute file permissions, Linux documents (files) have another set of attribute that control other characteristics of the file.
Permissions and Attributes
In Linux, who can access a file and what they can do with it is controlled by a
user-centric set of permissions. Whether you can read the contents of a file, write new data into the file,
or execute a file if it is a script or a program, is all
governed by that set of permissions. The permissions are applied to the file, but they define the
restrictions and capabilities for different categories of
user.
There are permissions for the owner of the
file, for the group of the file, and for others—that is, users who are not in
the first two categories. You can use the ls command with the -l (long listing) option to see the permissions on a file or directory.
We can see that file permissions are user-centeric because they have choices to remove permissions at the user level. By contrast, the attributes of a file system centric. Like persmissions, they're set on the file or directory. But once they're set, they're the same for all users.
Attrbiutes are a separate collection of settings from permissions. Attributes control characteristics such as immutability and other file system-level behaviors. To see the attributes of a file or directory we use the lsattr command. To set the attributes we use the chattr command.
Inode File system
Permissions and attributes are stored inside inodes. An inode is a file system structure that holds
information about file system objects such as files and directories. A file’s
location on the hard drive, its creation date, its permissions, and its
attributes are all stored within its inode.
Because different file systems have different underlying
structures and capabilities, attributes can behave differently—or be
completely ignored—by some file systems. In this article, we’re using ext4 which
is the default file system for many Linux distributions.
Looking at a File’s Attributes
The chattr and lsattr commands will already
be present on your computer so there’s no need to install anything.
To
check the attributes on the files in the current directory, use lsattr:
lsattr
┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ lsattr --------------e------- ./f.txt --------------e------- ./a.txt --------------e------- ./e.txt --------------e------- ./g.txt --------------e------- ./b.txt --------------e------- ./atul.txt --------------e------- ./hackingtruth.txt --------------e------- ./c.txt --------------e------- ./d.txt --------------e------- ./atulkumar.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$
The dashed lines are placeholders for attributes that are not set. The only
attribute that is set is the e (extents) attribute. This shows that the file
system inodes are using—or will use if required—extents to point to all
portions of the file on the hard drive.
If the file is held in one contiguous sequence of hard drive blocks, its inode
only has to record the first and last blocks used to store the file. If the
file is fragmented, the inode has to record the number of the first and last
block of each piece of the file. These pairs of hard drive block numbers are
called extents.
This is the list of the most commonly used attributes.
a: Append only. A file with this attribute can only
be appended to. It can still be written to, but only at the end of the file.
It is not possible to overwrite any of the existing data within the file.
c: Compressed. The file is automatically compressed on the hard drive and uncompressed
when it is read. Data written to the files is compressed before it is written
to the hard drive.
A: No atime updates. The atime is a
value in an inode that records the last time a file was accessed.
C: No copy-on-write. If two processes request access to a file, they can be given pointers to
the same file. They are only given their own unique copy of the file if they
try to write to the file, making it unique to that process.
d: No dump. The Linux dump command is used to write copies of entire file systems to
backup media. This attribute makes dump ignore the file. It is excluded from
the backup.
D: Synchronous directory updates. When
this attribute is turned on for a directory, all changes to that directory are
written synchronously—that is, immediately—on the hard drive. Data operations
can be buffered.
e: Extent format. The e attribute
indicates that the file system is using extents to map the location of the
file on the hard drive. You cannot change this with chattr. It is a function
of the operation of the file system.
i: Immutable. An
immutable file cannot be modified, including renaming and deleting. The root
user is the only person who can set or unset this attribute.
s: Secure deletion. When a file with this attribute set is deleted, the hard drive blocks that
held the file data are overwritten with bytes containing zeroes. Note that
this is not honored by the ext4 file system.
S: Synchronous updates. Changes to a file with its S attribute set are written to the file
synchronously.
u: Deleting a file that has its u
attribute set causes a copy of the file to be made. This can be beneficial to
file recovery if the file was removed in error.
Changing a File’s Attributes
The chattr command lets us change the attributes of
a file or directory. We can use
the + (set) and - (unset) operators to apply or remove an
attribute, similar to the chmod command and permissions.
The
chattr command also has an = (set only) operator.
This sets the attributes of a file or directory to only the attributes that
are specified in the command. That is, all attributes not listed on the
command line are unset.
Setting the Append Only Attribute
If you want use a: append attributes then if you want to change
the overwrite the file and add something, but it is not possible because A
file with this attribute can only be appended to. It can still be written to,
but only at the end of the file. It is not possible to overwrite any of the
existing data within the file.
┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ echo "Qm9iIC0gIVBAJCRXMHJEITEyMw== | base64 -d" > atul.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ cat atul.txt Qm9iIC0gIVBAJCRXMHJEITEyMw== | base64 -d ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ sudo chattr +a atul.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ lsattr --------------e------- ./f.txt --------------e------- ./a.txt --------------e------- ./e.txt --------------e------- ./g.txt --------------e------- ./b.txt -----a--------e------- ./atul.txt --------------e------- ./hackingtruth.txt --------------e------- ./c.txt --------------e------- ./d.txt --------------e------- ./atulkumar.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ echo "Qm" > atul.txt zsh: operation not permitted: atul.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$
We’ll redirect the output from ls into the file:
ls -l >
text-file.txt
sudo ls -l > text-file.txt
┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ lsattr atul.txt -----a--------e------- atul.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ ls -la > atul.txt zsh: operation not permitted: atul.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ sudo ls -la > atul.txt 1 ⨯ zsh: operation not permitted: atul.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ 1 ⨯
The operation is not permitted, even if we use the sudo command.
If
we use two angle brackets “>>” to redirect output it is appended
to the existing data in the file. That should be acceptable to our append-only
text file.
sudo ls -l >> text-file.txt
┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ lsattr atul.txt -----a--------e------- atul.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ cat atul.txt Qm9iIC0gIVBAJCRXMHJEITEyMw== | base64 -d ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ sudo ls -l >> atul.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ cat atul.txt Qm9iIC0gIVBAJCRXMHJEITEyMw== | base64 -d total 8 -rwxrwxrwx 1 root 1006 0 May 2 08:57 atulkumar.txt -rw-r--r-- 1 hackerboy root 41 May 3 12:59 atul.txt -rwxrwxrwx 1 hackerboy root 0 May 2 08:56 a.txt -rwxrwxrwx 1 hackerboy root 0 May 2 08:56 b.txt -rwxrwxrwx 1 hackerboy root 40 May 3 13:01 c.txt -rwxrwxrwx 1 hackerboy root 0 May 2 08:56 d.txt -rwxrwxrwx 1 hackerboy root 0 May 2 08:56 e.txt -rwxrwxrwx 1 hackerboy root 0 May 2 08:56 f.txt -rwxrwxrwx 1 hackerboy root 0 May 2 08:56 g.txt -rwxrwxrwx 1 root 1006 0 May 2 08:57 hackingtruth.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$
Although we can append data to the file, that is the only change we can make
to it. We can’t delete it and neither can root.
rm text-file.txt
sudo rm text-file.txt
┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ lsattr atul.txt -----a--------e------- atul.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ rm atul.txt rm: cannot remove 'atul.txt': Operation not permitted ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ sudo rm atul.txt 1 ⨯ rm: cannot remove 'atul.txt': Operation not permitted ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ 1 ⨯
Don’t Rely on Secure Deletion on ext4
As we pointed out, some operating systems do not support all of
the attributes. The secure delete attribute is not honored by the ext family
of file systems, including ext4. Don’t rely on this for the secure deletion of
files.
It’s easy to see that this doesn’t work in ext4. We’ll set
the s (secure deletion) attribute on a text file.
sudo chattr +s atul.txt
What we’re going to do is find out the inode that holds the metadata
about this file. The inode holds the first hard drive block occupied by the
file. The file contains some lorem ipsum placeholder text.
Advertisement
We’ll
read that block directly from the hard drive to verify we’re reading the
correct hard drive location. We’ll delete the file and then read that same
hard dive block once more. If the secure deletion attribute is being honored,
we should read zeroed bytes.
We can find the inode of the file by
using the hdparm command with the --fibmap (file block map) option.
sudo hdparm --fibmap third-file.txt
┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ lsattr atul.txt -----a--------e------- atul.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ chattr +s atul.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ lsattr atul.txt s----a--------e------- atul.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ sudo hdparm --fibmap atul.txt atul.txt: filesystem blocksize 4096, begins at LBA 872241152; assuming 512 byte sectors. byte_offset begin_LBA end_LBA sectors 0 931425384 931425391 8 ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$
The first hard drive block is 18100656. We’ll use the dd command to read
it.
The options are:
- if=/dev/sda: Read from the first hard drive on this computer.
- bs=512: Use a hard drive block size of 512 bytes.
- skip=18100656: Skip all blocks before block 18100656. In other words, start reading at block 18100656.
- count=1: Read one block of data.
sudo dd if=/dev/sda bs=512 skip=18100656 count=1
As expected we see the lorem ipsum placeholder text. We’re reading the correct
block on the hard drive.
┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ sudo dd if=/dev/sda bs=512 skip=931425384 count=1 Qm9iIC0gIVBAJCRXMHJEITEyMw== | base64 -d total 8 -rwxrwxrwx 1 root 1006 0 May 2 08:57 atulkumar.txt -rw-r--r-- 1 hackerboy root 41 May 3 12:59 atul.txt -rwxrwxrwx 1 hackerboy root 0 May 2 08:56 a.txt -rwxrwxrwx 1 hackerboy root 0 May 2 08:56 b.txt -rwxrwxrwx 1 hackerboy root 40 May 3 13:01 c.txt -rwxrwxrwx 1 hackerboy root 0 May 2 08:56 d.txt -rwxrwxrwx 1 hackerboy root 0 May 2 08:56 e.txt -rwxrwxrwx 1 hackerboy root 0 May 2 08:56 f.txt -rwxrwxrwx 1 hackerboy root 0 May 2 08:56 g.txt -r1+0 records in 1+0 records out 512 bytes copied, 0.0237929 s, 21.5 kB/s ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$
Now we’ll delete the file.
rm third-file.txt
┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ lsattr atul.txt 1 ⨯ s--------------------- atul.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$ rm atul.txt ┌──(hackerboy㉿KumarAtulJaiswal)-[~/Desktop/hackingtruth.org] └─$
Again, don’t depend on this for secure deletion on ext4.There are better
methods available to delete files so that they can’t be recovered.