|
@@ -15,15 +15,6 @@
|
|
|
#include <linux/rcupdate.h>
|
|
|
#include <linux/mutex.h>
|
|
|
|
|
|
-#define ACC_MKNOD 1
|
|
|
-#define ACC_READ 2
|
|
|
-#define ACC_WRITE 4
|
|
|
-#define ACC_MASK (ACC_MKNOD | ACC_READ | ACC_WRITE)
|
|
|
-
|
|
|
-#define DEV_BLOCK 1
|
|
|
-#define DEV_CHAR 2
|
|
|
-#define DEV_ALL 4 /* this represents all devices */
|
|
|
-
|
|
|
static DEFINE_MUTEX(devcgroup_mutex);
|
|
|
|
|
|
enum devcg_behavior {
|
|
@@ -246,21 +237,21 @@ static void set_access(char *acc, short access)
|
|
|
{
|
|
|
int idx = 0;
|
|
|
memset(acc, 0, ACCLEN);
|
|
|
- if (access & ACC_READ)
|
|
|
+ if (access & DEVCG_ACC_READ)
|
|
|
acc[idx++] = 'r';
|
|
|
- if (access & ACC_WRITE)
|
|
|
+ if (access & DEVCG_ACC_WRITE)
|
|
|
acc[idx++] = 'w';
|
|
|
- if (access & ACC_MKNOD)
|
|
|
+ if (access & DEVCG_ACC_MKNOD)
|
|
|
acc[idx++] = 'm';
|
|
|
}
|
|
|
|
|
|
static char type_to_char(short type)
|
|
|
{
|
|
|
- if (type == DEV_ALL)
|
|
|
+ if (type == DEVCG_DEV_ALL)
|
|
|
return 'a';
|
|
|
- if (type == DEV_CHAR)
|
|
|
+ if (type == DEVCG_DEV_CHAR)
|
|
|
return 'c';
|
|
|
- if (type == DEV_BLOCK)
|
|
|
+ if (type == DEVCG_DEV_BLOCK)
|
|
|
return 'b';
|
|
|
return 'X';
|
|
|
}
|
|
@@ -287,10 +278,10 @@ static int devcgroup_seq_show(struct seq_file *m, void *v)
|
|
|
* This way, the file remains as a "whitelist of devices"
|
|
|
*/
|
|
|
if (devcgroup->behavior == DEVCG_DEFAULT_ALLOW) {
|
|
|
- set_access(acc, ACC_MASK);
|
|
|
+ set_access(acc, DEVCG_ACC_MASK);
|
|
|
set_majmin(maj, ~0);
|
|
|
set_majmin(min, ~0);
|
|
|
- seq_printf(m, "%c %s:%s %s\n", type_to_char(DEV_ALL),
|
|
|
+ seq_printf(m, "%c %s:%s %s\n", type_to_char(DEVCG_DEV_ALL),
|
|
|
maj, min, acc);
|
|
|
} else {
|
|
|
list_for_each_entry_rcu(ex, &devcgroup->exceptions, list) {
|
|
@@ -309,10 +300,10 @@ static int devcgroup_seq_show(struct seq_file *m, void *v)
|
|
|
/**
|
|
|
* match_exception - iterates the exception list trying to find a complete match
|
|
|
* @exceptions: list of exceptions
|
|
|
- * @type: device type (DEV_BLOCK or DEV_CHAR)
|
|
|
+ * @type: device type (DEVCG_DEV_BLOCK or DEVCG_DEV_CHAR)
|
|
|
* @major: device file major number, ~0 to match all
|
|
|
* @minor: device file minor number, ~0 to match all
|
|
|
- * @access: permission mask (ACC_READ, ACC_WRITE, ACC_MKNOD)
|
|
|
+ * @access: permission mask (DEVCG_ACC_READ, DEVCG_ACC_WRITE, DEVCG_ACC_MKNOD)
|
|
|
*
|
|
|
* It is considered a complete match if an exception is found that will
|
|
|
* contain the entire range of provided parameters.
|
|
@@ -325,9 +316,9 @@ static bool match_exception(struct list_head *exceptions, short type,
|
|
|
struct dev_exception_item *ex;
|
|
|
|
|
|
list_for_each_entry_rcu(ex, exceptions, list) {
|
|
|
- if ((type & DEV_BLOCK) && !(ex->type & DEV_BLOCK))
|
|
|
+ if ((type & DEVCG_DEV_BLOCK) && !(ex->type & DEVCG_DEV_BLOCK))
|
|
|
continue;
|
|
|
- if ((type & DEV_CHAR) && !(ex->type & DEV_CHAR))
|
|
|
+ if ((type & DEVCG_DEV_CHAR) && !(ex->type & DEVCG_DEV_CHAR))
|
|
|
continue;
|
|
|
if (ex->major != ~0 && ex->major != major)
|
|
|
continue;
|
|
@@ -344,10 +335,10 @@ static bool match_exception(struct list_head *exceptions, short type,
|
|
|
/**
|
|
|
* match_exception_partial - iterates the exception list trying to find a partial match
|
|
|
* @exceptions: list of exceptions
|
|
|
- * @type: device type (DEV_BLOCK or DEV_CHAR)
|
|
|
+ * @type: device type (DEVCG_DEV_BLOCK or DEVCG_DEV_CHAR)
|
|
|
* @major: device file major number, ~0 to match all
|
|
|
* @minor: device file minor number, ~0 to match all
|
|
|
- * @access: permission mask (ACC_READ, ACC_WRITE, ACC_MKNOD)
|
|
|
+ * @access: permission mask (DEVCG_ACC_READ, DEVCG_ACC_WRITE, DEVCG_ACC_MKNOD)
|
|
|
*
|
|
|
* It is considered a partial match if an exception's range is found to
|
|
|
* contain *any* of the devices specified by provided parameters. This is
|
|
@@ -362,9 +353,9 @@ static bool match_exception_partial(struct list_head *exceptions, short type,
|
|
|
struct dev_exception_item *ex;
|
|
|
|
|
|
list_for_each_entry_rcu(ex, exceptions, list) {
|
|
|
- if ((type & DEV_BLOCK) && !(ex->type & DEV_BLOCK))
|
|
|
+ if ((type & DEVCG_DEV_BLOCK) && !(ex->type & DEVCG_DEV_BLOCK))
|
|
|
continue;
|
|
|
- if ((type & DEV_CHAR) && !(ex->type & DEV_CHAR))
|
|
|
+ if ((type & DEVCG_DEV_CHAR) && !(ex->type & DEVCG_DEV_CHAR))
|
|
|
continue;
|
|
|
/*
|
|
|
* We must be sure that both the exception and the provided
|
|
@@ -647,10 +638,10 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
|
|
|
}
|
|
|
return 0;
|
|
|
case 'b':
|
|
|
- ex.type = DEV_BLOCK;
|
|
|
+ ex.type = DEVCG_DEV_BLOCK;
|
|
|
break;
|
|
|
case 'c':
|
|
|
- ex.type = DEV_CHAR;
|
|
|
+ ex.type = DEVCG_DEV_CHAR;
|
|
|
break;
|
|
|
default:
|
|
|
return -EINVAL;
|
|
@@ -703,13 +694,13 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
|
|
|
for (b++, count = 0; count < 3; count++, b++) {
|
|
|
switch (*b) {
|
|
|
case 'r':
|
|
|
- ex.access |= ACC_READ;
|
|
|
+ ex.access |= DEVCG_ACC_READ;
|
|
|
break;
|
|
|
case 'w':
|
|
|
- ex.access |= ACC_WRITE;
|
|
|
+ ex.access |= DEVCG_ACC_WRITE;
|
|
|
break;
|
|
|
case 'm':
|
|
|
- ex.access |= ACC_MKNOD;
|
|
|
+ ex.access |= DEVCG_ACC_MKNOD;
|
|
|
break;
|
|
|
case '\n':
|
|
|
case '\0':
|
|
@@ -806,12 +797,12 @@ struct cgroup_subsys devices_cgrp_subsys = {
|
|
|
* @type: device type
|
|
|
* @major: device major number
|
|
|
* @minor: device minor number
|
|
|
- * @access: combination of ACC_WRITE, ACC_READ and ACC_MKNOD
|
|
|
+ * @access: combination of DEVCG_ACC_WRITE, DEVCG_ACC_READ and DEVCG_ACC_MKNOD
|
|
|
*
|
|
|
* returns 0 on success, -EPERM case the operation is not permitted
|
|
|
*/
|
|
|
-static int __devcgroup_check_permission(short type, u32 major, u32 minor,
|
|
|
- short access)
|
|
|
+int __devcgroup_check_permission(short type, u32 major, u32 minor,
|
|
|
+ short access)
|
|
|
{
|
|
|
struct dev_cgroup *dev_cgroup;
|
|
|
bool rc;
|
|
@@ -833,37 +824,3 @@ static int __devcgroup_check_permission(short type, u32 major, u32 minor,
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
-
|
|
|
-int __devcgroup_inode_permission(struct inode *inode, int mask)
|
|
|
-{
|
|
|
- short type, access = 0;
|
|
|
-
|
|
|
- if (S_ISBLK(inode->i_mode))
|
|
|
- type = DEV_BLOCK;
|
|
|
- if (S_ISCHR(inode->i_mode))
|
|
|
- type = DEV_CHAR;
|
|
|
- if (mask & MAY_WRITE)
|
|
|
- access |= ACC_WRITE;
|
|
|
- if (mask & MAY_READ)
|
|
|
- access |= ACC_READ;
|
|
|
-
|
|
|
- return __devcgroup_check_permission(type, imajor(inode), iminor(inode),
|
|
|
- access);
|
|
|
-}
|
|
|
-
|
|
|
-int devcgroup_inode_mknod(int mode, dev_t dev)
|
|
|
-{
|
|
|
- short type;
|
|
|
-
|
|
|
- if (!S_ISBLK(mode) && !S_ISCHR(mode))
|
|
|
- return 0;
|
|
|
-
|
|
|
- if (S_ISBLK(mode))
|
|
|
- type = DEV_BLOCK;
|
|
|
- else
|
|
|
- type = DEV_CHAR;
|
|
|
-
|
|
|
- return __devcgroup_check_permission(type, MAJOR(dev), MINOR(dev),
|
|
|
- ACC_MKNOD);
|
|
|
-
|
|
|
-}
|