Extended Attributes
A file or directory can have extended attributes, which are name and value pairs. If a file or directory has extended attributes, its inode will contain the block address where they are stored.
The extended attributes block has three sections to it. The first 32 bytes are used by the header, and following the header is the second section with a list of attribute name entries. The third section starts at the end of the block and works its way up. It contains the values for each of the attribute pairs, and they may not be in the same order as the name entries were. We can see this in Figure 15.1.
Figure 15.1. The extended attributes block has the name at the top and value at the bottom. They grow towards the middle.
The extended attribute header starts at byte 0 of the block and is 32-bytes long. It has the fields given in Table 15.15.
Byte Range |
Description |
Essential |
---|---|---|
03 |
Signature (0xEA020000) |
No |
47 |
Reference count |
No |
811 |
Number of blocks |
Yes |
1215 |
Hash |
No |
1631 |
Reserved |
No |
The reference count refers to how many files are using this block because files with the same extended attributes will share an extended attribute block. Linux currently does not support attribute lists with more than one block, but other OSes could in the future. The hash value is the hash for the attributes so that the OS can easily determine if two files have the same attributes.
The name entries start after the header, and each has the data structure given in Table 15.16.
Byte Range |
Description |
Essential |
---|---|---|
00 |
Length of name |
Yes |
11 |
Attribute type (see Table 15.17) |
Yes |
23 |
Offset to value |
Yes |
47 |
Block location of value |
Yes |
811 |
Size of value |
Yes |
1215 |
Hash of value |
No |
16+ |
Name in ASCII |
Yes |
The offset value is the byte offset in the block specified. For current Linux systems, there is only one block, and the block field is not set. The size value is the number of bytes in the value. The length of the name determines the length of the entry, and the next entry starts at the next 4-byte boundary. The entry type value can have one of the six values given in Table 15.17.
Type Value |
Description |
---|---|
1 |
User space attribute |
2 |
POSIX ACL |
3 |
POSIX ACL Default (directories only) |
4 |
Trusted space attribute |
5 |
LUSTRE (not currently used by Linux) |
6 |
Security space attribute |
If the type of the attribute is a user, trusted, or security space attribute, the value at the end of the block will simply be the value part of the attribute pair. If the type is one of the POSIX ACL types, the value has its own set of data structures.
The value part of a POSIX ACL attribute starts with a header and then a list of entries. The header data structure has only one field and is given in Table 15.18. The data structure for the ACL entries is given in Table 15.19.
Byte Range |
Description |
Essential |
---|---|---|
03 |
Version (1) |
Yes |
Byte Range |
Description |
Essential |
---|---|---|
01 |
Type (tag) (see Table 15.20) |
Yes |
23 |
Permissions (see Table 15.21) |
Yes |
47 |
User / Group ID (not included for some types) |
Yes |
The type field in the ACL entry identifies the type of permission that the entry is for. The values given in Table 15.20 are defined.
Type |
Description |
---|---|
0x01 |
Userspecified in inode |
0x04 |
Groupspecified in inode |
0x20 |
Otherall other users |
0x10 |
Effective rights mask |
0x02 |
Userspecified in attribute |
0x08 |
Groupspecified in attribute |
The first three types apply to the same owner, group, and "world" set of users that are normally used with ExtX inodes. In other words, the information in these entries should duplicate the information found in the inode. An entry that has one of these types is only four bytes in size because it does not use the ID field in bytes 4 to 7. The other types need to specify the user or group to which the permissions apply.
The permissions field in the entry has the flags in Table 15.21 defined.
Permission Flag |
Description |
---|---|
0x01 |
Execute |
0x02 |
Write |
0x04 |
Read |
Let's take a look at a block that contains some extended attributes.
# dcat f linux-ext3 ext3-2.dd 1238 0000000: 0000 02ea 0100 0000 0100 0000 7447 05e8 ............tG.. 0000016: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000032: 0601 c003 0000 0000 1900 0000 a8e9 5147 ..............QG 0000048: 736f 7572 6365 0000 0002 dc03 0000 0000 source.......... 0000064: 2400 0000 2500 ad01 0000 0000 0000 0000 $...%........... [REMOVED] 0000944: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 0000960: 7777 772e 6469 6774 6974 616c 2d65 7669 www.digtital-evi 0000976: 6465 6e63 652e 6f72 6700 0000 0100 0000 dence.org....... 0000992: 0100 0600 0200 0400 4a00 0000 0200 0600 ........J....... 0001008: f401 0000 0400 0400 1000 0600 2000 0400 ............ ...
The first four bytes show the signature value, bytes 4 to 7 shows a reference count of 1, and bytes 8 to 11 show a block count of 1. Byte 32 is where the first entry starts, and we see that its name length is 6. Its type is 1, which is user space attribute, and bytes 2 to 3 show that the value is located at byte offset 960 (0x03c0). Bytes 40 to 43 show the size of the value is 25 bytes, and byte 48 is the start of the name, which is "source." The name ends in byte 53, and the entries are on 4-byte boundaries, so we advance to byte 56 for the next attribute. The value for the first attribute can be found in bytes 960 to 984, and the value is "www.digital-evidence.org."
There is a second attribute in the block, and it is for an ACL. It starts at byte 988 and extends until byte 1023. The header is at byte 988 to 991, and the first entry is at byte 992 to 993. It has a type of 1, which is for the permissions of the user ID specified in the inode. The permission is given in bytes 994 to 995, and it is 0x06, so we know the owner has read and write permissions. The second entry starts at byte 996 and has a type of 2. It gives read permissions to the user with an ID of 74 (0x4a). The remaining permissions are left as an exercise, but here is the relevant output from running istat on the file:
# istat f linux-ext3 ext3-2.dd 70 [REMOVED] Extended Attributes (Block: 1238) user.source=www.digtital-evidence.org POSIX Access Control List Entries: uid: 0: Read, Write uid: 74: Read uid: 500: Read, Write gid: 0: Read mask: Read, Write other: Read [REMOVED]