@@ -363,7 +363,8 @@ static int vfs_fsinfo(struct path *path, struct fsinfo_kparams *params)
int (*fsinfo)(struct path *, struct fsinfo_kparams *);
int ret;
- if (params->request == FSINFO_ATTR_FSINFO) {
+ switch (params->request) {
+ case FSINFO_ATTR_FSINFO: {
struct fsinfo_fsinfo *info = params->buffer;
info->max_attr = FSINFO_ATTR__NR;
@@ -371,11 +372,18 @@ static int vfs_fsinfo(struct path *path, struct fsinfo_kparams *params)
return sizeof(*info);
}
- fsinfo = dentry->d_sb->s_op->fsinfo;
- if (!fsinfo) {
- if (!dentry->d_sb->s_op->statfs)
- return -EOPNOTSUPP;
- fsinfo = generic_fsinfo;
+ case FSINFO_ATTR_LSM_PARAMETERS:
+ fsinfo = security_sb_fsinfo;
+ break;
+
+ default:
+ fsinfo = dentry->d_sb->s_op->fsinfo;
+ if (!fsinfo) {
+ if (!dentry->d_sb->s_op->statfs)
+ return -EOPNOTSUPP;
+ fsinfo = generic_fsinfo;
+ }
+ break;
}
ret = security_sb_statfs(dentry);
@@ -566,6 +574,7 @@ static const struct fsinfo_attr_info fsinfo_buffer_info[FSINFO_ATTR__NR] = {
FSINFO_STRUCT_N (PARAM_SPECIFICATION, param_specification),
FSINFO_STRUCT_N (PARAM_ENUM, param_enum),
FSINFO_OPAQUE (PARAMETERS, -),
+ FSINFO_OPAQUE (LSM_PARAMETERS, -),
};
/**
@@ -108,6 +108,13 @@
* mountpoint.
* @dentry is a handle on the superblock for the filesystem.
* Return 0 if permission is granted.
+ * @sb_fsinfo:
+ * Query LSM information for a filesystem.
+ * @path is a handle on the superblock for the filesystem.
+ * @params is the fsinfo parameter and buffer block.
+ * - Currently, params->request can only be FSINFO_ATTR_LSM_PARAMETERS.
+ * Return the length of the data in the buffer (and can return -ENODATA to
+ * indicate no value under certain circumstances).
* @sb_mount:
* Check permission before an object specified by @dev_name is mounted on
* the mount point named by @nd. For an ordinary mount, @dev_name
@@ -1492,6 +1499,9 @@ union security_list_options {
int (*sb_kern_mount)(struct super_block *sb);
int (*sb_show_options)(struct seq_file *m, struct super_block *sb);
int (*sb_statfs)(struct dentry *dentry);
+#ifdef CONFIG_FSINFO
+ int (*sb_fsinfo)(struct path *path, struct fsinfo_kparams *params);
+#endif
int (*sb_mount)(const char *dev_name, const struct path *path,
const char *type, unsigned long flags, void *data);
int (*sb_umount)(struct vfsmount *mnt, int flags);
@@ -1838,6 +1848,9 @@ struct security_hook_heads {
struct hlist_head sb_kern_mount;
struct hlist_head sb_show_options;
struct hlist_head sb_statfs;
+#ifdef CONFIG_FSINFO
+ struct hlist_head sb_fsinfo;
+#endif
struct hlist_head sb_mount;
struct hlist_head sb_umount;
struct hlist_head sb_pivotroot;
@@ -57,6 +57,7 @@ struct mm_struct;
struct fs_context;
struct fs_parameter;
enum fs_value_type;
+struct fsinfo_kparams;
/* Default (no) options for the capable function */
#define CAP_OPT_NONE 0x0
@@ -237,6 +238,9 @@ int security_sb_remount(struct super_block *sb, void *mnt_opts);
int security_sb_kern_mount(struct super_block *sb);
int security_sb_show_options(struct seq_file *m, struct super_block *sb);
int security_sb_statfs(struct dentry *dentry);
+#ifdef CONFIG_FSINFO
+int security_sb_fsinfo(struct path *path, struct fsinfo_kparams *params);
+#endif
int security_sb_mount(const char *dev_name, const struct path *path,
const char *type, unsigned long flags, void *data);
int security_sb_umount(struct vfsmount *mnt, int flags);
@@ -575,6 +579,13 @@ static inline int security_sb_statfs(struct dentry *dentry)
return 0;
}
+#ifdef CONFIG_FSINFO
+static inline int security_sb_fsinfo(struct path *path, struct fsinfo_kparams *params)
+{
+ return 0;
+}
+#endif
+
static inline int security_sb_mount(const char *dev_name, const struct path *path,
const char *type, unsigned long flags,
void *data)
@@ -31,6 +31,7 @@ enum fsinfo_attribute {
FSINFO_ATTR_PARAM_SPECIFICATION = 13, /* Nth parameter specification */
FSINFO_ATTR_PARAM_ENUM = 14, /* Nth enum-to-val */
FSINFO_ATTR_PARAMETERS = 15, /* Mount parameters (large string) */
+ FSINFO_ATTR_LSM_PARAMETERS = 16, /* LSM Mount parameters (large string) */
FSINFO_ATTR__NR
};
@@ -82,6 +82,7 @@ static const struct fsinfo_attr_info fsinfo_buffer_info[FSINFO_ATTR__NR] = {
FSINFO_STRUCT_N (PARAM_SPECIFICATION, param_specification),
FSINFO_STRUCT_N (PARAM_ENUM, param_enum),
FSINFO_OVERLARGE (PARAMETERS, -),
+ FSINFO_OVERLARGE (LSM_PARAMETERS, -),
};
#define FSINFO_NAME(X,Y) [FSINFO_ATTR_##X] = #Y
@@ -102,6 +103,7 @@ static const char *fsinfo_attr_names[FSINFO_ATTR__NR] = {
FSINFO_NAME (PARAM_SPECIFICATION, param_specification),
FSINFO_NAME (PARAM_ENUM, param_enum),
FSINFO_NAME (PARAMETERS, parameters),
+ FSINFO_NAME (LSM_PARAMETERS, lsm_parameters),
};
union reply {
@@ -459,6 +461,7 @@ static int try_one(const char *file, struct fsinfo_params *params, bool raw)
switch (params->request) {
case FSINFO_ATTR_PARAMETERS:
+ case FSINFO_ATTR_LSM_PARAMETERS:
if (ret == 0)
return 0;
}
@@ -505,7 +508,8 @@ static int try_one(const char *file, struct fsinfo_params *params, bool raw)
return 0;
case __FSINFO_OVER:
- if (params->request == FSINFO_ATTR_PARAMETERS)
+ if (params->request == FSINFO_ATTR_PARAMETERS ||
+ params->request == FSINFO_ATTR_LSM_PARAMETERS)
dump_params(about, r, ret);
return 0;
@@ -25,6 +25,7 @@
#include <linux/ima.h>
#include <linux/evm.h>
#include <linux/fsnotify.h>
+#include <linux/fsinfo.h>
#include <linux/mman.h>
#include <linux/mount.h>
#include <linux/personality.h>
@@ -821,6 +822,17 @@ int security_sb_statfs(struct dentry *dentry)
return call_int_hook(sb_statfs, 0, dentry);
}
+#ifdef CONFIG_FSINFO
+int security_sb_fsinfo(struct path *path, struct fsinfo_kparams *params)
+{
+ int ret = -ENODATA;
+
+ if (params->request == FSINFO_ATTR_LSM_PARAMETERS)
+ ret = 0; /* This is cumulative amongst all LSMs */
+ return call_int_hook(sb_fsinfo, ret, path, params);
+}
+#endif
+
int security_sb_mount(const char *dev_name, const struct path *path,
const char *type, unsigned long flags, void *data)
{
Implement LSM parameter value retrieval with fsinfo() - akin to parsing /proc/mounts. This allows all the LSM parameters to be retrieved in one go with: struct fsinfo_params params = { .request = FSINFO_ATTR_LSM_PARAMETER, }; The format is a blob containing pairs of length-prefixed strings to avoid the need to escape commas and suchlike in the values. This is the same as for FSINFO_ATTR_PARAMETER. Signed-off-by: David Howells <dhowells@redhat.com> --- fs/fsinfo.c | 21 +++++++++++++++------ include/linux/lsm_hooks.h | 13 +++++++++++++ include/linux/security.h | 11 +++++++++++ include/uapi/linux/fsinfo.h | 1 + samples/vfs/test-fsinfo.c | 6 +++++- security/security.c | 12 ++++++++++++ 6 files changed, 57 insertions(+), 7 deletions(-)