linux/fs/reiserfs/xattr_security.c
<<
>>
Prefs
   1#include "reiserfs.h"
   2#include <linux/errno.h>
   3#include <linux/fs.h>
   4#include <linux/pagemap.h>
   5#include <linux/xattr.h>
   6#include <linux/slab.h>
   7#include "xattr.h"
   8#include <linux/security.h>
   9#include <asm/uaccess.h>
  10
  11static int
  12security_get(struct dentry *dentry, const char *name, void *buffer, size_t size,
  13                int handler_flags)
  14{
  15        if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))
  16                return -EINVAL;
  17
  18        if (IS_PRIVATE(dentry->d_inode))
  19                return -EPERM;
  20
  21        return reiserfs_xattr_get(dentry->d_inode, name, buffer, size);
  22}
  23
  24static int
  25security_set(struct dentry *dentry, const char *name, const void *buffer,
  26             size_t size, int flags, int handler_flags)
  27{
  28        if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))
  29                return -EINVAL;
  30
  31        if (IS_PRIVATE(dentry->d_inode))
  32                return -EPERM;
  33
  34        return reiserfs_xattr_set(dentry->d_inode, name, buffer, size, flags);
  35}
  36
  37static size_t security_list(struct dentry *dentry, char *list, size_t list_len,
  38                            const char *name, size_t namelen, int handler_flags)
  39{
  40        const size_t len = namelen + 1;
  41
  42        if (IS_PRIVATE(dentry->d_inode))
  43                return 0;
  44
  45        if (list && len <= list_len) {
  46                memcpy(list, name, namelen);
  47                list[namelen] = '\0';
  48        }
  49
  50        return len;
  51}
  52
  53/* Initializes the security context for a new inode and returns the number
  54 * of blocks needed for the transaction. If successful, reiserfs_security
  55 * must be released using reiserfs_security_free when the caller is done. */
  56int reiserfs_security_init(struct inode *dir, struct inode *inode,
  57                           const struct qstr *qstr,
  58                           struct reiserfs_security_handle *sec)
  59{
  60        int blocks = 0;
  61        int error;
  62
  63        sec->name = NULL;
  64
  65        /* Don't add selinux attributes on xattrs - they'll never get used */
  66        if (IS_PRIVATE(dir))
  67                return 0;
  68
  69        error = security_old_inode_init_security(inode, dir, qstr, &sec->name,
  70                                                 &sec->value, &sec->length);
  71        if (error) {
  72                if (error == -EOPNOTSUPP)
  73                        error = 0;
  74
  75                sec->name = NULL;
  76                sec->value = NULL;
  77                sec->length = 0;
  78                return error;
  79        }
  80
  81        if (sec->length && reiserfs_xattrs_initialized(inode->i_sb)) {
  82                blocks = reiserfs_xattr_jcreate_nblocks(inode) +
  83                         reiserfs_xattr_nblocks(inode, sec->length);
  84                /* We don't want to count the directories twice if we have
  85                 * a default ACL. */
  86                REISERFS_I(inode)->i_flags |= i_has_xattr_dir;
  87        }
  88        return blocks;
  89}
  90
  91int reiserfs_security_write(struct reiserfs_transaction_handle *th,
  92                            struct inode *inode,
  93                            struct reiserfs_security_handle *sec)
  94{
  95        int error;
  96        if (strlen(sec->name) < sizeof(XATTR_SECURITY_PREFIX))
  97                return -EINVAL;
  98
  99        error = reiserfs_xattr_set_handle(th, inode, sec->name, sec->value,
 100                                          sec->length, XATTR_CREATE);
 101        if (error == -ENODATA || error == -EOPNOTSUPP)
 102                error = 0;
 103
 104        return error;
 105}
 106
 107void reiserfs_security_free(struct reiserfs_security_handle *sec)
 108{
 109        kfree(sec->name);
 110        kfree(sec->value);
 111        sec->name = NULL;
 112        sec->value = NULL;
 113}
 114
 115const struct xattr_handler reiserfs_xattr_security_handler = {
 116        .prefix = XATTR_SECURITY_PREFIX,
 117        .get = security_get,
 118        .set = security_set,
 119        .list = security_list,
 120};
 121