Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/security/tomoyo/group.c
10814 views
1
/*
2
* security/tomoyo/group.c
3
*
4
* Copyright (C) 2005-2010 NTT DATA CORPORATION
5
*/
6
7
#include <linux/slab.h>
8
#include "common.h"
9
10
static bool tomoyo_same_path_group(const struct tomoyo_acl_head *a,
11
const struct tomoyo_acl_head *b)
12
{
13
return container_of(a, struct tomoyo_path_group, head)->member_name ==
14
container_of(b, struct tomoyo_path_group, head)->member_name;
15
}
16
17
static bool tomoyo_same_number_group(const struct tomoyo_acl_head *a,
18
const struct tomoyo_acl_head *b)
19
{
20
return !memcmp(&container_of(a, struct tomoyo_number_group, head)
21
->number,
22
&container_of(b, struct tomoyo_number_group, head)
23
->number,
24
sizeof(container_of(a, struct tomoyo_number_group, head)
25
->number));
26
}
27
28
/**
29
* tomoyo_write_group - Write "struct tomoyo_path_group"/"struct tomoyo_number_group" list.
30
*
31
* @data: String to parse.
32
* @is_delete: True if it is a delete request.
33
* @type: Type of this group.
34
*
35
* Returns 0 on success, negative value otherwise.
36
*/
37
int tomoyo_write_group(char *data, const bool is_delete, const u8 type)
38
{
39
struct tomoyo_group *group;
40
struct list_head *member;
41
char *w[2];
42
int error = -EINVAL;
43
if (!tomoyo_tokenize(data, w, sizeof(w)) || !w[1][0])
44
return -EINVAL;
45
group = tomoyo_get_group(w[0], type);
46
if (!group)
47
return -ENOMEM;
48
member = &group->member_list;
49
if (type == TOMOYO_PATH_GROUP) {
50
struct tomoyo_path_group e = { };
51
e.member_name = tomoyo_get_name(w[1]);
52
if (!e.member_name) {
53
error = -ENOMEM;
54
goto out;
55
}
56
error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
57
member, tomoyo_same_path_group);
58
tomoyo_put_name(e.member_name);
59
} else if (type == TOMOYO_NUMBER_GROUP) {
60
struct tomoyo_number_group e = { };
61
if (w[1][0] == '@'
62
|| !tomoyo_parse_number_union(w[1], &e.number)
63
|| e.number.values[0] > e.number.values[1])
64
goto out;
65
error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
66
member, tomoyo_same_number_group);
67
/*
68
* tomoyo_put_number_union() is not needed because
69
* w[1][0] != '@'.
70
*/
71
}
72
out:
73
tomoyo_put_group(group);
74
return error;
75
}
76
77
/**
78
* tomoyo_path_matches_group - Check whether the given pathname matches members of the given pathname group.
79
*
80
* @pathname: The name of pathname.
81
* @group: Pointer to "struct tomoyo_path_group".
82
*
83
* Returns matched member's pathname if @pathname matches pathnames in @group,
84
* NULL otherwise.
85
*
86
* Caller holds tomoyo_read_lock().
87
*/
88
const struct tomoyo_path_info *
89
tomoyo_path_matches_group(const struct tomoyo_path_info *pathname,
90
const struct tomoyo_group *group)
91
{
92
struct tomoyo_path_group *member;
93
list_for_each_entry_rcu(member, &group->member_list, head.list) {
94
if (member->head.is_deleted)
95
continue;
96
if (!tomoyo_path_matches_pattern(pathname, member->member_name))
97
continue;
98
return member->member_name;
99
}
100
return NULL;
101
}
102
103
/**
104
* tomoyo_number_matches_group - Check whether the given number matches members of the given number group.
105
*
106
* @min: Min number.
107
* @max: Max number.
108
* @group: Pointer to "struct tomoyo_number_group".
109
*
110
* Returns true if @min and @max partially overlaps @group, false otherwise.
111
*
112
* Caller holds tomoyo_read_lock().
113
*/
114
bool tomoyo_number_matches_group(const unsigned long min,
115
const unsigned long max,
116
const struct tomoyo_group *group)
117
{
118
struct tomoyo_number_group *member;
119
bool matched = false;
120
list_for_each_entry_rcu(member, &group->member_list, head.list) {
121
if (member->head.is_deleted)
122
continue;
123
if (min > member->number.values[1] ||
124
max < member->number.values[0])
125
continue;
126
matched = true;
127
break;
128
}
129
return matched;
130
}
131
132