#define XATTR_NAME_MAX 255 /* # chars in an extended attribute name */ #define XATTR_SIZE_MAX 65536 /* size of an extended attribute value (64k) */

After this preparation step, further processing is delegated to vfs_setxattr. The associated code flow diagram is shown in Figure 11-3.

Figure 11-3: Code flow diagram for vfs_setxattr.

At first, the kernel needs to make sure that the user is privileged to perform the desired operation; the choice is made by xattr_permission. For Read-Only or immutable inodes, the operation fails immediately; otherwise, the following checks are performed:

fs/xattr.c static int xattr_permission(struct inode *inode, const char *name, int mask) {

* No restriction for security.* and system.* from the VFS. Decision

* on these is left to the underlying file system / security module.


* The trusted.* namespace can only accessed by a privileged user.

if (!strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN)) return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM);

/* In user.* namespace, only regular files and directories can have

* extended attributes. For sticky directories, only the owner and

* privileged user can write attributes.

if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) { if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) return -EPERM;

if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) &&

(mask & MAY_WRITE) && !is_owner_or_cap(inode)) return -EPERM;

return permission(inode, mask, NULL);

The VFS layer does not care about attributes that live in the security or system namespace. Note that the request is granted if 0 is returned as result of xattr_permission! The kernel ignores these namespaces and delegates the choice to security modules that are included via numerous security-related calls, security_*, found everywhere in the kernel, or the underlying filesystem.

However, the VFS layer is concerned about the trusted namespace. Only a sufficiently privileged user (i.e., root or a user with appropriate capabilities) is allowed to perform operations on such attributes. For a change, the comments in the source code state precisely how the kernel thinks that attributes from the user namespace should be taken care of, so I need not add anything further.

Any decision for attributes from a different namespace from those processed until now is deferred to the generic permission function as discussed in Section 8.5.3. Note that this includes ACL checks that are implemented with the aid of extended attributes; how these checks are implemented is discussed in Section 11.2.2.

If the inode passed the permission check, vfs_setxattr continues as follows:

1. If a filesystem-specific setxattr method is available in the inode operations, it is called to perform the low-level interaction with the filesystem. After this, fsnotify_xattr uses the inotify mechanism to inform the userland about the extended attribute change.

2. If no setxattr method is available (i.e., if the underlying filesystem does not support extended attributes), but the extended attribute in question belongs to the security namespace, then the kernel tries to use a function that can be provided by security frameworks like SELinux. If no such framework is registered, the operation is denied.

This allows security labels on files that reside on filesystems without extended attribute support. It is the task of the security subsystem to store the information in a reasonable way.

Note that some more hook functions of the security framework are called during the extended attribute system calls. They are omitted here since if no extra security framework like SELinux is present, they will have no effect.

Since the implementation for the system calls getxattr and removexattr nearly completely follows the scheme presented for setxattr, it is not necessary to discuss them in greater depth. The differences are as follows:

□ getxattr does not need to use fnotify because nothing is modified.

□ removeattr need not copy an attribute value, but only the name from the userspace. No special casing for the security handler is required.

The code for listing all extended attributes associated with a file differs more from this scheme, particularly because no function vfs_listxattr is used. All work is performed in listxattr. The implementation proceeds in three easy steps:

1. Adapt the maximum size of the list as given by by the userspace program such that it is not higher than the maximal size of an extended attribute list as allowed by the kernel with xattr_list_max, and allocate the required memory.

2. Call listxattr from inode_operations to fill the allocated space with name/value pairs.

3. Copy the result back to the userspace.

Continue reading here: Generic Handler Functions

Was this article helpful?

0 0