← Back to context

Comment by neerajsi

2 years ago

I work on ReFS and a little bit on NTFS. Alternate data streams are simply seekable bags of bytes, just like the traditional main data file stream. Security descriptors, extended attributes, reparse points and other file metadata are represented as a more general concept called an "attribute".

You can't actually open a security descriptor attribute and modify select bytes of it to create an invalid security descriptor, as you would if it were a general purpose stream.

Help me understand the terminology. I thought alternative data streams were just non-resident attributes. Attributes like "$SECURITY_DESCRIPTOR" have reserved names but, conceptually, I thought were stored in the same manner as an alternative data stream. (Admittedly, I've never seen the real NTFS source code-- I've only perused open source tools and re-implementations.)

  • Essentially, attribute names directly specify the attribute type - so $SECURITY_DESCRIPTOR declared the entry in FILE attribute list to be a security descriptor. DATA attributes have another name field to handle multiple instances

    • > Essentially, attribute names directly specify the attribute type - so $SECURITY_DESCRIPTOR declared the entry in FILE attribute list to be a security descriptor. DATA attributes have another name field to handle multiple instances

      If you at the Linux kernel source code, `fs/ntfs3/ntfs.h` contains the following:

          struct ATTRIB {
              enum ATTR_TYPE type; // 0x00: The type of this attribute.
              __le32 size;         // 0x04: The size of this attribute.
              u8 non_res;          // 0x08: Is this attribute non-resident?
              u8 name_len;         // 0x09: This attribute name length.
              __le16 name_off;     // 0x0A: Offset to the attribute name.
              __le16 flags;        // 0x0C: See ATTR_FLAG_XXX.
              __le16 id;           // 0x0E: Unique id (per record).
              union {
                  struct ATTR_RESIDENT res;     // 0x10
                  struct ATTR_NONRESIDENT nres; // 0x10
              };
          };
      

      So the name field isn't specific to `$DATA` attributes, every attribute has it. However, for most attributes either the name is zero bytes, or it is a hardcoded name (like `$I30` for directories). Is `$DATA` the only one that can have different instances of the attribute with arbitrary names?

      4 replies →