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