aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2010-10-13 16:24:41 -0400
committerJames Morris <jmorris@namei.org>2010-10-20 19:12:48 -0400
commit2606fd1fa5710205b23ee859563502aa18362447 (patch)
treef79becd7010a2da1a765829fce0e09327cd50531
parent15714f7b58011cf3948cab2988abea560240c74f (diff)
secmark: make secmark object handling generic
Right now secmark has lots of direct selinux calls. Use all LSM calls and remove all SELinux specific knowledge. The only SELinux specific knowledge we leave is the mode. The only point is to make sure that other LSMs at least test this generic code before they assume it works. (They may also have to make changes if they do not represent labels as strings) Signed-off-by: Eric Paris <eparis@redhat.com> Acked-by: Paul Moore <paul.moore@hp.com> Acked-by: Patrick McHardy <kaber@trash.net> Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r--include/linux/netfilter/xt_SECMARK.h12
-rw-r--r--include/linux/security.h25
-rw-r--r--include/linux/selinux.h63
-rw-r--r--net/netfilter/xt_CT.c1
-rw-r--r--net/netfilter/xt_SECMARK.c35
-rw-r--r--security/capability.c17
-rw-r--r--security/security.c18
-rw-r--r--security/selinux/exports.c49
-rw-r--r--security/selinux/hooks.c24
-rw-r--r--security/selinux/include/security.h1
10 files changed, 104 insertions, 141 deletions
diff --git a/include/linux/netfilter/xt_SECMARK.h b/include/linux/netfilter/xt_SECMARK.h
index 6fcd3448b186..989092bd6274 100644
--- a/include/linux/netfilter/xt_SECMARK.h
+++ b/include/linux/netfilter/xt_SECMARK.h
@@ -11,18 +11,12 @@
11 * packets are being marked for. 11 * packets are being marked for.
12 */ 12 */
13#define SECMARK_MODE_SEL 0x01 /* SELinux */ 13#define SECMARK_MODE_SEL 0x01 /* SELinux */
14#define SECMARK_SELCTX_MAX 256 14#define SECMARK_SECCTX_MAX 256
15
16struct xt_secmark_target_selinux_info {
17 __u32 selsid;
18 char selctx[SECMARK_SELCTX_MAX];
19};
20 15
21struct xt_secmark_target_info { 16struct xt_secmark_target_info {
22 __u8 mode; 17 __u8 mode;
23 union { 18 __u32 secid;
24 struct xt_secmark_target_selinux_info sel; 19 char secctx[SECMARK_SECCTX_MAX];
25 } u;
26}; 20};
27 21
28#endif /*_XT_SECMARK_H_target */ 22#endif /*_XT_SECMARK_H_target */
diff --git a/include/linux/security.h b/include/linux/security.h
index 294a0b228123..d70adc394f62 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -959,6 +959,12 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
959 * Sets the new child socket's sid to the openreq sid. 959 * Sets the new child socket's sid to the openreq sid.
960 * @inet_conn_established: 960 * @inet_conn_established:
961 * Sets the connection's peersid to the secmark on skb. 961 * Sets the connection's peersid to the secmark on skb.
962 * @secmark_relabel_packet:
963 * check if the process should be allowed to relabel packets to the given secid
964 * @security_secmark_refcount_inc
965 * tells the LSM to increment the number of secmark labeling rules loaded
966 * @security_secmark_refcount_dec
967 * tells the LSM to decrement the number of secmark labeling rules loaded
962 * @req_classify_flow: 968 * @req_classify_flow:
963 * Sets the flow's sid to the openreq sid. 969 * Sets the flow's sid to the openreq sid.
964 * @tun_dev_create: 970 * @tun_dev_create:
@@ -1593,6 +1599,9 @@ struct security_operations {
1593 struct request_sock *req); 1599 struct request_sock *req);
1594 void (*inet_csk_clone) (struct sock *newsk, const struct request_sock *req); 1600 void (*inet_csk_clone) (struct sock *newsk, const struct request_sock *req);
1595 void (*inet_conn_established) (struct sock *sk, struct sk_buff *skb); 1601 void (*inet_conn_established) (struct sock *sk, struct sk_buff *skb);
1602 int (*secmark_relabel_packet) (u32 secid);
1603 void (*secmark_refcount_inc) (void);
1604 void (*secmark_refcount_dec) (void);
1596 void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl); 1605 void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl);
1597 int (*tun_dev_create)(void); 1606 int (*tun_dev_create)(void);
1598 void (*tun_dev_post_create)(struct sock *sk); 1607 void (*tun_dev_post_create)(struct sock *sk);
@@ -2547,6 +2556,9 @@ void security_inet_csk_clone(struct sock *newsk,
2547 const struct request_sock *req); 2556 const struct request_sock *req);
2548void security_inet_conn_established(struct sock *sk, 2557void security_inet_conn_established(struct sock *sk,
2549 struct sk_buff *skb); 2558 struct sk_buff *skb);
2559int security_secmark_relabel_packet(u32 secid);
2560void security_secmark_refcount_inc(void);
2561void security_secmark_refcount_dec(void);
2550int security_tun_dev_create(void); 2562int security_tun_dev_create(void);
2551void security_tun_dev_post_create(struct sock *sk); 2563void security_tun_dev_post_create(struct sock *sk);
2552int security_tun_dev_attach(struct sock *sk); 2564int security_tun_dev_attach(struct sock *sk);
@@ -2701,6 +2713,19 @@ static inline void security_inet_conn_established(struct sock *sk,
2701{ 2713{
2702} 2714}
2703 2715
2716static inline int security_secmark_relabel_packet(u32 secid)
2717{
2718 return 0;
2719}
2720
2721static inline void security_secmark_refcount_inc(void)
2722{
2723}
2724
2725static inline void security_secmark_refcount_dec(void)
2726{
2727}
2728
2704static inline int security_tun_dev_create(void) 2729static inline int security_tun_dev_create(void)
2705{ 2730{
2706 return 0; 2731 return 0;
diff --git a/include/linux/selinux.h b/include/linux/selinux.h
index 82e0f26a1299..44f459612690 100644
--- a/include/linux/selinux.h
+++ b/include/linux/selinux.h
@@ -21,74 +21,11 @@ struct kern_ipc_perm;
21#ifdef CONFIG_SECURITY_SELINUX 21#ifdef CONFIG_SECURITY_SELINUX
22 22
23/** 23/**
24 * selinux_string_to_sid - map a security context string to a security ID
25 * @str: the security context string to be mapped
26 * @sid: ID value returned via this.
27 *
28 * Returns 0 if successful, with the SID stored in sid. A value
29 * of zero for sid indicates no SID could be determined (but no error
30 * occurred).
31 */
32int selinux_string_to_sid(char *str, u32 *sid);
33
34/**
35 * selinux_secmark_relabel_packet_permission - secmark permission check
36 * @sid: SECMARK ID value to be applied to network packet
37 *
38 * Returns 0 if the current task is allowed to set the SECMARK label of
39 * packets with the supplied security ID. Note that it is implicit that
40 * the packet is always being relabeled from the default unlabeled value,
41 * and that the access control decision is made in the AVC.
42 */
43int selinux_secmark_relabel_packet_permission(u32 sid);
44
45/**
46 * selinux_secmark_refcount_inc - increments the secmark use counter
47 *
48 * SELinux keeps track of the current SECMARK targets in use so it knows
49 * when to apply SECMARK label access checks to network packets. This
50 * function incements this reference count to indicate that a new SECMARK
51 * target has been configured.
52 */
53void selinux_secmark_refcount_inc(void);
54
55/**
56 * selinux_secmark_refcount_dec - decrements the secmark use counter
57 *
58 * SELinux keeps track of the current SECMARK targets in use so it knows
59 * when to apply SECMARK label access checks to network packets. This
60 * function decements this reference count to indicate that one of the
61 * existing SECMARK targets has been removed/flushed.
62 */
63void selinux_secmark_refcount_dec(void);
64
65/**
66 * selinux_is_enabled - is SELinux enabled? 24 * selinux_is_enabled - is SELinux enabled?
67 */ 25 */
68bool selinux_is_enabled(void); 26bool selinux_is_enabled(void);
69#else 27#else
70 28
71static inline int selinux_string_to_sid(const char *str, u32 *sid)
72{
73 *sid = 0;
74 return 0;
75}
76
77static inline int selinux_secmark_relabel_packet_permission(u32 sid)
78{
79 return 0;
80}
81
82static inline void selinux_secmark_refcount_inc(void)
83{
84 return;
85}
86
87static inline void selinux_secmark_refcount_dec(void)
88{
89 return;
90}
91
92static inline bool selinux_is_enabled(void) 29static inline bool selinux_is_enabled(void)
93{ 30{
94 return false; 31 return false;
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c
index 0cb6053f02fd..782e51986a6f 100644
--- a/net/netfilter/xt_CT.c
+++ b/net/netfilter/xt_CT.c
@@ -9,7 +9,6 @@
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/gfp.h> 10#include <linux/gfp.h>
11#include <linux/skbuff.h> 11#include <linux/skbuff.h>
12#include <linux/selinux.h>
13#include <linux/netfilter_ipv4/ip_tables.h> 12#include <linux/netfilter_ipv4/ip_tables.h>
14#include <linux/netfilter_ipv6/ip6_tables.h> 13#include <linux/netfilter_ipv6/ip6_tables.h>
15#include <linux/netfilter/x_tables.h> 14#include <linux/netfilter/x_tables.h>
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index 364ad1600129..9faf5e050b79 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -14,8 +14,8 @@
14 */ 14 */
15#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 15#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/security.h>
17#include <linux/skbuff.h> 18#include <linux/skbuff.h>
18#include <linux/selinux.h>
19#include <linux/netfilter/x_tables.h> 19#include <linux/netfilter/x_tables.h>
20#include <linux/netfilter/xt_SECMARK.h> 20#include <linux/netfilter/xt_SECMARK.h>
21 21
@@ -39,9 +39,8 @@ secmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
39 39
40 switch (mode) { 40 switch (mode) {
41 case SECMARK_MODE_SEL: 41 case SECMARK_MODE_SEL:
42 secmark = info->u.sel.selsid; 42 secmark = info->secid;
43 break; 43 break;
44
45 default: 44 default:
46 BUG(); 45 BUG();
47 } 46 }
@@ -50,33 +49,33 @@ secmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
50 return XT_CONTINUE; 49 return XT_CONTINUE;
51} 50}
52 51
53static int checkentry_selinux(struct xt_secmark_target_info *info) 52static int checkentry_lsm(struct xt_secmark_target_info *info)
54{ 53{
55 int err; 54 int err;
56 struct xt_secmark_target_selinux_info *sel = &info->u.sel;
57 55
58 sel->selctx[SECMARK_SELCTX_MAX - 1] = '\0'; 56 info->secctx[SECMARK_SECCTX_MAX - 1] = '\0';
57 info->secid = 0;
59 58
60 err = selinux_string_to_sid(sel->selctx, &sel->selsid); 59 err = security_secctx_to_secid(info->secctx, strlen(info->secctx),
60 &info->secid);
61 if (err) { 61 if (err) {
62 if (err == -EINVAL) 62 if (err == -EINVAL)
63 pr_info("invalid SELinux context \'%s\'\n", 63 pr_info("invalid security context \'%s\'\n", info->secctx);
64 sel->selctx);
65 return err; 64 return err;
66 } 65 }
67 66
68 if (!sel->selsid) { 67 if (!info->secid) {
69 pr_info("unable to map SELinux context \'%s\'\n", sel->selctx); 68 pr_info("unable to map security context \'%s\'\n", info->secctx);
70 return -ENOENT; 69 return -ENOENT;
71 } 70 }
72 71
73 err = selinux_secmark_relabel_packet_permission(sel->selsid); 72 err = security_secmark_relabel_packet(info->secid);
74 if (err) { 73 if (err) {
75 pr_info("unable to obtain relabeling permission\n"); 74 pr_info("unable to obtain relabeling permission\n");
76 return err; 75 return err;
77 } 76 }
78 77
79 selinux_secmark_refcount_inc(); 78 security_secmark_refcount_inc();
80 return 0; 79 return 0;
81} 80}
82 81
@@ -100,16 +99,16 @@ static int secmark_tg_check(const struct xt_tgchk_param *par)
100 99
101 switch (info->mode) { 100 switch (info->mode) {
102 case SECMARK_MODE_SEL: 101 case SECMARK_MODE_SEL:
103 err = checkentry_selinux(info);
104 if (err)
105 return err;
106 break; 102 break;
107
108 default: 103 default:
109 pr_info("invalid mode: %hu\n", info->mode); 104 pr_info("invalid mode: %hu\n", info->mode);
110 return -EINVAL; 105 return -EINVAL;
111 } 106 }
112 107
108 err = checkentry_lsm(info);
109 if (err)
110 return err;
111
113 if (!mode) 112 if (!mode)
114 mode = info->mode; 113 mode = info->mode;
115 return 0; 114 return 0;
@@ -119,7 +118,7 @@ static void secmark_tg_destroy(const struct xt_tgdtor_param *par)
119{ 118{
120 switch (mode) { 119 switch (mode) {
121 case SECMARK_MODE_SEL: 120 case SECMARK_MODE_SEL:
122 selinux_secmark_refcount_dec(); 121 security_secmark_refcount_dec();
123 } 122 }
124} 123}
125 124
diff --git a/security/capability.c b/security/capability.c
index 95a6599a37bb..30ae00fbecd5 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -677,7 +677,18 @@ static void cap_inet_conn_established(struct sock *sk, struct sk_buff *skb)
677{ 677{
678} 678}
679 679
680static int cap_secmark_relabel_packet(u32 secid)
681{
682 return 0;
683}
680 684
685static void cap_secmark_refcount_inc(void)
686{
687}
688
689static void cap_secmark_refcount_dec(void)
690{
691}
681 692
682static void cap_req_classify_flow(const struct request_sock *req, 693static void cap_req_classify_flow(const struct request_sock *req,
683 struct flowi *fl) 694 struct flowi *fl)
@@ -777,7 +788,8 @@ static int cap_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
777 788
778static int cap_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) 789static int cap_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
779{ 790{
780 return -EOPNOTSUPP; 791 *secid = 0;
792 return 0;
781} 793}
782 794
783static void cap_release_secctx(char *secdata, u32 seclen) 795static void cap_release_secctx(char *secdata, u32 seclen)
@@ -1018,6 +1030,9 @@ void __init security_fixup_ops(struct security_operations *ops)
1018 set_to_cap_if_null(ops, inet_conn_request); 1030 set_to_cap_if_null(ops, inet_conn_request);
1019 set_to_cap_if_null(ops, inet_csk_clone); 1031 set_to_cap_if_null(ops, inet_csk_clone);
1020 set_to_cap_if_null(ops, inet_conn_established); 1032 set_to_cap_if_null(ops, inet_conn_established);
1033 set_to_cap_if_null(ops, secmark_relabel_packet);
1034 set_to_cap_if_null(ops, secmark_refcount_inc);
1035 set_to_cap_if_null(ops, secmark_refcount_dec);
1021 set_to_cap_if_null(ops, req_classify_flow); 1036 set_to_cap_if_null(ops, req_classify_flow);
1022 set_to_cap_if_null(ops, tun_dev_create); 1037 set_to_cap_if_null(ops, tun_dev_create);
1023 set_to_cap_if_null(ops, tun_dev_post_create); 1038 set_to_cap_if_null(ops, tun_dev_post_create);
diff --git a/security/security.c b/security/security.c
index 1cbcdfa4b015..b50f472061a4 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1136,6 +1136,24 @@ void security_inet_conn_established(struct sock *sk,
1136 security_ops->inet_conn_established(sk, skb); 1136 security_ops->inet_conn_established(sk, skb);
1137} 1137}
1138 1138
1139int security_secmark_relabel_packet(u32 secid)
1140{
1141 return security_ops->secmark_relabel_packet(secid);
1142}
1143EXPORT_SYMBOL(security_secmark_relabel_packet);
1144
1145void security_secmark_refcount_inc(void)
1146{
1147 security_ops->secmark_refcount_inc();
1148}
1149EXPORT_SYMBOL(security_secmark_refcount_inc);
1150
1151void security_secmark_refcount_dec(void)
1152{
1153 security_ops->secmark_refcount_dec();
1154}
1155EXPORT_SYMBOL(security_secmark_refcount_dec);
1156
1139int security_tun_dev_create(void) 1157int security_tun_dev_create(void)
1140{ 1158{
1141 return security_ops->tun_dev_create(); 1159 return security_ops->tun_dev_create();
diff --git a/security/selinux/exports.c b/security/selinux/exports.c
index c0a454aee1e0..90664385dead 100644
--- a/security/selinux/exports.c
+++ b/security/selinux/exports.c
@@ -11,58 +11,9 @@
11 * it under the terms of the GNU General Public License version 2, 11 * it under the terms of the GNU General Public License version 2,
12 * as published by the Free Software Foundation. 12 * as published by the Free Software Foundation.
13 */ 13 */
14#include <linux/types.h>
15#include <linux/kernel.h>
16#include <linux/module.h> 14#include <linux/module.h>
17#include <linux/selinux.h>
18#include <linux/fs.h>
19#include <linux/ipc.h>
20#include <asm/atomic.h>
21 15
22#include "security.h" 16#include "security.h"
23#include "objsec.h"
24
25/* SECMARK reference count */
26extern atomic_t selinux_secmark_refcount;
27
28int selinux_string_to_sid(char *str, u32 *sid)
29{
30 if (selinux_enabled)
31 return security_context_to_sid(str, strlen(str), sid);
32 else {
33 *sid = 0;
34 return 0;
35 }
36}
37EXPORT_SYMBOL_GPL(selinux_string_to_sid);
38
39int selinux_secmark_relabel_packet_permission(u32 sid)
40{
41 if (selinux_enabled) {
42 const struct task_security_struct *__tsec;
43 u32 tsid;
44
45 __tsec = current_security();
46 tsid = __tsec->sid;
47
48 return avc_has_perm(tsid, sid, SECCLASS_PACKET,
49 PACKET__RELABELTO, NULL);
50 }
51 return 0;
52}
53EXPORT_SYMBOL_GPL(selinux_secmark_relabel_packet_permission);
54
55void selinux_secmark_refcount_inc(void)
56{
57 atomic_inc(&selinux_secmark_refcount);
58}
59EXPORT_SYMBOL_GPL(selinux_secmark_refcount_inc);
60
61void selinux_secmark_refcount_dec(void)
62{
63 atomic_dec(&selinux_secmark_refcount);
64}
65EXPORT_SYMBOL_GPL(selinux_secmark_refcount_dec);
66 17
67bool selinux_is_enabled(void) 18bool selinux_is_enabled(void)
68{ 19{
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index db2b331de89a..d9154cf90ae1 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4279,6 +4279,27 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb)
4279 selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid); 4279 selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid);
4280} 4280}
4281 4281
4282static int selinux_secmark_relabel_packet(u32 sid)
4283{
4284 const struct task_security_struct *__tsec;
4285 u32 tsid;
4286
4287 __tsec = current_security();
4288 tsid = __tsec->sid;
4289
4290 return avc_has_perm(tsid, sid, SECCLASS_PACKET, PACKET__RELABELTO, NULL);
4291}
4292
4293static void selinux_secmark_refcount_inc(void)
4294{
4295 atomic_inc(&selinux_secmark_refcount);
4296}
4297
4298static void selinux_secmark_refcount_dec(void)
4299{
4300 atomic_dec(&selinux_secmark_refcount);
4301}
4302
4282static void selinux_req_classify_flow(const struct request_sock *req, 4303static void selinux_req_classify_flow(const struct request_sock *req,
4283 struct flowi *fl) 4304 struct flowi *fl)
4284{ 4305{
@@ -5533,6 +5554,9 @@ static struct security_operations selinux_ops = {
5533 .inet_conn_request = selinux_inet_conn_request, 5554 .inet_conn_request = selinux_inet_conn_request,
5534 .inet_csk_clone = selinux_inet_csk_clone, 5555 .inet_csk_clone = selinux_inet_csk_clone,
5535 .inet_conn_established = selinux_inet_conn_established, 5556 .inet_conn_established = selinux_inet_conn_established,
5557 .secmark_relabel_packet = selinux_secmark_relabel_packet,
5558 .secmark_refcount_inc = selinux_secmark_refcount_inc,
5559 .secmark_refcount_dec = selinux_secmark_refcount_dec,
5536 .req_classify_flow = selinux_req_classify_flow, 5560 .req_classify_flow = selinux_req_classify_flow,
5537 .tun_dev_create = selinux_tun_dev_create, 5561 .tun_dev_create = selinux_tun_dev_create,
5538 .tun_dev_post_create = selinux_tun_dev_post_create, 5562 .tun_dev_post_create = selinux_tun_dev_post_create,
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 4b66f19bb1f3..611a526afae7 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -9,6 +9,7 @@
9#define _SELINUX_SECURITY_H_ 9#define _SELINUX_SECURITY_H_
10 10
11#include <linux/magic.h> 11#include <linux/magic.h>
12#include <linux/types.h>
12#include "flask.h" 13#include "flask.h"
13 14
14#define SECSID_NULL 0x00000000 /* unspecified SID */ 15#define SECSID_NULL 0x00000000 /* unspecified SID */