Skip to content

Commit a5e3449

Browse files
hdmdaviespcmoore
authored andcommitted
netlabel: Add support for querying a CALIPSO DOI.
Query a specified DOI through the NLBL_CALIPSO_C_LIST command. It requires the attribute: NLBL_CALIPSO_A_DOI. The reply will contain: NLBL_CALIPSO_A_MTYPE Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
1 parent cb72d38 commit a5e3449

File tree

4 files changed

+193
-0
lines changed

4 files changed

+193
-0
lines changed

include/net/netlabel.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ struct netlbl_lsm_secattr {
223223
* struct netlbl_calipso_ops - NetLabel CALIPSO operations
224224
* @doi_add: add a CALIPSO DOI
225225
* @doi_free: free a CALIPSO DOI
226+
* @doi_getdef: returns a reference to a DOI
227+
* @doi_putdef: releases a reference of a DOI
226228
*
227229
* Description:
228230
* This structure is filled out by the CALIPSO engine and passed
@@ -234,6 +236,8 @@ struct netlbl_calipso_ops {
234236
int (*doi_add)(struct calipso_doi *doi_def,
235237
struct netlbl_audit *audit_info);
236238
void (*doi_free)(struct calipso_doi *doi_def);
239+
struct calipso_doi *(*doi_getdef)(u32 doi);
240+
void (*doi_putdef)(struct calipso_doi *doi_def);
237241
};
238242

239243
/*

net/ipv6/calipso.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,77 @@ static void calipso_doi_free(struct calipso_doi *doi_def)
144144
kfree(doi_def);
145145
}
146146

147+
/**
148+
* calipso_doi_free_rcu - Frees a DOI definition via the RCU pointer
149+
* @entry: the entry's RCU field
150+
*
151+
* Description:
152+
* This function is designed to be used as a callback to the call_rcu()
153+
* function so that the memory allocated to the DOI definition can be released
154+
* safely.
155+
*
156+
*/
157+
static void calipso_doi_free_rcu(struct rcu_head *entry)
158+
{
159+
struct calipso_doi *doi_def;
160+
161+
doi_def = container_of(entry, struct calipso_doi, rcu);
162+
calipso_doi_free(doi_def);
163+
}
164+
165+
/**
166+
* calipso_doi_getdef - Returns a reference to a valid DOI definition
167+
* @doi: the DOI value
168+
*
169+
* Description:
170+
* Searches for a valid DOI definition and if one is found it is returned to
171+
* the caller. Otherwise NULL is returned. The caller must ensure that
172+
* calipso_doi_putdef() is called when the caller is done.
173+
*
174+
*/
175+
static struct calipso_doi *calipso_doi_getdef(u32 doi)
176+
{
177+
struct calipso_doi *doi_def;
178+
179+
rcu_read_lock();
180+
doi_def = calipso_doi_search(doi);
181+
if (!doi_def)
182+
goto doi_getdef_return;
183+
if (!atomic_inc_not_zero(&doi_def->refcount))
184+
doi_def = NULL;
185+
186+
doi_getdef_return:
187+
rcu_read_unlock();
188+
return doi_def;
189+
}
190+
191+
/**
192+
* calipso_doi_putdef - Releases a reference for the given DOI definition
193+
* @doi_def: the DOI definition
194+
*
195+
* Description:
196+
* Releases a DOI definition reference obtained from calipso_doi_getdef().
197+
*
198+
*/
199+
static void calipso_doi_putdef(struct calipso_doi *doi_def)
200+
{
201+
if (!doi_def)
202+
return;
203+
204+
if (!atomic_dec_and_test(&doi_def->refcount))
205+
return;
206+
spin_lock(&calipso_doi_list_lock);
207+
list_del_rcu(&doi_def->list);
208+
spin_unlock(&calipso_doi_list_lock);
209+
210+
call_rcu(&doi_def->rcu, calipso_doi_free_rcu);
211+
}
212+
147213
static const struct netlbl_calipso_ops ops = {
148214
.doi_add = calipso_doi_add,
149215
.doi_free = calipso_doi_free,
216+
.doi_getdef = calipso_doi_getdef,
217+
.doi_putdef = calipso_doi_putdef,
150218
};
151219

152220
/**

net/netlabel/netlabel_calipso.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,65 @@ static int netlbl_calipso_add(struct sk_buff *skb, struct genl_info *info)
124124
return ret_val;
125125
}
126126

127+
/**
128+
* netlbl_calipso_list - Handle a LIST message
129+
* @skb: the NETLINK buffer
130+
* @info: the Generic NETLINK info block
131+
*
132+
* Description:
133+
* Process a user generated LIST message and respond accordingly.
134+
* Returns zero on success and negative values on error.
135+
*
136+
*/
137+
static int netlbl_calipso_list(struct sk_buff *skb, struct genl_info *info)
138+
{
139+
int ret_val;
140+
struct sk_buff *ans_skb = NULL;
141+
void *data;
142+
u32 doi;
143+
struct calipso_doi *doi_def;
144+
145+
if (!info->attrs[NLBL_CALIPSO_A_DOI]) {
146+
ret_val = -EINVAL;
147+
goto list_failure;
148+
}
149+
150+
doi = nla_get_u32(info->attrs[NLBL_CALIPSO_A_DOI]);
151+
152+
doi_def = calipso_doi_getdef(doi);
153+
if (!doi_def) {
154+
ret_val = -EINVAL;
155+
goto list_failure;
156+
}
157+
158+
ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
159+
if (!ans_skb) {
160+
ret_val = -ENOMEM;
161+
goto list_failure_put;
162+
}
163+
data = genlmsg_put_reply(ans_skb, info, &netlbl_calipso_gnl_family,
164+
0, NLBL_CALIPSO_C_LIST);
165+
if (!data) {
166+
ret_val = -ENOMEM;
167+
goto list_failure_put;
168+
}
169+
170+
ret_val = nla_put_u32(ans_skb, NLBL_CALIPSO_A_MTYPE, doi_def->type);
171+
if (ret_val != 0)
172+
goto list_failure_put;
173+
174+
calipso_doi_putdef(doi_def);
175+
176+
genlmsg_end(ans_skb, data);
177+
return genlmsg_reply(ans_skb, info);
178+
179+
list_failure_put:
180+
calipso_doi_putdef(doi_def);
181+
list_failure:
182+
kfree_skb(ans_skb);
183+
return ret_val;
184+
}
185+
127186
/* NetLabel Generic NETLINK Command Definitions
128187
*/
129188

@@ -135,6 +194,13 @@ static const struct genl_ops netlbl_calipso_ops[] = {
135194
.doit = netlbl_calipso_add,
136195
.dumpit = NULL,
137196
},
197+
{
198+
.cmd = NLBL_CALIPSO_C_LIST,
199+
.flags = 0,
200+
.policy = calipso_genl_policy,
201+
.doit = netlbl_calipso_list,
202+
.dumpit = NULL,
203+
},
138204
};
139205

140206
/* NetLabel Generic NETLINK Protocol Functions
@@ -214,3 +280,39 @@ void calipso_doi_free(struct calipso_doi *doi_def)
214280
if (ops)
215281
ops->doi_free(doi_def);
216282
}
283+
284+
/**
285+
* calipso_doi_getdef - Returns a reference to a valid DOI definition
286+
* @doi: the DOI value
287+
*
288+
* Description:
289+
* Searches for a valid DOI definition and if one is found it is returned to
290+
* the caller. Otherwise NULL is returned. The caller must ensure that
291+
* calipso_doi_putdef() is called when the caller is done.
292+
*
293+
*/
294+
struct calipso_doi *calipso_doi_getdef(u32 doi)
295+
{
296+
struct calipso_doi *ret_val = NULL;
297+
const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
298+
299+
if (ops)
300+
ret_val = ops->doi_getdef(doi);
301+
return ret_val;
302+
}
303+
304+
/**
305+
* calipso_doi_putdef - Releases a reference for the given DOI definition
306+
* @doi_def: the DOI definition
307+
*
308+
* Description:
309+
* Releases a DOI definition reference obtained from calipso_doi_getdef().
310+
*
311+
*/
312+
void calipso_doi_putdef(struct calipso_doi *doi_def)
313+
{
314+
const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
315+
316+
if (ops)
317+
ops->doi_putdef(doi_def);
318+
}

net/netlabel/netlabel_calipso.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,23 @@
4646
*
4747
* If using CALIPSO_MAP_PASS no additional attributes are required.
4848
*
49+
* o LIST:
50+
* Sent by an application to list the details of a DOI definition. On
51+
* success the kernel should send a response using the following format.
52+
*
53+
* Required attributes:
54+
*
55+
* NLBL_CALIPSO_A_DOI
56+
*
57+
* The valid response message format depends on the type of the DOI mapping,
58+
* the defined formats are shown below.
59+
*
60+
* Required attributes:
61+
*
62+
* NLBL_CALIPSO_A_MTYPE
63+
*
64+
* If using CALIPSO_MAP_PASS no additional attributes are required.
65+
*
4966
*/
5067

5168
/* NetLabel CALIPSO commands */
@@ -86,5 +103,7 @@ static inline int netlbl_calipso_genl_init(void)
86103
int calipso_doi_add(struct calipso_doi *doi_def,
87104
struct netlbl_audit *audit_info);
88105
void calipso_doi_free(struct calipso_doi *doi_def);
106+
struct calipso_doi *calipso_doi_getdef(u32 doi);
107+
void calipso_doi_putdef(struct calipso_doi *doi_def);
89108

90109
#endif

0 commit comments

Comments
 (0)