mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
hfsplus: rework functionality of getting, setting and deleting of extended attributes
Rework functionality of getting, setting and deleting of extended attributes. Signed-off-by: Vyacheslav Dubeyko <slava@dubeyko.com> Reported-by: Hin-Tak Leung <htl10@users.sourceforge.net> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Christoph Hellwig <hch@lst.de> Cc: Jan Kara <jack@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
committed by
Linus Torvalds
parent
3e05ca20fb
commit
127e5f5ae5
709
fs/hfsplus/xattr.c
Normal file
709
fs/hfsplus/xattr.c
Normal file
File diff suppressed because it is too large
Load Diff
60
fs/hfsplus/xattr.h
Normal file
60
fs/hfsplus/xattr.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* linux/fs/hfsplus/xattr.h
|
||||
*
|
||||
* Vyacheslav Dubeyko <slava@dubeyko.com>
|
||||
*
|
||||
* Logic of processing extended attributes
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_HFSPLUS_XATTR_H
|
||||
#define _LINUX_HFSPLUS_XATTR_H
|
||||
|
||||
#include <linux/xattr.h>
|
||||
|
||||
extern const struct xattr_handler hfsplus_xattr_osx_handler;
|
||||
extern const struct xattr_handler hfsplus_xattr_user_handler;
|
||||
extern const struct xattr_handler hfsplus_xattr_trusted_handler;
|
||||
/*extern const struct xattr_handler hfsplus_xattr_acl_access_handler;*/
|
||||
/*extern const struct xattr_handler hfsplus_xattr_acl_default_handler;*/
|
||||
extern const struct xattr_handler hfsplus_xattr_security_handler;
|
||||
|
||||
extern const struct xattr_handler *hfsplus_xattr_handlers[];
|
||||
|
||||
int __hfsplus_setxattr(struct inode *inode, const char *name,
|
||||
const void *value, size_t size, int flags);
|
||||
|
||||
static inline int hfsplus_setxattr(struct dentry *dentry, const char *name,
|
||||
const void *value, size_t size, int flags)
|
||||
{
|
||||
return __hfsplus_setxattr(dentry->d_inode, name, value, size, flags);
|
||||
}
|
||||
|
||||
ssize_t hfsplus_getxattr(struct dentry *dentry, const char *name,
|
||||
void *value, size_t size);
|
||||
|
||||
ssize_t hfsplus_listxattr(struct dentry *dentry, char *buffer, size_t size);
|
||||
|
||||
int hfsplus_removexattr(struct dentry *dentry, const char *name);
|
||||
|
||||
int hfsplus_init_security(struct inode *inode, struct inode *dir,
|
||||
const struct qstr *qstr);
|
||||
|
||||
static inline int hfsplus_init_acl(struct inode *inode, struct inode *dir)
|
||||
{
|
||||
/*TODO: implement*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int hfsplus_init_inode_security(struct inode *inode,
|
||||
struct inode *dir,
|
||||
const struct qstr *qstr)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = hfsplus_init_acl(inode, dir);
|
||||
if (!err)
|
||||
err = hfsplus_init_security(inode, dir, qstr);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
104
fs/hfsplus/xattr_security.c
Normal file
104
fs/hfsplus/xattr_security.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* linux/fs/hfsplus/xattr_trusted.c
|
||||
*
|
||||
* Vyacheslav Dubeyko <slava@dubeyko.com>
|
||||
*
|
||||
* Handler for storing security labels as extended attributes.
|
||||
*/
|
||||
|
||||
#include <linux/security.h>
|
||||
#include "hfsplus_fs.h"
|
||||
#include "xattr.h"
|
||||
|
||||
static int hfsplus_security_getxattr(struct dentry *dentry, const char *name,
|
||||
void *buffer, size_t size, int type)
|
||||
{
|
||||
char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
|
||||
size_t len = strlen(name);
|
||||
|
||||
if (!strcmp(name, ""))
|
||||
return -EINVAL;
|
||||
|
||||
if (len + XATTR_SECURITY_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
strcpy(xattr_name, XATTR_SECURITY_PREFIX);
|
||||
strcpy(xattr_name + XATTR_SECURITY_PREFIX_LEN, name);
|
||||
|
||||
return hfsplus_getxattr(dentry, xattr_name, buffer, size);
|
||||
}
|
||||
|
||||
static int hfsplus_security_setxattr(struct dentry *dentry, const char *name,
|
||||
const void *buffer, size_t size, int flags, int type)
|
||||
{
|
||||
char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
|
||||
size_t len = strlen(name);
|
||||
|
||||
if (!strcmp(name, ""))
|
||||
return -EINVAL;
|
||||
|
||||
if (len + XATTR_SECURITY_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
strcpy(xattr_name, XATTR_SECURITY_PREFIX);
|
||||
strcpy(xattr_name + XATTR_SECURITY_PREFIX_LEN, name);
|
||||
|
||||
return hfsplus_setxattr(dentry, xattr_name, buffer, size, flags);
|
||||
}
|
||||
|
||||
static size_t hfsplus_security_listxattr(struct dentry *dentry, char *list,
|
||||
size_t list_size, const char *name, size_t name_len, int type)
|
||||
{
|
||||
/*
|
||||
* This method is not used.
|
||||
* It is used hfsplus_listxattr() instead of generic_listxattr().
|
||||
*/
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int hfsplus_initxattrs(struct inode *inode,
|
||||
const struct xattr *xattr_array,
|
||||
void *fs_info)
|
||||
{
|
||||
const struct xattr *xattr;
|
||||
char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
|
||||
size_t xattr_name_len;
|
||||
int err = 0;
|
||||
|
||||
for (xattr = xattr_array; xattr->name != NULL; xattr++) {
|
||||
xattr_name_len = strlen(xattr->name);
|
||||
|
||||
if (xattr_name_len == 0)
|
||||
continue;
|
||||
|
||||
if (xattr_name_len + XATTR_SECURITY_PREFIX_LEN >
|
||||
HFSPLUS_ATTR_MAX_STRLEN)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
strcpy(xattr_name, XATTR_SECURITY_PREFIX);
|
||||
strcpy(xattr_name +
|
||||
XATTR_SECURITY_PREFIX_LEN, xattr->name);
|
||||
memset(xattr_name +
|
||||
XATTR_SECURITY_PREFIX_LEN + xattr_name_len, 0, 1);
|
||||
|
||||
err = __hfsplus_setxattr(inode, xattr_name,
|
||||
xattr->value, xattr->value_len, 0);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int hfsplus_init_security(struct inode *inode, struct inode *dir,
|
||||
const struct qstr *qstr)
|
||||
{
|
||||
return security_inode_init_security(inode, dir, qstr,
|
||||
&hfsplus_initxattrs, NULL);
|
||||
}
|
||||
|
||||
const struct xattr_handler hfsplus_xattr_security_handler = {
|
||||
.prefix = XATTR_SECURITY_PREFIX,
|
||||
.list = hfsplus_security_listxattr,
|
||||
.get = hfsplus_security_getxattr,
|
||||
.set = hfsplus_security_setxattr,
|
||||
};
|
||||
63
fs/hfsplus/xattr_trusted.c
Normal file
63
fs/hfsplus/xattr_trusted.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* linux/fs/hfsplus/xattr_trusted.c
|
||||
*
|
||||
* Vyacheslav Dubeyko <slava@dubeyko.com>
|
||||
*
|
||||
* Handler for trusted extended attributes.
|
||||
*/
|
||||
|
||||
#include "hfsplus_fs.h"
|
||||
#include "xattr.h"
|
||||
|
||||
static int hfsplus_trusted_getxattr(struct dentry *dentry, const char *name,
|
||||
void *buffer, size_t size, int type)
|
||||
{
|
||||
char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
|
||||
size_t len = strlen(name);
|
||||
|
||||
if (!strcmp(name, ""))
|
||||
return -EINVAL;
|
||||
|
||||
if (len + XATTR_TRUSTED_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
strcpy(xattr_name, XATTR_TRUSTED_PREFIX);
|
||||
strcpy(xattr_name + XATTR_TRUSTED_PREFIX_LEN, name);
|
||||
|
||||
return hfsplus_getxattr(dentry, xattr_name, buffer, size);
|
||||
}
|
||||
|
||||
static int hfsplus_trusted_setxattr(struct dentry *dentry, const char *name,
|
||||
const void *buffer, size_t size, int flags, int type)
|
||||
{
|
||||
char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
|
||||
size_t len = strlen(name);
|
||||
|
||||
if (!strcmp(name, ""))
|
||||
return -EINVAL;
|
||||
|
||||
if (len + XATTR_TRUSTED_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
strcpy(xattr_name, XATTR_TRUSTED_PREFIX);
|
||||
strcpy(xattr_name + XATTR_TRUSTED_PREFIX_LEN, name);
|
||||
|
||||
return hfsplus_setxattr(dentry, xattr_name, buffer, size, flags);
|
||||
}
|
||||
|
||||
static size_t hfsplus_trusted_listxattr(struct dentry *dentry, char *list,
|
||||
size_t list_size, const char *name, size_t name_len, int type)
|
||||
{
|
||||
/*
|
||||
* This method is not used.
|
||||
* It is used hfsplus_listxattr() instead of generic_listxattr().
|
||||
*/
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
const struct xattr_handler hfsplus_xattr_trusted_handler = {
|
||||
.prefix = XATTR_TRUSTED_PREFIX,
|
||||
.list = hfsplus_trusted_listxattr,
|
||||
.get = hfsplus_trusted_getxattr,
|
||||
.set = hfsplus_trusted_setxattr,
|
||||
};
|
||||
63
fs/hfsplus/xattr_user.c
Normal file
63
fs/hfsplus/xattr_user.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* linux/fs/hfsplus/xattr_user.c
|
||||
*
|
||||
* Vyacheslav Dubeyko <slava@dubeyko.com>
|
||||
*
|
||||
* Handler for user extended attributes.
|
||||
*/
|
||||
|
||||
#include "hfsplus_fs.h"
|
||||
#include "xattr.h"
|
||||
|
||||
static int hfsplus_user_getxattr(struct dentry *dentry, const char *name,
|
||||
void *buffer, size_t size, int type)
|
||||
{
|
||||
char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
|
||||
size_t len = strlen(name);
|
||||
|
||||
if (!strcmp(name, ""))
|
||||
return -EINVAL;
|
||||
|
||||
if (len + XATTR_USER_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
strcpy(xattr_name, XATTR_USER_PREFIX);
|
||||
strcpy(xattr_name + XATTR_USER_PREFIX_LEN, name);
|
||||
|
||||
return hfsplus_getxattr(dentry, xattr_name, buffer, size);
|
||||
}
|
||||
|
||||
static int hfsplus_user_setxattr(struct dentry *dentry, const char *name,
|
||||
const void *buffer, size_t size, int flags, int type)
|
||||
{
|
||||
char xattr_name[HFSPLUS_ATTR_MAX_STRLEN + 1] = {0};
|
||||
size_t len = strlen(name);
|
||||
|
||||
if (!strcmp(name, ""))
|
||||
return -EINVAL;
|
||||
|
||||
if (len + XATTR_USER_PREFIX_LEN > HFSPLUS_ATTR_MAX_STRLEN)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
strcpy(xattr_name, XATTR_USER_PREFIX);
|
||||
strcpy(xattr_name + XATTR_USER_PREFIX_LEN, name);
|
||||
|
||||
return hfsplus_setxattr(dentry, xattr_name, buffer, size, flags);
|
||||
}
|
||||
|
||||
static size_t hfsplus_user_listxattr(struct dentry *dentry, char *list,
|
||||
size_t list_size, const char *name, size_t name_len, int type)
|
||||
{
|
||||
/*
|
||||
* This method is not used.
|
||||
* It is used hfsplus_listxattr() instead of generic_listxattr().
|
||||
*/
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
const struct xattr_handler hfsplus_xattr_user_handler = {
|
||||
.prefix = XATTR_USER_PREFIX,
|
||||
.list = hfsplus_user_listxattr,
|
||||
.get = hfsplus_user_getxattr,
|
||||
.set = hfsplus_user_setxattr,
|
||||
};
|
||||
Reference in New Issue
Block a user