cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

attributes.rst (6150B)


      1.. SPDX-License-Identifier: GPL-2.0
      2
      3Extended Attributes
      4-------------------
      5
      6Extended attributes (xattrs) are typically stored in a separate data
      7block on the disk and referenced from inodes via ``inode.i_file_acl*``.
      8The first use of extended attributes seems to have been for storing file
      9ACLs and other security data (selinux). With the ``user_xattr`` mount
     10option it is possible for users to store extended attributes so long as
     11all attribute names begin with “user”; this restriction seems to have
     12disappeared as of Linux 3.0.
     13
     14There are two places where extended attributes can be found. The first
     15place is between the end of each inode entry and the beginning of the
     16next inode entry. For example, if inode.i_extra_isize = 28 and
     17sb.inode_size = 256, then there are 256 - (128 + 28) = 100 bytes
     18available for in-inode extended attribute storage. The second place
     19where extended attributes can be found is in the block pointed to by
     20``inode.i_file_acl``. As of Linux 3.11, it is not possible for this
     21block to contain a pointer to a second extended attribute block (or even
     22the remaining blocks of a cluster). In theory it is possible for each
     23attribute's value to be stored in a separate data block, though as of
     24Linux 3.11 the code does not permit this.
     25
     26Keys are generally assumed to be ASCIIZ strings, whereas values can be
     27strings or binary data.
     28
     29Extended attributes, when stored after the inode, have a header
     30``ext4_xattr_ibody_header`` that is 4 bytes long:
     31
     32.. list-table::
     33   :widths: 8 8 24 40
     34   :header-rows: 1
     35
     36   * - Offset
     37     - Type
     38     - Name
     39     - Description
     40   * - 0x0
     41     - __le32
     42     - h_magic
     43     - Magic number for identification, 0xEA020000. This value is set by the
     44       Linux driver, though e2fsprogs doesn't seem to check it(?)
     45
     46The beginning of an extended attribute block is in
     47``struct ext4_xattr_header``, which is 32 bytes long:
     48
     49.. list-table::
     50   :widths: 8 8 24 40
     51   :header-rows: 1
     52
     53   * - Offset
     54     - Type
     55     - Name
     56     - Description
     57   * - 0x0
     58     - __le32
     59     - h_magic
     60     - Magic number for identification, 0xEA020000.
     61   * - 0x4
     62     - __le32
     63     - h_refcount
     64     - Reference count.
     65   * - 0x8
     66     - __le32
     67     - h_blocks
     68     - Number of disk blocks used.
     69   * - 0xC
     70     - __le32
     71     - h_hash
     72     - Hash value of all attributes.
     73   * - 0x10
     74     - __le32
     75     - h_checksum
     76     - Checksum of the extended attribute block.
     77   * - 0x14
     78     - __u32
     79     - h_reserved[3]
     80     - Zero.
     81
     82The checksum is calculated against the FS UUID, the 64-bit block number
     83of the extended attribute block, and the entire block (header +
     84entries).
     85
     86Following the ``struct ext4_xattr_header`` or
     87``struct ext4_xattr_ibody_header`` is an array of
     88``struct ext4_xattr_entry``; each of these entries is at least 16 bytes
     89long. When stored in an external block, the ``struct ext4_xattr_entry``
     90entries must be stored in sorted order. The sort order is
     91``e_name_index``, then ``e_name_len``, and finally ``e_name``.
     92Attributes stored inside an inode do not need be stored in sorted order.
     93
     94.. list-table::
     95   :widths: 8 8 24 40
     96   :header-rows: 1
     97
     98   * - Offset
     99     - Type
    100     - Name
    101     - Description
    102   * - 0x0
    103     - __u8
    104     - e_name_len
    105     - Length of name.
    106   * - 0x1
    107     - __u8
    108     - e_name_index
    109     - Attribute name index. There is a discussion of this below.
    110   * - 0x2
    111     - __le16
    112     - e_value_offs
    113     - Location of this attribute's value on the disk block where it is stored.
    114       Multiple attributes can share the same value. For an inode attribute
    115       this value is relative to the start of the first entry; for a block this
    116       value is relative to the start of the block (i.e. the header).
    117   * - 0x4
    118     - __le32
    119     - e_value_inum
    120     - The inode where the value is stored. Zero indicates the value is in the
    121       same block as this entry. This field is only used if the
    122       INCOMPAT_EA_INODE feature is enabled.
    123   * - 0x8
    124     - __le32
    125     - e_value_size
    126     - Length of attribute value.
    127   * - 0xC
    128     - __le32
    129     - e_hash
    130     - Hash value of attribute name and attribute value. The kernel doesn't
    131       update the hash for in-inode attributes, so for that case this value
    132       must be zero, because e2fsck validates any non-zero hash regardless of
    133       where the xattr lives.
    134   * - 0x10
    135     - char
    136     - e_name[e_name_len]
    137     - Attribute name. Does not include trailing NULL.
    138
    139Attribute values can follow the end of the entry table. There appears to
    140be a requirement that they be aligned to 4-byte boundaries. The values
    141are stored starting at the end of the block and grow towards the
    142xattr_header/xattr_entry table. When the two collide, the overflow is
    143put into a separate disk block. If the disk block fills up, the
    144filesystem returns -ENOSPC.
    145
    146The first four fields of the ``ext4_xattr_entry`` are set to zero to
    147mark the end of the key list.
    148
    149Attribute Name Indices
    150~~~~~~~~~~~~~~~~~~~~~~
    151
    152Logically speaking, extended attributes are a series of key=value pairs.
    153The keys are assumed to be NULL-terminated strings. To reduce the amount
    154of on-disk space that the keys consume, the beginning of the key string
    155is matched against the attribute name index. If a match is found, the
    156attribute name index field is set, and matching string is removed from
    157the key name. Here is a map of name index values to key prefixes:
    158
    159.. list-table::
    160   :widths: 16 64
    161   :header-rows: 1
    162
    163   * - Name Index
    164     - Key Prefix
    165   * - 0
    166     - (no prefix)
    167   * - 1
    168     - “user.”
    169   * - 2
    170     - “system.posix_acl_access”
    171   * - 3
    172     - “system.posix_acl_default”
    173   * - 4
    174     - “trusted.”
    175   * - 6
    176     - “security.”
    177   * - 7
    178     - “system.” (inline_data only?)
    179   * - 8
    180     - “system.richacl” (SuSE kernels only?)
    181
    182For example, if the attribute key is “user.fubar”, the attribute name
    183index is set to 1 and the “fubar” name is recorded on disk.
    184
    185POSIX ACLs
    186~~~~~~~~~~
    187
    188POSIX ACLs are stored in a reduced version of the Linux kernel (and
    189libacl's) internal ACL format. The key difference is that the version
    190number is different (1) and the ``e_id`` field is only stored for named
    191user and group ACLs.