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