diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/device_cgroup.c | 65 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 24 |
2 files changed, 37 insertions, 52 deletions
diff --git a/security/device_cgroup.c b/security/device_cgroup.c index e8aad69f0d69..c123628d3f84 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c | |||
@@ -53,22 +53,17 @@ struct dev_cgroup { | |||
53 | 53 | ||
54 | static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s) | 54 | static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s) |
55 | { | 55 | { |
56 | return container_of(s, struct dev_cgroup, css); | 56 | return s ? container_of(s, struct dev_cgroup, css) : NULL; |
57 | } | ||
58 | |||
59 | static inline struct dev_cgroup *cgroup_to_devcgroup(struct cgroup *cgroup) | ||
60 | { | ||
61 | return css_to_devcgroup(cgroup_subsys_state(cgroup, devices_subsys_id)); | ||
62 | } | 57 | } |
63 | 58 | ||
64 | static inline struct dev_cgroup *task_devcgroup(struct task_struct *task) | 59 | static inline struct dev_cgroup *task_devcgroup(struct task_struct *task) |
65 | { | 60 | { |
66 | return css_to_devcgroup(task_subsys_state(task, devices_subsys_id)); | 61 | return css_to_devcgroup(task_css(task, devices_subsys_id)); |
67 | } | 62 | } |
68 | 63 | ||
69 | struct cgroup_subsys devices_subsys; | 64 | struct cgroup_subsys devices_subsys; |
70 | 65 | ||
71 | static int devcgroup_can_attach(struct cgroup *new_cgrp, | 66 | static int devcgroup_can_attach(struct cgroup_subsys_state *new_css, |
72 | struct cgroup_taskset *set) | 67 | struct cgroup_taskset *set) |
73 | { | 68 | { |
74 | struct task_struct *task = cgroup_taskset_first(set); | 69 | struct task_struct *task = cgroup_taskset_first(set); |
@@ -193,18 +188,16 @@ static inline bool is_devcg_online(const struct dev_cgroup *devcg) | |||
193 | /** | 188 | /** |
194 | * devcgroup_online - initializes devcgroup's behavior and exceptions based on | 189 | * devcgroup_online - initializes devcgroup's behavior and exceptions based on |
195 | * parent's | 190 | * parent's |
196 | * @cgroup: cgroup getting online | 191 | * @css: css getting online |
197 | * returns 0 in case of success, error code otherwise | 192 | * returns 0 in case of success, error code otherwise |
198 | */ | 193 | */ |
199 | static int devcgroup_online(struct cgroup *cgroup) | 194 | static int devcgroup_online(struct cgroup_subsys_state *css) |
200 | { | 195 | { |
201 | struct dev_cgroup *dev_cgroup, *parent_dev_cgroup = NULL; | 196 | struct dev_cgroup *dev_cgroup = css_to_devcgroup(css); |
197 | struct dev_cgroup *parent_dev_cgroup = css_to_devcgroup(css_parent(css)); | ||
202 | int ret = 0; | 198 | int ret = 0; |
203 | 199 | ||
204 | mutex_lock(&devcgroup_mutex); | 200 | mutex_lock(&devcgroup_mutex); |
205 | dev_cgroup = cgroup_to_devcgroup(cgroup); | ||
206 | if (cgroup->parent) | ||
207 | parent_dev_cgroup = cgroup_to_devcgroup(cgroup->parent); | ||
208 | 201 | ||
209 | if (parent_dev_cgroup == NULL) | 202 | if (parent_dev_cgroup == NULL) |
210 | dev_cgroup->behavior = DEVCG_DEFAULT_ALLOW; | 203 | dev_cgroup->behavior = DEVCG_DEFAULT_ALLOW; |
@@ -219,9 +212,9 @@ static int devcgroup_online(struct cgroup *cgroup) | |||
219 | return ret; | 212 | return ret; |
220 | } | 213 | } |
221 | 214 | ||
222 | static void devcgroup_offline(struct cgroup *cgroup) | 215 | static void devcgroup_offline(struct cgroup_subsys_state *css) |
223 | { | 216 | { |
224 | struct dev_cgroup *dev_cgroup = cgroup_to_devcgroup(cgroup); | 217 | struct dev_cgroup *dev_cgroup = css_to_devcgroup(css); |
225 | 218 | ||
226 | mutex_lock(&devcgroup_mutex); | 219 | mutex_lock(&devcgroup_mutex); |
227 | dev_cgroup->behavior = DEVCG_DEFAULT_NONE; | 220 | dev_cgroup->behavior = DEVCG_DEFAULT_NONE; |
@@ -231,7 +224,8 @@ static void devcgroup_offline(struct cgroup *cgroup) | |||
231 | /* | 224 | /* |
232 | * called from kernel/cgroup.c with cgroup_lock() held. | 225 | * called from kernel/cgroup.c with cgroup_lock() held. |
233 | */ | 226 | */ |
234 | static struct cgroup_subsys_state *devcgroup_css_alloc(struct cgroup *cgroup) | 227 | static struct cgroup_subsys_state * |
228 | devcgroup_css_alloc(struct cgroup_subsys_state *parent_css) | ||
235 | { | 229 | { |
236 | struct dev_cgroup *dev_cgroup; | 230 | struct dev_cgroup *dev_cgroup; |
237 | 231 | ||
@@ -244,11 +238,10 @@ static struct cgroup_subsys_state *devcgroup_css_alloc(struct cgroup *cgroup) | |||
244 | return &dev_cgroup->css; | 238 | return &dev_cgroup->css; |
245 | } | 239 | } |
246 | 240 | ||
247 | static void devcgroup_css_free(struct cgroup *cgroup) | 241 | static void devcgroup_css_free(struct cgroup_subsys_state *css) |
248 | { | 242 | { |
249 | struct dev_cgroup *dev_cgroup; | 243 | struct dev_cgroup *dev_cgroup = css_to_devcgroup(css); |
250 | 244 | ||
251 | dev_cgroup = cgroup_to_devcgroup(cgroup); | ||
252 | __dev_exception_clean(dev_cgroup); | 245 | __dev_exception_clean(dev_cgroup); |
253 | kfree(dev_cgroup); | 246 | kfree(dev_cgroup); |
254 | } | 247 | } |
@@ -291,10 +284,10 @@ static void set_majmin(char *str, unsigned m) | |||
291 | sprintf(str, "%u", m); | 284 | sprintf(str, "%u", m); |
292 | } | 285 | } |
293 | 286 | ||
294 | static int devcgroup_seq_read(struct cgroup *cgroup, struct cftype *cft, | 287 | static int devcgroup_seq_read(struct cgroup_subsys_state *css, |
295 | struct seq_file *m) | 288 | struct cftype *cft, struct seq_file *m) |
296 | { | 289 | { |
297 | struct dev_cgroup *devcgroup = cgroup_to_devcgroup(cgroup); | 290 | struct dev_cgroup *devcgroup = css_to_devcgroup(css); |
298 | struct dev_exception_item *ex; | 291 | struct dev_exception_item *ex; |
299 | char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN]; | 292 | char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN]; |
300 | 293 | ||
@@ -394,12 +387,10 @@ static bool may_access(struct dev_cgroup *dev_cgroup, | |||
394 | static int parent_has_perm(struct dev_cgroup *childcg, | 387 | static int parent_has_perm(struct dev_cgroup *childcg, |
395 | struct dev_exception_item *ex) | 388 | struct dev_exception_item *ex) |
396 | { | 389 | { |
397 | struct cgroup *pcg = childcg->css.cgroup->parent; | 390 | struct dev_cgroup *parent = css_to_devcgroup(css_parent(&childcg->css)); |
398 | struct dev_cgroup *parent; | ||
399 | 391 | ||
400 | if (!pcg) | 392 | if (!parent) |
401 | return 1; | 393 | return 1; |
402 | parent = cgroup_to_devcgroup(pcg); | ||
403 | return may_access(parent, ex, childcg->behavior); | 394 | return may_access(parent, ex, childcg->behavior); |
404 | } | 395 | } |
405 | 396 | ||
@@ -451,13 +442,13 @@ static void revalidate_active_exceptions(struct dev_cgroup *devcg) | |||
451 | static int propagate_exception(struct dev_cgroup *devcg_root, | 442 | static int propagate_exception(struct dev_cgroup *devcg_root, |
452 | struct dev_exception_item *ex) | 443 | struct dev_exception_item *ex) |
453 | { | 444 | { |
454 | struct cgroup *root = devcg_root->css.cgroup, *pos; | 445 | struct cgroup_subsys_state *pos; |
455 | int rc = 0; | 446 | int rc = 0; |
456 | 447 | ||
457 | rcu_read_lock(); | 448 | rcu_read_lock(); |
458 | 449 | ||
459 | cgroup_for_each_descendant_pre(pos, root) { | 450 | css_for_each_descendant_pre(pos, &devcg_root->css) { |
460 | struct dev_cgroup *devcg = cgroup_to_devcgroup(pos); | 451 | struct dev_cgroup *devcg = css_to_devcgroup(pos); |
461 | 452 | ||
462 | /* | 453 | /* |
463 | * Because devcgroup_mutex is held, no devcg will become | 454 | * Because devcgroup_mutex is held, no devcg will become |
@@ -465,7 +456,7 @@ static int propagate_exception(struct dev_cgroup *devcg_root, | |||
465 | * methods), and online ones are safe to access outside RCU | 456 | * methods), and online ones are safe to access outside RCU |
466 | * read lock without bumping refcnt. | 457 | * read lock without bumping refcnt. |
467 | */ | 458 | */ |
468 | if (!is_devcg_online(devcg)) | 459 | if (pos == &devcg_root->css || !is_devcg_online(devcg)) |
469 | continue; | 460 | continue; |
470 | 461 | ||
471 | rcu_read_unlock(); | 462 | rcu_read_unlock(); |
@@ -524,15 +515,11 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, | |||
524 | char temp[12]; /* 11 + 1 characters needed for a u32 */ | 515 | char temp[12]; /* 11 + 1 characters needed for a u32 */ |
525 | int count, rc = 0; | 516 | int count, rc = 0; |
526 | struct dev_exception_item ex; | 517 | struct dev_exception_item ex; |
527 | struct cgroup *p = devcgroup->css.cgroup; | 518 | struct dev_cgroup *parent = css_to_devcgroup(css_parent(&devcgroup->css)); |
528 | struct dev_cgroup *parent = NULL; | ||
529 | 519 | ||
530 | if (!capable(CAP_SYS_ADMIN)) | 520 | if (!capable(CAP_SYS_ADMIN)) |
531 | return -EPERM; | 521 | return -EPERM; |
532 | 522 | ||
533 | if (p->parent) | ||
534 | parent = cgroup_to_devcgroup(p->parent); | ||
535 | |||
536 | memset(&ex, 0, sizeof(ex)); | 523 | memset(&ex, 0, sizeof(ex)); |
537 | b = buffer; | 524 | b = buffer; |
538 | 525 | ||
@@ -677,13 +664,13 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup, | |||
677 | return rc; | 664 | return rc; |
678 | } | 665 | } |
679 | 666 | ||
680 | static int devcgroup_access_write(struct cgroup *cgrp, struct cftype *cft, | 667 | static int devcgroup_access_write(struct cgroup_subsys_state *css, |
681 | const char *buffer) | 668 | struct cftype *cft, const char *buffer) |
682 | { | 669 | { |
683 | int retval; | 670 | int retval; |
684 | 671 | ||
685 | mutex_lock(&devcgroup_mutex); | 672 | mutex_lock(&devcgroup_mutex); |
686 | retval = devcgroup_update_access(cgroup_to_devcgroup(cgrp), | 673 | retval = devcgroup_update_access(css_to_devcgroup(css), |
687 | cft->private, buffer); | 674 | cft->private, buffer); |
688 | mutex_unlock(&devcgroup_mutex); | 675 | mutex_unlock(&devcgroup_mutex); |
689 | return retval; | 676 | return retval; |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 3f7682a387b7..eefbd10e408f 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -1998,12 +1998,11 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address) | |||
1998 | * | 1998 | * |
1999 | * Create or update the port list entry | 1999 | * Create or update the port list entry |
2000 | */ | 2000 | */ |
2001 | static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address, | 2001 | static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, |
2002 | int act) | 2002 | int act) |
2003 | { | 2003 | { |
2004 | __be16 *bep; | 2004 | __be16 *bep; |
2005 | __be32 *be32p; | 2005 | __be32 *be32p; |
2006 | struct sockaddr_in6 *addr6; | ||
2007 | struct smk_port_label *spp; | 2006 | struct smk_port_label *spp; |
2008 | struct socket_smack *ssp = sk->sk_security; | 2007 | struct socket_smack *ssp = sk->sk_security; |
2009 | struct smack_known *skp; | 2008 | struct smack_known *skp; |
@@ -2025,10 +2024,9 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr *address, | |||
2025 | /* | 2024 | /* |
2026 | * Get the IP address and port from the address. | 2025 | * Get the IP address and port from the address. |
2027 | */ | 2026 | */ |
2028 | addr6 = (struct sockaddr_in6 *)address; | 2027 | port = ntohs(address->sin6_port); |
2029 | port = ntohs(addr6->sin6_port); | 2028 | bep = (__be16 *)(&address->sin6_addr); |
2030 | bep = (__be16 *)(&addr6->sin6_addr); | 2029 | be32p = (__be32 *)(&address->sin6_addr); |
2031 | be32p = (__be32 *)(&addr6->sin6_addr); | ||
2032 | 2030 | ||
2033 | /* | 2031 | /* |
2034 | * It's remote, so port lookup does no good. | 2032 | * It's remote, so port lookup does no good. |
@@ -2060,9 +2058,9 @@ auditout: | |||
2060 | ad.a.u.net->family = sk->sk_family; | 2058 | ad.a.u.net->family = sk->sk_family; |
2061 | ad.a.u.net->dport = port; | 2059 | ad.a.u.net->dport = port; |
2062 | if (act == SMK_RECEIVING) | 2060 | if (act == SMK_RECEIVING) |
2063 | ad.a.u.net->v6info.saddr = addr6->sin6_addr; | 2061 | ad.a.u.net->v6info.saddr = address->sin6_addr; |
2064 | else | 2062 | else |
2065 | ad.a.u.net->v6info.daddr = addr6->sin6_addr; | 2063 | ad.a.u.net->v6info.daddr = address->sin6_addr; |
2066 | #endif | 2064 | #endif |
2067 | return smk_access(skp, object, MAY_WRITE, &ad); | 2065 | return smk_access(skp, object, MAY_WRITE, &ad); |
2068 | } | 2066 | } |
@@ -2201,7 +2199,8 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, | |||
2201 | case PF_INET6: | 2199 | case PF_INET6: |
2202 | if (addrlen < sizeof(struct sockaddr_in6)) | 2200 | if (addrlen < sizeof(struct sockaddr_in6)) |
2203 | return -EINVAL; | 2201 | return -EINVAL; |
2204 | rc = smk_ipv6_port_check(sock->sk, sap, SMK_CONNECTING); | 2202 | rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap, |
2203 | SMK_CONNECTING); | ||
2205 | break; | 2204 | break; |
2206 | } | 2205 | } |
2207 | return rc; | 2206 | return rc; |
@@ -3034,7 +3033,7 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, | |||
3034 | int size) | 3033 | int size) |
3035 | { | 3034 | { |
3036 | struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; | 3035 | struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; |
3037 | struct sockaddr *sap = (struct sockaddr *) msg->msg_name; | 3036 | struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; |
3038 | int rc = 0; | 3037 | int rc = 0; |
3039 | 3038 | ||
3040 | /* | 3039 | /* |
@@ -3121,9 +3120,8 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, | |||
3121 | return smack_net_ambient; | 3120 | return smack_net_ambient; |
3122 | } | 3121 | } |
3123 | 3122 | ||
3124 | static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr *sap) | 3123 | static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) |
3125 | { | 3124 | { |
3126 | struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap; | ||
3127 | u8 nexthdr; | 3125 | u8 nexthdr; |
3128 | int offset; | 3126 | int offset; |
3129 | int proto = -EINVAL; | 3127 | int proto = -EINVAL; |
@@ -3181,7 +3179,7 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
3181 | struct netlbl_lsm_secattr secattr; | 3179 | struct netlbl_lsm_secattr secattr; |
3182 | struct socket_smack *ssp = sk->sk_security; | 3180 | struct socket_smack *ssp = sk->sk_security; |
3183 | struct smack_known *skp; | 3181 | struct smack_known *skp; |
3184 | struct sockaddr sadd; | 3182 | struct sockaddr_in6 sadd; |
3185 | int rc = 0; | 3183 | int rc = 0; |
3186 | struct smk_audit_info ad; | 3184 | struct smk_audit_info ad; |
3187 | #ifdef CONFIG_AUDIT | 3185 | #ifdef CONFIG_AUDIT |