0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/slab.h>
0009 #include <uapi/linux/mount.h>
0010 #include "common.h"
0011
0012
0013 static const char * const tomoyo_mounts[TOMOYO_MAX_SPECIAL_MOUNT] = {
0014 [TOMOYO_MOUNT_BIND] = "--bind",
0015 [TOMOYO_MOUNT_MOVE] = "--move",
0016 [TOMOYO_MOUNT_REMOUNT] = "--remount",
0017 [TOMOYO_MOUNT_MAKE_UNBINDABLE] = "--make-unbindable",
0018 [TOMOYO_MOUNT_MAKE_PRIVATE] = "--make-private",
0019 [TOMOYO_MOUNT_MAKE_SLAVE] = "--make-slave",
0020 [TOMOYO_MOUNT_MAKE_SHARED] = "--make-shared",
0021 };
0022
0023
0024
0025
0026
0027
0028
0029
0030 static int tomoyo_audit_mount_log(struct tomoyo_request_info *r)
0031 {
0032 return tomoyo_supervisor(r, "file mount %s %s %s 0x%lX\n",
0033 r->param.mount.dev->name,
0034 r->param.mount.dir->name,
0035 r->param.mount.type->name,
0036 r->param.mount.flags);
0037 }
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 static bool tomoyo_check_mount_acl(struct tomoyo_request_info *r,
0048 const struct tomoyo_acl_info *ptr)
0049 {
0050 const struct tomoyo_mount_acl *acl =
0051 container_of(ptr, typeof(*acl), head);
0052
0053 return tomoyo_compare_number_union(r->param.mount.flags,
0054 &acl->flags) &&
0055 tomoyo_compare_name_union(r->param.mount.type,
0056 &acl->fs_type) &&
0057 tomoyo_compare_name_union(r->param.mount.dir,
0058 &acl->dir_name) &&
0059 (!r->param.mount.need_dev ||
0060 tomoyo_compare_name_union(r->param.mount.dev,
0061 &acl->dev_name));
0062 }
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 static int tomoyo_mount_acl(struct tomoyo_request_info *r,
0078 const char *dev_name,
0079 const struct path *dir, const char *type,
0080 unsigned long flags)
0081 {
0082 struct tomoyo_obj_info obj = { };
0083 struct path path;
0084 struct file_system_type *fstype = NULL;
0085 const char *requested_type = NULL;
0086 const char *requested_dir_name = NULL;
0087 const char *requested_dev_name = NULL;
0088 struct tomoyo_path_info rtype;
0089 struct tomoyo_path_info rdev;
0090 struct tomoyo_path_info rdir;
0091 int need_dev = 0;
0092 int error = -ENOMEM;
0093
0094 r->obj = &obj;
0095
0096
0097 requested_type = tomoyo_encode(type);
0098 if (!requested_type)
0099 goto out;
0100 rtype.name = requested_type;
0101 tomoyo_fill_path_info(&rtype);
0102
0103
0104 obj.path2 = *dir;
0105 requested_dir_name = tomoyo_realpath_from_path(dir);
0106 if (!requested_dir_name) {
0107 error = -ENOMEM;
0108 goto out;
0109 }
0110 rdir.name = requested_dir_name;
0111 tomoyo_fill_path_info(&rdir);
0112
0113
0114 if (type == tomoyo_mounts[TOMOYO_MOUNT_REMOUNT]) {
0115
0116 } else if (type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE] ||
0117 type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE] ||
0118 type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE] ||
0119 type == tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED]) {
0120
0121 } else if (type == tomoyo_mounts[TOMOYO_MOUNT_BIND] ||
0122 type == tomoyo_mounts[TOMOYO_MOUNT_MOVE]) {
0123 need_dev = -1;
0124 } else {
0125 fstype = get_fs_type(type);
0126 if (!fstype) {
0127 error = -ENODEV;
0128 goto out;
0129 }
0130 if (fstype->fs_flags & FS_REQUIRES_DEV)
0131
0132 need_dev = 1;
0133 }
0134 if (need_dev) {
0135
0136 if (!dev_name || kern_path(dev_name, LOOKUP_FOLLOW, &path)) {
0137 error = -ENOENT;
0138 goto out;
0139 }
0140 obj.path1 = path;
0141 requested_dev_name = tomoyo_realpath_from_path(&path);
0142 if (!requested_dev_name) {
0143 error = -ENOENT;
0144 goto out;
0145 }
0146 } else {
0147
0148 if (!dev_name)
0149 dev_name = "<NULL>";
0150 requested_dev_name = tomoyo_encode(dev_name);
0151 if (!requested_dev_name) {
0152 error = -ENOMEM;
0153 goto out;
0154 }
0155 }
0156 rdev.name = requested_dev_name;
0157 tomoyo_fill_path_info(&rdev);
0158 r->param_type = TOMOYO_TYPE_MOUNT_ACL;
0159 r->param.mount.need_dev = need_dev;
0160 r->param.mount.dev = &rdev;
0161 r->param.mount.dir = &rdir;
0162 r->param.mount.type = &rtype;
0163 r->param.mount.flags = flags;
0164 do {
0165 tomoyo_check_acl(r, tomoyo_check_mount_acl);
0166 error = tomoyo_audit_mount_log(r);
0167 } while (error == TOMOYO_RETRY_REQUEST);
0168 out:
0169 kfree(requested_dev_name);
0170 kfree(requested_dir_name);
0171 if (fstype)
0172 put_filesystem(fstype);
0173 kfree(requested_type);
0174
0175 if (obj.path1.dentry)
0176 path_put(&obj.path1);
0177 return error;
0178 }
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191 int tomoyo_mount_permission(const char *dev_name, const struct path *path,
0192 const char *type, unsigned long flags,
0193 void *data_page)
0194 {
0195 struct tomoyo_request_info r;
0196 int error;
0197 int idx;
0198
0199 if (tomoyo_init_request_info(&r, NULL, TOMOYO_MAC_FILE_MOUNT)
0200 == TOMOYO_CONFIG_DISABLED)
0201 return 0;
0202 if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
0203 flags &= ~MS_MGC_MSK;
0204 if (flags & MS_REMOUNT) {
0205 type = tomoyo_mounts[TOMOYO_MOUNT_REMOUNT];
0206 flags &= ~MS_REMOUNT;
0207 } else if (flags & MS_BIND) {
0208 type = tomoyo_mounts[TOMOYO_MOUNT_BIND];
0209 flags &= ~MS_BIND;
0210 } else if (flags & MS_SHARED) {
0211 if (flags & (MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
0212 return -EINVAL;
0213 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SHARED];
0214 flags &= ~MS_SHARED;
0215 } else if (flags & MS_PRIVATE) {
0216 if (flags & (MS_SHARED | MS_SLAVE | MS_UNBINDABLE))
0217 return -EINVAL;
0218 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_PRIVATE];
0219 flags &= ~MS_PRIVATE;
0220 } else if (flags & MS_SLAVE) {
0221 if (flags & (MS_SHARED | MS_PRIVATE | MS_UNBINDABLE))
0222 return -EINVAL;
0223 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_SLAVE];
0224 flags &= ~MS_SLAVE;
0225 } else if (flags & MS_UNBINDABLE) {
0226 if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE))
0227 return -EINVAL;
0228 type = tomoyo_mounts[TOMOYO_MOUNT_MAKE_UNBINDABLE];
0229 flags &= ~MS_UNBINDABLE;
0230 } else if (flags & MS_MOVE) {
0231 type = tomoyo_mounts[TOMOYO_MOUNT_MOVE];
0232 flags &= ~MS_MOVE;
0233 }
0234 if (!type)
0235 type = "<NULL>";
0236 idx = tomoyo_read_lock();
0237 error = tomoyo_mount_acl(&r, dev_name, path, type, flags);
0238 tomoyo_read_unlock(idx);
0239 return error;
0240 }