LSM: Multiple concurrent LSMs
Subsystems (23)
Casey Schaufler
maintainerv14 cover LSM: Multiple concurrent LSMs
Subject: [PATCH v14 0/6] LSM: Multiple concurrent LSMs
Version 14 of this patchset is based on v3.10.
It required significant change from version 13 due to changes in the audit code. It came out cleaner, especially in the changes to NetLabel. This version supports all existing LSMs running together at the same time. The combinations tested most completely are:
apparmor,tomoyo,smack,yama - Ubuntu
apparmor,selinux,smack,yama - Fedora
I have been unable to figure out how to configure SELinux on Ubuntu and TOMOYO on Fedora. That's the only reason the list does not include all five LSMs at once. Combining LSMs that use networking is tricky, but can be done. There are changes coming from AppArmor that might make it even trickier, but that's a problem for the future.
Change the infrastructure for Linux Security Modules (LSM)s from a single vector of hook handlers to a list based method for handling multiple concurrent modules. All combinations of existing LSMs are supported.
The "security=" boot option takes a comma separated list of LSMs, registering them in the order presented. The LSM hooks will be executed in the order registered. Hooks that return errors are not short circuited. All hooks are called even if one of the LSM hooks fails. The result returned will be that of the last LSM hook that failed.
All behavior from security/capability.c has been moved into the hook handling. The security/commoncap functions used to get called from the LSM specific code. The handling of the capability functions has been moved out of the LSMs and into the hook handling.
A level of indirection has been introduced in the handling of security blobs. LSMs no longer access ->security fields directly, instead they use an abstraction provided by lsm_[gs]et field functions.
The notion that "the security context" can be represented as a single u32 "secid" does not scale to the case where multiple LSMs want to provide "the security context". The XFRM and secmark facilities appear unlikely to ever allow for more than the existing 32 bit values. The NetLabel scheme might possibly be used to represent more than one labeling scheme (CIPSO does allow for multiple tags) although there is no plan to do so at this time. The SO_PEERSEC scheme is capable of providing information from multiple LSMs. Auditing can deal with multiple secids.
The NetLabel, XFRM and secmark facilities are restricted to use by one LSM at a time. The SO_PEERSEC facility can provide information from multiple LSMs, but existing user space tools don't understand that. The default behavior is to assign each of these facilities to the first registered LSM that uses them. They can be configured for use by any of the LSMs that provide hooks for them. SO_PEERSEC can be configured to provide information from all of the LSMs that provide hooks.
The /proc/*/attr interfaces are given to one LSM. This can be done by setting CONFIG_SECURITY_PRESENT. Additional interfaces have been created in /proc/*/attr so that each LSM has its own named interfaces. The name of the presenting LSM can be read from /sys/kernel/security/present. The list of LSMs being used can be read from /sys/kernel/security/lsm.
A "security context" may now contrain information processed by more than one LSM. The proper form of a security context identifies the information it contains by LSM:
smack='Pop'selinux='system_u:object_r:etc_r:s0'
A security context without the LSM identifying lsm='<text>' gets passed through to all of the LSMs that use a security context. This maintains compatability in the case where there is only one LSM using the security context.
--- Documentation/security/LSM.txt | 56 +- drivers/usb/core/devio.c | 13 +- fs/proc/base.c | 36 +- fs/sysfs/dir.c | 3 +- fs/sysfs/inode.c | 12 +- fs/sysfs/sysfs.h | 7 +- fs/xattr.c | 8 +- include/linux/cred.h | 4 +- include/linux/lsm.h | 300 +++ include/linux/lsm_audit.h | 9 +- include/linux/sched.h | 2 +- include/linux/security.h | 580 ++++-- include/net/af_unix.h | 5 +- include/net/netlabel.h | 15 +- include/net/scm.h | 11 +- include/net/xfrm.h | 9 +- kernel/audit.c | 55 +- kernel/audit.h | 9 +- kernel/auditfilter.c | 4 +- kernel/auditsc.c | 53 +- kernel/cred.c | 17 +- kernel/signal.c | 7 +- net/ipv4/cipso_ipv4.c | 9 +- net/ipv4/ip_sockglue.c | 8 +- .../netfilter/nf_conntrack_l3proto_ipv4_compat.c | 8 +- net/netfilter/nf_conntrack_netlink.c | 13 +- net/netfilter/nf_conntrack_standalone.c | 8 +- net/netfilter/xt_SECMARK.c | 13 +- net/netlabel/netlabel_kapi.c | 47 +- net/netlabel/netlabel_unlabeled.c | 57 +- net/netlabel/netlabel_user.c | 10 +- net/netlabel/netlabel_user.h | 1 + net/unix/af_unix.c | 14 +- net/xfrm/xfrm_user.c | 33 +- security/Kconfig | 226 ++- security/Makefile | 3 +- security/apparmor/context.c | 10 +- security/apparmor/domain.c | 12 +- security/apparmor/include/apparmor.h | 3 + security/apparmor/include/context.h | 9 +- security/apparmor/lsm.c | 64 +- security/capability.c | 1106 ----------- security/commoncap.c | 6 - security/inode.c | 77 +- security/integrity/ima/ima.h | 4 +- security/integrity/ima/ima_policy.c | 6 +- security/security.c | 2082 +++++++++++++++++--- security/selinux/hooks.c | 431 ++-- security/selinux/include/objsec.h | 1 + security/selinux/include/xfrm.h | 2 +- security/selinux/netlabel.c | 46 +- security/selinux/selinuxfs.c | 7 +- security/selinux/ss/services.c | 5 +- security/selinux/xfrm.c | 9 +- security/smack/smack.h | 7 +- security/smack/smack_access.c | 2 +- security/smack/smack_lsm.c | 338 ++-- security/smack/smackfs.c | 26 +- security/tomoyo/common.h | 6 +- security/tomoyo/domain.c | 2 +- security/tomoyo/securityfs_if.c | 7 +- security/tomoyo/tomoyo.c | 34 +- security/yama/Kconfig | 7 - security/yama/yama_lsm.c | 33 +- 64 files changed, 3679 insertions(+), 2328 deletions(-)
--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.
Casey Schaufler
maintainerPATCH v14 1/6 LSM: Security blob abstraction
Subject: [PATCH v14 1/6] LSM: Security blob abstraction
Create an abstracted interface for security blobs. Instead of directly accessing security blob pointers Use lsm_get and lsm_set functions that hide the actual mechanism used to maintain the security blobs. This affects most uses of inode->i_security, file->f_security, cred->security and similar fields in keys, sockets, superblocks, ipc and keys.
The use of a single 32 bit integer to refer to a security blob does not scale to the case where there may be more than one relevant security blob. Where it is possible to do so the use of secids (u32) has been replaced with a struct secids, which provides for multiple u32 values. There are components where u32 secids remain at the request of the maintainer of that component.
--- drivers/usb/core/devio.c | 13 +- include/linux/cred.h | 4 +- include/linux/lsm.h | 177 +++++++++++ include/linux/sched.h | 2 +- include/linux/security.h | 76 +++-- include/net/af_unix.h | 2 +- include/net/netlabel.h | 5 +- include/net/scm.h | 4 +- include/net/xfrm.h | 5 +- kernel/audit.c | 41 ++- kernel/audit.h | 9 +- kernel/auditfilter.c | 4 +- kernel/auditsc.c | 43 +-- kernel/cred.c | 6 +- kernel/signal.c | 7 +- net/ipv4/cipso_ipv4.c | 8 +- net/ipv4/ip_sockglue.c | 5 +- .../netfilter/nf_conntrack_l3proto_ipv4_compat.c | 5 +- net/netfilter/nf_conntrack_netlink.c | 9 +- net/netfilter/nf_conntrack_standalone.c | 5 +- net/netfilter/xt_SECMARK.c | 7 +- net/netlabel/netlabel_unlabeled.c | 32 +- net/netlabel/netlabel_user.c | 5 +- net/netlabel/netlabel_user.h | 1 + net/unix/af_unix.c | 8 +- net/xfrm/xfrm_user.c | 33 +- security/apparmor/context.c | 10 +- security/apparmor/domain.c | 8 +- security/apparmor/include/apparmor.h | 3 + security/apparmor/include/context.h | 9 +- security/apparmor/lsm.c | 34 +- security/integrity/ima/ima.h | 4 +- security/integrity/ima/ima_policy.c | 6 +- security/security.c | 69 ++-- security/selinux/hooks.c | 333 +++++++++++--------- security/selinux/include/objsec.h | 1 + security/selinux/include/xfrm.h | 2 +- security/selinux/netlabel.c | 13 +- security/selinux/selinuxfs.c | 7 +- security/selinux/ss/services.c | 5 +- security/selinux/xfrm.c | 9 +- security/smack/smack.h | 7 +- security/smack/smack_access.c | 2 +- security/smack/smack_lsm.c | 180 +++++------ security/smack/smackfs.c | 16 +- security/tomoyo/common.h | 4 +- security/tomoyo/domain.c | 2 +- security/tomoyo/securityfs_if.c | 7 +- security/tomoyo/tomoyo.c | 23 +- 49 files changed, 815 insertions(+), 455 deletions(-)
drivers/usb/core/devio.c +8 -5
@@ -47,6 +47,7 @@#include <linux/cdev.h> #include <linux/notifier.h> #include <linux/security.h> +#include <linux/lsm.h> #include <linux/user_namespace.h> #include <linux/scatterlist.h> #include <asm/uaccess.h>
@@ -75,7 +76,7 @@ struct dev_state {const struct cred *cred;void __user *disccontext;unsigned long ifclaimed; -u32 secid; +struct secids secid;u32 disabled_bulk_eps; };
@@ -91,7 +92,7 @@ struct async {struct urb *urb;unsigned int mem_usage;int status; -u32 secid; +struct secids secid;u8 bulk_addr;u8 bulk_status; };
@@ -492,10 +493,11 @@ static void async_completed(struct urb *urb)struct dev_state *ps = as->ps;struct siginfo sinfo;struct pid *pid =NULL ; -u32 secid =0 ; +struct secids secid;const struct cred *cred =NULL ;int signr; +lsm_init_secid (&secid,0 ,0 );spin_lock (&ps->lock);list_move_tail (&as->asynclist, &ps->async_completed); as->status = urb->status;
@@ -521,7 +523,8 @@ static void async_completed(struct urb *urb)spin_unlock (&ps->lock);if (signr) { -kill_pid_info_as_cred (sinfo.si_signo, &sinfo, pid, cred, secid); +kill_pid_info_as_cred (sinfo.si_signo, &sinfo, pid, cred, + &secid);put_pid (pid);put_cred (cred); }
@@ -2217,7 +2220,7 @@ static void usbdev_remove(struct usb_device *udev) sinfo.si_code =SI_ASYNCIO ; sinfo.si_addr = ps->disccontext;kill_pid_info_as_cred (ps->discsignr, &sinfo, - ps->disc_pid, ps->cred, ps->secid); + ps->disc_pid, ps->cred, &ps->secid); } } }
include/linux/cred.h +2 -2
@@ -22,6 +22,7 @@struct user_struct ;struct cred ;struct inode ; +struct secids ;/* * COW Supplementary groups list
@@ -151,7 +152,7 @@ extern const struct cred *override_creds(const struct cred *);extern void revert_creds (const struct cred *);extern struct cred *prepare_kernel_cred (struct task_struct *);extern int change_create_files_as (struct cred *,struct inode *); -extern int set_security_override (struct cred *,u32 ); +extern int set_security_override (struct cred *,struct secids *);extern int set_security_override_from_ctx (struct cred *,const char *);extern int set_create_files_as (struct cred *,struct inode *);extern void __init cred_init (void );
@@ -338,7 +339,6 @@ static inline void put_cred(const struct cred *_cred)#define current_fsgid () (current_cred_xxx(fsgid))#define current_cap () (current_cred_xxx(cap_effective))#define current_user () (current_cred_xxx(user)) -#define current_security () (current_cred_xxx(security))extern struct user_namespace init_user_ns;#ifdef CONFIG_USER_NS
include/linux/lsm.h new file +177 -0
177 lines not on this page · raw message
include/linux/sched.h +1 -1
@@ -2010,7 +2010,7 @@ extern int force_sig_info(int, struct siginfo *, struct task_struct *);extern int __kill_pgrp_info (int sig,struct siginfo *info,struct pid *pgrp);extern int kill_pid_info (int sig,struct siginfo *info,struct pid *pid);extern int kill_pid_info_as_cred (int ,struct siginfo *,struct pid *, -const struct cred *,u32 ); +const struct cred *,struct secids *);extern int kill_pgrp (struct pid *pid,int sig,int priv);extern int kill_pid (struct pid *pid,int sig,int priv);extern int kill_proc_info (int ,struct siginfo *,pid_t );
include/linux/security.h +50 -26
210 lines not on this page · raw message
include/net/af_unix.h +1 -1
@@ -33,7 +33,7 @@ struct unix_skb_parms {kgid_t gid;struct scm_fp_list *fp;/* Passed files */ #ifdef CONFIG_SECURITY_NETWORK -u32 secid;/* Security ID */ +struct secids secid;/* Security ID */ #endif };
include/net/netlabel.h +3 -2
@@ -36,6 +36,7 @@#include <linux/skbuff.h> #include <linux/in.h> #include <linux/in6.h> +#include <linux/lsm.h> #include <net/netlink.h> #include <net/request_sock.h> #include <linux/atomic.h>
@@ -109,7 +110,7 @@ struct cipso_v4_doi;/* NetLabel audit information */ struct netlbl_audit { -u32 secid; +struct secids secid;kuid_t loginuid;u32 sessionid; };
@@ -213,7 +214,7 @@ struct netlbl_lsm_secattr {struct netlbl_lsm_secattr_catmap *cat;u32 lvl; } mls; -u32 secid; +struct secids secid; } attr; };
include/net/scm.h +2 -2
@@ -29,7 +29,7 @@ struct scm_cookie {struct scm_fp_list *fp;/* Passed files */ struct scm_creds creds;/* Skb credentials */ #ifdef CONFIG_SECURITY_NETWORK -u32 secid;/* Passed security ID */ +struct secids secid;/* Passed security ID */ #endif };
@@ -93,7 +93,7 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scint err;if (test_bit (SOCK_PASSSEC , &sock->flags)) { - err =security_secid_to_secctx (scm->secid, &secdata, &seclen); + err =security_secid_to_secctx (&scm->secid, &secdata, &seclen);if (!err) {put_cmsg (msg,SOL_SOCKET ,SCM_SECURITY , seclen, secdata);
include/net/xfrm.h +4 -1
@@ -13,6 +13,7 @@#include <linux/mutex.h> #include <linux/audit.h> #include <linux/slab.h> +#include <linux/lsm.h> #include <net/sock.h> #include <net/dst.h>
@@ -699,11 +700,13 @@ static inline void xfrm_audit_helper_usrinfo(kuid_t auid, u32 ses, u32 secid, {char *secctx;u32 secctx_len; +struct secids secids;audit_log_format (audit_buf," auid=%u ses=%u" ,from_kuid (&init_user_ns, auid), ses); +lsm_init_secid (&secids, secid,0 );if (secid !=0 && -security_secid_to_secctx (secid, &secctx, &secctx_len) ==0 ) { +security_secid_to_secctx (&secids, &secctx, &secctx_len) ==0 ) {audit_log_format (audit_buf," subj=%s" , secctx);security_release_secctx (secctx, secctx_len); }else
kernel/audit.c +24 -17
103 lines not on this page · raw message
kernel/audit.h +5 -4
@@ -22,6 +22,7 @@#include <linux/fs.h> #include <linux/audit.h> #include <linux/skbuff.h> +#include <linux/lsm.h> #include <uapi/linux/mqueue.h> /* 0 = no checking
@@ -93,7 +94,7 @@ struct audit_names {kuid_t uid;kgid_t gid;dev_t rdev; -u32 osid; +struct secids osid;struct audit_cap_data fcap;unsigned int fcap_ver;unsigned char type;/* record type */
@@ -145,7 +146,7 @@ struct audit_context {kuid_t target_auid;kuid_t target_uid;unsigned int target_sessionid; -u32 target_sid; +struct secids target_sid;char target_comm[TASK_COMM_LEN ];struct audit_tree_refs *trees, *first_trees;
@@ -162,7 +163,7 @@ struct audit_context {kuid_t uid;kgid_t gid;umode_t mode; -u32 osid; +struct secids osid;int has_perm;uid_t perm_uid;gid_t perm_gid;
@@ -303,7 +304,7 @@ extern char *audit_unpack_string(void **, size_t *, size_t);extern pid_t audit_sig_pid;extern kuid_t audit_sig_uid; -extern u32 audit_sig_sid; +extern struct secids audit_sig_sid;#ifdef CONFIG_AUDITSYSCALL extern int __audit_signal_info (int sig,struct task_struct *t);
kernel/auditfilter.c +2 -2
@@ -1216,7 +1216,7 @@ static int audit_filter_user_rules(struct audit_krule *rule, int type,for (i =0 ; i < rule->field_count; i++) {struct audit_field *f = &rule->fields[i];int result =0 ; -u32 sid; +struct secids sid;switch (f->type) {case AUDIT_PID :
@@ -1246,7 +1246,7 @@ static int audit_filter_user_rules(struct audit_krule *rule, int type,case AUDIT_SUBJ_CLR :if (f->lsm_rule) {security_task_getsecid (current, &sid); - result = security_audit_rule_match(sid, + result = security_audit_rule_match(&sid, f->type, f->op, f->lsm_rule,
kernel/auditsc.c +25 -18
125 lines not on this page · raw message
kernel/cred.c +3 -3
@@ -641,7 +641,7 @@ EXPORT_SYMBOL(prepare_kernel_cred);* Set the LSM security ID in a set of credentials so that the subjective * security is overridden when an alternative set of credentials is used. */ -int set_security_override (struct cred *new,u32 secid) +int set_security_override (struct cred *new,struct secids *secid) {return security_kernel_act_as (new, secid); }
@@ -659,14 +659,14 @@ EXPORT_SYMBOL(set_security_override);*/ int set_security_override_from_ctx (struct cred *new,const char *secctx) { -u32 secid; +struct secids secid;int ret; ret =security_secctx_to_secid (secctx,strlen (secctx), &secid);if (ret <0 )return ret; -return set_security_override (new, secid); +return set_security_override (new, &secid); }EXPORT_SYMBOL (set_security_override_from_ctx);
kernel/signal.c +5 -2
@@ -19,6 +19,7 @@#include <linux/binfmts.h> #include <linux/coredump.h> #include <linux/security.h> +#include <linux/lsm.h> #include <linux/syscalls.h> #include <linux/ptrace.h> #include <linux/signal.h>
@@ -789,6 +790,7 @@ static int check_kill_permission(int sig, struct siginfo *info, {struct pid *sid;int error; +struct secids secid;if (!valid_signal (sig))return -EINVAL ;
@@ -816,7 +818,8 @@ static int check_kill_permission(int sig, struct siginfo *info, } } -return security_task_kill (t, info, sig,0 ); +lsm_init_secid (&secid,0 ,0 ); +return security_task_kill (t, info, sig, &secid); }/**
@@ -1390,7 +1393,7 @@ static int kill_as_cred_perm(const struct cred *cred,/* like kill_pid_info(), but doesn't use uid/euid of "current" */ int kill_pid_info_as_cred (int sig,struct siginfo *info,struct pid *pid, -const struct cred *cred,u32 secid) +const struct cred *cred,struct secids *secid) {int ret = -EINVAL ;struct task_struct *p;
net/ipv4/cipso_ipv4.c +6 -2
@@ -45,6 +45,7 @@#include <linux/jhash.h> #include <linux/audit.h> #include <linux/slab.h> +#include <linux/lsm.h> #include <net/ip.h> #include <net/icmp.h> #include <net/tcp.h>
@@ -1569,7 +1570,7 @@ static int cipso_v4_gentag_loc(const struct cipso_v4_doi *doi_def, buffer[0 ] =CIPSO_V4_TAG_LOCAL ; buffer[1 ] =CIPSO_V4_TAG_LOC_BLEN ; - *(u32 *)&buffer[2 ] = secattr->attr.secid; + *(u32 *)&buffer[2 ] =lsm_get_secid (&secattr->attr.secid,0 );return CIPSO_V4_TAG_LOC_BLEN ; }
@@ -1589,7 +1590,10 @@ static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def,const unsigned char *tag, struct netlbl_lsm_secattr *secattr) { - secattr->attr.secid = *(u32 *)&tag[2]; + u32 secid; + + secid = *(u32 *)&tag[2 ]; +lsm_init_secid (&secattr->attr.secid, secid,0 ); secattr->flags |=NETLBL_SECATTR_SECID ;return 0 ;
net/ipv4/ip_sockglue.c +3 -2
@@ -108,14 +108,15 @@ static void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb)static void ip_cmsg_recv_security (struct msghdr *msg,struct sk_buff *skb) {char *secdata; -u32 seclen, secid; +u32 seclen; +struct secids secid;int err; err =security_socket_getpeersec_dgram (NULL , skb, &secid);if (err)return ; - err =security_secid_to_secctx (secid, &secdata, &seclen); + err =security_secid_to_secctx (&secid, &secdata, &seclen);if (err)return ;
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +4 -1
@@ -13,6 +13,7 @@#include <linux/seq_file.h> #include <linux/percpu.h> #include <linux/security.h> +#include <linux/lsm.h> #include <net/net_namespace.h> #include <linux/netfilter.h>
@@ -99,8 +100,10 @@ static int ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)int ret;u32 len;char *secctx; +struct secids secid; - ret =security_secid_to_secctx (ct->secmark, &secctx, &len); +lsm_init_secid (&secid, ct->secmark,0 ); + ret =security_secid_to_secctx (&secid, &secctx, &len);if (ret)return 0 ;
net/netfilter/nf_conntrack_netlink.c +7 -2
@@ -23,6 +23,7 @@#include <linux/types.h> #include <linux/timer.h> #include <linux/security.h> +#include <linux/lsm.h> #include <linux/skbuff.h> #include <linux/errno.h> #include <linux/netlink.h>
@@ -301,8 +302,10 @@ ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)struct nlattr *nest_secctx;int len, ret;char *secctx; +struct secids secid; - ret =security_secid_to_secctx (ct->secmark, &secctx, &len); +lsm_init_secid (&secid, ct->secmark,0 ); + ret =security_secid_to_secctx (&secid, &secctx, &len);if (ret)return 0 ;
@@ -548,8 +551,10 @@ ctnetlink_secctx_size(const struct nf_conn *ct) {#ifdef CONFIG_NF_CONNTRACK_SECMARK int len, ret; +struct secids secid; - ret =security_secid_to_secctx (ct->secmark,NULL , &len); +lsm_init_secid (&secid, ct->secmark,0 ); + ret =security_secid_to_secctx (&secid,NULL , &len);if (ret)return 0 ;
net/netfilter/nf_conntrack_standalone.c +4 -1
@@ -17,6 +17,7 @@#include <linux/percpu.h> #include <linux/netdevice.h> #include <linux/security.h> +#include <linux/lsm.h> #include <net/net_namespace.h> #ifdef CONFIG_SYSCTL #include <linux/sysctl.h>
@@ -124,8 +125,10 @@ static int ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)int ret;u32 len;char *secctx; +struct secids secid; - ret =security_secid_to_secctx (ct->secmark, &secctx, &len); +lsm_init_secid (&secid, ct->secmark,0 ); + ret =security_secid_to_secctx (&secid, &secctx, &len);if (ret)return 0 ;
net/netfilter/xt_SECMARK.c +5 -2
@@ -15,6 +15,7 @@#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt#include <linux/module.h> #include <linux/security.h> +#include <linux/lsm.h> #include <linux/skbuff.h> #include <linux/netfilter/x_tables.h> #include <linux/netfilter/xt_SECMARK.h>
@@ -52,24 +53,26 @@ secmark_tg(struct sk_buff *skb, const struct xt_action_param *par)static int checkentry_lsm (struct xt_secmark_target_info *info) {int err; +struct secids secid; info->secctx[SECMARK_SECCTX_MAX -1 ] ='\0' ; info->secid =0 ; err =security_secctx_to_secid (info->secctx,strlen (info->secctx), - &info->secid); + &secid);if (err) {if (err == -EINVAL )pr_info ("invalid security context \'%s\'\n" , info->secctx);return err; } + info->secid =lsm_get_secid (&secid,0 );if (!info->secid) {pr_info ("unable to map security context \'%s\'\n" , info->secctx);return -ENOENT ; } - err =security_secmark_relabel_packet (info->secid); + err =security_secmark_relabel_packet (&secid);if (err) {pr_info ("unable to obtain relabeling permission\n" );return err;
net/netlabel/netlabel_unlabeled.c +18 -14
@@ -81,7 +81,7 @@ struct netlbl_unlhsh_tbl {#define netlbl_unlhsh_addr4_entry (iter) \ container_of(iter, struct netlbl_unlhsh_addr4, list)struct netlbl_unlhsh_addr4 { -u32 secid; +struct secids secid;struct netlbl_af4list list;struct rcu_head rcu;
@@ -89,7 +89,7 @@ struct netlbl_unlhsh_addr4 {#define netlbl_unlhsh_addr6_entry (iter) \ container_of(iter, struct netlbl_unlhsh_addr6, list)struct netlbl_unlhsh_addr6 { -u32 secid; +struct secids secid;struct netlbl_af6list list;struct rcu_head rcu;
@@ -263,7 +263,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, entry->list.addr = addr->s_addr & mask->s_addr; entry->list.mask = mask->s_addr; entry->list.valid =1 ; - entry->secid = secid; +lsm_init_secid (&entry->secid, secid,0 );spin_lock (&netlbl_unlhsh_lock); ret_val =netlbl_af4list_add (&entry->list, &iface->addr4_list);
@@ -307,7 +307,7 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, entry->list.addr.s6_addr32[3 ] &= mask->s6_addr32[3 ]; entry->list.mask = *mask; entry->list.valid =1 ; - entry->secid = secid; +lsm_init_secid (&entry->secid, secid,0 );spin_lock (&netlbl_unlhsh_lock); ret_val =netlbl_af6list_add (&entry->list, &iface->addr6_list);
@@ -394,6 +394,7 @@ int netlbl_unlhsh_add(struct net *net,struct net_device *dev;struct netlbl_unlhsh_iface *iface;struct audit_buffer *audit_buf =NULL ; +struct secids secids;char *secctx =NULL ;u32 secctx_len;
@@ -458,7 +459,8 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return:rcu_read_unlock ();if (audit_buf !=NULL ) { -if (security_secid_to_secctx (secid, +lsm_init_secid (&secids, secid,0 ); +if (security_secid_to_secctx (&secids, &secctx, &secctx_len) ==0 ) {audit_log_format (audit_buf," sec_obj=%s" , secctx);
@@ -515,7 +517,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,if (dev !=NULL )dev_put (dev);if (entry !=NULL && -security_secid_to_secctx (entry->secid, +security_secid_to_secctx (&entry->secid, &secctx, &secctx_len) ==0 ) {audit_log_format (audit_buf," sec_obj=%s" , secctx);security_release_secctx (secctx, secctx_len);
@@ -576,7 +578,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,if (dev !=NULL )dev_put (dev);if (entry !=NULL && -security_secid_to_secctx (entry->secid, +security_secid_to_secctx (&entry->secid, &secctx, &secctx_len) ==0 ) {audit_log_format (audit_buf," sec_obj=%s" , secctx);security_release_secctx (secctx, secctx_len);
@@ -902,7 +904,7 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb,void *addr;void *mask;u32 addr_len; -u32 secid; +struct secids secid;struct netlbl_audit audit_info;/* Don't allow users to add both IPv4 and IPv6 addresses for a
@@ -931,7 +933,8 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb,return ret_val;return netlbl_unlhsh_add (&init_net, - dev_name, addr, mask, addr_len, secid, + dev_name, addr, mask, addr_len, +lsm_get_secid (&secid,0 ), &audit_info); }
@@ -953,7 +956,7 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb,void *addr;void *mask;u32 addr_len; -u32 secid; +struct secids secid;struct netlbl_audit audit_info;/* Don't allow users to add both IPv4 and IPv6 addresses for a
@@ -980,7 +983,8 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb,return ret_val;return netlbl_unlhsh_add (&init_net, -NULL , addr, mask, addr_len, secid, +NULL , addr, mask, addr_len, +lsm_get_secid (&secid,0 ), &audit_info); }
@@ -1092,7 +1096,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,struct netlbl_unlhsh_walk_arg *cb_arg = arg;struct net_device *dev;void *data; -u32 secid; +struct secids *secid;char *secctx;u32 secctx_len;
@@ -1134,7 +1138,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,if (ret_val !=0 ) goto list_cb_failure; - secid = addr4->secid; + secid = &addr4->secid; }else { ret_val = nla_put(cb_arg->skb, NLBL_UNLABEL_A_IPV6ADDR,
@@ -1150,7 +1154,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,if (ret_val !=0 ) goto list_cb_failure; - secid = addr6->secid; + secid = &addr6->secid; } ret_val =security_secid_to_secctx (secid, &secctx, &secctx_len);
net/netlabel/netlabel_user.c +3 -2
@@ -35,6 +35,7 @@#include <linux/audit.h> #include <linux/tty.h> #include <linux/security.h> +#include <linux/lsm.h> #include <linux/gfp.h> #include <net/sock.h> #include <net/netlink.h>
@@ -112,8 +113,8 @@ struct audit_buffer *netlbl_audit_start_common(int type,from_kuid (&init_user_ns, audit_info->loginuid), audit_info->sessionid); -if (audit_info->secid !=0 && -security_secid_to_secctx (audit_info->secid, +if (!lsm_zero_secid (&audit_info->secid) && +security_secid_to_secctx (&audit_info->secid, &secctx, &secctx_len) ==0 ) {audit_log_format (audit_buf," subj=%s" , secctx);
net/netlabel/netlabel_user.h +1 -0
@@ -35,6 +35,7 @@#include <linux/skbuff.h> #include <linux/capability.h> #include <linux/audit.h> +#include <linux/lsm.h> #include <net/netlink.h> #include <net/genetlink.h> #include <net/netlabel.h>
net/unix/af_unix.c +6 -2
@@ -137,12 +137,16 @@ static struct hlist_head *unix_sockets_unbound(void *addr)#ifdef CONFIG_SECURITY_NETWORK static void unix_get_secdata (struct scm_cookie *scm,struct sk_buff *skb) { -memcpy (UNIXSID (skb), &scm->secid,sizeof (u32)); +struct secids *skb_secid =UNIXSID (skb); + + *skb_secid = scm->secid; }static inline void unix_set_secdata (struct scm_cookie *scm,struct sk_buff *skb) { - scm->secid = *UNIXSID (skb); +struct secids *skb_secid =UNIXSID (skb); + + scm->secid = *skb_secid; }#else static inline void unix_get_secdata (struct scm_cookie *scm,struct sk_buff *skb)
net/xfrm/xfrm_user.c +25 -8
@@ -23,6 +23,7 @@#include <linux/ipsec.h> #include <linux/init.h> #include <linux/security.h> +#include <linux/lsm.h> #include <net/sock.h> #include <net/xfrm.h> #include <net/netlink.h>
@@ -601,6 +602,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,kuid_t loginuid =audit_get_loginuid (current);u32 sessionid =audit_get_sessionid (current);u32 sid; +struct secids sids; err =verify_newsa_info (p, attrs);if (err)
@@ -616,7 +618,8 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,else err =xfrm_state_update (x); -security_task_getsecid (current, &sid); +security_task_getsecid (current, &sids); + sid =lsm_get_secid (&sids,0 );xfrm_audit_state_add (x, err ?0 :1 , loginuid, sessionid, sid);if (err <0 ) {
@@ -680,6 +683,7 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh,kuid_t loginuid =audit_get_loginuid (current);u32 sessionid =audit_get_sessionid (current);u32 sid; +struct secids sids; x =xfrm_user_state_lookup (net, p, attrs, &err);if (x ==NULL )
@@ -704,7 +708,8 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh,km_state_notify (x, &c); out: -security_task_getsecid (current, &sid); +security_task_getsecid (current, &sids); + sid =lsm_get_secid (&sids,0 );xfrm_audit_state_delete (x, err ?0 :1 , loginuid, sessionid, sid);xfrm_state_put (x);return err;
@@ -1406,6 +1411,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,kuid_t loginuid =audit_get_loginuid (current);u32 sessionid =audit_get_sessionid (current);u32 sid; +struct secids sids; err =verify_newpolicy_info (p);if (err)
@@ -1424,7 +1430,8 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,* a type XFRM_MSG_UPDPOLICY - JHS */ excl = nlh->nlmsg_type ==XFRM_MSG_NEWPOLICY ; err =xfrm_policy_insert (p->dir, xp, excl); -security_task_getsecid (current, &sid); +security_task_getsecid (current, &sids); + sid =lsm_get_secid (&sids,0 );xfrm_audit_policy_add (xp, err ?0 :1 , loginuid, sessionid, sid);if (err) {
@@ -1664,8 +1671,10 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,kuid_t loginuid =audit_get_loginuid (current);u32 sessionid =audit_get_sessionid (current);u32 sid; +struct secids sids; -security_task_getsecid (current, &sid); +security_task_getsecid (current, &sids); + sid =lsm_get_secid (&sids,0 );xfrm_audit_policy_delete (xp, err ?0 :1 , loginuid, sessionid, sid);
@@ -1693,11 +1702,13 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,struct km_event c;struct xfrm_usersa_flush *p =nlmsg_data (nlh);struct xfrm_audit audit_info; +struct secids secid;int err; audit_info.loginuid =audit_get_loginuid (current); audit_info.sessionid =audit_get_sessionid (current); -security_task_getsecid (current, &audit_info.secid); +security_task_getsecid (current, &secid); + audit_info.secid =lsm_get_secid (&secid,0 ); err =xfrm_state_flush (net, p->proto, &audit_info);if (err) {if (err == -ESRCH )/* empty table */
@@ -1883,6 +1894,7 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,u8 type =XFRM_POLICY_TYPE_MAIN ;int err;struct xfrm_audit audit_info; +struct secids secid; err =copy_from_user_policy_type (&type, attrs);if (err)
@@ -1890,7 +1902,8 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, audit_info.loginuid =audit_get_loginuid (current); audit_info.sessionid =audit_get_sessionid (current); -security_task_getsecid (current, &audit_info.secid); +security_task_getsecid (current, &secid); + audit_info.secid =lsm_get_secid (&secid,0 ); err =xfrm_policy_flush (net, type, &audit_info);if (err) {if (err == -ESRCH )/* empty table */
@@ -1960,8 +1973,10 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,kuid_t loginuid =audit_get_loginuid (current);u32 sessionid =audit_get_sessionid (current);u32 sid; +struct secids sids; -security_task_getsecid (current, &sid); +security_task_getsecid (current, &sids); + sid =lsm_get_secid (&sids,0 );xfrm_policy_delete (xp, p->dir);xfrm_audit_policy_delete (xp,1 , loginuid, sessionid, sid);
@@ -2003,8 +2018,10 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,kuid_t loginuid =audit_get_loginuid (current);u32 sessionid =audit_get_sessionid (current);u32 sid; +struct secids sids; -security_task_getsecid (current, &sid); +security_task_getsecid (current, &sids); + sid =lsm_get_secid (&sids,0 );__xfrm_state_delete (x);xfrm_audit_state_delete (x,1 , loginuid, sessionid, sid); }
security/apparmor/context.c +5 -5
@@ -76,7 +76,7 @@ void aa_dup_task_context(struct aa_task_cxt *new, const struct aa_task_cxt *old)*/ int aa_replace_current_profile (struct aa_profile *profile) { -struct aa_task_cxt *cxt =current_cred ()->security; +struct aa_task_cxt *cxt =lsm_get_cred (current_cred (), &apparmor_ops);struct cred *new;BUG_ON (!profile);
@@ -87,7 +87,7 @@ int aa_replace_current_profile(struct aa_profile *profile)if (!new)return -ENOMEM ; - cxt = new->security; + cxt =lsm_get_cred (new, &apparmor_ops);if (unconfined (profile) || (cxt->profile->ns != profile->ns)) {/* if switching to unconfined or a different profile namespace * clear out context state
@@ -123,7 +123,7 @@ int aa_set_current_onexec(struct aa_profile *profile)if (!new)return -ENOMEM ; - cxt = new->security; + cxt =lsm_get_cred (new, &apparmor_ops);aa_get_profile (profile);aa_put_profile (cxt->onexec); cxt->onexec = profile;
@@ -150,7 +150,7 @@ int aa_set_current_hat(struct aa_profile *profile, u64 token)return -ENOMEM ;BUG_ON (!profile); - cxt = new->security; + cxt =lsm_get_cred (new, &apparmor_ops);if (!cxt->previous) {/* transfer refcount */ cxt->previous = cxt->profile;
@@ -187,7 +187,7 @@ int aa_restore_previous_profile(u64 token)if (!new)return -ENOMEM ; - cxt = new->security; + cxt =lsm_get_cred (new, &apparmor_ops);if (cxt->token != token) {abort_creds (new);return -EACCES ;
security/apparmor/domain.c +4 -4
@@ -360,7 +360,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)if (bprm->cred_prepared)return 0 ; - cxt = bprm->cred->security; + cxt =lsm_get_cred (bprm->cred, &apparmor_ops);BUG_ON (!cxt); profile =aa_get_profile (aa_newest_version (cxt->profile));
@@ -557,7 +557,7 @@ int apparmor_bprm_secureexec(struct linux_binprm *bprm)void apparmor_bprm_committing_creds (struct linux_binprm *bprm) {struct aa_profile *profile =__aa_current_profile (); -struct aa_task_cxt *new_cxt = bprm->cred->security; +struct aa_task_cxt *new_cxt =lsm_get_cred (bprm->cred, &apparmor_ops);/* bail out if unconfined or not changing profile */ if ((new_cxt->profile == profile) ||
@@ -634,7 +634,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)/* released below */ cred =get_current_cred (); - cxt = cred->security; + cxt =lsm_get_cred (cred, &apparmor_ops); profile =aa_cred_profile (cred); previous_profile = cxt->previous;
@@ -770,7 +770,7 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec, } cred =get_current_cred (); - cxt = cred->security; + cxt =lsm_get_cred (cred, &apparmor_ops); profile =aa_cred_profile (cred);/*
security/apparmor/include/apparmor.h +3 -0
@@ -61,6 +61,9 @@ extern unsigned int aa_g_path_max;/* Flag indicating whether initialization completed */ extern int apparmor_initialized__initdata ; +extern struct security_operations apparmor_ops; + +/* fn's in lib */ char *aa_split_fqname (char *args,char **ns_name);void aa_info_message (const char *str);
security/apparmor/include/context.h +6 -3
@@ -18,6 +18,7 @@#include <linux/cred.h> #include <linux/slab.h> #include <linux/sched.h> +#include <linux/lsm.h> #include "policy.h"
@@ -89,7 +90,8 @@ int aa_restore_previous_profile(u64 cookie);*/ static inline bool __aa_task_is_confined (struct task_struct *task) { -struct aa_task_cxt *cxt =__task_cred (task)->security; +struct aa_task_cxt *cxt = +lsm_get_cred (__task_cred (task), &apparmor_ops);BUG_ON (!cxt || !cxt->profile);if (unconfined (aa_newest_version (cxt->profile)))
@@ -108,7 +110,7 @@ static inline bool __aa_task_is_confined(struct task_struct *task)*/ static inline struct aa_profile *aa_cred_profile (const struct cred *cred) { -struct aa_task_cxt *cxt = cred->security; +struct aa_task_cxt *cxt =lsm_get_cred (cred, &apparmor_ops);BUG_ON (!cxt || !cxt->profile);return aa_newest_version (cxt->profile); }
@@ -136,7 +138,8 @@ static inline struct aa_profile *__aa_current_profile(void)*/ static inline struct aa_profile *aa_current_profile (void ) { -const struct aa_task_cxt *cxt =current_cred ()->security; +const struct aa_task_cxt *cxt = +lsm_get_cred (current_cred (), &apparmor_ops);struct aa_profile *profile;BUG_ON (!cxt || !cxt->profile);
security/apparmor/lsm.c +17 -17
@@ -48,8 +48,8 @@ int apparmor_initialized __initdata;*/ static void apparmor_cred_free (struct cred *cred) { -aa_free_task_context (cred->security); - cred->security =NULL ; +aa_free_task_context (lsm_get_cred (cred, &apparmor_ops)); +lsm_set_cred (cred,NULL , &apparmor_ops); }/*
@@ -62,7 +62,7 @@ static int apparmor_cred_alloc_blank(struct cred *cred, gfp_t gfp)if (!cxt)return -ENOMEM ; - cred->security = cxt; +lsm_set_cred (cred, cxt, &apparmor_ops);return 0 ; }
@@ -77,8 +77,8 @@ static int apparmor_cred_prepare(struct cred *new, const struct cred *old,if (!cxt)return -ENOMEM ; -aa_dup_task_context (cxt, old->security); - new->security = cxt; +aa_dup_task_context (cxt,lsm_get_cred (old, &apparmor_ops)); +lsm_set_cred (new, cxt, &apparmor_ops);return 0 ; }
@@ -87,8 +87,8 @@ static int apparmor_cred_prepare(struct cred *new, const struct cred *old,*/ static void apparmor_cred_transfer (struct cred *new,const struct cred *old) { -const struct aa_task_cxt *old_cxt = old->security; -struct aa_task_cxt *new_cxt = new->security; +const struct aa_task_cxt *old_cxt =lsm_get_cred (old, &apparmor_ops); +struct aa_task_cxt *new_cxt =lsm_get_cred (new, &apparmor_ops);aa_dup_task_context (new_cxt, old_cxt); }
@@ -375,7 +375,7 @@ static int apparmor_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)static int apparmor_file_open (struct file *file,const struct cred *cred) { -struct aa_file_cxt *fcxt = file->f_security; +struct aa_file_cxt *fcxt =lsm_get_file (file, &apparmor_ops);struct aa_profile *profile;int error =0 ;
@@ -409,8 +409,8 @@ static int apparmor_file_open(struct file *file, const struct cred *cred)static int apparmor_file_alloc_security (struct file *file) {/* freed by apparmor_file_free_security */ - file->f_security =aa_alloc_file_context (GFP_KERNEL ); -if (!file->f_security) +lsm_set_file (file,aa_alloc_file_context (GFP_KERNEL ), &apparmor_ops); +if (!lsm_get_file (file, &apparmor_ops))return -ENOMEM ;return 0 ;
@@ -418,14 +418,14 @@ static int apparmor_file_alloc_security(struct file *file)static void apparmor_file_free_security (struct file *file) { -struct aa_file_cxt *cxt = file->f_security; +struct aa_file_cxt *cxt =lsm_get_file (file, &apparmor_ops);aa_free_file_context (cxt); }static int common_file_perm (int op,struct file *file,u32 mask) { -struct aa_file_cxt *fcxt = file->f_security; +struct aa_file_cxt *fcxt =lsm_get_file (file, &apparmor_ops);struct aa_profile *profile, *fprofile =aa_cred_profile (file->f_cred);int error =0 ;
@@ -472,7 +472,7 @@ static int common_mmap(int op, struct file *file, unsigned long prot,struct dentry *dentry;int mask =0 ; -if (!file || !file->f_security) +if (!file || !lsm_get_file (file, &apparmor_ops))return 0 ;if (prot &PROT_READ )
@@ -510,7 +510,7 @@ static int apparmor_getprocattr(struct task_struct *task, char *name,struct aa_profile *profile;/* released below */ const struct cred *cred =get_task_cred (task); -struct aa_task_cxt *cxt = cred->security; +struct aa_task_cxt *cxt =lsm_get_cred (cred, &apparmor_ops); profile =aa_cred_profile (cred);if (strcmp (name,"current" ) ==0 )
@@ -614,7 +614,7 @@ static int apparmor_task_setrlimit(struct task_struct *task,return error; } -static struct security_operations apparmor_ops = { +struct security_operations apparmor_ops = { .name ="apparmor" , .ptrace_access_check = apparmor_ptrace_access_check,
@@ -886,7 +886,7 @@ static int __init set_init_cxt(void)return -ENOMEM ; cxt->profile =aa_get_profile (root_ns->unconfined); - cred->security = cxt; +lsm_set_cred (cred, cxt, &apparmor_ops);return 0 ; }
@@ -931,7 +931,7 @@ static int __init apparmor_init(void)return error; set_init_cxt_out: -aa_free_task_context (current->real_cred->security); +aa_free_task_context (lsm_get_cred (current->real_cred, &apparmor_ops)); register_security_out:aa_free_root_ns ();
security/integrity/ima/ima.h +2 -2
@@ -192,8 +192,8 @@ static inline int security_filter_rule_init(u32 field, u32 op, char *rulestr,return -EINVAL ; } -static inline int security_filter_rule_match (u32 secid,u32 field,u32 op, -void *lsmrule, +static inline int security_filter_rule_match (struct secids *secid,u32 field, +u32 op,void *lsmrule,struct audit_context *actx) {return -EINVAL ;
security/integrity/ima/ima_policy.c +3 -3
@@ -184,7 +184,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule,return false;for (i =0 ; i <MAX_LSM_RULES ; i++) {int rc =0 ; -u32 osid, sid; +struct secids osid, sid;int retried =0 ;if (!rule->lsm[i].rule)
@@ -195,7 +195,7 @@ retry:case LSM_OBJ_ROLE :case LSM_OBJ_TYPE :security_inode_getsecid (inode, &osid); - rc = security_filter_rule_match(osid, + rc = security_filter_rule_match(&osid, rule->lsm[i].type, Audit_equal, rule->lsm[i].rule,
@@ -205,7 +205,7 @@ retry:case LSM_SUBJ_ROLE :case LSM_SUBJ_TYPE :security_task_getsecid (tsk, &sid); - rc = security_filter_rule_match(sid, + rc = security_filter_rule_match(&sid, rule->lsm[i].type, Audit_equal, rule->lsm[i].rule,
security/security.c +47 -22
148 lines not on this page · raw message
security/selinux/hooks.c +188 -145
1,009 lines not on this page · raw message
security/selinux/include/objsec.h +1 -0
@@ -119,5 +119,6 @@ struct key_security_struct { };extern unsigned int selinux_checkreqprot; +extern struct security_operations selinux_ops;#endif /* _SELINUX_OBJSEC_H_ */
security/selinux/include/xfrm.h +1 -1
@@ -31,7 +31,7 @@ static inline struct inode_security_struct *get_sock_isec(struct sock *sk)if (!sk->sk_socket)return NULL ; -return SOCK_INODE (sk->sk_socket)->i_security; +return lsm_get_inode (SOCK_INODE (sk->sk_socket), &selinux_ops); }#ifdef CONFIG_SECURITY_NETWORK_XFRM
security/selinux/netlabel.c +7 -6
@@ -81,7 +81,7 @@ static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,static struct netlbl_lsm_secattr *selinux_netlbl_sock_genattr (struct sock *sk) {int rc; -struct sk_security_struct *sksec = sk->sk_security; +struct sk_security_struct *sksec =lsm_get_sock (sk, &selinux_ops);struct netlbl_lsm_secattr *secattr;if (sksec->nlbl_secattr !=NULL )
@@ -221,7 +221,8 @@ int selinux_netlbl_skbuff_setsid(struct sk_buff *skb,* being labeled by it's parent socket, if it is just exit */ sk = skb->sk;if (sk !=NULL ) { -struct sk_security_struct *sksec = sk->sk_security; +struct sk_security_struct *sksec = +lsm_get_sock (sk, &selinux_ops);if (sksec->nlbl_state !=NLBL_REQSKB )return 0 ; secattr = sksec->nlbl_secattr;
@@ -283,7 +284,7 @@ inet_conn_request_return:*/ void selinux_netlbl_inet_csk_clone (struct sock *sk,u16 family) { -struct sk_security_struct *sksec = sk->sk_security; +struct sk_security_struct *sksec =lsm_get_sock (sk, &selinux_ops);if (family ==PF_INET ) sksec->nlbl_state =NLBL_LABELED ;
@@ -304,7 +305,7 @@ void selinux_netlbl_inet_csk_clone(struct sock *sk, u16 family)int selinux_netlbl_socket_post_create (struct sock *sk,u16 family) {int rc; -struct sk_security_struct *sksec = sk->sk_security; +struct sk_security_struct *sksec =lsm_get_sock (sk, &selinux_ops);struct netlbl_lsm_secattr *secattr;if (family !=PF_INET )
@@ -402,7 +403,7 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, {int rc =0 ;struct sock *sk = sock->sk; -struct sk_security_struct *sksec = sk->sk_security; +struct sk_security_struct *sksec =lsm_get_sock (sk, &selinux_ops);struct netlbl_lsm_secattr secattr; if (level == IPPROTO_IP && optname == IP_OPTIONS &&
@@ -435,7 +436,7 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock,int selinux_netlbl_socket_connect (struct sock *sk,struct sockaddr *addr) {int rc; -struct sk_security_struct *sksec = sk->sk_security; +struct sk_security_struct *sksec =lsm_get_sock (sk, &selinux_ops);struct netlbl_lsm_secattr *secattr; if (sksec->nlbl_state != NLBL_REQSKB &&
security/selinux/selinuxfs.c +4 -3
@@ -23,6 +23,7 @@#include <linux/init.h> #include <linux/string.h> #include <linux/security.h> +#include <linux/lsm.h> #include <linux/major.h> #include <linux/seq_file.h> #include <linux/percpu.h>
@@ -83,7 +84,7 @@ static int task_has_security(struct task_struct *tsk,u32 sid =0 ;rcu_read_lock (); - tsec =__task_cred (tsk)->security; + tsec =lsm_get_cred (__task_cred (tsk), &selinux_ops);if (tsec) sid = tsec->sid;rcu_read_unlock ();
@@ -1262,7 +1263,7 @@ static int sel_make_bools(void)if (len >=PAGE_SIZE ) goto out; - isec = (struct inode_security_struct *)inode->i_security; + isec =lsm_get_inode (inode, &selinux_ops); ret =security_genfs_sid ("selinuxfs" , page,SECCLASS_FILE , &sid);if (ret) goto out;
@@ -1827,7 +1828,7 @@ static int sel_fill_super(struct super_block *sb, void *data, int silent) goto err; inode->i_ino = ++sel_last_ino; - isec = (struct inode_security_struct *)inode->i_security; + isec =lsm_get_inode (inode, &selinux_ops); isec->sid =SECINITSID_DEVNULL ; isec->sclass =SECCLASS_CHR_FILE ; isec->initialized =1 ;
security/selinux/ss/services.c +3 -2
@@ -48,6 +48,7 @@#include <linux/in.h> #include <linux/sched.h> #include <linux/audit.h> +#include <linux/lsm.h> #include <linux/mutex.h> #include <linux/selinux.h> #include <linux/flex_array.h>
@@ -3129,7 +3130,7 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,if (secattr->flags &NETLBL_SECATTR_CACHE ) *sid = *(u32 *)secattr->cache->data;else if (secattr->flags &NETLBL_SECATTR_SECID ) - *sid = secattr->attr.secid; + *sid =lsm_get_secid (&secattr->attr.secid,0 );else if (secattr->flags &NETLBL_SECATTR_MLS_LVL ) { rc = -EIDRM ; ctx =sidtab_search (&sidtab,SECINITSID_NETMSG );
@@ -3204,7 +3205,7 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)if (secattr->domain ==NULL ) goto out; - secattr->attr.secid = sid; +lsm_set_secid (&secattr->attr.secid, sid,0 ); secattr->flags |=NETLBL_SECATTR_DOMAIN_CPY |NETLBL_SECATTR_SECID ;mls_export_netlbl_lvl (ctx, secattr); rc =mls_export_netlbl_cat (ctx, secattr);
security/selinux/xfrm.c +6 -3
@@ -198,7 +198,8 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *uctx, u32 sid) { int rc = 0; -const struct task_security_struct *tsec =current_security (); +const struct task_security_struct *tsec = +lsm_get_cred (current_cred (), &selinux_ops);struct xfrm_sec_ctx *ctx =NULL ;char *ctx_str =NULL ;u32 str_len;
@@ -336,7 +337,8 @@ void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx)*/ int selinux_xfrm_policy_delete (struct xfrm_sec_ctx *ctx) { -const struct task_security_struct *tsec =current_security (); +const struct task_security_struct *tsec = +lsm_get_cred (current_cred (), &selinux_ops);if (!ctx)return 0 ;
@@ -377,7 +379,8 @@ void selinux_xfrm_state_free(struct xfrm_state *x)*/ int selinux_xfrm_state_delete (struct xfrm_state *x) { -const struct task_security_struct *tsec =current_security (); +const struct task_security_struct *tsec = +lsm_get_cred (current_cred (), &selinux_ops);struct xfrm_sec_ctx *ctx = x->security;if (!ctx)
security/smack/smack.h +4 -3
@@ -16,6 +16,7 @@#include <linux/capability.h> #include <linux/spinlock.h> #include <linux/security.h> +#include <linux/lsm.h> #include <linux/in.h> #include <net/netlabel.h> #include <linux/list.h>
@@ -240,7 +241,7 @@ extern struct security_operations smack_ops;*/ static inline int smk_inode_transmutable (const struct inode *isp) { -struct inode_smack *sip = isp->i_security; +struct inode_smack *sip =lsm_get_inode (isp, &smack_ops);return (sip->smk_flags &SMK_INODE_TRANSMUTE ) !=0 ; }
@@ -249,7 +250,7 @@ static inline int smk_inode_transmutable(const struct inode *isp)*/ static inline char *smk_of_inode (const struct inode *isp) { -struct inode_smack *sip = isp->i_security; +struct inode_smack *sip =lsm_get_inode (isp, &smack_ops);return sip->smk_inode; }
@@ -274,7 +275,7 @@ static inline char *smk_of_forked(const struct task_smack *tsp)*/ static inline char *smk_of_current (void ) { -return smk_of_task (current_security ()); +return smk_of_task (lsm_get_cred (current_cred (), &smack_ops)); }/*
security/smack/smack_access.c +1 -1
@@ -197,7 +197,7 @@ out_audit:*/ int smk_curacc (char *obj_label,u32 mode,struct smk_audit_info *a) { -struct task_smack *tsp =current_security (); +struct task_smack *tsp =lsm_get_cred (current_cred (), &smack_ops);char *sp =smk_of_task (tsp);int may;int rc;
security/smack/smack_lsm.c +91 -89
100 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.
Part of the diff is not shown here. View the raw message.
Re: [PATCH v14 1/6] LSM: Security blob abstraction
Quoted 10 lines · Casey Schaufler
Subject: [PATCH v14 1/6] LSM: Security blob abstraction
Create an abstracted interface for security blobs. Instead of directly accessing security blob pointers Use
lsm_getandlsm_setfunctions that hide the actual mechanism used to maintain the security blobs. This affects most uses ofinode->i_security,file->f_security,cred->securityand similar fields in keys, sockets, superblocks, ipc and keys.
Quoted 7 lines
The use of a single 32 bit integer to refer to a security blob does not scale to the case where there may be more than one relevant security blob. Where it is possible to do so the use of secids (u32) has been replaced with a struct secids, which provides for multiple u32 values. There are components where u32 secids remain at the request of the maintainer of that component.
If I boot with "security=apparmor", lsm_set_blob ends up with a NULL "bp" and Oopses the kernel. Still happens with "security=yama,apparmor". As soon as I add smack anywhere in the list, everything is fine. It seems like the AppArmor init needs to be changed to:
security/apparmor/lsm.c +3 -3
@@ -875,9 +875,9 @@ static int __init set_init_cxt(void)return -ENOMEM ; cxt->profile =aa_get_profile (root_ns->unconfined); -lsm_set_cred (cred, cxt, &apparmor_ops); - -return 0 ; +printk (KERN_INFO "AA: cred:%p cxt:%p &apparmor_ops:%p\n" , + cred, cxt, &apparmor_ops); +return lsm_set_init_cred (cred, cxt, &apparmor_ops); }static int __init apparmor_init (void )
Or maybe it still needs lsm_set_cred, but an earlier lsm_set_init_cred? It's not clear to me yet.
-Kees
Signature · 2 lines
Kees Cook Chrome OS Security
Casey Schaufler
maintainerRe: [PATCH v14 1/6] LSM: Security blob abstraction
Quoted 30 lines · Kees Cook
Quoted 10 lines · Casey Schaufler
Subject: [PATCH v14 1/6] LSM: Security blob abstraction
Create an abstracted interface for security blobs. Instead of directly accessing security blob pointers Use
lsm_getandlsm_setfunctions that hide the actual mechanism used to maintain the security blobs. This affects most uses ofinode->i_security,file->f_security,cred->securityand similar fields in keys, sockets, superblocks, ipc and keys.Quoted 7 lines
The use of a single 32 bit integer to refer to a security blob does not scale to the case where there may be more than one relevant security blob. Where it is possible to do so the use of secids (u32) has been replaced with a struct secids, which provides for multiple u32 values. There are components where u32 secids remain at the request of the maintainer of that component.
If I boot with "security=apparmor",
lsm_set_blobends up with a NULL "bp" and Oopses the kernel. Still happens with "security=yama,apparmor". As soon as I add smack anywhere in the list, everything is fine. It seems like the AppArmor init needs to be changed to:security/apparmor/lsm.c +0
-0
security/apparmor/lsm.c static int __init set_init_cxt(void) · line 880
Quoted 9 lines
security/apparmor/lsm.c +3
-3@@ -875,9 +875,9 @@ static int __init set_init_cxt(void)return -ENOMEM ; cxt->profile =aa_get_profile (root_ns->unconfined); -lsm_set_cred (cred, cxt, &apparmor_ops); - -return 0 ; +printk (KERN_INFO "AA: cred:%p cxt:%p &apparmor_ops:%p\n" , + cred, cxt, &apparmor_ops); +return lsm_set_init_cred (cred, cxt, &apparmor_ops);
I've incorporated this fix (without the printk) and she looks good.
Quoted 9 lines
security/apparmor/lsm.c +0
-0}static int __init apparmor_init (void )Or maybe it still needs
lsm_set_cred, but an earlierlsm_set_init_cred? It's not clear to me yet.-Kees
Casey Schaufler
maintainerPATCH v14 2/6 LSM: Move the capability LSM into the hook handlers
In reply to Casey SchauflerSubject: [PATCH v14 2/6] LSM: Move the capability LSM into the hook handlers
Move the capability module hooks out of thier own module and into security.c. Pull the calls out of the LSMs as well, as the call is getting already getting done. It turns out that in all but a few cases the LSMs that provide those hooks call the capability function themselves.
When a secctx is generated it may be done for a specific LSM or for a collection of LSMs. In the former case the LSM's free function will be required to release the memory involved, while in the latter case the lsm infrastructure's free code needs to be called. The context generation has to note which LSM created a context, or if it was done for a set.
--- fs/sysfs/dir.c | 3 +- fs/sysfs/inode.c | 12 ++- fs/sysfs/sysfs.h | 7 +- fs/xattr.c | 8 +- include/linux/lsm.h | 46 +++++++++ include/linux/security.h | 40 +++++--- include/net/scm.h | 9 +- include/net/xfrm.h | 6 +- kernel/audit.c | 22 +++-- kernel/auditsc.c | 10 +- kernel/cred.c | 11 ++- net/ipv4/cipso_ipv4.c | 3 +- net/ipv4/ip_sockglue.c | 5 +- .../netfilter/nf_conntrack_l3proto_ipv4_compat.c | 5 +- net/netfilter/nf_conntrack_netlink.c | 8 +- net/netfilter/nf_conntrack_standalone.c | 5 +- net/netfilter/xt_SECMARK.c | 4 +- net/netlabel/netlabel_unlabeled.c | 28 +++--- net/netlabel/netlabel_user.c | 5 +- net/xfrm/xfrm_user.c | 16 +-- security/apparmor/domain.c | 13 +-- security/apparmor/lsm.c | 22 +---- security/security.c | 104 +++++++++++++++++--- security/selinux/hooks.c | 73 +------------- security/selinux/ss/services.c | 4 +- security/smack/smack_lsm.c | 45 ++------- security/tomoyo/common.h | 2 +- security/tomoyo/tomoyo.c | 6 -- security/yama/yama_lsm.c | 24 +---- 29 files changed, 296 insertions(+), 250 deletions(-)
fs/sysfs/dir.c +2 -1
@@ -278,7 +278,8 @@ void release_sysfs_dirent(struct sysfs_dirent * sd)kfree (sd->s_name);if (sd->s_iattr && sd->s_iattr->ia_secdata)security_release_secctx (sd->s_iattr->ia_secdata, - sd->s_iattr->ia_secdata_len); + sd->s_iattr->ia_secdata_len, + sd->s_iattr->ia_sop);kfree (sd->s_iattr);sysfs_free_ino (sd->s_ino);kmem_cache_free (sysfs_dir_cachep, sd);
fs/sysfs/inode.c +8 -4
@@ -130,7 +130,9 @@ out:return error; } -static int sysfs_sd_setsecdata (struct sysfs_dirent *sd,void **secdata,u32 *secdata_len) +static int sysfs_sd_setsecdata (struct sysfs_dirent *sd,void **secdata, +u32 *secdata_len, +struct security_operations *sop) {struct sysfs_inode_attrs *iattrs;void *old_secdata;
@@ -148,6 +150,7 @@ static int sysfs_sd_setsecdata(struct sysfs_dirent *sd, void **secdata, u32 *sec iattrs->ia_secdata = *secdata; iattrs->ia_secdata_len = *secdata_len; + iattrs->ia_sop = sop; *secdata = old_secdata; *secdata_len = old_secdata_len;
@@ -161,6 +164,7 @@ int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value,void *secdata;int error;u32 secdata_len =0 ; +struct security_operations *sop;if (!sd)return -EINVAL ;
@@ -172,16 +176,16 @@ int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value,if (error) goto out; error =security_inode_getsecctx (dentry->d_inode, - &secdata, &secdata_len); + &secdata, &secdata_len, &sop);if (error) goto out;mutex_lock (&sysfs_mutex); - error =sysfs_sd_setsecdata (sd, &secdata, &secdata_len); + error =sysfs_sd_setsecdata (sd, &secdata, &secdata_len, sop);mutex_unlock (&sysfs_mutex);if (secdata) -security_release_secctx (secdata, secdata_len); +security_release_secctx (secdata, secdata_len, sop); }else return -EINVAL ; out:
fs/sysfs/sysfs.h +4 -3
@@ -39,9 +39,10 @@ struct sysfs_elem_bin_attr { };struct sysfs_inode_attrs { -struct iattr ia_iattr; -void *ia_secdata; -u32 ia_secdata_len; +struct iattr ia_iattr; +void *ia_secdata; +u32 ia_secdata_len; +struct security_operations *ia_sop; };/*
fs/xattr.c +5 -3
@@ -148,13 +148,15 @@ xattr_getsecurity(struct inode *inode, const char *name, void *value, {void *buffer =NULL ;ssize_t len; +struct security_operations *sop;if (!value || !size) { - len =security_inode_getsecurity (inode, name, &buffer, false); + len =security_inode_getsecurity (inode, name, &buffer, false, + &sop); goto out_noalloc; } - len =security_inode_getsecurity (inode, name, &buffer, true); + len =security_inode_getsecurity (inode, name, &buffer, true, &sop);if (len <0 )return len;if (size < len) {
@@ -163,7 +165,7 @@ xattr_getsecurity(struct inode *inode, const char *name, void *value, }memcpy (value, buffer, len); out: -security_release_secctx (buffer, len); +security_release_secctx (buffer, len, sop); out_noalloc:return len; }
include/linux/lsm.h +46 -0
56 lines not on this page · raw message
include/linux/security.h +28 -12
@@ -1773,7 +1773,9 @@ int security_inode_listxattr(struct dentry *dentry);int security_inode_removexattr (struct dentry *dentry,const char *name);int security_inode_need_killpriv (struct dentry *dentry);int security_inode_killpriv (struct dentry *dentry); -int security_inode_getsecurity (const struct inode *inode,const char *name,void **buffer,bool alloc); +int security_inode_getsecurity (const struct inode *inode,const char *name, +void **buffer,bool alloc, +struct security_operations **sop);int security_inode_setsecurity (struct inode *inode,const char *name,const void *value,size_t size,int flags);int security_inode_listsecurity (struct inode *inode,char *buffer,size_t buffer_size);void security_inode_getsecid (const struct inode *inode,struct secids *secid);
@@ -1850,15 +1852,22 @@ void security_d_instantiate(struct dentry *dentry, struct inode *inode);int security_getprocattr (struct task_struct *p,char *name,char **value);int security_setprocattr (struct task_struct *p,char *name,void *value,size_t size);int security_netlink_send (struct sock *sk,struct sk_buff *skb); -int security_secid_to_secctx (struct secids *secid,char **secdata,u32 *seclen); +int security_secid_to_secctx (struct secids *secid,char **secdata,u32 *seclen, +struct security_operations **secops);int security_secctx_to_secid (const char *secdata,u32 seclen, -struct secids *secid); -void security_release_secctx (char *secdata,u32 seclen); +struct secids *secid, +struct security_operations *secops); +void security_release_secctx (char *secdata,u32 seclen, +struct security_operations *secops);int security_inode_notifysecctx (struct inode *inode,void *ctx,u32 ctxlen);int security_inode_setsecctx (struct dentry *dentry,void *ctx,u32 ctxlen); -int security_inode_getsecctx (struct inode *inode,void **ctx,u32 *ctxlen); +int security_inode_getsecctx (struct inode *inode,void **ctx,u32 *ctxlen, +struct security_operations **secops);#else /* CONFIG_SECURITY */ +struct security_operations { +}; +struct security_mnt_opts { };
@@ -2184,7 +2193,10 @@ static inline int security_inode_killpriv(struct dentry *dentry)return cap_inode_killpriv (dentry); } -static inline int security_inode_getsecurity (const struct inode *inode,const char *name,void **buffer,bool alloc) +static inline int security_inode_getsecurity (const struct inode *inode, +const char *name,void **buffer, +bool alloc, +struct security_operations **sop) {return -EOPNOTSUPP ; }
@@ -2539,19 +2551,21 @@ static inline int security_netlink_send(struct sock *sk, struct sk_buff *skb) }static inline int security_secid_to_secctx (struct secids *secid, -char **secdata,u32 *seclen) +char **secdata,u32 *seclen, +struct security_operations **secops) {return -EOPNOTSUPP ; } -static inline int security_secctx_to_secid (const char *secdata, -u32 seclen, -struct secids *secid) +static inline int security_secctx_to_secid (const char *secdata,u32 seclen, +struct secids *secid, +struct security_operations *secops) {return -EOPNOTSUPP ; } -static inline void security_release_secctx (char *secdata,u32 seclen) +static inline void security_release_secctx (char *secdata,u32 seclen, +struct security_operations *secops) { }
@@ -2563,7 +2577,9 @@ static inline int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 {return -EOPNOTSUPP ; } -static inline int security_inode_getsecctx (struct inode *inode,void **ctx,u32 *ctxlen) +static inline int security_inode_getsecctx (struct inode *inode,void **ctx, +u32 *ctxlen, +struct security_operations **secops) {return -EOPNOTSUPP ; }
include/net/scm.h +6 -3
@@ -91,13 +91,16 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scchar *secdata;u32 seclen;int err; +struct security_operations *sop;if (test_bit (SOCK_PASSSEC , &sock->flags)) { - err =security_secid_to_secctx (&scm->secid, &secdata, &seclen); + err =security_secid_to_secctx (&scm->secid, &secdata, + &seclen, &sop);if (!err) { -put_cmsg (msg,SOL_SOCKET ,SCM_SECURITY , seclen, secdata); -security_release_secctx (secdata, seclen); +put_cmsg (msg,SOL_SOCKET ,SCM_SECURITY , seclen, + secdata); +security_release_secctx (secdata, seclen, sop); } } }
include/net/xfrm.h +4 -2
@@ -701,14 +701,16 @@ static inline void xfrm_audit_helper_usrinfo(kuid_t auid, u32 ses, u32 secid,char *secctx;u32 secctx_len;struct secids secids; +struct security_operations *sop;audit_log_format (audit_buf," auid=%u ses=%u" ,from_kuid (&init_user_ns, auid), ses);lsm_init_secid (&secids, secid,0 );if (secid !=0 && -security_secid_to_secctx (&secids, &secctx, &secctx_len) ==0 ) { +security_secid_to_secctx (&secids, &secctx, &secctx_len, + &sop) ==0 ) {audit_log_format (audit_buf," subj=%s" , secctx); -security_release_secctx (secctx, secctx_len); +security_release_secctx (secctx, secctx_len, sop); }else audit_log_task_context (audit_buf); }
kernel/audit.c +13 -9
@@ -640,6 +640,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)struct audit_sig_info *sig_data;char *ctx =NULL ;u32 len; +struct security_operations *sop; err =audit_netlink_ok (skb, msg_type);if (err)
@@ -795,21 +796,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) len =0 ;if (!lsm_zero_secid (&audit_sig_sid)) { err =security_secid_to_secctx (&audit_sig_sid, &ctx, - &len); + &len, &sop);if (err)return err; } sig_data =kmalloc (sizeof (*sig_data) + len,GFP_KERNEL );if (!sig_data) {if (!lsm_zero_secid (&audit_sig_sid)) -security_release_secctx (ctx, len); +security_release_secctx (ctx, len, sop);return -ENOMEM ; } sig_data->uid =from_kuid (&init_user_ns, audit_sig_uid); sig_data->pid = audit_sig_pid;if (!lsm_zero_secid (&audit_sig_sid)) {memcpy (sig_data->ctx, ctx, len); -security_release_secctx (ctx, len); +security_release_secctx (ctx, len, sop); }audit_send_reply (NETLINK_CB (skb).portid, seq,AUDIT_SIGNAL_INFO ,0 ,0 , sig_data,sizeof (*sig_data) + len);
@@ -1480,6 +1481,7 @@ void audit_copy_inode(struct audit_names *name, const struct dentry *dentry,void audit_log_name (struct audit_context *context,struct audit_names *n,struct path *path,int record_num,int *call_panic) { +struct security_operations *sop;struct audit_buffer *ab; ab =audit_log_start (context,GFP_KERNEL ,AUDIT_PATH );if (!ab)
@@ -1526,13 +1528,13 @@ void audit_log_name(struct audit_context *context, struct audit_names *n,if (!lsm_zero_secid (&n->osid)) {char *ctx =NULL ;u32 len; -if (security_secid_to_secctx (&n->osid, &ctx, &len)) { +if (security_secid_to_secctx (&n->osid, &ctx, &len, &sop)) {audit_log_format (ab," osid=%u" , n->osid.si_count);if (call_panic) *call_panic =2 ; }else {audit_log_format (ab," obj=%s" , ctx); -security_release_secctx (ctx, len); +security_release_secctx (ctx, len, sop); } }
@@ -1546,12 +1548,13 @@ int audit_log_task_context(struct audit_buffer *ab)unsigned len;int error;struct secids sid; +struct security_operations *sop;security_task_getsecid (current, &sid);if (lsm_zero_secid (&sid))return 0 ; - error =security_secid_to_secctx (&sid, &ctx, &len); + error =security_secid_to_secctx (&sid, &ctx, &len, &sop);if (error) {if (error != -EINVAL ) goto error_path;
@@ -1559,7 +1562,7 @@ int audit_log_task_context(struct audit_buffer *ab) }audit_log_format (ab," subj=%s" , ctx); -security_release_secctx (ctx, len); +security_release_secctx (ctx, len, sop);return 0 ; error_path:
@@ -1728,13 +1731,14 @@ void audit_log_secctx(struct audit_buffer *ab, u32 secid)u32 len;char *secctx;struct secids secids; +struct security_operations *sop;lsm_init_secid (&secids, secid,0 ); -if (security_secid_to_secctx (&secids, &secctx, &len)) { +if (security_secid_to_secctx (&secids, &secctx, &len, &sop)) {audit_panic ("Cannot convert secid to context" ); }else {audit_log_format (ab," obj=%s" , secctx); -security_release_secctx (secctx, len); +security_release_secctx (secctx, len, sop); } }EXPORT_SYMBOL (audit_log_secctx);
kernel/auditsc.c +6 -4
@@ -984,6 +984,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,char *ctx =NULL ;u32 len;int rc =0 ; +struct security_operations *sop; ab =audit_log_start (context,GFP_KERNEL ,AUDIT_OBJ_PID );if (!ab)
@@ -993,12 +994,12 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,from_kuid (&init_user_ns, auid), from_kuid(&init_user_ns, uid), sessionid);if (!lsm_zero_secid (sid)) { -if (security_secid_to_secctx (sid, &ctx, &len)) { +if (security_secid_to_secctx (sid, &ctx, &len, &sop)) {audit_log_format (ab," obj=(none)" ); rc =1 ; }else {audit_log_format (ab," obj=%s" , ctx); -security_release_secctx (ctx, len); +security_release_secctx (ctx, len, sop); } }audit_log_format (ab," ocomm=" );
@@ -1220,12 +1221,13 @@ static void show_special(struct audit_context *context, int *call_panic)if (!lsm_zero_secid (osid)) {char *ctx =NULL ;u32 len; -if (security_secid_to_secctx (osid, &ctx, &len)) { +struct security_operations *sop; +if (security_secid_to_secctx (osid, &ctx, &len, &sop)) {audit_log_format (ab," osc=%u" , osid->si_count); *call_panic =1 ; }else {audit_log_format (ab," obj=%s" , ctx); -security_release_secctx (ctx, len); +security_release_secctx (ctx, len, sop); } }if (context->ipc.has_perm) {
kernel/cred.c +8 -3
@@ -653,16 +653,21 @@ EXPORT_SYMBOL(set_security_override);* @secctx: The LSM security context to generate the security ID from. * * Set the LSM security ID in a set of credentials so that the subjective -* security is overridden when an alternative set of credentials is used. The -* security ID is specified in string form as a security context to be +* security is overridden when an alternative set of credentials is used. +* The security ID is specified in string form as a security context to be * interpreted by the LSM. +* +* The last parameter to security_secctx_to_secid() indicates which +* LSM should interpret the context string. NULL means that the LSM +* infrastructure may have to figure out for itself which LSM or set +* of LSMs should get called. */ int set_security_override_from_ctx (struct cred *new,const char *secctx) {struct secids secid;int ret; - ret =security_secctx_to_secid (secctx,strlen (secctx), &secid); + ret =security_secctx_to_secid (secctx,strlen (secctx), &secid,NULL );if (ret <0 )return ret;
net/ipv4/cipso_ipv4.c +2 -1
@@ -1570,7 +1570,8 @@ static int cipso_v4_gentag_loc(const struct cipso_v4_doi *doi_def, buffer[0 ] =CIPSO_V4_TAG_LOCAL ; buffer[1 ] =CIPSO_V4_TAG_LOC_BLEN ; - *(u32 *)&buffer[2 ] =lsm_get_secid (&secattr->attr.secid,0 ); + *(u32 *)&buffer[2 ] =lsm_get_secid (&secattr->attr.secid, +lsm_netlbl_order ());return CIPSO_V4_TAG_LOC_BLEN ; }
net/ipv4/ip_sockglue.c +3 -2
@@ -111,17 +111,18 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)u32 seclen;struct secids secid;int err; +struct security_operations *sop; err =security_socket_getpeersec_dgram (NULL , skb, &secid);if (err)return ; - err =security_secid_to_secctx (&secid, &secdata, &seclen); + err =security_secid_to_secctx (&secid, &secdata, &seclen, &sop);if (err)return ;put_cmsg (msg,SOL_IP ,SCM_SECURITY , seclen, secdata); -security_release_secctx (secdata, seclen); +security_release_secctx (secdata, seclen, sop); }static void ip_cmsg_recv_dstaddr (struct msghdr *msg,struct sk_buff *skb)
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +3 -2
@@ -101,15 +101,16 @@ static int ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)u32 len;char *secctx;struct secids secid; +struct security_operations *sop;lsm_init_secid (&secid, ct->secmark,0 ); - ret =security_secid_to_secctx (&secid, &secctx, &len); + ret =security_secid_to_secctx (&secid, &secctx, &len, &sop);if (ret)return 0 ; ret =seq_printf (s,"secctx=%s " , secctx); -security_release_secctx (secctx, len); +security_release_secctx (secctx, len, sop); return ret; }#else
net/netfilter/nf_conntrack_netlink.c +5 -3
@@ -303,9 +303,10 @@ ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)int len, ret;char *secctx;struct secids secid; +struct security_operations *sop;lsm_init_secid (&secid, ct->secmark,0 ); - ret =security_secid_to_secctx (&secid, &secctx, &len); + ret =security_secid_to_secctx (&secid, &secctx, &len, &sop);if (ret)return 0 ;
@@ -320,7 +321,7 @@ ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct) ret =0 ; nla_put_failure: -security_release_secctx (secctx, len); +security_release_secctx (secctx, len, sop); return ret; }#else
@@ -552,9 +553,10 @@ ctnetlink_secctx_size(const struct nf_conn *ct)#ifdef CONFIG_NF_CONNTRACK_SECMARK int len, ret;struct secids secid; +struct security_operations *sop;lsm_init_secid (&secid, ct->secmark,0 ); - ret =security_secid_to_secctx (&secid,NULL , &len); + ret =security_secid_to_secctx (&secid,NULL , &len, &sop);if (ret)return 0 ;
net/netfilter/nf_conntrack_standalone.c +3 -2
@@ -126,15 +126,16 @@ static int ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)u32 len;char *secctx;struct secids secid; +struct security_operations *sop;lsm_init_secid (&secid, ct->secmark,0 ); - ret =security_secid_to_secctx (&secid, &secctx, &len); + ret =security_secid_to_secctx (&secid, &secctx, &len, &sop);if (ret)return 0 ; ret =seq_printf (s,"secctx=%s " , secctx); -security_release_secctx (secctx, len); +security_release_secctx (secctx, len, sop); return ret; }#else
net/netfilter/xt_SECMARK.c +2 -2
@@ -59,14 +59,14 @@ static int checkentry_lsm(struct xt_secmark_target_info *info) info->secid =0 ; err =security_secctx_to_secid (info->secctx,strlen (info->secctx), - &secid); + &secid,lsm_secmark_ops ());if (err) {if (err == -EINVAL )pr_info ("invalid security context \'%s\'\n" , info->secctx);return err; } - info->secid =lsm_get_secid (&secid,0 ); + info->secid =lsm_get_secid (&secid,lsm_secmark_order ());if (!info->secid) {pr_info ("unable to map security context \'%s\'\n" , info->secctx);return -ENOENT ;
net/netlabel/netlabel_unlabeled.c +16 -12
@@ -397,6 +397,7 @@ int netlbl_unlhsh_add(struct net *net,struct secids secids;char *secctx =NULL ;u32 secctx_len; +struct security_operations *sop;if (addr_len !=sizeof (struct in_addr ) && addr_len !=sizeof (struct in6_addr ))
@@ -462,9 +463,9 @@ unlhsh_add_return:lsm_init_secid (&secids, secid,0 );if (security_secid_to_secctx (&secids, &secctx, - &secctx_len) ==0 ) { + &secctx_len, &sop) ==0 ) {audit_log_format (audit_buf," sec_obj=%s" , secctx); -security_release_secctx (secctx, secctx_len); +security_release_secctx (secctx, secctx_len, sop); }audit_log_format (audit_buf," res=%u" , ret_val ==0 ?1 :0 );audit_log_end (audit_buf);
@@ -497,6 +498,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,struct net_device *dev;char *secctx;u32 secctx_len; +struct security_operations *sop;spin_lock (&netlbl_unlhsh_lock); list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr,
@@ -518,9 +520,9 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,dev_put (dev);if (entry !=NULL &&security_secid_to_secctx (&entry->secid, - &secctx, &secctx_len) ==0 ) { + &secctx, &secctx_len, &sop) ==0 ) {audit_log_format (audit_buf," sec_obj=%s" , secctx); -security_release_secctx (secctx, secctx_len); +security_release_secctx (secctx, secctx_len, sop); }audit_log_format (audit_buf," res=%u" , entry !=NULL ?1 :0 );audit_log_end (audit_buf);
@@ -559,6 +561,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,struct net_device *dev;char *secctx;u32 secctx_len; +struct security_operations *sop;spin_lock (&netlbl_unlhsh_lock); list_entry =netlbl_af6list_remove (addr, mask, &iface->addr6_list);
@@ -579,9 +582,9 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,dev_put (dev);if (entry !=NULL &&security_secid_to_secctx (&entry->secid, - &secctx, &secctx_len) ==0 ) { + &secctx, &secctx_len, &sop) ==0 ) {audit_log_format (audit_buf," sec_obj=%s" , secctx); -security_release_secctx (secctx, secctx_len); +security_release_secctx (secctx, secctx_len, sop); }audit_log_format (audit_buf," res=%u" , entry !=NULL ?1 :0 );audit_log_end (audit_buf);
@@ -928,13 +931,13 @@ static int netlbl_unlabel_staticadd(struct sk_buff *skb, ret_val =security_secctx_to_secid (nla_data (info->attrs[NLBL_UNLABEL_A_SECCTX ]),nla_len (info->attrs[NLBL_UNLABEL_A_SECCTX ]), - &secid); + &secid,lsm_netlbl_ops ());if (ret_val !=0 )return ret_val;return netlbl_unlhsh_add (&init_net, dev_name, addr, mask, addr_len, -lsm_get_secid (&secid,0 ), +lsm_get_secid (&secid,lsm_netlbl_order ()), &audit_info); }
@@ -978,13 +981,13 @@ static int netlbl_unlabel_staticadddef(struct sk_buff *skb, ret_val =security_secctx_to_secid (nla_data (info->attrs[NLBL_UNLABEL_A_SECCTX ]),nla_len (info->attrs[NLBL_UNLABEL_A_SECCTX ]), - &secid); + &secid,lsm_netlbl_ops ());if (ret_val !=0 )return ret_val;return netlbl_unlhsh_add (&init_net,NULL , addr, mask, addr_len, -lsm_get_secid (&secid,0 ), +lsm_get_secid (&secid,lsm_netlbl_order ()), &audit_info); }
@@ -1099,6 +1102,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,struct secids *secid;char *secctx;u32 secctx_len; +struct security_operations *sop; data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, cb_arg->seq, &netlbl_unlabel_gnl_family,
@@ -1157,14 +1161,14 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, secid = &addr6->secid; } - ret_val =security_secid_to_secctx (secid, &secctx, &secctx_len); + ret_val =security_secid_to_secctx (secid, &secctx, &secctx_len, &sop);if (ret_val !=0 ) goto list_cb_failure; ret_val =nla_put (cb_arg->skb,NLBL_UNLABEL_A_SECCTX , secctx_len, secctx); -security_release_secctx (secctx, secctx_len); +security_release_secctx (secctx, secctx_len, sop);if (ret_val !=0 ) goto list_cb_failure;
net/netlabel/netlabel_user.c +3 -2
@@ -101,6 +101,7 @@ struct audit_buffer *netlbl_audit_start_common(int type,struct audit_buffer *audit_buf;char *secctx;u32 secctx_len; +struct security_operations *sop;if (audit_enabled ==0 )return NULL ;
@@ -116,9 +117,9 @@ struct audit_buffer *netlbl_audit_start_common(int type,if (!lsm_zero_secid (&audit_info->secid) &&security_secid_to_secctx (&audit_info->secid, &secctx, - &secctx_len) ==0 ) { + &secctx_len, &sop) ==0 ) {audit_log_format (audit_buf," subj=%s" , secctx); -security_release_secctx (secctx, secctx_len); +security_release_secctx (secctx, secctx_len, sop); }return audit_buf;
net/xfrm/xfrm_user.c +8 -8
@@ -619,7 +619,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, err =xfrm_state_update (x);security_task_getsecid (current, &sids); - sid =lsm_get_secid (&sids,0 ); + sid =lsm_get_secid (&sids,lsm_xfrm_order ());xfrm_audit_state_add (x, err ?0 :1 , loginuid, sessionid, sid);if (err <0 ) {
@@ -709,7 +709,7 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, out:security_task_getsecid (current, &sids); - sid =lsm_get_secid (&sids,0 ); + sid =lsm_get_secid (&sids,lsm_xfrm_order ());xfrm_audit_state_delete (x, err ?0 :1 , loginuid, sessionid, sid);xfrm_state_put (x);return err;
@@ -1431,7 +1431,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, excl = nlh->nlmsg_type ==XFRM_MSG_NEWPOLICY ; err =xfrm_policy_insert (p->dir, xp, excl);security_task_getsecid (current, &sids); - sid =lsm_get_secid (&sids,0 ); + sid =lsm_get_secid (&sids,lsm_xfrm_order ());xfrm_audit_policy_add (xp, err ?0 :1 , loginuid, sessionid, sid);if (err) {
@@ -1674,7 +1674,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,struct secids sids;security_task_getsecid (current, &sids); - sid =lsm_get_secid (&sids,0 ); + sid =lsm_get_secid (&sids,lsm_xfrm_order ());xfrm_audit_policy_delete (xp, err ?0 :1 , loginuid, sessionid, sid);
@@ -1708,7 +1708,7 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, audit_info.loginuid =audit_get_loginuid (current); audit_info.sessionid =audit_get_sessionid (current);security_task_getsecid (current, &secid); - audit_info.secid =lsm_get_secid (&secid,0 ); + audit_info.secid =lsm_get_secid (&secid,lsm_xfrm_order ()); err =xfrm_state_flush (net, p->proto, &audit_info);if (err) {if (err == -ESRCH )/* empty table */
@@ -1903,7 +1903,7 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, audit_info.loginuid =audit_get_loginuid (current); audit_info.sessionid =audit_get_sessionid (current);security_task_getsecid (current, &secid); - audit_info.secid =lsm_get_secid (&secid,0 ); + audit_info.secid =lsm_get_secid (&secid,lsm_xfrm_order ()); err =xfrm_policy_flush (net, type, &audit_info);if (err) {if (err == -ESRCH )/* empty table */
@@ -1976,7 +1976,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,struct secids sids;security_task_getsecid (current, &sids); - sid =lsm_get_secid (&sids,0 ); + sid =lsm_get_secid (&sids,lsm_xfrm_order ());xfrm_policy_delete (xp, p->dir);xfrm_audit_policy_delete (xp,1 , loginuid, sessionid, sid);
@@ -2021,7 +2021,7 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,struct secids sids;security_task_getsecid (current, &sids); - sid =lsm_get_secid (&sids,0 ); + sid =lsm_get_secid (&sids,lsm_xfrm_order ());__xfrm_state_delete (x);xfrm_audit_state_delete (x,1 , loginuid, sessionid, sid); }
security/apparmor/domain.c +4 -9
@@ -353,9 +353,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) file_inode(bprm->file)->i_mode };const char *name =NULL , *target =NULL , *info =NULL ; -int error =cap_bprm_set_creds (bprm); -if (error) -return error; +int error;if (bprm->cred_prepared)return 0 ;
@@ -539,15 +537,12 @@ cleanup:*/ int apparmor_bprm_secureexec (struct linux_binprm *bprm) { -int ret =cap_bprm_secureexec (bprm); -/* the decision to use secure exec is computed in set_creds * and stored in bprm->unsafe. */ -if (!ret && (bprm->unsafe &AA_SECURE_X_NEEDED )) - ret =1 ; - -return ret; +if (bprm->unsafe &AA_SECURE_X_NEEDED ) +return 1 ; +return 0 ; }/**
security/apparmor/lsm.c +5 -17
@@ -96,19 +96,11 @@ static void apparmor_cred_transfer(struct cred *new, const struct cred *old)static int apparmor_ptrace_access_check (struct task_struct *child,unsigned int mode) { -int error =cap_ptrace_access_check (child, mode); -if (error) -return error; -return aa_ptrace (current, child, mode); }static int apparmor_ptrace_traceme (struct task_struct *parent) { -int error =cap_ptrace_traceme (parent); -if (error) -return error; -return aa_ptrace (parent, current,PTRACE_MODE_ATTACH ); }
@@ -139,15 +131,11 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,static int apparmor_capable (const struct cred *cred,struct user_namespace *ns,int cap,int audit) { -struct aa_profile *profile; -/* cap_capable returns 0 on success, else -EPERM */ -int error =cap_capable (cred, ns, cap, audit); -if (!error) { - profile =aa_cred_profile (cred); -if (!unconfined (profile)) - error =aa_capable (current, profile, cap, audit); - } -return error; +struct aa_profile *profile =aa_cred_profile (cred); + +if (!unconfined (profile)) +return aa_capable (current, profile, cap, audit); +return 0 ; }/**
security/security.c +93 -11
249 lines not on this page · raw message
security/selinux/hooks.c +5 -68
147 lines not on this page · raw message
security/selinux/ss/services.c +2 -2
@@ -3130,7 +3130,7 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,if (secattr->flags &NETLBL_SECATTR_CACHE ) *sid = *(u32 *)secattr->cache->data;else if (secattr->flags &NETLBL_SECATTR_SECID ) - *sid =lsm_get_secid (&secattr->attr.secid,0 ); + *sid =lsm_get_secid (&secattr->attr.secid,lsm_netlbl_order ());else if (secattr->flags &NETLBL_SECATTR_MLS_LVL ) { rc = -EIDRM ; ctx =sidtab_search (&sidtab,SECINITSID_NETMSG );
@@ -3205,7 +3205,7 @@ int security_netlbl_sid_to_secattr(u32 sid, struct netlbl_lsm_secattr *secattr)if (secattr->domain ==NULL ) goto out; -lsm_set_secid (&secattr->attr.secid, sid,0 ); +lsm_set_secid (&secattr->attr.secid, sid,lsm_netlbl_order ()); secattr->flags |=NETLBL_SECATTR_DOMAIN_CPY |NETLBL_SECATTR_SECID ;mls_export_netlbl_lvl (ctx, secattr); rc =mls_export_netlbl_cat (ctx, secattr);
security/smack/smack_lsm.c +8 -37
94 lines not on this page · raw message
security/tomoyo/common.h +1 -1
@@ -1217,7 +1217,7 @@ static inline struct tomoyo_domain_info *tomoyo_domain(void)static inline struct tomoyo_domain_info *tomoyo_real_domain (struct task_struct *task) { -return task_cred_xxx (task, security); +return lsm_get_cred (__task_cred (task), &tomoyo_ops); }/**
security/tomoyo/tomoyo.c +0 -6
@@ -72,12 +72,6 @@ static void tomoyo_cred_free(struct cred *cred)*/ static int tomoyo_bprm_set_creds (struct linux_binprm *bprm) { -int rc; - - rc =cap_bprm_set_creds (bprm); -if (rc) -return rc; -/* * Do only if this function is called for the first time of an execve * operation.
security/yama/yama_lsm.c +3 -21
@@ -154,13 +154,9 @@ void yama_task_free(struct task_struct *task)int yama_task_prctl (int option,unsigned long arg2,unsigned long arg3,unsigned long arg4,unsigned long arg5) { -int rc; +int rc =0 ;struct task_struct *myself = current; - rc =cap_task_prctl (option, arg2, arg3, arg4, arg5); -if (rc != -ENOSYS ) -return rc; -switch (option) {case PR_SET_PTRACER :/* Since a thread can call prctl(), find the group leader
@@ -282,14 +278,7 @@ static int ptracer_exception_found(struct task_struct *tracer,int yama_ptrace_access_check (struct task_struct *child,unsigned int mode) { -int rc; - -/* If standard caps disallows it, so does Yama. We should -* only tighten restrictions further. -*/ - rc =cap_ptrace_access_check (child, mode); -if (rc) -return rc; +int rc =0 ;/* require ptrace target be a child of ptracer on attach */ if (mode ==PTRACE_MODE_ATTACH ) {
@@ -335,14 +324,7 @@ int yama_ptrace_access_check(struct task_struct *child,*/ int yama_ptrace_traceme (struct task_struct *parent) { -int rc; - -/* If standard caps disallows it, so does Yama. We should -* only tighten restrictions further. -*/ - rc =cap_ptrace_traceme (parent); -if (rc) -return rc; +int rc =0 ;/* Only disallow PTRACE_TRACEME on more aggressive settings. */ switch (ptrace_scope) {
--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.
Casey Schaufler
maintainerPATCH v14 3/6 LSM: Explicit individual LSM associations
In reply to Casey SchauflerSubject: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Expand the /proc/.../attr interface set to help include LSM specific entries as well as the traditional shared "current", "prev" and "exec" entries. Each LSM that uses one of the traditional interfaces gets it's own interface prefixed with the LSM name for the ones it cares about. Thus, we have "smack.current", "selinux.current" and "apparmor.current" in addition to "current".
Add two new interfaces under /sys/kernel/security. The lsm interface displays the comma seperated list of active LSMs. The present interface displays the name of the LSM providing the traditional /proc/.../attr interfaces. User space code should no longer have to grub around in odd places to determine what LSM is being used and thus what data is available to it.
Introduce feature specific security operation vectors for NetLabel, XFRM, secmark and presentation in the traditional /proc/.../attr interfaces. This allows proper handling of secids.
Add NetLabel interfaces that allow an LSM to request ownership of the NetLabel subsystem and to determine whether or not it has that ownership. These interfaces are intended to allow a future in which NetLabel can support multiple LSMs at the same time, although they do not do so now.
--- drivers/usb/core/devio.c | 2 +- fs/proc/base.c | 30 ++++- include/linux/lsm.h | 57 ++++++++-- include/linux/security.h | 14 +++ include/net/netlabel.h | 10 +- include/net/xfrm.h | 2 +- kernel/audit.c | 2 +- kernel/auditsc.c | 2 +- kernel/signal.c | 2 +- net/ipv4/cipso_ipv4.c | 2 +- .../netfilter/nf_conntrack_l3proto_ipv4_compat.c | 2 +- net/netfilter/nf_conntrack_netlink.c | 4 +- net/netfilter/nf_conntrack_standalone.c | 2 +- net/netlabel/netlabel_kapi.c | 47 +++++++- net/netlabel/netlabel_unlabeled.c | 11 +- security/apparmor/lsm.c | 1 + security/inode.c | 73 +++++++++++- security/security.c | 116 ++++++++++++++++++-- security/selinux/hooks.c | 12 +- security/selinux/netlabel.c | 4 +- security/smack/smack_lsm.c | 91 ++++++++------- security/smack/smackfs.c | 12 +- 22 files changed, 403 insertions(+), 95 deletions(-)
drivers/usb/core/devio.c +1 -1
@@ -497,7 +497,7 @@ static void async_completed(struct urb *urb)const struct cred *cred =NULL ;int signr; -lsm_init_secid (&secid,0 ,0 ); +lsm_init_secid (&secid,0 ,-1 );spin_lock (&ps->lock);list_move_tail (&as->asynclist, &ps->async_completed); as->status = urb->status;
fs/proc/base.c +24 -6
@@ -2354,12 +2354,30 @@ static const struct file_operations proc_pid_attr_operations = { };static const struct pid_entry attr_dir_stuff[] = { -REG ("current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("prev" ,S_IRUGO , proc_pid_attr_operations), -REG ("exec" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("fscreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("keycreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("sockcreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +REG ("current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +REG ("prev" ,S_IRUGO , proc_pid_attr_operations), +REG ("exec" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +REG ("fscreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +REG ("keycreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +REG ("sockcreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +REG ("context" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +#ifdef CONFIG_SECURITY_SELINUX +REG ("selinux.current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +REG ("selinux.prev" ,S_IRUGO , proc_pid_attr_operations), +REG ("selinux.exec" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +REG ("selinux.fscreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +REG ("selinux.keycreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +REG ("selinux.sockcreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +#endif + #ifdef CONFIG_SECURITY_SMACK +REG ("smack.current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +#endif +#ifdef CONFIG_SECURITY_APPARMOR +REG ("apparmor.current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +REG ("apparmor.prev" ,S_IRUGO , proc_pid_attr_operations), +REG ("apparmor.exec" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +#endif + }; static int proc_attr_dir_readdir(struct file * filp,
include/linux/lsm.h +48 -9
102 lines not on this page · raw message
include/linux/security.h +14 -0
@@ -151,6 +151,12 @@ struct request_sock;#define LSM_UNSAFE_PTRACE_CAP 4#define LSM_UNSAFE_NO_NEW_PRIVS 8 +/* Unstackable features */ +#define LSM_FEATURE_PRESENT 0x1 +#define LSM_FEATURE_NETLABEL 0x2 +#define LSM_FEATURE_XFRM 0x4 +#define LSM_FEATURE_SECMARK 0x8 +#ifdef CONFIG_MMU extern int mmap_min_addr_handler (struct ctl_table *table,int write,void __user *buffer,size_t *lenp,loff_t *ppos);
@@ -202,6 +208,12 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)* @name: * A string that acts as a unique identifier for the LSM with max number * of characters = SECURITY_NAME_MAX. +* @order: +* The numeric order in which this LSM will be invoked. +* Set during LSM initialization. Used to identify +* which security blob to use when there is more than one LSM. +* @features: +* Indicates which of the unshared facilities this LSM supports. * * Security hooks for program execution operations. *
@@ -1411,6 +1423,8 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)*/ struct security_operations {char name[SECURITY_NAME_MAX +1 ]; +int order; +int features;int (*ptrace_access_check) (struct task_struct *child,unsigned int mode);int (*ptrace_traceme) (struct task_struct *parent);
include/net/netlabel.h +8 -2
@@ -407,7 +407,9 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,/* * LSM protocol operations (NetLabel LSM/kernel API) */ -int netlbl_enabled (void ); +int netlbl_enabled (struct security_operations *lsm); +int netlbl_lsm_owner (struct security_operations *lsm); +int netlbl_lsm_register (struct security_operations *lsm);int netlbl_sock_setattr (struct sock *sk,u16 family,const struct netlbl_lsm_secattr *secattr);
@@ -521,7 +523,11 @@ static inline int netlbl_secattr_catmap_setrng( {return 0 ; } -static inline int netlbl_enabled (void ) +static inline int netlbl_lsm_register (struct security_operations *lsm) +{ +return 0 ; +} +static inline int netlbl_enabled (struct security_operations *lsm) {return 0 ; }
include/net/xfrm.h +1 -1
@@ -705,7 +705,7 @@ static inline void xfrm_audit_helper_usrinfo(kuid_t auid, u32 ses, u32 secid,audit_log_format (audit_buf," auid=%u ses=%u" ,from_kuid (&init_user_ns, auid), ses); -lsm_init_secid (&secids, secid,0 ); +lsm_init_secid (&secids, secid,lsm_xfrm_order ());if (secid !=0 &&security_secid_to_secctx (&secids, &secctx, &secctx_len, &sop) ==0 ) {
kernel/audit.c +1 -1
@@ -1733,7 +1733,7 @@ void audit_log_secctx(struct audit_buffer *ab, u32 secid)struct secids secids;struct security_operations *sop; -lsm_init_secid (&secids, secid,0 ); +lsm_init_secid (&secids, secid,lsm_secmark_order ());if (security_secid_to_secctx (&secids, &secctx, &len, &sop)) {audit_panic ("Cannot convert secid to context" ); }else {
kernel/auditsc.c +1 -1
@@ -1542,7 +1542,7 @@ void __audit_syscall_exit(int success, long return_code) context->aux =NULL ; context->aux_pids =NULL ; context->target_pid =0 ; -lsm_init_secid (&context->target_sid,0 ,0 ); +lsm_init_secid (&context->target_sid,0 ,-1 ); context->sockaddr_len =0 ; context->type =0 ; context->fds[0 ] =-1 ;
kernel/signal.c +1 -1
@@ -818,7 +818,7 @@ static int check_kill_permission(int sig, struct siginfo *info, } } -lsm_init_secid (&secid,0 ,0 ); +lsm_init_secid (&secid,0 ,-1 );return security_task_kill (t, info, sig, &secid); }
net/ipv4/cipso_ipv4.c +1 -1
@@ -1594,7 +1594,7 @@ static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def,u32 secid; secid = *(u32 *)&tag[2 ]; -lsm_init_secid (&secattr->attr.secid, secid,0 ); +lsm_init_secid (&secattr->attr.secid, secid,lsm_netlbl_order ()); secattr->flags |=NETLBL_SECATTR_SECID ;return 0 ;
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +1 -1
@@ -103,7 +103,7 @@ static int ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)struct secids secid;struct security_operations *sop; -lsm_init_secid (&secid, ct->secmark,0 ); +lsm_init_secid (&secid, ct->secmark,lsm_secmark_order ()); ret =security_secid_to_secctx (&secid, &secctx, &len, &sop);if (ret)return 0 ;
net/netfilter/nf_conntrack_netlink.c +2 -2
@@ -305,7 +305,7 @@ ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)struct secids secid;struct security_operations *sop; -lsm_init_secid (&secid, ct->secmark,0 ); +lsm_init_secid (&secid, ct->secmark,lsm_secmark_order ()); ret =security_secid_to_secctx (&secid, &secctx, &len, &sop);if (ret)return 0 ;
@@ -555,7 +555,7 @@ ctnetlink_secctx_size(const struct nf_conn *ct)struct secids secid;struct security_operations *sop; -lsm_init_secid (&secid, ct->secmark,0 ); +lsm_init_secid (&secid, ct->secmark,lsm_secmark_order ()); ret =security_secid_to_secctx (&secid,NULL , &len, &sop);if (ret)return 0 ;
net/netfilter/nf_conntrack_standalone.c +1 -1
@@ -128,7 +128,7 @@ static int ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)struct secids secid;struct security_operations *sop; -lsm_init_secid (&secid, ct->secmark,0 ); +lsm_init_secid (&secid, ct->secmark,lsm_secmark_order ()); ret =security_secid_to_secctx (&secid, &secctx, &len, &sop);if (ret)return 0 ;
net/netlabel/netlabel_kapi.c +46 -1
60 lines not on this page · raw message
net/netlabel/netlabel_unlabeled.c +6 -5
@@ -263,7 +263,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, entry->list.addr = addr->s_addr & mask->s_addr; entry->list.mask = mask->s_addr; entry->list.valid =1 ; -lsm_init_secid (&entry->secid, secid,0 ); +lsm_init_secid (&entry->secid, secid,lsm_netlbl_order ());spin_lock (&netlbl_unlhsh_lock); ret_val =netlbl_af4list_add (&entry->list, &iface->addr4_list);
@@ -307,7 +307,7 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, entry->list.addr.s6_addr32[3 ] &= mask->s6_addr32[3 ]; entry->list.mask = *mask; entry->list.valid =1 ; -lsm_init_secid (&entry->secid, secid,0 ); +lsm_init_secid (&entry->secid, secid,lsm_netlbl_order ());spin_lock (&netlbl_unlhsh_lock); ret_val =netlbl_af6list_add (&entry->list, &iface->addr6_list);
@@ -460,7 +460,7 @@ int netlbl_unlhsh_add(struct net *net, unlhsh_add_return:rcu_read_unlock ();if (audit_buf !=NULL ) { -lsm_init_secid (&secids, secid,0 ); +lsm_init_secid (&secids, secid,lsm_netlbl_order ());if (security_secid_to_secctx (&secids, &secctx, &secctx_len, &sop) ==0 ) {
@@ -1099,7 +1099,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,struct netlbl_unlhsh_walk_arg *cb_arg = arg;struct net_device *dev;void *data; -struct secids *secid; +const struct secids *secid;char *secctx;u32 secctx_len;struct security_operations *sop;
@@ -1161,7 +1161,8 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd, secid = &addr6->secid; } - ret_val =security_secid_to_secctx (secid, &secctx, &secctx_len, &sop); + ret_val =security_secid_to_secctx ((struct secids *)secid, &secctx, + &secctx_len, &sop);if (ret_val !=0 ) goto list_cb_failure; ret_val = nla_put(cb_arg->skb,
security/apparmor/lsm.c +1 -0
@@ -604,6 +604,7 @@ static int apparmor_task_setrlimit(struct task_struct *task,struct security_operations apparmor_ops = { .name ="apparmor" , + .features =LSM_FEATURE_PRESENT , .ptrace_access_check = apparmor_ptrace_access_check, .ptrace_traceme = apparmor_ptrace_traceme,
security/inode.c +71 -2
92 lines not on this page · raw message
security/security.c +107 -9
192 lines not on this page · raw message
security/selinux/hooks.c +8 -4
@@ -4159,7 +4159,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)return selinux_sock_rcv_skb_compat (sk, skb, family); secmark_active =selinux_secmark_enabled (); - peerlbl_active =netlbl_enabled () ||selinux_xfrm_enabled (); + peerlbl_active =netlbl_enabled (&selinux_ops) ||selinux_xfrm_enabled ();if (!secmark_active && !peerlbl_active)return 0 ;
@@ -4542,7 +4542,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,return NF_ACCEPT ; secmark_active =selinux_secmark_enabled (); - netlbl_active =netlbl_enabled (); + netlbl_active =netlbl_enabled (&selinux_ops); peerlbl_active = netlbl_active ||selinux_xfrm_enabled ();if (!secmark_active && !peerlbl_active)return NF_ACCEPT ;
@@ -4607,7 +4607,7 @@ static unsigned int selinux_ip_output(struct sk_buff *skb, {u32 sid; -if (!netlbl_enabled ()) +if (!netlbl_enabled (&selinux_ops))return NF_ACCEPT ;/* we do this in the LOCAL_OUT path and not the POST_ROUTING path
@@ -4696,7 +4696,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,return NF_ACCEPT ;#endif secmark_active =selinux_secmark_enabled (); - peerlbl_active =netlbl_enabled () ||selinux_xfrm_enabled (); + peerlbl_active =netlbl_enabled (&selinux_ops) ||selinux_xfrm_enabled ();if (!secmark_active && !peerlbl_active)return NF_ACCEPT ;
@@ -5511,6 +5511,10 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer)struct security_operations selinux_ops = { .name ="selinux" , + .features =LSM_FEATURE_PRESENT | +LSM_FEATURE_NETLABEL | +LSM_FEATURE_XFRM | +LSM_FEATURE_SECMARK , .ptrace_access_check = selinux_ptrace_access_check, .ptrace_traceme = selinux_ptrace_traceme,
security/selinux/netlabel.c +2 -2
@@ -180,7 +180,7 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,int rc;struct netlbl_lsm_secattr secattr; -if (!netlbl_enabled ()) { +if (!netlbl_enabled (&selinux_ops)) { *sid =SECSID_NULL ;return 0 ; }
@@ -351,7 +351,7 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,u32 perm;struct netlbl_lsm_secattr secattr; -if (!netlbl_enabled ()) +if (!netlbl_enabled (&selinux_ops))return 0 ;netlbl_secattr_init (&secattr);
security/smack/smack_lsm.c +52 -39
147 lines not on this page · raw message
security/smack/smackfs.c +6 -6
@@ -165,7 +165,8 @@ static void smk_netlabel_audit_set(struct netlbl_audit *nap) { nap->loginuid =audit_get_loginuid (current); nap->sessionid =audit_get_sessionid (current); -lsm_init_secid (&nap->secid,smack_to_secid (smk_of_current ()),0 ); +lsm_init_secid (&nap->secid,smack_to_secid (smk_of_current ()), +lsm_netlbl_order ()); }/*
@@ -1236,12 +1237,12 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, }smk_netlabel_audit_set (&audit_info); + rc =0 ;if (found ==0 ) { skp =kzalloc (sizeof (*skp),GFP_KERNEL );if (skp ==NULL ) rc = -ENOMEM ;else { - rc =0 ; skp->smk_host.sin_addr.s_addr = newname.sin_addr.s_addr; skp->smk_mask.s_addr = mask.s_addr; skp->smk_label = sp;
@@ -1250,12 +1251,11 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf, }else {/* we delete the unlabeled entry, only if the previous label * wasn't the special CIPSO option */ -if (skp->smk_label != smack_cipso_option) +if (skp->smk_label != smack_cipso_option && +netlbl_lsm_owner (&smack_ops)) rc =netlbl_cfg_unlbl_static_del (&init_net,NULL , &skp->smk_host.sin_addr, &skp->smk_mask,PF_INET , &audit_info); -else - rc =0 ; skp->smk_label = sp; }
@@ -1264,7 +1264,7 @@ static ssize_t smk_write_netlbladdr(struct file *file, const char __user *buf,* this host so that incoming packets get labeled. * but only if we didn't get the special CIPSO option */ -if (rc ==0 && sp != smack_cipso_option) +if (rc ==0 && sp != smack_cipso_option &&netlbl_lsm_owner (&smack_ops)) rc =netlbl_cfg_unlbl_static_add (&init_net,NULL , &skp->smk_host.sin_addr, &skp->smk_mask,PF_INET ,smack_to_secid (skp->smk_label), &audit_info);
--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.
Re: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Quoted 104 lines · Casey Schaufler
Subject: [PATCH v14 3/6] LSM: Explicit individual LSM associations [...]
Introduce feature specific security operation vectors for NetLabel, XFRM, secmark and presentation in the traditional/proc/.../attrinterfaces. This allows proper handling of secids.
[...]include/linux/lsm.h +43
-9@@ -164,9 +164,18 @@ static inline void lsm_init_secid(struct secids *secid, u32 lsecid, int order) {memset (secid,0 ,sizeof (*secid)); -if (lsecid !=0 ) +if (lsecid ==0 ) +return ; +/* +* An order of -1 means set it for all LSMs. +*/ +if (order <0 ) { + secid->si_lsm[0 ] = lsecid; + secid->si_count++; + }else { + secid->si_lsm[order] = lsecid; secid->si_count =1 ; - secid->si_lsm[order] = lsecid; + } }static inline int lsm_zero_secid (struct secids *secid)@@ -178,39 +187,64 @@ static inline int lsm_zero_secid(struct secids *secid)#ifdef CONFIG_SECURITY +extern struct security_operations *present_ops;static inline struct security_operations *lsm_present_ops (void ) { -return security_ops; +return present_ops; }static inline int lsm_present_order (void ) { -return 0 ; +return present_ops->order; } +#ifdef CONFIG_NETLABEL +extern struct security_operations *netlbl_ops; +static inline struct security_operations *lsm_netlbl_ops (void ) { -return security_ops; +return netlbl_ops; }static inline int lsm_netlbl_order (void ) { -return 0 ; +return netlbl_ops->order; } +#endif /* CONFIG_NETLABEL */ + +#ifdef CONFIG_SECURITY_NETWORK_XFRM +extern struct security_operations *xfrm_ops;static inline struct security_operations *lsm_xfrm_ops (void ) { -return security_ops; +return xfrm_ops; }static inline int lsm_xfrm_order (void ) { -return 0 ; +return xfrm_ops->order; } +#endif /* CONFIG_SECURITY_NETWORK_XFRM */ + +#ifdef CONFIG_NETWORK_SECMARK +extern struct security_operations *secmark_ops;static inline struct security_operations *lsm_secmark_ops (void ) { -return security_ops; +return secmark_ops; +} + +static inline int lsm_secmark_order (void ) +{ +return secmark_ops->order; +} +#endif /* CONFIG_NETWORK_SECMARK */ + +#else /* CONFIG_SECURITY */ + +static inline int lsm_xfrm_order (void ) +{ +return 0 ; }static inline int lsm_secmark_order (void )@@ -218,6 +252,11 @@ static inline int lsm_secmark_order(void)return 0 ;
include/linux/lsm.h static inline int lsm_secmark_order(void) · line 262
Quoted 10 lines
include/linux/lsm.h +5
-0} +static inline struct security_operations *lsm_secmark_ops (void ) +{ +return NULL ; +} +#endif /* CONFIG_SECURITY */ #endif /* ! _LINUX_LSM_H */
Something went wrong here with the #ifdef/#else stuff here. I built without CONFIG_SECURITY_NETWORK_XFRM and it fails, missing lsm_xfrm_order().
If I added an #else to the CONFIG_SECURITY_NETWORK_XFRM check and made lsm_xfrm_order() return 0 there too, it built fine.
-Kees
Signature · 2 lines
Kees Cook Chrome OS Security
Casey Schaufler
maintainerRe: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Quoted 115 lines · Kees Cook
Quoted 113 lines · Casey Schaufler
Subject: [PATCH v14 3/6] LSM: Explicit individual LSM associations [...]
Introduce feature specific security operation vectors for NetLabel, XFRM, secmark and presentation in the traditional/proc/.../attrinterfaces. This allows proper handling of secids.
[...]include/linux/lsm.h +48
-9@@ -164,9 +164,18 @@ static inline void lsm_init_secid(struct secids *secid, u32 lsecid, int order) {memset (secid,0 ,sizeof (*secid)); -if (lsecid !=0 ) +if (lsecid ==0 ) +return ; +/* +* An order of -1 means set it for all LSMs. +*/ +if (order <0 ) { + secid->si_lsm[0 ] = lsecid; + secid->si_count++; + }else { + secid->si_lsm[order] = lsecid; secid->si_count =1 ; - secid->si_lsm[order] = lsecid; + } }static inline int lsm_zero_secid (struct secids *secid)@@ -178,39 +187,64 @@ static inline int lsm_zero_secid(struct secids *secid)#ifdef CONFIG_SECURITY +extern struct security_operations *present_ops;static inline struct security_operations *lsm_present_ops (void ) { -return security_ops; +return present_ops; }static inline int lsm_present_order (void ) { -return 0 ; +return present_ops->order; } +#ifdef CONFIG_NETLABEL +extern struct security_operations *netlbl_ops; +static inline struct security_operations *lsm_netlbl_ops (void ) { -return security_ops; +return netlbl_ops; }static inline int lsm_netlbl_order (void ) { -return 0 ; +return netlbl_ops->order; } +#endif /* CONFIG_NETLABEL */ + +#ifdef CONFIG_SECURITY_NETWORK_XFRM +extern struct security_operations *xfrm_ops;static inline struct security_operations *lsm_xfrm_ops (void ) { -return security_ops; +return xfrm_ops; }static inline int lsm_xfrm_order (void ) { -return 0 ; +return xfrm_ops->order; } +#endif /* CONFIG_SECURITY_NETWORK_XFRM */ + +#ifdef CONFIG_NETWORK_SECMARK +extern struct security_operations *secmark_ops;static inline struct security_operations *lsm_secmark_ops (void ) { -return security_ops; +return secmark_ops; +} + +static inline int lsm_secmark_order (void ) +{ +return secmark_ops->order; +} +#endif /* CONFIG_NETWORK_SECMARK */ + +#else /* CONFIG_SECURITY */ + +static inline int lsm_xfrm_order (void ) +{ +return 0 ; }static inline int lsm_secmark_order (void )@@ -218,6 +252,11 @@ static inline int lsm_secmark_order(void) return 0; } +static inline struct security_operations *lsm_secmark_ops (void ) +{ +return NULL ; +} +#endif /* CONFIG_SECURITY */
Quoted 7 lines
include/linux/lsm.h static inline int lsm_secmark_order(void) · line 262
Quoted 1 line
include/linux/lsm.h +0
-0#endif /* ! _LINUX_LSM_H */ Something went wrong here with the #ifdef/#else stuff here. I built without
CONFIG_SECURITY_NETWORK_XFRMand it fails, missinglsm_xfrm_order().If I added an #else to the
CONFIG_SECURITY_NETWORK_XFRMcheck and madelsm_xfrm_order()return 0 there too, it built fine.
Yup, I missed that configuration iteration at the end. I've incorporated a fix.
Quoted 3 lines
-Kees
Paul Moore
maintainerRe: [PATCH v14 3/6] LSM: Explicit individual LSM associations
In reply to Casey SchauflerQuoted 18 lines · Casey Schaufler
Subject: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Expand the
/proc/.../attrinterface set to help include LSM specific entries as well as the traditional shared "current", "prev" and "exec" entries. Each LSM that uses one of the traditional interfaces gets it's own interface prefixed with the LSM name for the ones it cares about. Thus, we have "smack.current", "selinux.current" and "apparmor.current" in addition to "current".Add two new interfaces under
/sys/kernel/security. The lsm interface displays the comma seperated list of active LSMs. The present interface displays the name of the LSM providing the traditional/proc/.../attrinterfaces. User space code should no longer have to grub around in odd places to determine what LSM is being used and thus what data is available to it.
Quoted 4 lines
Introduce feature specific security operation vectors for NetLabel, XFRM, secmark and presentation in the traditional
/proc/.../attrinterfaces. This allows proper handling of secids.
Maybe I missed something, can you elaborate on this, perhaps even provide an example for us simple minded folk?
Quoted 8 lines
Add NetLabel interfaces that allow an LSM to request ownership of the NetLabel subsystem and to determine whether or not it has that ownership. These interfaces are intended to allow a future in which NetLabel can support multiple LSMs at the same time, although they do not do so now.
Signed-off-by Casey Schaufler <[email protected]>
...
Quoted 16 lines
include/net/netlabel.h +0
-0@@ -407,7 +407,9 @@ int netlbl_secattr_catmap_setrng(struct
netlbl_lsm_secattr_catmap*catmap, /*
* LSM protocol operations (NetLabel LSM/kernel API) */include/net/netlabel.h +3
-1-int netlbl_enabled (void ); +int netlbl_enabled (struct security_operations *lsm); +int netlbl_lsm_owner (struct security_operations *lsm); +int netlbl_lsm_register (struct security_operations *lsm);int netlbl_sock_setattr (struct sock *sk,u16 family,const struct netlbl_lsm_secattr *secattr);@@ -521,7 +523,11 @@ static inline int netlbl_secattr_catmap_setrng( {return 0 ;
include/net/netlabel.h static inline int netlbl_secattr_catmap_setrng( · line 533
Quoted 10 lines
include/net/netlabel.h +5
-1} -static inline int netlbl_enabled (void ) +static inline int netlbl_lsm_register (struct security_operations *lsm) +{ +return 0 ; +} +static inline int netlbl_enabled (struct security_operations *lsm) {return 0 ; }
Is it worth including a static inline for netlabel_lsm_owner() for the sake of completeness? I haven't looked closely enough yet to know if it is strictly necessary or not.
net/ipv4/cipso_ipv4.c static int cipso_v4_parsetag_loc(const struct · line 1598
Quoted 11 lines
net/ipv4/cipso_ipv4.c +1
-1@@ -1594,7 +1594,7 @@ static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def, u32 secid; secid = *(u32 *)&tag[2 ]; -lsm_init_secid (&secattr->attr.secid, secid,0 ); +lsm_init_secid (&secattr->attr.secid, secid,lsm_netlbl_order ()); secattr->flags |=NETLBL_SECATTR_SECID ;
I still need to wrap my head around all the changes, but I *think* this change may not be necessary since NetLabel isn't multi-LSM aware at the moment. If this change is necessary, then there are likely other changes that need to be made as well, the NetLabel LSM cache would be my main concern.
Quoted 56 lines
net/netlabel/netlabel_kapi.c +0
-0@@ -608,6 +608,47 @@ int netlbl_secattr_catmap_setrng(struct
netlbl_lsm_secattr_catmap*catmap, *//**
+ *netlbl_lsm_register- Reserve the NetLabel subsystem for an LSM
+ * @lsm: the security module making the request
+ *
+ * Description:
+ * To avoid potential conflicting views between LSMs over
+ * what should go in the network label reserve the Netlabel
+ * mechanism for use by one LSM.netlbl_enabledwill return
+ * false for all other LSMs.
+ *
+ */net/netlabel/netlabel_kapi.c +16
-0+int netlbl_lsm_register (struct security_operations *lsm) +{ +if (lsm ==NULL ) +return -EINVAL ; + +if (lsm_netlbl_ops () ==NULL ) + netlbl_ops = lsm; +else if (lsm_netlbl_ops () != lsm) +return -EBUSY ; + +printk (KERN_INFO "NetLabel: Registered LSM \"%s\".\n" , lsm->name); +return 0 ; +} + +/** +* netlbl_lsm_owner - Report if the NetLabel subsystem is registered for an LSM + * @lsm: the security module making the request
+ *
+ * Description:
+ * Report whether the LSM passed is the LSM registered for NetLabel
+ *
+ * Returns 1 if this is the registered NetLabel LSM, 0 otherwise
+ */net/netlabel/netlabel_kapi.c +8
-0+int netlbl_lsm_owner (struct security_operations *lsm) +{ +if (lsm_netlbl_ops () == lsm) +return 1 ; +return 0 ; +} + +/** * netlbl_enabled - Determine if the NetLabel subsystem is enabled * * Description: @@ -619,8 +660,12 @@ int netlbl_secattr_catmap_setrng(struct
netlbl_lsm_secattr_catmap*catmap, * be disabled.
*
*/
net/netlabel/netlabel_kapi.c int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap, · line 668
Quoted 7 lines
net/netlabel/netlabel_kapi.c +5
-1-int netlbl_enabled (void ) +int netlbl_enabled (struct security_operations *lsm) { +if (lsm_netlbl_ops () ==NULL ) +return 0 ; +if (lsm_netlbl_ops () != lsm) +return 0 ;
How about some simplification in the above?
struct security_operations *sops = lsm_netlbl_ops(); if (sops == NULL || sops != lsm) return 0;
Quoted 3 lines
net/netlabel/netlabel_kapi.c +0
-0/* At some point we probably want to expose this mechanism to the user * as well so that admins can toggle NetLabel regardless of the * configuration */
...
net/netlabel/netlabel_unlabeled.c static int netlbl_unlhsh_add_addr4(struct · line 266
Quoted 10 lines
(quoted diff) +0
-0
b/net/netlabel/netlabel_unlabeled.cindex 3e9064a..be4e083 100644net/netlabel/netlabel_unlabeled.c +1
-1@@ -263,7 +263,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, entry->list.addr = addr->s_addr & mask->s_addr; entry->list.mask = mask->s_addr; entry->list.valid =1 ; -lsm_init_secid (&entry->secid, secid,0 ); +lsm_init_secid (&entry->secid, secid,lsm_netlbl_order ());
See my above comments in the CIPSO code.
net/netlabel/netlabel_unlabeled.c static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, · line 310
Quoted 9 lines
net/netlabel/netlabel_unlabeled.c +0
-0spin_lock (&netlbl_unlhsh_lock); ret_val =netlbl_af4list_add (&entry->list, &iface->addr4_list);@@ -307,7 +307,7 @@ static int netlbl_unlhsh_add_addr6(struct
netlbl_unlhsh_iface*iface, entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3];net/netlabel/netlabel_unlabeled.c +1
-1entry->list.mask = *mask; entry->list.valid =1 ; -lsm_init_secid (&entry->secid, secid,0 ); +lsm_init_secid (&entry->secid, secid,lsm_netlbl_order ());
Same. You get the idea ...
Signature · 2 lines
paul moore www.paul-moore.com
Casey Schaufler
maintainerRe: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Quoted 19 lines · Paul Moore
Quoted 18 lines · Casey Schaufler
Subject: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Expand the
/proc/.../attrinterface set to help include LSM specific entries as well as the traditional shared "current", "prev" and "exec" entries. Each LSM that uses one of the traditional interfaces gets it's own interface prefixed with the LSM name for the ones it cares about. Thus, we have "smack.current", "selinux.current" and "apparmor.current" in addition to "current".Add two new interfaces under
/sys/kernel/security. The lsm interface displays the comma seperated list of active LSMs. The present interface displays the name of the LSM providing the traditional/proc/.../attrinterfaces. User space code should no longer have to grub around in odd places to determine what LSM is being used and thus what data is available to it.
Quoted 6 lines
Quoted 4 lines
Introduce feature specific security operation vectors for NetLabel, XFRM, secmark and presentation in the traditional
/proc/.../attrinterfaces. This allows proper handling of secids.Maybe I missed something, can you elaborate on this, perhaps even provide an example for us simple minded folk?
There are a set of facilities that (currently, at least) can't be shared by multiple LSMs for one reason or another. XFRM and secmark have pretty well been declared as hopeless for expansion due to the sk_buff "32 bits is all you're ever going to get now shut up and go away" stance taken by certain networking maintainers. NetLabel might possibly be made to support multiple CIPSO tag types and while I don't think that it makes sense to put much effort into doing so, if there is a coin flip choice it should go in the direction of allowing it. The presentation facility is there to address the "current" interface in /proc, where backward compatibility is necessary.
Audit, on the other hand, uses secids but is capable of dealing with multiple LSMs, provided it can identify which LSM goes with which secid.
The most general case (audit) needs to keep a secid for each LSM. This is easy enough to do. The networking facilities (XFRM, secmark and NetLabel) always want to deal with exactly one, although as I mentioned previously, NetLabel could conceivably be multiple LSM aware someday. When audit and XFRM interact there needs to be a way to identify which of the secids audit is going to use is the one XFRM cares about.
There are two ways to do this. One is to identify the security_operations structure associated with the LSM or to identify the slot in the secids structure that holds that LSM's secid. The security_operations structure contains the information about the slot in the secids structure. The most general way to identify the information about these special cases is to identify the security_operations that go with them.
I hope that is helpful. I fear that I may not be getting the core concept across. The idea is to make it easier to deal with the special interfaces in the general cases.
Quoted 31 lines
Quoted 8 lines
Add NetLabel interfaces that allow an LSM to request ownership of the NetLabel subsystem and to determine whether or not it has that ownership. These interfaces are intended to allow a future in which NetLabel can support multiple LSMs at the same time, although they do not do so now.
Signed-off-by Casey Schaufler <[email protected]>...
Quoted 21 lines
include/net/netlabel.h +0
-0@@ -407,7 +407,9 @@ int netlbl_secattr_catmap_setrng(struct
netlbl_lsm_secattr_catmap*catmap, /*
* LSM protocol operations (NetLabel LSM/kernel API) */include/net/netlabel.h +6
-2-int netlbl_enabled (void ); +int netlbl_enabled (struct security_operations *lsm); +int netlbl_lsm_owner (struct security_operations *lsm); +int netlbl_lsm_register (struct security_operations *lsm);int netlbl_sock_setattr (struct sock *sk,u16 family,const struct netlbl_lsm_secattr *secattr);@@ -521,7 +523,11 @@ static inline int netlbl_secattr_catmap_setrng( {return 0 ; } -static inline int netlbl_enabled (void ) +static inline int netlbl_lsm_register (struct security_operations *lsm) +{ +return 0 ;
Quoted 8 lines
include/net/netlabel.h static inline int netlbl_secattr_catmap_setrng( · line 533
Quoted 5 lines
include/net/netlabel.h +2
-0+} +static inline int netlbl_enabled (struct security_operations *lsm) {return 0 ; }Is it worth including a static inline for
netlabel_lsm_owner()for the sake of completeness? I haven't looked closely enough yet to know if it is strictly necessary or not.
I don't think it ever comes up, which would imply we don't need netlbl_enabled(), either.
Quoted 7 lines
Quoted 7 lines
net/ipv4/cipso_ipv4.c +0
-0@@ -1594,7 +1594,7 @@ static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def, u32 secid;
Quoted 8 lines
net/ipv4/cipso_ipv4.c static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def, · line 1598
Quoted 4 lines
net/ipv4/cipso_ipv4.c +1
-1secid = *(u32 *)&tag[2 ]; -lsm_init_secid (&secattr->attr.secid, secid,0 ); +lsm_init_secid (&secattr->attr.secid, secid,lsm_netlbl_order ()); secattr->flags |=NETLBL_SECATTR_SECID ;I still need to wrap my head around all the changes, but I *think* this change may not be necessary since NetLabel isn't multi-LSM aware at the moment. If this change is necessary, then there are likely other changes that need to be made as well, the NetLabel LSM cache would be my main concern.
Using the NetLabel secid slot is necessary because when we get into the auditing code the secid needs to be in the right place to associate it with the right LSM.
Quoted 65 lines
Quoted 56 lines
net/netlabel/netlabel_kapi.c +0
-0@@ -608,6 +608,47 @@ int netlbl_secattr_catmap_setrng(struct
netlbl_lsm_secattr_catmap*catmap, *//**
+ *netlbl_lsm_register- Reserve the NetLabel subsystem for an LSM
+ * @lsm: the security module making the request
+ *
+ * Description:
+ * To avoid potential conflicting views between LSMs over
+ * what should go in the network label reserve the Netlabel
+ * mechanism for use by one LSM.netlbl_enabledwill return
+ * false for all other LSMs.
+ *
+ */net/netlabel/netlabel_kapi.c +16
-0+int netlbl_lsm_register (struct security_operations *lsm) +{ +if (lsm ==NULL ) +return -EINVAL ; + +if (lsm_netlbl_ops () ==NULL ) + netlbl_ops = lsm; +else if (lsm_netlbl_ops () != lsm) +return -EBUSY ; + +printk (KERN_INFO "NetLabel: Registered LSM \"%s\".\n" , lsm->name); +return 0 ; +} + +/** +* netlbl_lsm_owner - Report if the NetLabel subsystem is registered for an LSM + * @lsm: the security module making the request
+ *
+ * Description:
+ * Report whether the LSM passed is the LSM registered for NetLabel
+ *
+ * Returns 1 if this is the registered NetLabel LSM, 0 otherwise
+ */net/netlabel/netlabel_kapi.c +8
-0+int netlbl_lsm_owner (struct security_operations *lsm) +{ +if (lsm_netlbl_ops () == lsm) +return 1 ; +return 0 ; +} + +/** * netlbl_enabled - Determine if the NetLabel subsystem is enabled * * Description: @@ -619,8 +660,12 @@ int netlbl_secattr_catmap_setrng(struct
netlbl_lsm_secattr_catmap*catmap, * be disabled.
*
*/net/netlabel/netlabel_kapi.c int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap, · line 668
Quoted 7 lines
net/netlabel/netlabel_kapi.c +5
-1-int netlbl_enabled (void ) +int netlbl_enabled (struct security_operations *lsm) { +if (lsm_netlbl_ops () ==NULL ) +return 0 ; +if (lsm_netlbl_ops () != lsm) +return 0 ;How about some simplification in the above?
Quoted 4 lines
struct security_operations *sops = lsm_netlbl_ops(); if (sops == NULL || sops != lsm) return 0;
Sure.
Quoted 17 lines
Quoted 3 lines
net/netlabel/netlabel_kapi.c +0
-0/* At some point we probably want to expose this mechanism to the user * as well so that admins can toggle NetLabel regardless of the * configuration */ ...
net/netlabel/netlabel_unlabeled.c static int netlbl_unlhsh_add_addr4(struct · line 266
Quoted 10 lines
(quoted diff) +0
-0
b/net/netlabel/netlabel_unlabeled.cindex 3e9064a..be4e083 100644net/netlabel/netlabel_unlabeled.c +1
-1@@ -263,7 +263,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, entry->list.addr = addr->s_addr & mask->s_addr; entry->list.mask = mask->s_addr; entry->list.valid =1 ; -lsm_init_secid (&entry->secid, secid,0 ); +lsm_init_secid (&entry->secid, secid,lsm_netlbl_order ());See my above comments in the CIPSO code.
Quoted 11 lines
net/netlabel/netlabel_unlabeled.c static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, · line 310
Quoted 9 lines
net/netlabel/netlabel_unlabeled.c +0
-0spin_lock (&netlbl_unlhsh_lock); ret_val =netlbl_af4list_add (&entry->list, &iface->addr4_list);@@ -307,7 +307,7 @@ static int netlbl_unlhsh_add_addr6(struct
netlbl_unlhsh_iface*iface, entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3];net/netlabel/netlabel_unlabeled.c +1
-1entry->list.mask = *mask; entry->list.valid =1 ; -lsm_init_secid (&entry->secid, secid,0 ); +lsm_init_secid (&entry->secid, secid,lsm_netlbl_order ());Same. You get the idea ...
--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.
Paul Moore
maintainerRe: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Quoted 25 lines · Casey Schaufler
Quoted 24 lines · Paul Moore
Quoted 22 lines · Casey Schaufler
Subject: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Expand the
/proc/.../attrinterface set to help include LSM specific entries as well as the traditional shared "current", "prev" and "exec" entries. Each LSM that uses one of the traditional interfaces gets it's own interface prefixed with the LSM name for the ones it cares about. Thus, we have "smack.current", "selinux.current" and "apparmor.current" in addition to "current".Add two new interfaces under
/sys/kernel/security. The lsm interface displays the comma seperated list of active LSMs. The present interface displays the name of the LSM providing the traditional/proc/.../attrinterfaces. User space code should no longer have to grub around in odd places to determine what LSM is being used and thus what data is available to it.Introduce feature specific security operation vectors for NetLabel, XFRM, secmark and presentation in the traditional
/proc/.../attrinterfaces. This allows proper handling of secids.
Quoted 5 lines
Quoted 2 lines
Maybe I missed something, can you elaborate on this, perhaps even provide an example for us simple minded folk?
There are a set of facilities that (currently, at least) can't be shared by multiple LSMs ...
I should have been more specific.
Thanks for the explanation, but that I understand the problems of stacking LSM/secids, we've had that conversation a few times now. The explanation I was hoping for had to do with this sentence:
"Introduce feature specific security operation vectors for
NetLabel, XFRM, secmark and presentation in the traditional /proc/.../attr interfaces."
Can you explain this a bit more? When I looked at the patch - and maybe I'm missing something - I didn't see anything in /proc that dealt with NetLabel, XFRM, and/or Secmark.
Quoted 48 lines
Quoted 48 lines
Quoted 8 lines
Add NetLabel interfaces that allow an LSM to request ownership of the NetLabel subsystem and to determine whether or not it has that ownership. These interfaces are intended to allow a future in which NetLabel can support multiple LSMs at the same time, although they do not do so now.
Signed-off-by Casey Schaufler <[email protected]>...
Quoted 37 lines
include/net/netlabel.h +0
-0@@ -407,7 +407,9 @@ int netlbl_secattr_catmap_setrng(struct
netlbl_lsm_secattr_catmap*catmap, /** LSM protocol operations (NetLabel LSM/kernel API) */
include/net/netlabel.h +8
-2-int netlbl_enabled (void ); +int netlbl_enabled (struct security_operations *lsm); +int netlbl_lsm_owner (struct security_operations *lsm); +int netlbl_lsm_register (struct security_operations *lsm);int netlbl_sock_setattr (struct sock *sk,u16 family,const struct netlbl_lsm_secattr *secattr);@@ -521,7 +523,11 @@ static inline int netlbl_secattr_catmap_setrng( {return 0 ; } -static inline int netlbl_enabled (void ) +static inline int netlbl_lsm_register (struct security_operations *lsm) +{ +return 0 ; +} +static inline int netlbl_enabled (struct security_operations *lsm) {return 0 ;
Quoted 8 lines
Quoted 5 lines
Quoted 1 line
}
Is it worth including a static inline for
netlabel_lsm_owner()for the sake of completeness? I haven't looked closely enough yet to know if it is strictly necessary or not.I don't think it ever comes up, which would imply we don't need
netlbl_enabled(), either.
Probably not, but I like the safety of having it defined. I guess that is why I would prefer having netlabel_lsm_owner() defined here as well.
Quoted 20 lines
Quoted 12 lines
Quoted 12 lines
net/ipv4/cipso_ipv4.c +1
-1@@ -1594,7 +1594,7 @@ static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def, u32 secid; secid = *(u32 *)&tag[2 ]; -lsm_init_secid (&secattr->attr.secid, secid,0 ); +lsm_init_secid (&secattr->attr.secid, secid,lsm_netlbl_order ());Quoted 7 lines
net/ipv4/cipso_ipv4.c static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def, · line 1598
Quoted 1 line
net/ipv4/cipso_ipv4.c +0
-0secattr->flags |=NETLBL_SECATTR_SECID ;I still need to wrap my head around all the changes, but I *think* this change may not be necessary since NetLabel isn't multi-LSM aware at the moment. If this change is necessary, then there are likely other changes that need to be made as well, the NetLabel LSM cache would be my main concern.
Quoted 3 lines
Using the NetLabel secid slot is necessary because when we get into the auditing code the secid needs to be in the right place to associate it with the right LSM.
Fair enough.
Signature · 2 lines
paul moore www.paul-moore.com
Casey Schaufler
maintainerRe: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Quoted 35 lines · Paul Moore
Quoted 20 lines · Casey Schaufler
Quoted 19 lines · Paul Moore
Quoted 18 lines · Casey Schaufler
Subject: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Expand the
/proc/.../attrinterface set to help include LSM specific entries as well as the traditional shared "current", "prev" and "exec" entries. Each LSM that uses one of the traditional interfaces gets it's own interface prefixed with the LSM name for the ones it cares about. Thus, we have "smack.current", "selinux.current" and "apparmor.current" in addition to "current".Add two new interfaces under
/sys/kernel/security. The lsm interface displays the comma seperated list of active LSMs. The present interface displays the name of the LSM providing the traditional/proc/.../attrinterfaces. User space code should no longer have to grub around in odd places to determine what LSM is being used and thus what data is available to it.Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
Introduce feature specific security operation vectors for NetLabel, XFRM, secmark and presentation in the traditional
/proc/.../attrinterfaces. This allows proper handling of secids.Maybe I missed something, can you elaborate on this, perhaps even provide an example for us simple minded folk?
There are a set of facilities that (currently, at least) can't be shared by multiple LSMs ...
I should have been more specific.
Thanks for the explanation, but that I understand the problems of stacking LSM/secids, we've had that conversation a few times now. The explanation I was hoping for had to do with this sentence:
Quoted 7 lines
"Introduce feature specific security operation vectors for
NetLabel, XFRM, secmark and presentation in the traditional/proc/.../attrinterfaces."Can you explain this a bit more? When I looked at the patch - and maybe I'm missing something - I didn't see anything in /proc that dealt with NetLabel, XFRM, and/or Secmark.
Just so. I have failed to communicate clearly.
"Each feature that requires support by a single, selected LSM
is identified by a global pointer to that LSM's security_operations structure."
NetLabel, XFRM and secmark are networking interfaces that can send the security information from a single LSM along with the packets of data.
/proc/.../attr/current and SO_PEERSEC are interfaces that could send information from multiple LSMs, but in most cases you have to choose one LSM to placate your user space tools.
In all of these cases it is necessary to identify the LSM to use. Even though the end use is quite different the mechanism to support the identification is the same.
Quoted 48 lines
Quoted 48 lines
Quoted 48 lines
Quoted 9 lines
Add NetLabel interfaces that allow an LSM to request ownership of the NetLabel subsystem and to determine whether or not it has that ownership. These interfaces are intended to allow a future in which NetLabel can support multiple LSMs at the same time, although they do not do so now.
Signed-off-by Casey Schaufler <[email protected]>...
Quoted 37 lines
include/net/netlabel.h +0
-0@@ -407,7 +407,9 @@ int netlbl_secattr_catmap_setrng(struct
netlbl_lsm_secattr_catmap*catmap, /** LSM protocol operations (NetLabel LSM/kernel API) */
include/net/netlabel.h +8
-2-int netlbl_enabled (void ); +int netlbl_enabled (struct security_operations *lsm); +int netlbl_lsm_owner (struct security_operations *lsm); +int netlbl_lsm_register (struct security_operations *lsm);int netlbl_sock_setattr (struct sock *sk,u16 family,const struct netlbl_lsm_secattr *secattr);@@ -521,7 +523,11 @@ static inline int netlbl_secattr_catmap_setrng( {return 0 ; } -static inline int netlbl_enabled (void ) +static inline int netlbl_lsm_register (struct security_operations *lsm) +{ +return 0 ; +} +static inline int netlbl_enabled (struct security_operations *lsm) {return 0 ;
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
}
Is it worth including a static inline for
netlabel_lsm_owner()for the sake of completeness? I haven't looked closely enough yet to know if it is strictly necessary or not.I don't think it ever comes up, which would imply we don't need
netlbl_enabled(), either.Probably not, but I like the safety of having it defined. I guess that is why I would prefer having
netlabel_lsm_owner()defined here as well.
Not a problem. I'll add it.
Quoted 18 lines
Quoted 18 lines
Quoted 18 lines
net/ipv4/cipso_ipv4.c static int cipso_v4_parsetag_loc(const struct · line 1600
Quoted 13 lines
net/ipv4/cipso_ipv4.c +1
-1@@ -1594,7 +1594,7 @@ static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def, u32 secid; secid = *(u32 *)&tag[2 ]; -lsm_init_secid (&secattr->attr.secid, secid,0 ); +lsm_init_secid (&secattr->attr.secid, secid,lsm_netlbl_order ()); secattr->flags |=NETLBL_SECATTR_SECID ;I still need to wrap my head around all the changes, but I *think* this change may not be necessary since NetLabel isn't multi-LSM aware at the moment. If this change is necessary, then there are likely other changes that need to be made as well, the NetLabel LSM cache would be my main concern.
Quoted 5 lines
Quoted 3 lines
Using the NetLabel secid slot is necessary because when we get into the auditing code the secid needs to be in the right place to associate it with the right LSM.
Fair enough.
--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.
Paul Moore
maintainerRe: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Quoted 57 lines · Casey Schaufler
Quoted 38 lines · Paul Moore
Quoted 25 lines · Casey Schaufler
Quoted 24 lines · Paul Moore
Quoted 22 lines · Casey Schaufler
Subject: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Expand the
/proc/.../attrinterface set to help include LSM specific entries as well as the traditional shared "current", "prev" and "exec" entries. Each LSM that uses one of the traditional interfaces gets it's own interface prefixed with the LSM name for the ones it cares about. Thus, we have "smack.current", "selinux.current" and "apparmor.current" in addition to "current".Add two new interfaces under
/sys/kernel/security. The lsm interface displays the comma seperated list of active LSMs. The present interface displays the name of the LSM providing the traditional/proc/.../attrinterfaces. User space code should no longer have to grub around in odd places to determine what LSM is being used and thus what data is available to it.Introduce feature specific security operation vectors for NetLabel, XFRM, secmark and presentation in the traditional
/proc/.../attrinterfaces. This allows proper handling of secids.Quoted 5 lines
Quoted 2 lines
Maybe I missed something, can you elaborate on this, perhaps even provide an example for us simple minded folk?
There are a set of facilities that (currently, at least) can't be shared by multiple LSMs ...
I should have been more specific.
Thanks for the explanation, but that I understand the problems of stacking LSM/secids, we've had that conversation a few times now. The explanation I was hoping for had to do with this sentence:
Quoted 7 lines
"Introduce feature specific security operation vectors for
NetLabel, XFRM, secmark and presentation in the traditional/proc/.../attrinterfaces."Can you explain this a bit more? When I looked at the patch - and maybe I'm missing something - I didn't see anything in /proc that dealt with NetLabel, XFRM, and/or Secmark.
Just so. I have failed to communicate clearly.
"Each feature that requires support by a single, selected LSM
is identified by a global pointer to that LSM'ssecurity_operationsstructure."NetLabel, XFRM and secmark are networking interfaces that can send the security information from a single LSM along with the packets of data.
Quoted 7 lines
/proc/.../attr/currentandSO_PEERSECare interfaces that could send information from multiple LSMs, but in most cases you have to choose one LSM to placate your user space tools.In all of these cases it is necessary to identify the LSM to use. Even though the end use is quite different the mechanism to support the identification is the same.
Okay, so if I understand everything correctly, there are no new entries in /proc relating specifically to NetLabel, XFRM, or Secmark; although there are new LSM specific entries for the general /proc entries that exist now. Yes?
Signature · 2 lines
paul moore www.paul-moore.com
Casey Schaufler
maintainerRe: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Quoted 58 lines · Paul Moore
Quoted 57 lines · Casey Schaufler
Quoted 35 lines · Paul Moore
Quoted 20 lines · Casey Schaufler
Quoted 19 lines · Paul Moore
Quoted 18 lines · Casey Schaufler
Subject: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Expand the
/proc/.../attrinterface set to help include LSM specific entries as well as the traditional shared "current", "prev" and "exec" entries. Each LSM that uses one of the traditional interfaces gets it's own interface prefixed with the LSM name for the ones it cares about. Thus, we have "smack.current", "selinux.current" and "apparmor.current" in addition to "current".Add two new interfaces under
/sys/kernel/security. The lsm interface displays the comma seperated list of active LSMs. The present interface displays the name of the LSM providing the traditional/proc/.../attrinterfaces. User space code should no longer have to grub around in odd places to determine what LSM is being used and thus what data is available to it.Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
Introduce feature specific security operation vectors for NetLabel, XFRM, secmark and presentation in the traditional
/proc/.../attrinterfaces. This allows proper handling of secids.Maybe I missed something, can you elaborate on this, perhaps even provide an example for us simple minded folk?
There are a set of facilities that (currently, at least) can't be shared by multiple LSMs ...
I should have been more specific.
Thanks for the explanation, but that I understand the problems of stacking LSM/secids, we've had that conversation a few times now. The explanation I was hoping for had to do with this sentence:
Quoted 7 lines
"Introduce feature specific security operation vectors for
NetLabel, XFRM, secmark and presentation in the traditional/proc/.../attrinterfaces."Can you explain this a bit more? When I looked at the patch - and maybe I'm missing something - I didn't see anything in /proc that dealt with NetLabel, XFRM, and/or Secmark.
Just so. I have failed to communicate clearly.
"Each feature that requires support by a single, selected LSM
is identified by a global pointer to that LSM'ssecurity_operationsstructure."NetLabel, XFRM and secmark are networking interfaces that can send the security information from a single LSM along with the packets of data.
/proc/.../attr/currentandSO_PEERSECare interfaces that could send information from multiple LSMs, but in most cases you have to choose one LSM to placate your user space tools.
Quoted 6 lines
Quoted 3 lines
In all of these cases it is necessary to identify the LSM to use. Even though the end use is quite different the mechanism to support the identification is the same.
Okay, so if I understand everything correctly, there are no new entries in /proc relating specifically to NetLabel, XFRM, or Secmark; although there are new LSM specific entries for the general /proc entries that exist now. Yes?
That's correct.
There is /sys/kernel/security/present, which tells you which LSM is going to show up in /proc/.../attr/current.
Should we have /sys/kernel/security/XFRM, /sys/kernel/security/secmark, /sys/kernel/security/NetLabel and /sys/kernel/security/SO_PEERCRED?
Paul Moore
maintainerRe: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Quoted 6 lines · Casey Schaufler
Quoted 4 lines · Paul Moore
Okay, so if I understand everything correctly, there are no new entries in /proc relating specifically to NetLabel, XFRM, or Secmark; although there are new LSM specific entries for the general /proc entries that exist now. Yes?
Quoted 7 lines
That's correct.
There is
/sys/kernel/security/present, which tells you which LSM is going to show up in/proc/.../attr/current.Should we have
/sys/kernel/security/XFRM,/sys/kernel/security/secmark,/sys/kernel/security/NetLabeland/sys/kernel/security/SO_PEERCRED?
Maybe.
While they might be helpful, I'm not 100% certain they are needed and further I'm not sure they are the "right" solution at this point. Any thoughts, both for and against, are welcome.
Signature · 2 lines
paul moore www.paul-moore.com
Casey Schaufler
maintainerRe: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Quoted 11 lines · Paul Moore
Quoted 10 lines · Casey Schaufler
Quoted 4 lines · Paul Moore
Okay, so if I understand everything correctly, there are no new entries in /proc relating specifically to NetLabel, XFRM, or Secmark; although there are new LSM specific entries for the general /proc entries that exist now. Yes?
That's correct.
There is
/sys/kernel/security/present, which tells you which LSM is going to show up in/proc/.../attr/current.
Quoted 8 lines
Quoted 2 lines
Should we have
/sys/kernel/security/XFRM,/sys/kernel/security/secmark,/sys/kernel/security/NetLabeland/sys/kernel/security/SO_PEERCRED?Maybe.
While they might be helpful, I'm not 100% certain they are needed and further I'm not sure they are the "right" solution at this point. Any thoughts, both for and against, are welcome.
What might be a more correct solution? Assuming, of course, that there's a real problem.
--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.
Paul Moore
maintainerRe: [PATCH v14 3/6] LSM: Explicit individual LSM associations
Quoted 18 lines · Casey Schaufler
Quoted 17 lines · Paul Moore
Quoted 15 lines · Casey Schaufler
Quoted 6 lines · Paul Moore
Okay, so if I understand everything correctly, there are no new entries in
/proc relating specifically to NetLabel, XFRM, or Secmark; although there
are new LSM specific entries for the general /proc entries that exist now. Yes?That's correct.
There is
/sys/kernel/security/present, which tells you which LSM is going to show up in/proc/.../attr/current.Should we have
/sys/kernel/security/XFRM,/sys/kernel/security/secmark,/sys/kernel/security/NetLabeland/sys/kernel/security/SO_PEERCRED?
Quoted 8 lines
Quoted 5 lines
Maybe.
While they might be helpful, I'm not 100% certain they are needed and further I'm not sure they are the "right" solution at this point. Any thoughts, both for and against, are welcome.
What might be a more correct solution? Assuming, of course, that there's a real problem.
Well, like I said, I'm not sure they are needed in the first place, in other words, I'm not sure there is a problem. As for the correct solution, I think we need to understand the problem, if there is one, before we can understand the solution.
How is that for an answer? :)
In short, I think we are best leaving them out until something comes along which requires that we add the /proc entries.
Signature · 2 lines
paul moore www.paul-moore.com
Casey Schaufler
maintainerPATCH v14 4/6 LSM: List based multiple LSM hooks
In reply to Casey SchauflerSubject: [PATCH v14 4/6] LSM: List based multiple LSM hooks
Change the basic hook logic to call all available LSM versions of a particular hook. If the hook returns a value return the last error code encountered, or success. If the hook does not return a value just call them all. There are special cases that violate this scheme, and they are handled individually. Except in rare occasions the existing security modules get the same arguments as they did before.
Introduce vectored security blobs. Security blobs are handled by allocating a master blob that contains the blob pointers provided by the individual LSMs. These master blobs are managed in the lsm infrastructure.
Restructure the interpretation of the security= boot option and CONFIG_SECURITY_DEFAULT to allow an ordered list of security modules. Provide configuration options for the features that don't combine well, NetLabel, xfrm, secmark and SO_PEERSEC.
Remove special case Yama stacking.
Remove the register_security interface and do all of the work of registering an LSM in security_module_enable instead.
Put the security_module_disable interface (formerly reset_security_ops) under ifdef. Make it general on the off chance another LSM may want to use it in the future.
--- fs/proc/base.c | 8 +- include/linux/lsm.h | 101 ++- include/linux/security.h | 427 ++++++--- include/net/af_unix.h | 5 +- kernel/audit.c | 2 +- kernel/auditsc.c | 2 +- net/netfilter/xt_SECMARK.c | 6 +- net/netlabel/netlabel_user.c | 2 +- net/unix/af_unix.c | 14 +- security/Kconfig | 194 ++++- security/Makefile | 2 +- security/apparmor/domain.c | 9 +- security/apparmor/lsm.c | 9 - security/commoncap.c | 6 - security/inode.c | 12 +- security/security.c | 1979 ++++++++++++++++++++++++++++++++++-------- security/selinux/hooks.c | 53 +- security/selinux/netlabel.c | 29 +- security/smack/smack_lsm.c | 48 +- security/tomoyo/tomoyo.c | 9 +- security/yama/Kconfig | 7 - security/yama/yama_lsm.c | 9 - 22 files changed, 2290 insertions(+), 643 deletions(-)
fs/proc/base.c +4 -4
@@ -131,11 +131,11 @@ struct pid_entry {#define REG (NAME ,MODE , fops) \ NOD(NAME, (S_IFREG|(MODE)), NULL, &fops, {})#define INF (NAME ,MODE , read) \ - NOD(NAME, (S_IFREG|(MODE)), \ + NOD(NAME, (S_IFREG|(MODE)), \ NULL, &proc_info_file_operations, \ { .proc_read = read } )#define ONE (NAME ,MODE , show) \ - NOD(NAME, (S_IFREG|(MODE)), \ + NOD(NAME, (S_IFREG|(MODE)), \ NULL, &proc_single_file_operations, \ { .proc_show = show } )
@@ -210,7 +210,7 @@ static int proc_pid_cmdline(struct task_struct *task, char * buffer)if (!mm->arg_end) goto out_mm;/* Shh! No looking before we're done */ - len = mm->arg_end - mm->arg_start; + len = mm->arg_end - mm->arg_start;if (len >PAGE_SIZE ) len =PAGE_SIZE ;
@@ -2369,7 +2369,7 @@ static const struct pid_entry attr_dir_stuff[] = { REG("selinux.keycreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations), REG("selinux.sockcreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations),#endif -#ifdef CONFIG_SECURITY_SMACK +#ifdef CONFIG_SECURITY_SMACK REG ("smack.current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), #endif #ifdef CONFIG_SECURITY_APPARMOR
include/linux/lsm.h +62 -39
226 lines not on this page · raw message
include/linux/security.h +324 -103
729 lines not on this page · raw message
include/net/af_unix.h +2 -3
@@ -33,12 +33,11 @@ struct unix_skb_parms {kgid_t gid;struct scm_fp_list *fp;/* Passed files */ #ifdef CONFIG_SECURITY_NETWORK -struct secids secid;/* Security ID */ +struct secids *secid;/* Security ID */ #endif }; -#define UNIXCB (skb) (*(struct unix_skb_parms *)&((skb)->cb)) -#define UNIXSID (skb) (&UNIXCB((skb)).secid) +#define UNIXCB (skb) (*(struct unix_skb_parms *)&((skb)->cb))#define unix_state_lock (s) spin_lock(&unix_sk(s)->lock)#define unix_state_unlock (s) spin_unlock(&unix_sk(s)->lock)
kernel/audit.c +1 -1
@@ -1529,7 +1529,7 @@ void audit_log_name(struct audit_context *context, struct audit_names *n,char *ctx =NULL ;u32 len;if (security_secid_to_secctx (&n->osid, &ctx, &len, &sop)) { -audit_log_format (ab," osid=%u" , n->osid.si_count); +audit_log_format (ab," osid=%u" ,0 );if (call_panic) *call_panic =2 ; }else {
kernel/auditsc.c +1 -1
@@ -1223,7 +1223,7 @@ static void show_special(struct audit_context *context, int *call_panic)u32 len;struct security_operations *sop;if (security_secid_to_secctx (osid, &ctx, &len, &sop)) { -audit_log_format (ab," osc=%u" , osid->si_count); +audit_log_format (ab," osc=%u" ,0 ); *call_panic =1 ; }else {audit_log_format (ab," obj=%s" , ctx);
net/netfilter/xt_SECMARK.c +4 -2
@@ -62,13 +62,15 @@ static int checkentry_lsm(struct xt_secmark_target_info *info) &secid, lsm_secmark_ops());if (err) {if (err == -EINVAL ) -pr_info ("invalid security context \'%s\'\n" , info->secctx); +pr_info ("invalid security context \'%s\'\n" , + info->secctx);return err; } info->secid =lsm_get_secid (&secid,lsm_secmark_order ());if (!info->secid) { -pr_info ("unable to map security context \'%s\'\n" , info->secctx); +pr_info ("unable to map security context \'%s\'\n" , + info->secctx);return -ENOENT ; }
net/netlabel/netlabel_user.c +1 -1
@@ -114,7 +114,7 @@ struct audit_buffer *netlbl_audit_start_common(int type,from_kuid (&init_user_ns, audit_info->loginuid), audit_info->sessionid); -if (!lsm_zero_secid (&audit_info->secid) && +if (lsm_get_secid (&audit_info->secid,lsm_netlbl_order ()) &&security_secid_to_secctx (&audit_info->secid, &secctx, &secctx_len, &sop) ==0 ) {
net/unix/af_unix.c +10 -4
@@ -137,16 +137,22 @@ static struct hlist_head *unix_sockets_unbound(void *addr)#ifdef CONFIG_SECURITY_NETWORK static void unix_get_secdata (struct scm_cookie *scm,struct sk_buff *skb) { -struct secids *skb_secid =UNIXSID (skb); +struct secids *sip =kzalloc (sizeof (*sip),GFP_KERNEL ); - *skb_secid = scm->secid; +if (sip) +memcpy (sip, &scm->secid,sizeof (*sip)); +UNIXCB (skb).secid = sip; }static inline void unix_set_secdata (struct scm_cookie *scm,struct sk_buff *skb) { -struct secids *skb_secid =UNIXSID (skb); +struct secids *sip =UNIXCB (skb).secid; - scm->secid = *skb_secid; +if (sip) { +memcpy (&scm->secid, sip,sizeof (scm->secid)); +kfree (sip); + }else +memset (&scm->secid,0 ,sizeof (scm->secid)); }#else static inline void unix_get_secdata (struct scm_cookie *scm,struct sk_buff *skb)
security/Kconfig +167 -27
228 lines not on this page · raw message
security/Makefile +1 -1
@@ -14,8 +14,8 @@ obj-y += commoncap.o obj-$(CONFIG_MMU) += min_addr.o # Object file lists -obj-$(CONFIG_SECURITY) += security.o capability.o obj-$(CONFIG_SECURITYFS) += inode.o +obj-$(CONFIG_SECURITY) += security.o # Must precede capability.o in order to stack properly. obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o
security/apparmor/domain.c +6 -3
@@ -537,12 +537,15 @@ cleanup:*/ int apparmor_bprm_secureexec (struct linux_binprm *bprm) { +int ret =cap_bprm_secureexec (bprm); +/* the decision to use secure exec is computed in set_creds * and stored in bprm->unsafe. */ -if (bprm->unsafe &AA_SECURE_X_NEEDED ) -return 1 ; -return 0 ; +if (!ret && (bprm->unsafe &AA_SECURE_X_NEEDED )) + ret =1 ; + +return ret; }/**
security/apparmor/lsm.c +0 -9
@@ -902,12 +902,6 @@ static int __init apparmor_init(void) goto register_security_out; } - error =register_security (&apparmor_ops); -if (error) { -AA_ERROR ("Unable to register AppArmor\n" ); - goto set_init_cxt_out; - } -/* Report that AppArmor successfully initialized */ apparmor_initialized =1 ;if (aa_g_profile_mode ==APPARMOR_COMPLAIN )
@@ -919,9 +913,6 @@ static int __init apparmor_init(void)return error; -set_init_cxt_out: -aa_free_task_context (lsm_get_cred (current->real_cred, &apparmor_ops)); - register_security_out:aa_free_root_ns ();
security/commoncap.c +0 -6
@@ -988,9 +988,3 @@ int cap_mmap_addr(unsigned long addr) }return ret; } - -int cap_mmap_file (struct file *file,unsigned long reqprot, -unsigned long prot,unsigned long flags) -{ -return 0 ; -}
security/inode.c +8 -4
@@ -225,15 +225,19 @@ static ssize_t lsm_read(struct file *filp, char __user *buf, size_t count,char *data;int len; - data =kzalloc (SECURITY_NAME_MAX +1 ,GFP_KERNEL ); + data =kzalloc (LSM_NAMES_MAX +1 ,GFP_KERNEL );if (data ==NULL )return -ENOMEM ; -strcat (data, sop->name); -strcat (data,"\n" ); +list_for_each_entry (sop, &lsm_hooks[lsm_name], list[lsm_name]) { +strcat (data, sop->name); +strcat (data,"," ); + } len =strlen (data); +if (len >1 ) + data[len-1 ] ='\n' ; - len =simple_read_from_buffer (buf, count, ppos, data, len +1 ); + len =simple_read_from_buffer (buf, count, ppos, data, len);kfree (data);return len;
security/security.c +1612 -367
1,627 lines not on this page · raw message
security/selinux/hooks.c +30 -23
53 lines not on this page · raw message
security/smack/smack_lsm.c +27 -21
48 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Part of the diff is not shown here. View the raw message.
Casey Schaufler
maintainerPATCH v14 5/6 LSM: SO_PEERSEC configuration options
In reply to Casey SchauflerSubject: [PATCH v14 5/6] LSM: SO_PEERSEC configuration options
Refine the handling of SO_PEERSEC to enable legacy user space runtimes, Fedora in particular, when running with multiple LSMs that are capable of providing information using getsockopt(). This introduces an additional configuration option, and requires that the default be the legacy behavior.
--- include/linux/lsm.h | 15 +++++ include/linux/lsm_audit.h | 9 +-- include/linux/security.h | 7 +- include/net/scm.h | 2 +- include/net/xfrm.h | 2 +- kernel/audit.c | 8 +-- kernel/auditsc.c | 4 +- net/ipv4/ip_sockglue.c | 2 +- .../netfilter/nf_conntrack_l3proto_ipv4_compat.c | 2 +- net/netfilter/nf_conntrack_netlink.c | 4 +- net/netfilter/nf_conntrack_standalone.c | 2 +- net/netlabel/netlabel_unlabeled.c | 8 +-- net/netlabel/netlabel_user.c | 2 +- security/Kconfig | 52 ++++++++++++--- security/security.c | 70 ++++++++++---------- security/selinux/hooks.c | 2 +- security/smack/smack_lsm.c | 2 +- 17 files changed, 120 insertions(+), 73 deletions(-)
include/linux/lsm.h +15 -0
@@ -263,6 +263,16 @@ static inline int lsm_secmark_order(void) }#endif /* CONFIG_NETWORK_SECMARK */ +static inline int lsm_peersec_order (void ) +{ +return peersec_ops->order; +} + +static inline struct security_operations *lsm_peersec_ops (void ) +{ +return peersec_ops; +} +#else /* CONFIG_SECURITY */ static inline int lsm_xfrm_order (void )
@@ -280,6 +290,11 @@ static inline struct security_operations *lsm_secmark_ops(void)return NULL ; } +static inline struct security_operations *lsm_peersec_ops (void ) +{ +return NULL ; +} +#endif /* CONFIG_SECURITY */ #endif /* ! _LINUX_LSM_H */
include/linux/lsm_audit.h +3 -6
@@ -69,18 +69,15 @@ struct common_audit_data {#endif char *kmod_name; } u; -/* this union contains LSM specific data */ -union {#ifdef CONFIG_SECURITY_SMACK -struct smack_audit_data *smack_audit_data; +struct smack_audit_data *smack_audit_data;#endif #ifdef CONFIG_SECURITY_SELINUX -struct selinux_audit_data *selinux_audit_data; +struct selinux_audit_data *selinux_audit_data;#endif #ifdef CONFIG_SECURITY_APPARMOR -struct apparmor_audit_data *apparmor_audit_data; +struct apparmor_audit_data *apparmor_audit_data;#endif - };/* per LSM data pointer union */ };#define v4info fam.v4
include/linux/security.h +6 -1
@@ -57,7 +57,11 @@ struct mm_struct;#define SECURITY_NAME_MAX 10/* Maximum number of LSMs that can be used at a time. */ +#ifdef CONFIG_SECURITY #define LSM_SLOTS CONFIG_SECURITY_LSM_MAX +#else +#define LSM_SLOTS 1 +#endif #define LSM_NAMES_MAX ((SECURITY_NAME_MAX + 1) * LSM_SLOTS)/* If capable should audit the security request */
@@ -152,7 +156,7 @@ struct request_sock;#define LSM_FEATURE_NETLABEL 0x02#define LSM_FEATURE_XFRM 0x04#define LSM_FEATURE_SECMARK 0x08 -#define LSM_FEATURE_SECIDS 0x10 +#define LSM_FEATURE_PEERSEC 0x10#ifdef CONFIG_MMU extern int mmap_min_addr_handler(struct ctl_table *table, int write,
@@ -1938,6 +1942,7 @@ extern void __init security_fixup_ops(struct security_operations *ops);#ifdef CONFIG_SECURITY_SELINUX_DISABLE extern void security_module_disable (struct security_operations *ops);#endif /* CONFIG_SECURITY_SELINUX_DISABLE */ +extern struct security_operations *peersec_ops;/* Security operations */ int security_ptrace_access_check (struct task_struct *child,unsigned int mode);
include/net/scm.h +1 -1
@@ -91,7 +91,7 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scchar *secdata;u32 seclen;int err; -struct security_operations *sop; +struct security_operations *sop = peersec_ops;if (test_bit (SOCK_PASSSEC , &sock->flags)) { err = security_secid_to_secctx(&scm->secid, &secdata,
include/net/xfrm.h +1 -1
@@ -701,7 +701,7 @@ static inline void xfrm_audit_helper_usrinfo(kuid_t auid, u32 ses, u32 secid,char *secctx;u32 secctx_len;struct secids secids; -struct security_operations *sop; +struct security_operations *sop =lsm_peersec_ops ();audit_log_format (audit_buf," auid=%u ses=%u" ,from_kuid (&init_user_ns, auid), ses);
kernel/audit.c +4 -4
@@ -640,7 +640,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)struct audit_sig_info *sig_data;char *ctx =NULL ;u32 len; -struct security_operations *sop; +struct security_operations *sop =NULL ; err =audit_netlink_ok (skb, msg_type);if (err)
@@ -1481,7 +1481,7 @@ void audit_copy_inode(struct audit_names *name, const struct dentry *dentry,void audit_log_name (struct audit_context *context,struct audit_names *n,struct path *path,int record_num,int *call_panic) { -struct security_operations *sop; +struct security_operations *sop =NULL ;struct audit_buffer *ab; ab =audit_log_start (context,GFP_KERNEL ,AUDIT_PATH );if (!ab)
@@ -1548,7 +1548,7 @@ int audit_log_task_context(struct audit_buffer *ab)unsigned len;int error;struct secids sid; -struct security_operations *sop; +struct security_operations *sop =NULL ;security_task_getsecid (current, &sid);if (lsm_zero_secid (&sid))
@@ -1731,7 +1731,7 @@ void audit_log_secctx(struct audit_buffer *ab, u32 secid)u32 len;char *secctx;struct secids secids; -struct security_operations *sop; +struct security_operations *sop =lsm_secmark_ops ();lsm_init_secid (&secids, secid,lsm_secmark_order ());if (security_secid_to_secctx (&secids, &secctx, &len, &sop)) {
kernel/auditsc.c +2 -2
@@ -984,7 +984,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,char *ctx =NULL ;u32 len;int rc =0 ; -struct security_operations *sop; +struct security_operations *sop =NULL ; ab =audit_log_start (context,GFP_KERNEL ,AUDIT_OBJ_PID );if (!ab)
@@ -1221,7 +1221,7 @@ static void show_special(struct audit_context *context, int *call_panic)if (!lsm_zero_secid (osid)) {char *ctx =NULL ;u32 len; -struct security_operations *sop; +struct security_operations *sop =NULL ;if (security_secid_to_secctx (osid, &ctx, &len, &sop)) {audit_log_format (ab," osc=%u" ,0 ); *call_panic =1 ;
net/ipv4/ip_sockglue.c +1 -1
@@ -111,7 +111,7 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)u32 seclen;struct secids secid;int err; -struct security_operations *sop; +struct security_operations *sop =lsm_peersec_ops (); err =security_socket_getpeersec_dgram (NULL , skb, &secid);if (err)
net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +1 -1
@@ -101,7 +101,7 @@ static int ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)u32 len;char *secctx;struct secids secid; -struct security_operations *sop; +struct security_operations *sop =lsm_secmark_ops ();lsm_init_secid (&secid, ct->secmark,lsm_secmark_order ()); ret =security_secid_to_secctx (&secid, &secctx, &len, &sop);
net/netfilter/nf_conntrack_netlink.c +2 -2
@@ -303,7 +303,7 @@ ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)int len, ret;char *secctx;struct secids secid; -struct security_operations *sop; +struct security_operations *sop =lsm_secmark_ops ();lsm_init_secid (&secid, ct->secmark,lsm_secmark_order ()); ret =security_secid_to_secctx (&secid, &secctx, &len, &sop);
@@ -553,7 +553,7 @@ ctnetlink_secctx_size(const struct nf_conn *ct)#ifdef CONFIG_NF_CONNTRACK_SECMARK int len, ret;struct secids secid; -struct security_operations *sop; +struct security_operations *sop =lsm_secmark_ops ();lsm_init_secid (&secid, ct->secmark,lsm_secmark_order ()); ret =security_secid_to_secctx (&secid,NULL , &len, &sop);
net/netfilter/nf_conntrack_standalone.c +1 -1
@@ -126,7 +126,7 @@ static int ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)u32 len;char *secctx;struct secids secid; -struct security_operations *sop; +struct security_operations *sop =lsm_secmark_ops ();lsm_init_secid (&secid, ct->secmark,lsm_secmark_order ()); ret =security_secid_to_secctx (&secid, &secctx, &len, &sop);
net/netlabel/netlabel_unlabeled.c +4 -4
@@ -397,7 +397,7 @@ int netlbl_unlhsh_add(struct net *net,struct secids secids;char *secctx =NULL ;u32 secctx_len; -struct security_operations *sop; +struct security_operations *sop =lsm_netlbl_ops ();if (addr_len !=sizeof (struct in_addr ) && addr_len !=sizeof (struct in6_addr ))
@@ -498,7 +498,7 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,struct net_device *dev;char *secctx;u32 secctx_len; -struct security_operations *sop; +struct security_operations *sop =lsm_netlbl_ops ();spin_lock (&netlbl_unlhsh_lock); list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr,
@@ -561,7 +561,7 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,struct net_device *dev;char *secctx;u32 secctx_len; -struct security_operations *sop; +struct security_operations *sop =lsm_netlbl_ops ();spin_lock (&netlbl_unlhsh_lock); list_entry =netlbl_af6list_remove (addr, mask, &iface->addr6_list);
@@ -1102,7 +1102,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,const struct secids *secid;char *secctx;u32 secctx_len; -struct security_operations *sop; +struct security_operations *sop =lsm_netlbl_ops (); data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).portid, cb_arg->seq, &netlbl_unlabel_gnl_family,
net/netlabel/netlabel_user.c +1 -1
@@ -101,7 +101,7 @@ struct audit_buffer *netlbl_audit_start_common(int type,struct audit_buffer *audit_buf;char *secctx;u32 secctx_len; -struct security_operations *sop; +struct security_operations *sop =lsm_netlbl_ops ();if (audit_enabled ==0 )return NULL ;
security/Kconfig +42 -10
59 lines not on this page · raw message
security/security.c +34 -36
143 lines not on this page · raw message
security/selinux/hooks.c +1 -1
@@ -5526,7 +5526,7 @@ struct security_operations selinux_ops = {LSM_FEATURE_NETLABEL |LSM_FEATURE_XFRM |LSM_FEATURE_SECMARK | - LSM_FEATURE_SECIDS, + LSM_FEATURE_PEERSEC, .ptrace_access_check = selinux_ptrace_access_check, .ptrace_traceme = selinux_ptrace_traceme,
security/smack/smack_lsm.c +1 -1
@@ -3386,7 +3386,7 @@ struct security_operations smack_ops = { .name = "smack", .features =LSM_FEATURE_PRESENT |LSM_FEATURE_NETLABEL | - LSM_FEATURE_SECIDS, + LSM_FEATURE_PEERSEC, .ptrace_access_check = smack_ptrace_access_check, .ptrace_traceme = smack_ptrace_traceme,
--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.
Paul Moore
maintainerRe: [PATCH v14 5/6] LSM: SO_PEERSEC configuration options
Quoted 9 lines · Casey Schaufler
Subject: [PATCH v14 5/6] LSM:
SO_PEERSECconfiguration optionsRefine the handling of
SO_PEERSECto enable legacy user space runtimes, Fedora in particular, when running with multiple LSMs that are capable of providing information usinggetsockopt(). This introduces an additional configuration option, and requires that the default be the legacy behavior.Signed-off-by Casey Schaufler <[email protected]>
...
Quoted 18 lines
security/Kconfig +5
-6@@ -157,17 +157,49 @@ config SECMARK_LSM help The name of the LSM to use with the networking secmark -config SECURITY_PLAIN_CONTEXT - bool "Backward compatable contexts without lsm='value' formatting" - depends on SECURITY_SELINUX || SECURITY_SMACK - default y +choice + depends on SECURITY && (SECURITY_SELINUX || SECURITY_SMACK) + prompt "Peersec LSM" + default PEERSEC_SECURITY_FIRST + help - Without this value set security context strings will - include the name of the lsm with which they are associated
security/Kconfig config SECMARK_LSM · line 171
Quoted 10 lines
security/Kconfig +6
-4- even if there is only one LSM that uses security contexts. - This matches the way contexts were handled before it was - possible to have multiple concurrent security modules. - If you are unsure how to answer this question, answer Y. + Select the security module that will send attribute + information in IP header options. + Most SELinux configurations do not take advantage + of Netlabel, while all Smack configurations do. Unless + there is a need to do otherwise chose Smack in preference + to SELinux.
I'm not hugely in love with the help text; the first sentence seems to be all that is needed, the second seems unnecessary and not exactly fair to the LSMs.
Quoted 33 lines
security/Kconfig +30
-0+ config PEERSEC_SECURITY_FIRST + bool "First LSM providing for SO_PEERSEC" + help + Provide the first available LSM's information with SO_PEERSEC + + config PEERSEC_SECURITY_ALL + bool "Use lsm='value'lsm='value' format" + help + Provide all available security information in SO_PEERSEC + + config PEERSEC_SECURITY_SELINUX + bool "SELinux" if SECURITY_SELINUX=y + help + Provide SELinux context with SO_PEERSEC + + config PEERSEC_SECURITY_SMACK + bool "Smack" if SECURITY_SMACK=y + help + Provide Smack labels with SO_PEERSEC + +endchoice + +config PEERSEC_LSM + string + default "smack" if PEERSEC_SECURITY_SMACK + default "selinux" if PEERSEC_SECURITY_SELINUX + default "(all)" if PEERSEC_SECURITY_ALL + default "(first)" + help + The name of the LSM to use with Netlabel config SECURITY_PATH bool "Security hooks for pathname based access control"
Signature · 2 lines
paul moore www.paul-moore.com
Casey Schaufler
maintainerRe: [PATCH v14 5/6] LSM: SO_PEERSEC configuration options
Quoted 34 lines · Paul Moore
Quoted 9 lines · Casey Schaufler
Subject: [PATCH v14 5/6] LSM:
SO_PEERSECconfiguration optionsRefine the handling of
SO_PEERSECto enable legacy user space runtimes, Fedora in particular, when running with multiple LSMs that are capable of providing information usinggetsockopt(). This introduces an additional configuration option, and requires that the default be the legacy behavior.Signed-off-by Casey Schaufler <[email protected]>...
Quoted 22 lines
security/Kconfig +5
-10@@ -157,17 +157,49 @@ config SECMARK_LSM help The name of the LSM to use with the networking secmark -config SECURITY_PLAIN_CONTEXT - bool "Backward compatable contexts without lsm='value' formatting" - depends on SECURITY_SELINUX || SECURITY_SMACK - default y +choice + depends on SECURITY && (SECURITY_SELINUX || SECURITY_SMACK) + prompt "Peersec LSM" + default PEERSEC_SECURITY_FIRST + help - Without this value set security context strings will - include the name of the lsm with which they are associated - even if there is only one LSM that uses security contexts. - This matches the way contexts were handled before it was - possible to have multiple concurrent security modules. - If you are unsure how to answer this question, answer Y.
Quoted 8 lines
security/Kconfig config SECMARK_LSM · line 171
Quoted 6 lines
security/Kconfig +6
-0+ Select the security module that will send attribute + information in IP header options. + Most SELinux configurations do not take advantage + of Netlabel, while all Smack configurations do. Unless + there is a need to do otherwise chose Smack in preference + to SELinux.I'm not hugely in love with the help text; the first sentence seems to be all that is needed, the second seems unnecessary and not exactly fair to the LSMs.
I can take out the "friendly advice". What it really should say is more on the lines of:
If you have gotten to the point where you have to make this decision you should probably call it a work day, go home, have a nice drink and spend some time with a loved one. In the morning take a good hard look at your network configuration. You may end up with a different security policies being enforced with IPv4 and IPv6 communications.
Quoted 32 lines
Quoted 32 lines
security/Kconfig +30
-0+ config PEERSEC_SECURITY_FIRST + bool "First LSM providing for SO_PEERSEC" + help + Provide the first available LSM's information with SO_PEERSEC + + config PEERSEC_SECURITY_ALL + bool "Use lsm='value'lsm='value' format" + help + Provide all available security information in SO_PEERSEC + + config PEERSEC_SECURITY_SELINUX + bool "SELinux" if SECURITY_SELINUX=y + help + Provide SELinux context with SO_PEERSEC + + config PEERSEC_SECURITY_SMACK + bool "Smack" if SECURITY_SMACK=y + help + Provide Smack labels with SO_PEERSEC + +endchoice + +config PEERSEC_LSM + string + default "smack" if PEERSEC_SECURITY_SMACK + default "selinux" if PEERSEC_SECURITY_SELINUX + default "(all)" if PEERSEC_SECURITY_ALL + default "(first)" + help + The name of the LSM to use with Netlabel
Quoted 2 lines
security/Kconfig config SECMARK_LSM · line 205
Quoted 2 lines
security/Kconfig +0
-0config SECURITY_PATH bool "Security hooks for pathname based access control"
--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.
Paul Moore
maintainerRe: [PATCH v14 5/6] LSM: SO_PEERSEC configuration options
Quoted 54 lines · Casey Schaufler
Quoted 33 lines · Paul Moore
Quoted 9 lines · Casey Schaufler
Subject: [PATCH v14 5/6] LSM:
SO_PEERSECconfiguration optionsRefine the handling of
SO_PEERSECto enable legacy user space runtimes, Fedora in particular, when running with multiple LSMs that are capable of providing information usinggetsockopt(). This introduces an additional configuration option, and requires that the default be the legacy behavior.Signed-off-by Casey Schaufler <[email protected]>...
Quoted 20 lines
security/Kconfig +5
-4@@ -157,17 +157,49 @@ config SECMARK_LSM help The name of the LSM to use with the networking secmark -config SECURITY_PLAIN_CONTEXT - bool "Backward compatable contexts without lsm='value' formatting" - depends on SECURITY_SELINUX || SECURITY_SMACK - default y +choice + depends on SECURITY && (SECURITY_SELINUX || SECURITY_SMACK) + prompt "Peersec LSM" + default PEERSEC_SECURITY_FIRST + helpQuoted 16 lines
security/Kconfig config SECMARK_LSM · line 171
Quoted 12 lines
security/Kconfig +6
-6- Without this value set security context strings will - include the name of the lsm with which they are associated - even if there is only one LSM that uses security contexts. - This matches the way contexts were handled before it was - possible to have multiple concurrent security modules. - If you are unsure how to answer this question, answer Y. + Select the security module that will send attribute + information in IP header options. + Most SELinux configurations do not take advantage + of Netlabel, while all Smack configurations do. Unless + there is a need to do otherwise chose Smack in preference + to SELinux.I'm not hugely in love with the help text; the first sentence seems to be all that is needed, the second seems unnecessary and not exactly fair to the LSMs.
I can take out the "friendly advice". What it really should say is more on the lines of:
Quoted 6 lines
If you have gotten to the point where you have to make this decision you should probably call it a work day, go home, have a nice drink and spend some time with a loved one. In the morning take a good hard look at your network configuration. You may end up with a different security policies being enforced with IPv4 and IPv6 communications.
Perfect ;)
Signature · 2 lines
paul moore www.paul-moore.com
Casey Schaufler
maintainerPATCH v14 6/6 LSM: Multiple LSM Documentation and cleanup
In reply to Casey SchauflerSubject: [PATCH v14 6/6] LSM: Multiple LSM Documentation and cleanup
Add documentation and remove the obsolete capability LSM. Clean up some comments in security.h
--- Documentation/security/LSM.txt | 56 +- include/linux/security.h | 48 +- security/Makefile | 1 - security/capability.c | 1106 ---------------------------------------- 4 files changed, 77 insertions(+), 1134 deletions(-)
Documentation/security/LSM.txt +46 -10
@@ -7,20 +7,56 @@ various security checks to be hooked by new kernel extensions. The name loadable kernel modules. Instead, they are selectable at build-time via CONFIG_DEFAULT_SECURITY and can be overridden at boot-time via the "security=..." kernel command line argument, in the case where multiple -LSMs were built into a given kernel. +LSMs were built into a given kernel. The names of the active LSMs +can be read from /sys/kernel/security/lsm. + +Both CONFIG_DEFAULT_SECURITY and the "security=" option take a comma +separated list of LSM names. The LSM hooks are invoked in the order +specified. All hooks provided are invoked regardless of the outcome +of preceding hooks. Hooks that return success or failure results +return success if all of the LSM provided hooks succeed and the error +code of the last failing hook on error. + +Information from an LSM can come in one of two forms. The raw data +used by the LSM is typically the preferred form. SELinux contexts and +Smack labels are examples of raw LSM data. If the data from multiple +LSMs is presented together it will be in the form: + + lsmname='value'[lsmname='value']... + +Interfaces that accept LSM data as input accept this format as well, +passing only the relevant portion of the data to each LSM. + +The /proc filesystem attribute interface supports files from a time +when only one LSM could be used at a time. CONFIG_PRESENT_SECURITY +defines which LSM uses these interfaces. The name of this LSM can be +read from /sys/kernel/security/present. There are also LSM identified +interfaces which should be used in preference to the undifferentiated +interfaces. The attribute interface "context" always provides the +data from all LSMs that maintain it in the lsmname='value' format. + +The three networking mechanisms supporting LSM attributes are +restricted to providing those attributes for a single LSM each. +CONFIG_SECMARK_LSM specifies which LSM will provide hooks for the +secmark mechanism. CONFIG_NETLABEL_LSM specifies which LSM hooks +are used by NetLabel to provide IPv4 CIPSO headers. CONFIG_XFRM_LSM +specifies the LSM providing xfrm hooks. CONFIG_PEERSEC_LSM allows +for either a specific LSM to provide data with SO_PEERSEC or for +all LSMs that provide data to do so. + +The Linux capabilities system is used in conjunction with any LSMs. +LSM hooks are called after the capability checks in most cases, +but after in a small number of cases. All LSM hooks need to be aware +of the potential interactions with the capability system. For more +details on capabilities, see capabilities(7) in the Linux man-pages +project. The primary users of the LSM interface are Mandatory Access Control (MAC) extensions which provide a comprehensive security policy. Examples include SELinux, Smack, Tomoyo, and AppArmor. In addition to the larger -MAC extensions, other extensions can be built using the LSM to provide -specific changes to system operation when these tweaks are not available -in the core functionality of Linux itself. - -Without a specific LSM built into the kernel, the default LSM will be the -Linux capabilities system. Most LSMs choose to extend the capabilities -system, building their checks on top of the defined capability hooks. -For more details on capabilities, see capabilities(7) in the Linux -man-pages project. +MAC extensions, other extensions such as Yama can be built using the LSM +to provide specific changes to system operation when these tweaks are not +available in the core functionality of Linux itself. Based on http://kerneltrap.org/Linux/Documenting_Security_Module_Intent, a new LSM is accepted into the kernel when its intent (a description of
include/linux/security.h +31 -17
143 lines not on this page · raw message
security/Makefile +0 -1
@@ -9,7 +9,6 @@ subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor subdir-$(CONFIG_SECURITY_YAMA) += yama -# always enable default capabilities obj-y += commoncap.o obj-$(CONFIG_MMU) += min_addr.o
security/capability.c deleted +0 -1106
1,106 lines not on this page · raw message
--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.
Randy Dunlap
reviewerRe: [PATCH v14 6/6] LSM: Multiple LSM Documentation and cleanup
Quoted 29 lines · Casey Schaufler
Subject: [PATCH v14 6/6] LSM: Multiple LSM Documentation and cleanup
Add documentation and remove the obsolete capability LSM. Clean up some comments in
security.hSigned-off-by Casey Schaufler <[email protected]>--- Documentation/security/LSM.txt | 56 +- include/linux/security.h | 48 +- security/Makefile | 1 - security/capability.c | 1106 ---------------------------------------- 4 files changed, 77 insertions(+), 1134 deletions(-)Documentation/security/LSM.txt +6
-1@@ -7,20 +7,56 @@ various security checks to be hooked by new kernel extensions. The name loadable kernel modules. Instead, they are selectable at build-time via CONFIG_DEFAULT_SECURITY and can be overridden at boot-time via the "security=..." kernel command line argument, in the case where multiple -LSMs were built into a given kernel. +LSMs were built into a given kernel. The names of the active LSMs +can be read from /sys/kernel/security/lsm. + +Both CONFIG_DEFAULT_SECURITY and the "security=" option take a comma +separated list of LSM names. The LSM hooks are invoked in the order +specified. All hooks provided are invoked regardless of the outcome
Documentation/security/LSM.txt various security checks to be hooked by new kernel extensions. The name · line 25
Quoted 10 lines
Documentation/security/LSM.txt +10
-0+of preceding hooks. Hooks that return success or failure results +return success if all of the LSM provided hooks succeed and the error +code of the last failing hook on error. + +Information from an LSM can come in one of two forms. The raw data +used by the LSM is typically the preferred form. SELinux contexts and +Smack labels are examples of raw LSM data. If the data from multiple +LSMs is presented together it will be in the form: + + lsmname='value'[lsmname='value']...
no commas? just (made up example):
smack='label'selinux='notstrict'
Quoted 13 lines
Documentation/security/LSM.txt +13
-0+ +Interfaces that accept LSM data as input accept this format as well, +passing only the relevant portion of the data to each LSM. + +The /proc filesystem attribute interface supports files from a time +when only one LSM could be used at a time. CONFIG_PRESENT_SECURITY +defines which LSM uses these interfaces. The name of this LSM can be +read from /sys/kernel/security/present. There are also LSM identified +interfaces which should be used in preference to the undifferentiated +interfaces. The attribute interface "context" always provides the +data from all LSMs that maintain it in the lsmname='value' format. + +The three networking mechanisms supporting LSM attributes are
Documentation/security/LSM.txt various security checks to be hooked by new kernel extensions. The name · line 48
Quoted 10 lines
Documentation/security/LSM.txt +10
-0+restricted to providing those attributes for a single LSM each. +CONFIG_SECMARK_LSM specifies which LSM will provide hooks for the +secmark mechanism. CONFIG_NETLABEL_LSM specifies which LSM hooks +are used by NetLabel to provide IPv4 CIPSO headers. CONFIG_XFRM_LSM +specifies the LSM providing xfrm hooks. CONFIG_PEERSEC_LSM allows +for either a specific LSM to provide data with SO_PEERSEC or for +all LSMs that provide data to do so. + +The Linux capabilities system is used in conjunction with any LSMs. +LSM hooks are called after the capability checks in most cases,
^^^^^
Documentation/security/LSM.txt various security checks to be hooked by new kernel extensions. The name · line 49
Quoted 1 line
Documentation/security/LSM.txt +1
-0+but after in a small number of cases. All LSM hooks need to be aware
^^^^^
one of these 'after's should be 'before' ??
Quoted 22 lines
Documentation/security/LSM.txt +6
-9+of the potential interactions with the capability system. For more +details on capabilities, see capabilities(7) in the Linux man-pages +project. The primary users of the LSM interface are Mandatory Access Control (MAC) extensions which provide a comprehensive security policy. Examples include SELinux, Smack, Tomoyo, and AppArmor. In addition to the larger -MAC extensions, other extensions can be built using the LSM to provide -specific changes to system operation when these tweaks are not available -in the core functionality of Linux itself. - -Without a specific LSM built into the kernel, the default LSM will be the -Linux capabilities system. Most LSMs choose to extend the capabilities -system, building their checks on top of the defined capability hooks. -For more details on capabilities, see capabilities(7) in the Linux -man-pages project. +MAC extensions, other extensions such as Yama can be built using the LSM +to provide specific changes to system operation when these tweaks are not +available in the core functionality of Linux itself. Based on http://kerneltrap.org/Linux/Documenting_Security_Module_Intent, a new LSM is accepted into the kernel when its intent (a description of
Signature · 1 line
~Randy
Casey Schaufler
maintainerRe: [PATCH v14 6/6] LSM: Multiple LSM Documentation and cleanup
Quoted 42 lines · Randy Dunlap
Quoted 29 lines · Casey Schaufler
Subject: [PATCH v14 6/6] LSM: Multiple LSM Documentation and cleanup
Add documentation and remove the obsolete capability LSM. Clean up some comments in
security.hSigned-off-by Casey Schaufler <[email protected]>--- Documentation/security/LSM.txt | 56 +- include/linux/security.h | 48 +- security/Makefile | 1 - security/capability.c | 1106 ---------------------------------------- 4 files changed, 77 insertions(+), 1134 deletions(-)Documentation/security/LSM.txt +6
-1@@ -7,20 +7,56 @@ various security checks to be hooked by new kernel extensions. The name loadable kernel modules. Instead, they are selectable at build-time via CONFIG_DEFAULT_SECURITY and can be overridden at boot-time via the "security=..." kernel command line argument, in the case where multiple -LSMs were built into a given kernel. +LSMs were built into a given kernel. The names of the active LSMs +can be read from /sys/kernel/security/lsm. + +Both CONFIG_DEFAULT_SECURITY and the "security=" option take a comma +separated list of LSM names. The LSM hooks are invoked in the order +specified. All hooks provided are invoked regardless of the outcomeDocumentation/security/LSM.txt various security checks to be hooked by new kernel extensions. The name · line 25
Quoted 10 lines
Documentation/security/LSM.txt +10
-0+of preceding hooks. Hooks that return success or failure results +return success if all of the LSM provided hooks succeed and the error +code of the last failing hook on error. + +Information from an LSM can come in one of two forms. The raw data +used by the LSM is typically the preferred form. SELinux contexts and +Smack labels are examples of raw LSM data. If the data from multiple +LSMs is presented together it will be in the form: + + lsmname='value'[lsmname='value']...no commas? just (made up example):
Quoted 1 line
smack='label'selinux='notstrict'
That's correct. No commas. Because all values are quoted commas are unnecessary. If I want the SELinux portion of a context I can call
sscanf(source, "selinux='%[^']'", result);
and comma separation helps not a bit.
Quoted 24 lines
Quoted 13 lines
Documentation/security/LSM.txt +13
-0+ +Interfaces that accept LSM data as input accept this format as well, +passing only the relevant portion of the data to each LSM. + +The /proc filesystem attribute interface supports files from a time +when only one LSM could be used at a time. CONFIG_PRESENT_SECURITY +defines which LSM uses these interfaces. The name of this LSM can be +read from /sys/kernel/security/present. There are also LSM identified +interfaces which should be used in preference to the undifferentiated +interfaces. The attribute interface "context" always provides the +data from all LSMs that maintain it in the lsmname='value' format. + +The three networking mechanisms supporting LSM attributes areDocumentation/security/LSM.txt various security checks to be hooked by new kernel extensions. The name · line 48
Quoted 10 lines
Documentation/security/LSM.txt +10
-0+restricted to providing those attributes for a single LSM each. +CONFIG_SECMARK_LSM specifies which LSM will provide hooks for the +secmark mechanism. CONFIG_NETLABEL_LSM specifies which LSM hooks +are used by NetLabel to provide IPv4 CIPSO headers. CONFIG_XFRM_LSM +specifies the LSM providing xfrm hooks. CONFIG_PEERSEC_LSM allows +for either a specific LSM to provide data with SO_PEERSEC or for +all LSMs that provide data to do so. + +The Linux capabilities system is used in conjunction with any LSMs. +LSM hooks are called after the capability checks in most cases,^^^^^
Quoted 4 lines
Documentation/security/LSM.txt various security checks to be hooked by new kernel extensions. The name · line 49
Quoted 1 line
Documentation/security/LSM.txt +1
-0+but after in a small number of cases. All LSM hooks need to be aware^^^^^
one of these 'after's should be 'before' ??
Yup. The latter should in fact be "before".
Quoted 23 lines
Quoted 23 lines
Documentation/security/LSM.txt +6
-9+of the potential interactions with the capability system. For more +details on capabilities, see capabilities(7) in the Linux man-pages +project. The primary users of the LSM interface are Mandatory Access Control (MAC) extensions which provide a comprehensive security policy. Examples include SELinux, Smack, Tomoyo, and AppArmor. In addition to the larger -MAC extensions, other extensions can be built using the LSM to provide -specific changes to system operation when these tweaks are not available -in the core functionality of Linux itself. - -Without a specific LSM built into the kernel, the default LSM will be the -Linux capabilities system. Most LSMs choose to extend the capabilities -system, building their checks on top of the defined capability hooks. -For more details on capabilities, see capabilities(7) in the Linux -man-pages project. +MAC extensions, other extensions such as Yama can be built using the LSM +to provide specific changes to system operation when these tweaks are not +available in the core functionality of Linux itself. Based on http://kerneltrap.org/Linux/Documenting_Security_Module_Intent, a new LSM is accepted into the kernel when its intent (a description of
Quoted 9 lines · Casey Schaufler
Subject: [PATCH v14 0/6] LSM: Multiple concurrent LSMs
Version 14 of this patchset is based on v3.10.
It required significant change from version 13 due to changes in the audit code. It came out cleaner, especially in the changes to NetLabel. This version supports all existing LSMs running together at the same time. The combinations tested most completely are:
Quoted 3 lines
apparmor,tomoyo,smack,yama - Ubuntu
apparmor,selinux,smack,yama - Fedora
Does this change the way one would develop a new LSM module? I presume it does not
Quoted 13 lines
I have been unable to figure out how to configure SELinux on Ubuntu and TOMOYO on Fedora. That's the only reason the list does not include all five LSMs at once. Combining LSMs that use networking is tricky, but can be done. There are changes coming from AppArmor that might make it even trickier, but that's a problem for the future.
Change the infrastructure for Linux Security Modules (LSM)s from a single vector of hook handlers to a list based method for handling multiple concurrent modules. All combinations of existing LSMs are supported.
Quoted 7 lines
The "security=" boot option takes a comma separated list of LSMs, registering them in the order presented. The LSM hooks will be executed in the order registered. Hooks that return errors are not short circuited. All hooks are called even if one of the LSM hooks fails. The result returned will be that of the last LSM hook that failed.
This is an important design trade-off. From my perspective I think you might want to revisit this, today it sounds like effective security == all hooks process and allow the operation. In this world a lack of proper policy/setting can make hooks fail. I've not yet looked at the code, but you might want to revisit this.
Quoted 41 lines
All behavior from
security/capability.chas been moved into the hook handling. Thesecurity/commoncapfunctions used to get called from the LSM specific code. The handling of the capability functions has been moved out of the LSMs and into the hook handling.A level of indirection has been introduced in the handling of security blobs. LSMs no longer access ->security fields directly, instead they use an abstraction provided by lsm_[gs]et field functions.
The notion that "the security context" can be represented as a single u32 "secid" does not scale to the case where multiple LSMs want to provide "the security context". The XFRM and secmark facilities appear unlikely to ever allow for more than the existing 32 bit values. The NetLabel scheme might possibly be used to represent more than one labeling scheme (CIPSO does allow for multiple tags) although there is no plan to do so at this time. The
SO_PEERSECscheme is capable of providing information from multiple LSMs. Auditing can deal with multiple secids.The NetLabel, XFRM and secmark facilities are restricted to use by one LSM at a time. The
SO_PEERSECfacility can provide information from multiple LSMs, but existing user space tools don't understand that. The default behavior is to assign each of these facilities to the first registered LSM that uses them. They can be configured for use by any of the LSMs that provide hooks for them.SO_PEERSECcan be configured to provide information from all of the LSMs that provide hooks.The
/proc/*/attrinterfaces are given to one LSM. This can be done by settingCONFIG_SECURITY_PRESENT. Additional interfaces have been created in/proc/*/attrso that each LSM has its own named interfaces. The name of the presenting LSM can be read from/sys/kernel/security/present. The list of LSMs being used can be read from/sys/kernel/security/lsm.A "security context" may now contrain information processed by more than one LSM. The proper form of a security context identifies the information it contains by LSM:
Quoted 8 lines
smack='Pop'selinux='system_u:object_r:etc_r:s0'A security context without the LSM identifying lsm='<text>' gets passed through to all of the LSMs that use a security context. This maintains compatability in the case where there is only one LSM using the security context.
Signed-off-by Casey Schaufler <[email protected]>
Balbir Singh
Casey Schaufler
maintainerQuoted 11 lines · Balbir Singh
Quoted 9 lines · Casey Schaufler
Subject: [PATCH v14 0/6] LSM: Multiple concurrent LSMs
Version 14 of this patchset is based on v3.10.
It required significant change from version 13 due to changes in the audit code. It came out cleaner, especially in the changes to NetLabel. This version supports all existing LSMs running together at the same time. The combinations tested most completely are:
Quoted 5 lines
Quoted 3 lines
apparmor,tomoyo,smack,yama - Ubuntu
apparmor,selinux,smack,yama - FedoraDoes this change the way one would develop a new LSM module? I presume it does not
The change that LSM developers need to be aware of is the security blob abstraction. Instead of using cred->security, inode->i_security and the like the code needs to use lsm_get_cred() and lsm_set_cred() and similar functions.
Quoted 20 lines
Quoted 13 lines
I have been unable to figure out how to configure SELinux on Ubuntu and TOMOYO on Fedora. That's the only reason the list does not include all five LSMs at once. Combining LSMs that use networking is tricky, but can be done. There are changes coming from AppArmor that might make it even trickier, but that's a problem for the future.
Change the infrastructure for Linux Security Modules (LSM)s from a single vector of hook handlers to a list based method for handling multiple concurrent modules. All combinations of existing LSMs are supported.
Quoted 7 lines
The "security=" boot option takes a comma separated list of LSMs, registering them in the order presented. The LSM hooks will be executed in the order registered. Hooks that return errors are not short circuited. All hooks are called even if one of the LSM hooks fails. The result returned will be that of the last LSM hook that failed.
Quoted 5 lines
This is an important design trade-off. From my perspective I think you might want to revisit this, today it sounds like effective security == all hooks process and allow the operation. In this world a lack of proper policy/setting can make hooks fail. I've not yet looked at the code, but you might want to revisit this.
The result of an LSM hook will be failure if any of the LSMs indicates failure. The key here is that all of the LSM hooks get called even if it's known that the overall result is failure. This is done because many LSM hooks maintain internal state and shortcutting can disrupt that.
Quoted 48 lines
Quoted 48 lines
All behavior from
security/capability.chas been moved into the hook handling. Thesecurity/commoncapfunctions used to get called from the LSM specific code. The handling of the capability functions has been moved out of the LSMs and into the hook handling.A level of indirection has been introduced in the handling of security blobs. LSMs no longer access ->security fields directly, instead they use an abstraction provided by lsm_[gs]et field functions.
The notion that "the security context" can be represented as a single u32 "secid" does not scale to the case where multiple LSMs want to provide "the security context". The XFRM and secmark facilities appear unlikely to ever allow for more than the existing 32 bit values. The NetLabel scheme might possibly be used to represent more than one labeling scheme (CIPSO does allow for multiple tags) although there is no plan to do so at this time. The
SO_PEERSECscheme is capable of providing information from multiple LSMs. Auditing can deal with multiple secids.The NetLabel, XFRM and secmark facilities are restricted to use by one LSM at a time. The
SO_PEERSECfacility can provide information from multiple LSMs, but existing user space tools don't understand that. The default behavior is to assign each of these facilities to the first registered LSM that uses them. They can be configured for use by any of the LSMs that provide hooks for them.SO_PEERSECcan be configured to provide information from all of the LSMs that provide hooks.The
/proc/*/attrinterfaces are given to one LSM. This can be done by settingCONFIG_SECURITY_PRESENT. Additional interfaces have been created in/proc/*/attrso that each LSM has its own named interfaces. The name of the presenting LSM can be read from/sys/kernel/security/present. The list of LSMs being used can be read from/sys/kernel/security/lsm.A "security context" may now contrain information processed by more than one LSM. The proper form of a security context identifies the information it contains by LSM:
smack='Pop'selinux='system_u:object_r:etc_r:s0'A security context without the LSM identifying lsm='<text>' gets passed through to all of the LSMs that use a security context. This maintains compatability in the case where there is only one LSM using the security context.
Quoted 8 lines
Quoted 1 line
Signed-off-by Casey Schaufler <[email protected]>Balbir Singh
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.
Quoted 15 lines · Casey Schaufler
Quoted 14 lines · Balbir Singh
Quoted 12 lines · Casey Schaufler
Subject: [PATCH v14 0/6] LSM: Multiple concurrent LSMs
Version 14 of this patchset is based on v3.10.
It required significant change from version 13 due to changes in the audit code. It came out cleaner, especially in the changes to NetLabel. This version supports all existing LSMs running together at the same time. The combinations tested most completely are:apparmor,tomoyo,smack,yama - Ubuntu
apparmor,selinux,smack,yama - Fedora
Quoted 8 lines
Quoted 2 lines
Does this change the way one would develop a new LSM module? I presume it does not
The change that LSM developers need to be aware of is the security blob abstraction. Instead of using
cred->security,inode->i_securityand the like the code needs to uselsm_get_cred()andlsm_set_cred()and similar functions.
OK
Quoted 26 lines
Quoted 20 lines
Quoted 13 lines
I have been unable to figure out how to configure SELinux on Ubuntu and TOMOYO on Fedora. That's the only reason the list does not include all five LSMs at once. Combining LSMs that use networking is tricky, but can be done. There are changes coming from AppArmor that might make it even trickier, but that's a problem for the future.
Change the infrastructure for Linux Security Modules (LSM)s from a single vector of hook handlers to a list based method for handling multiple concurrent modules. All combinations of existing LSMs are supported.
Quoted 7 lines
The "security=" boot option takes a comma separated list of LSMs, registering them in the order presented. The LSM hooks will be executed in the order registered. Hooks that return errors are not short circuited. All hooks are called even if one of the LSM hooks fails. The result returned will be that of the last LSM hook that failed.
Quoted 5 lines
This is an important design trade-off. From my perspective I think you might want to revisit this, today it sounds like effective security == all hooks process and allow the operation. In this world a lack of proper policy/setting can make hooks fail. I've not yet looked at the code, but you might want to revisit this.
Quoted 6 lines
The result of an LSM hook will be failure if any of the LSMs indicates failure. The key here is that all of the LSM hooks get called even if it's known that the overall result is failure. This is done because many LSM hooks maintain internal state and shortcutting can disrupt that.
Thanks for clarifying
Balbir
Quoted 4 lines · Casey Schaufler
The
/proc/*/attrinterfaces are given to one LSM. This can be done by settingCONFIG_SECURITY_PRESENT. Additional interfaces have been created in/proc/*/attrso that each LSM has its own named interfaces. The name of the presenting LSM can be read from
For me, this is one problem that was bothering me, but it was a cosmetic one that I'd mentioned before: I really disliked the /proc/$pid/attr interface being named "$lsm.$file". I feel it's important to build directories in attr/ for each LSM. So, I spent time to figure out a way to do this. This patch changes the interface to /proc/$pid/attr/$lsm/$file instead, which I feel has a much more appealing organizational structure.
-Kees
---
Subject: [PATCH] LSM: use subdirectories for LSM attr files
Instead of filling the /proc/$pid/attr/ directory with every LSM's needed attr files, insert a directory entry for each LSM which contains the needed files.
--- fs/proc/base.c | 95 ++++++++++++++++++++++++++++++++++++---------- fs/proc/internal.h | 1 + include/linux/security.h | 11 +++--- security/security.c | 67 ++++++++++++++------------------ 4 files changed, 112 insertions(+), 62 deletions(-)
fs/proc/base.c +76 -19
@@ -138,6 +138,10 @@ struct pid_entry {NOD (NAME , (S_IFREG |(MODE )), \NULL , &proc_single_file_operations, \ { .proc_show = show } ) +#define ATTR (LSM ,NAME ,MODE ) \ + NOD(NAME, (S_IFREG|(MODE)), \ + NULL, &proc_pid_attr_operations, \ + { .lsm = LSM } )/* * Count the number of hardlinks for the pid_entry table, excluding the .
@@ -2292,7 +2296,7 @@ static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,if (!task)return -ESRCH ; - length =security_getprocattr (task, + length =security_getprocattr (task,PROC_I (inode)->op.lsm, (char *)file->f_path.dentry->d_name.name, &p);put_task_struct (task);
@@ -2335,7 +2339,7 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,if (length <0 ) goto out_free; - length =security_setprocattr (task, + length =security_setprocattr (task,PROC_I (inode)->op.lsm, (char *)file->f_path.dentry->d_name.name, (void *)page, count);mutex_unlock (&task->signal->cred_guard_mutex);
@@ -2353,29 +2357,82 @@ static const struct file_operations proc_pid_attr_operations = { .llseek = generic_file_llseek, }; +#define LSM_DIR_OPS (LSM ) \ +static int proc_##LSM##_attr_dir_readdir(struct file * filp, \ + void * dirent, filldir_t filldir) \ +{ \ + return proc_pident_readdir(filp, dirent, filldir, \ + LSM##_attr_dir_stuff, \ + ARRAY_SIZE(LSM##_attr_dir_stuff)); \ +} \ +\ +static const struct file_operations proc_##LSM##_attr_dir_ops = { \ + .read = generic_read_dir, \ + .readdir = proc_##LSM##_attr_dir_readdir, \ + .llseek = default_llseek, \ +}; \ +\ +static struct dentry *proc_##LSM##_attr_dir_lookup(struct inode *dir, \ + struct dentry *dentry, unsigned int flags) \ +{ \ + return proc_pident_lookup(dir, dentry, \ + LSM##_attr_dir_stuff, \ + ARRAY_SIZE(LSM##_attr_dir_stuff)); \ +} \ +\ +static const struct inode_operations proc_##LSM##_attr_dir_inode_ops = { \ + .lookup = proc_##LSM##_attr_dir_lookup, \ + .getattr = pid_getattr, \ + .setattr = proc_setattr, \ +}; + +#ifdef CONFIG_SECURITY_SELINUX +static const struct pid_entry selinux_attr_dir_stuff[] = { +ATTR ("selinux" ,"current" ,S_IRUGO |S_IWUGO ), +ATTR ("selinux" ,"prev" ,S_IRUGO ), +ATTR ("selinux" ,"exec" ,S_IRUGO |S_IWUGO ), +ATTR ("selinux" ,"fscreate" ,S_IRUGO |S_IWUGO ), +ATTR ("selinux" ,"keycreate" ,S_IRUGO |S_IWUGO ), +ATTR ("selinux" ,"sockcreate" ,S_IRUGO |S_IWUGO ), +}; +LSM_DIR_OPS (selinux); +#endif + +#ifdef CONFIG_SECURITY_SMACK +static const struct pid_entry smack_attr_dir_stuff[] = { +ATTR ("smack" ,"current" ,S_IRUGO |S_IWUGO ), +}; +LSM_DIR_OPS (smack); +#endif + +#ifdef CONFIG_SECURITY_APPARMOR +static const struct pid_entry apparmor_attr_dir_stuff[] = { +ATTR ("apparmor" ,"current" ,S_IRUGO |S_IWUGO ), +ATTR ("apparmor" ,"prev" ,S_IRUGO ), +ATTR ("apparmor" ,"exec" ,S_IRUGO |S_IWUGO ), +}; +LSM_DIR_OPS (apparmor); +#endif +static const struct pid_entry attr_dir_stuff[] = { -REG ("current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("prev" ,S_IRUGO , proc_pid_attr_operations), -REG ("exec" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("fscreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("keycreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("sockcreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("context" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +ATTR (NULL ,"current" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"prev" ,S_IRUGO ), +ATTR (NULL ,"exec" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"fscreate" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"keycreate" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"sockcreate" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"context" ,S_IRUGO |S_IWUGO ), #ifdef CONFIG_SECURITY_SELINUX -REG ("selinux.current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("selinux.prev" ,S_IRUGO , proc_pid_attr_operations), -REG ("selinux.exec" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("selinux.fscreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("selinux.keycreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("selinux.sockcreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +DIR ("selinux" ,S_IRUGO |S_IXUGO , + proc_selinux_attr_dir_inode_ops, proc_selinux_attr_dir_ops), #endif #ifdef CONFIG_SECURITY_SMACK -REG ("smack.current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +DIR ("smack" ,S_IRUGO |S_IXUGO , + proc_smack_attr_dir_inode_ops, proc_smack_attr_dir_ops), #endif #ifdef CONFIG_SECURITY_APPARMOR -REG ("apparmor.current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("apparmor.prev" ,S_IRUGO , proc_pid_attr_operations), -REG ("apparmor.exec" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +DIR ("apparmor" ,S_IRUGO |S_IXUGO , + proc_apparmor_attr_dir_inode_ops, proc_apparmor_attr_dir_ops), #endif };
fs/proc/internal.h +1 -0
@@ -56,6 +56,7 @@ union proc_op {int (*proc_show)(struct seq_file *m,struct pid_namespace *ns,struct pid *pid,struct task_struct *task); +const char *lsm; };struct proc_inode {
include/linux/security.h +6 -5
@@ -2115,9 +2115,10 @@ int security_sem_semctl(struct sem_array *sma, int cmd);int security_sem_semop (struct sem_array *sma,struct sembuf *sops,unsigned nsops,int alter);void security_d_instantiate (struct dentry *dentry,struct inode *inode); -int security_getprocattr (struct task_struct *p,char *name,char **value); -int security_setprocattr (struct task_struct *p,char *name,void *value, -size_t size); +int security_getprocattr (struct task_struct *p,const char *lsm,char *name, +char **value); +int security_setprocattr (struct task_struct *p,const char *lsm,char *name, +void *value,size_t size);int security_netlink_send (struct sock *sk,struct sk_buff *skb);int security_secid_to_secctx (struct secids *secid,char **secdata,u32 *seclen,struct security_operations **secops);
@@ -2801,8 +2802,8 @@ static inline void security_d_instantiate(struct dentry *dentry, struct inode *inode) { } -static inline int security_getprocattr (struct task_struct *p,char *name, -char **value) +static inline int security_getprocattr (struct task_struct *p,char *lsm, +char *name,char **value) {return -EINVAL ; }
security/security.c +29 -38
103 lines not on this page · raw message
Signature · 6 lines
1.7.9.5 -- Kees Cook Chrome OS Security
Casey Schaufler
maintainerQuoted 11 lines · Kees Cook
Quoted 4 lines · Casey Schaufler
The
/proc/*/attrinterfaces are given to one LSM. This can be done by settingCONFIG_SECURITY_PRESENT. Additional interfaces have been created in/proc/*/attrso that each LSM has its own named interfaces. The name of the presenting LSM can be read fromFor me, this is one problem that was bothering me, but it was a cosmetic one that I'd mentioned before: I really disliked the
/proc/$pid/attrinterface being named "$lsm.$file". I feel it's important to build directories in attr/ for each LSM. So, I spent time to figure out a way to do this. This patch changes the interface to/proc/$pid/attr/$lsm/$fileinstead, which I feel has a much more appealing organizational structure.
I will confess that the reason I went with <lsm>.current instead of <lsm>/current was that the former was easier to implement.
Quoted 72 lines
-Kees
---
Subject: [PATCH] LSM: use subdirectories for LSM attr filesInstead of filling the
/proc/$pid/attr/directory with every LSM's needed attr files, insert a directory entry for each LSM which contains the needed files.Signed-off-by Kees Cook <[email protected]>--- fs/proc/base.c | 95 ++++++++++++++++++++++++++++++++++++---------- fs/proc/internal.h | 1 + include/linux/security.h | 11 +++--- security/security.c | 67 ++++++++++++++------------------ 4 files changed, 112 insertions(+), 62 deletions(-)fs/proc/base.c +24
-2@@ -138,6 +138,10 @@ struct pid_entry {NOD (NAME , (S_IFREG |(MODE )), \NULL , &proc_single_file_operations, \ { .proc_show = show } ) +#define ATTR (LSM ,NAME ,MODE ) \ + NOD(NAME, (S_IFREG|(MODE)), \ + NULL, &proc_pid_attr_operations, \ + { .lsm = LSM } )/* * Count the number of hardlinks for the pid_entry table, excluding the . @@ -2292,7 +2296,7 @@ static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,if (!task)return -ESRCH ; - length =security_getprocattr (task, + length =security_getprocattr (task,PROC_I (inode)->op.lsm, (char *)file->f_path.dentry->d_name.name, &p);put_task_struct (task);@@ -2335,7 +2339,7 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,if (length <0 ) goto out_free; - length =security_setprocattr (task, + length =security_setprocattr (task,PROC_I (inode)->op.lsm, (char *)file->f_path.dentry->d_name.name, (void *)page, count);mutex_unlock (&task->signal->cred_guard_mutex);@@ -2353,29 +2357,82 @@ static const struct file_operations proc_pid_attr_operations = { .llseek = generic_file_llseek, }; +#define LSM_DIR_OPS (LSM ) \ +static int proc_##LSM##_attr_dir_readdir(struct file * filp, \ + void * dirent, filldir_t filldir) \ +{ \ + return proc_pident_readdir(filp, dirent, filldir, \ + LSM##_attr_dir_stuff, \ + ARRAY_SIZE(LSM##_attr_dir_stuff)); \ +} \ +\ +static const struct file_operations proc_##LSM##_attr_dir_ops = { \ + .read = generic_read_dir, \ + .readdir = proc_##LSM##_attr_dir_readdir, \ + .llseek = default_llseek, \ +}; \ +\ +static struct dentry *proc_##LSM##_attr_dir_lookup(struct inode *dir, \ + struct dentry *dentry, unsigned int flags) \ +{ \
fs/proc/base.c static const struct file_operations proc_pid_attr_operations = { · line 2387
Quoted 10 lines
fs/proc/base.c +10
-0+return proc_pident_lookup (dir, dentry, \ + LSM##_attr_dir_stuff, \ + ARRAY_SIZE(LSM##_attr_dir_stuff)); \ +} \ +\ +static const struct inode_operations proc_##LSM##_attr_dir_inode_ops = { \ + .lookup = proc_##LSM##_attr_dir_lookup, \ + .getattr = pid_getattr, \ + .setattr = proc_setattr, \ +};
That's one hell of a macro you got there, Kees. I'm not saying it's bad, but it is quite the mouthful.
Quoted 19 lines
fs/proc/base.c +19
-0+ +#ifdef CONFIG_SECURITY_SELINUX +static const struct pid_entry selinux_attr_dir_stuff[] = { +ATTR ("selinux" ,"current" ,S_IRUGO |S_IWUGO ), +ATTR ("selinux" ,"prev" ,S_IRUGO ), +ATTR ("selinux" ,"exec" ,S_IRUGO |S_IWUGO ), +ATTR ("selinux" ,"fscreate" ,S_IRUGO |S_IWUGO ), +ATTR ("selinux" ,"keycreate" ,S_IRUGO |S_IWUGO ), +ATTR ("selinux" ,"sockcreate" ,S_IRUGO |S_IWUGO ), +}; +LSM_DIR_OPS (selinux); +#endif + +#ifdef CONFIG_SECURITY_SMACK +static const struct pid_entry smack_attr_dir_stuff[] = { +ATTR ("smack" ,"current" ,S_IRUGO |S_IWUGO ), +}; +LSM_DIR_OPS (smack); +#endif
fs/proc/base.c static const struct file_operations proc_pid_attr_operations = { · line 2416
Quoted 10 lines
fs/proc/base.c +10
-0+ +#ifdef CONFIG_SECURITY_APPARMOR +static const struct pid_entry apparmor_attr_dir_stuff[] = { +ATTR ("apparmor" ,"current" ,S_IRUGO |S_IWUGO ), +ATTR ("apparmor" ,"prev" ,S_IRUGO ), +ATTR ("apparmor" ,"exec" ,S_IRUGO |S_IWUGO ), +}; +LSM_DIR_OPS (apparmor); +#endif +
%s/dir_stuff/dir_entries/g
It doesn't have to be "entries", but "stuff" is horribly non-descriptive.
Quoted 162 lines
fs/proc/base.c +13
-17static const struct pid_entry attr_dir_stuff[] = { -REG ("current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("prev" ,S_IRUGO , proc_pid_attr_operations), -REG ("exec" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("fscreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("keycreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("sockcreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("context" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +ATTR (NULL ,"current" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"prev" ,S_IRUGO ), +ATTR (NULL ,"exec" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"fscreate" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"keycreate" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"sockcreate" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"context" ,S_IRUGO |S_IWUGO ), #ifdef CONFIG_SECURITY_SELINUX -REG ("selinux.current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("selinux.prev" ,S_IRUGO , proc_pid_attr_operations), -REG ("selinux.exec" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("selinux.fscreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("selinux.keycreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("selinux.sockcreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +DIR ("selinux" ,S_IRUGO |S_IXUGO , + proc_selinux_attr_dir_inode_ops, proc_selinux_attr_dir_ops), #endif #ifdef CONFIG_SECURITY_SMACK -REG ("smack.current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +DIR ("smack" ,S_IRUGO |S_IXUGO , + proc_smack_attr_dir_inode_ops, proc_smack_attr_dir_ops), #endif #ifdef CONFIG_SECURITY_APPARMOR -REG ("apparmor.current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("apparmor.prev" ,S_IRUGO , proc_pid_attr_operations), -REG ("apparmor.exec" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +DIR ("apparmor" ,S_IRUGO |S_IXUGO , + proc_apparmor_attr_dir_inode_ops, proc_apparmor_attr_dir_ops), #endif };fs/proc/internal.h +1
-0@@ -56,6 +56,7 @@ union proc_op {int (*proc_show)(struct seq_file *m,struct pid_namespace *ns,struct pid *pid,struct task_struct *task); +const char *lsm; };struct proc_inode {include/linux/security.h +6
-5@@ -2115,9 +2115,10 @@ int security_sem_semctl(struct sem_array *sma, int cmd);int security_sem_semop (struct sem_array *sma,struct sembuf *sops,unsigned nsops,int alter);void security_d_instantiate (struct dentry *dentry,struct inode *inode); -int security_getprocattr (struct task_struct *p,char *name,char **value); -int security_setprocattr (struct task_struct *p,char *name,void *value, -size_t size); +int security_getprocattr (struct task_struct *p,const char *lsm,char *name, +char **value); +int security_setprocattr (struct task_struct *p,const char *lsm,char *name, +void *value,size_t size);int security_netlink_send (struct sock *sk,struct sk_buff *skb);int security_secid_to_secctx (struct secids *secid,char **secdata,u32 *seclen,struct security_operations **secops);@@ -2801,8 +2802,8 @@ static inline void security_d_instantiate(struct dentry *dentry, struct inode *inode) { } -static inline int security_getprocattr (struct task_struct *p,char *name, -char **value) +static inline int security_getprocattr (struct task_struct *p,char *lsm, +char *name,char **value) {return -EINVAL ; }security/security.c +21
-27@@ -1897,74 +1897,65 @@ void security_d_instantiate(struct dentry *dentry, struct inode *inode) }EXPORT_SYMBOL (security_d_instantiate); -int security_getprocattr (struct task_struct *p,char *name,char **value) +int security_getprocattr (struct task_struct *p,const char *lsm,char *name, +char **value) {struct security_operations *sop =NULL ;struct secids secid; -char *lsm; -int lsmlen;int ret;/* -* Names will either be in the legacy form containing -* no periods (".") or they will be the LSM name followed -* by the legacy suffix. "current" or "selinux.current" -* The exception is "context", which gets all of the LSMs. -* -* Legacy names are handled by the presenting LSM. -* Suffixed names are handled by the named LSM. +* Target LSM will be either NULL or looked up by name. Names with +* a NULL LSM (legacy) are handled by the presenting LSM. The +* exception is "context", which gets all of the LSMs. */ if (strcmp (name,"context" ) ==0 ) { +char *lsmname; +int lsmlen; +security_task_getsecid (p, &secid); - ret =security_secid_to_secctx (&secid, &lsm, &lsmlen, &sop); + ret =security_secid_to_secctx (&secid, &lsmname, &lsmlen, &sop);if (ret ==0 ) { - *value =kstrdup (lsm,GFP_KERNEL ); + *value =kstrdup (lsmname,GFP_KERNEL );if (*value ==NULL ) ret = -ENOMEM ;else ret =strlen (*value); -security_release_secctx (lsm, lsmlen, sop); +security_release_secctx (lsmname, lsmlen, sop); }return ret; } -if (present_ops && !strchr (name,'.' )) -return present_getprocattr (p, name, value); - -for_each_hook (sop, getprocattr) { - lsm = sop->name; - lsmlen =strlen (lsm); -if (!strncmp (name, lsm, lsmlen) && name[lsmlen] =='.' ) -return sop->getprocattr (p, name + lsmlen +1 , value); +if (!lsm) { +if (present_ops) +return present_getprocattr (p, name, value); + }else { +for_each_hook (sop, getprocattr) { +if (!strcmp (lsm, sop->name)) +return sop->getprocattr (p, name, value); + } }return -EINVAL ; } -int security_setprocattr (struct task_struct *p,char *name,void *value, -size_t size) +int security_setprocattr (struct task_struct *p,const char *lsm,char *name, +void *value,size_t size) {struct security_operations *sop; -char *lsm; -int lsmlen;/* -* Names will either be in the legacy form containing -* no periods (".") or they will be the LSM name followed
security/security.c void security_d_instantiate(struct dentry *dentry, struct inode *inode) · line 1951
Quoted 10 lines
security/security.c +2
-5-* by the legacy suffix. -* "current" or "selinux.current" -* -* Legacy names are handled by the presenting LSM. -* Suffixed names are handled by the named LSM. +* Target LSM will be either NULL or looked up by name. Names with +* a NULL LSM (legacy) are handled by the presenting LSM. The */ if (present_ops && !strchr (name,'.' ))return present_setprocattr (p, name, value, size);
We'll want to loose the preceding two lines, and add some later.
security/security.c void security_d_instantiate(struct dentry *dentry, struct inode *inode)
Quoted 13 lines
security/security.c +6
-7-for_each_hook (sop, setprocattr) { - lsm = sop->name; - lsmlen =strlen (lsm); -if (!strncmp (name, lsm, lsmlen) && name[lsmlen] =='.' ) -return sop->setprocattr (p, name + lsmlen +1 , value, - size); +if (lsm) { +for_each_hook (sop, setprocattr) { +if (!strcmp (lsm, sop->name)) +return sop->setprocattr (p, name, value, + size); + } - }
+ } else if (present_ops) + return present_setprocattr(p, name, value, size);
Quoted 2 lines
security/security.c +0
-0return -EINVAL ; }
Quoted 13 lines · Casey Schaufler
Quoted 11 lines · Kees Cook
Quoted 4 lines · Casey Schaufler
The
/proc/*/attrinterfaces are given to one LSM. This can be done by settingCONFIG_SECURITY_PRESENT. Additional interfaces have been created in/proc/*/attrso that each LSM has its own named interfaces. The name of the presenting LSM can be read fromFor me, this is one problem that was bothering me, but it was a cosmetic one that I'd mentioned before: I really disliked the
/proc/$pid/attrinterface being named "$lsm.$file". I feel it's important to build directories in attr/ for each LSM. So, I spent time to figure out a way to do this. This patch changes the interface to/proc/$pid/attr/$lsm/$fileinstead, which I feel has a much more appealing organizational structure.
Quoted 2 lines
I will confess that the reason I went with <lsm>.current instead of <lsm>/current was that the former was easier to implement.
Yeah, that's totally fine. It wasn't very obvious (to me) how to implement this initially, so no problem at all. I'm glad there was something more than bug fixes I could contribute to this series. :)
Quoted 78 lines
Quoted 78 lines
-Kees
---
Subject: [PATCH] LSM: use subdirectories for LSM attr filesInstead of filling the
/proc/$pid/attr/directory with every LSM's needed attr files, insert a directory entry for each LSM which contains the needed files.Signed-off-by Kees Cook <[email protected]>--- fs/proc/base.c | 95 ++++++++++++++++++++++++++++++++++++---------- fs/proc/internal.h | 1 + include/linux/security.h | 11 +++--- security/security.c | 67 ++++++++++++++------------------ 4 files changed, 112 insertions(+), 62 deletions(-)fs/proc/base.c +29
-2@@ -138,6 +138,10 @@ struct pid_entry {NOD (NAME , (S_IFREG |(MODE )), \NULL , &proc_single_file_operations, \ { .proc_show = show } ) +#define ATTR (LSM ,NAME ,MODE ) \ + NOD(NAME, (S_IFREG|(MODE)), \ + NULL, &proc_pid_attr_operations, \ + { .lsm = LSM } )/* * Count the number of hardlinks for the pid_entry table, excluding the . @@ -2292,7 +2296,7 @@ static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,if (!task)return -ESRCH ; - length =security_getprocattr (task, + length =security_getprocattr (task,PROC_I (inode)->op.lsm, (char *)file->f_path.dentry->d_name.name, &p);put_task_struct (task);@@ -2335,7 +2339,7 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,if (length <0 ) goto out_free; - length =security_setprocattr (task, + length =security_setprocattr (task,PROC_I (inode)->op.lsm, (char *)file->f_path.dentry->d_name.name, (void *)page, count);mutex_unlock (&task->signal->cred_guard_mutex);@@ -2353,29 +2357,82 @@ static const struct file_operations proc_pid_attr_operations = { .llseek = generic_file_llseek, }; +#define LSM_DIR_OPS (LSM ) \ +static int proc_##LSM##_attr_dir_readdir(struct file * filp, \ + void * dirent, filldir_t filldir) \ +{ \ + return proc_pident_readdir(filp, dirent, filldir, \ + LSM##_attr_dir_stuff, \ + ARRAY_SIZE(LSM##_attr_dir_stuff)); \ +} \ +\ +static const struct file_operations proc_##LSM##_attr_dir_ops = { \ + .read = generic_read_dir, \ + .readdir = proc_##LSM##_attr_dir_readdir, \ + .llseek = default_llseek, \ +}; \ +\ +static struct dentry *proc_##LSM##_attr_dir_lookup(struct inode *dir, \ + struct dentry *dentry, unsigned int flags) \ +{ \ + return proc_pident_lookup(dir, dentry, \ + LSM##_attr_dir_stuff, \ + ARRAY_SIZE(LSM##_attr_dir_stuff)); \ +} \ +\
Quoted 8 lines
fs/proc/base.c static const struct file_operations proc_pid_attr_operations = { · line 2387
Quoted 5 lines
fs/proc/base.c +5
-0+static const struct inode_operations proc_##LSM##_attr_dir_inode_ops = { \ + .lookup = proc_##LSM##_attr_dir_lookup, \ + .getattr = pid_getattr, \ + .setattr = proc_setattr, \ +};That's one hell of a macro you got there, Kees. I'm not saying it's bad, but it is quite the mouthful.
Heh, yeah. And this is the reduced version! I haven't found a good way to make this smaller yet.
Quoted 24 lines
Quoted 24 lines
fs/proc/base.c +24
-0+ +#ifdef CONFIG_SECURITY_SELINUX +static const struct pid_entry selinux_attr_dir_stuff[] = { +ATTR ("selinux" ,"current" ,S_IRUGO |S_IWUGO ), +ATTR ("selinux" ,"prev" ,S_IRUGO ), +ATTR ("selinux" ,"exec" ,S_IRUGO |S_IWUGO ), +ATTR ("selinux" ,"fscreate" ,S_IRUGO |S_IWUGO ), +ATTR ("selinux" ,"keycreate" ,S_IRUGO |S_IWUGO ), +ATTR ("selinux" ,"sockcreate" ,S_IRUGO |S_IWUGO ), +}; +LSM_DIR_OPS (selinux); +#endif + +#ifdef CONFIG_SECURITY_SMACK +static const struct pid_entry smack_attr_dir_stuff[] = { +ATTR ("smack" ,"current" ,S_IRUGO |S_IWUGO ), +}; +LSM_DIR_OPS (smack); +#endif + +#ifdef CONFIG_SECURITY_APPARMOR +static const struct pid_entry apparmor_attr_dir_stuff[] = { +ATTR ("apparmor" ,"current" ,S_IRUGO |S_IWUGO ), + ATTR("apparmor", "prev", S_IRUGO),
Quoted 8 lines
fs/proc/base.c static const struct file_operations proc_pid_attr_operations = { · line 2416
Quoted 5 lines
fs/proc/base.c +5
-0+ATTR ("apparmor" ,"exec" ,S_IRUGO |S_IWUGO ), +}; +LSM_DIR_OPS (apparmor); +#endif +%s/dir_stuff/dir_entries/g
It doesn't have to be "entries", but "stuff" is horribly non-descriptive.
Using "entries" is fine by me. I was modeling it entirely after the existing code (see "attr_dir_stuff" below).
Quoted 192 lines
Quoted 164 lines
fs/proc/base.c +13
-17static const struct pid_entry attr_dir_stuff[] = { -REG ("current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("prev" ,S_IRUGO , proc_pid_attr_operations), -REG ("exec" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("fscreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("keycreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("sockcreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("context" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +ATTR (NULL ,"current" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"prev" ,S_IRUGO ), +ATTR (NULL ,"exec" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"fscreate" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"keycreate" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"sockcreate" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"context" ,S_IRUGO |S_IWUGO ), #ifdef CONFIG_SECURITY_SELINUX -REG ("selinux.current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("selinux.prev" ,S_IRUGO , proc_pid_attr_operations), -REG ("selinux.exec" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("selinux.fscreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("selinux.keycreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("selinux.sockcreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +DIR ("selinux" ,S_IRUGO |S_IXUGO , + proc_selinux_attr_dir_inode_ops, proc_selinux_attr_dir_ops), #endif #ifdef CONFIG_SECURITY_SMACK -REG ("smack.current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +DIR ("smack" ,S_IRUGO |S_IXUGO , + proc_smack_attr_dir_inode_ops, proc_smack_attr_dir_ops), #endif #ifdef CONFIG_SECURITY_APPARMOR -REG ("apparmor.current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("apparmor.prev" ,S_IRUGO , proc_pid_attr_operations), -REG ("apparmor.exec" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +DIR ("apparmor" ,S_IRUGO |S_IXUGO , + proc_apparmor_attr_dir_inode_ops, proc_apparmor_attr_dir_ops), #endif };fs/proc/internal.h +1
-0@@ -56,6 +56,7 @@ union proc_op {int (*proc_show)(struct seq_file *m,struct pid_namespace *ns,struct pid *pid,struct task_struct *task); +const char *lsm; };struct proc_inode {include/linux/security.h +6
-5@@ -2115,9 +2115,10 @@ int security_sem_semctl(struct sem_array *sma, int cmd);int security_sem_semop (struct sem_array *sma,struct sembuf *sops,unsigned nsops,int alter);void security_d_instantiate (struct dentry *dentry,struct inode *inode); -int security_getprocattr (struct task_struct *p,char *name,char **value); -int security_setprocattr (struct task_struct *p,char *name,void *value, -size_t size); +int security_getprocattr (struct task_struct *p,const char *lsm,char *name, +char **value); +int security_setprocattr (struct task_struct *p,const char *lsm,char *name, +void *value,size_t size);int security_netlink_send (struct sock *sk,struct sk_buff *skb);int security_secid_to_secctx (struct secids *secid,char **secdata,u32 *seclen,struct security_operations **secops);@@ -2801,8 +2802,8 @@ static inline void security_d_instantiate(struct dentry *dentry, struct inode *inode) { } -static inline int security_getprocattr (struct task_struct *p,char *name, -char **value) +static inline int security_getprocattr (struct task_struct *p,char *lsm, +char *name,char **value) {return -EINVAL ; }security/security.c +21
-27@@ -1897,74 +1897,65 @@ void security_d_instantiate(struct dentry *dentry, struct inode *inode) }EXPORT_SYMBOL (security_d_instantiate); -int security_getprocattr (struct task_struct *p,char *name,char **value) +int security_getprocattr (struct task_struct *p,const char *lsm,char *name, +char **value) {struct security_operations *sop =NULL ;struct secids secid; -char *lsm; -int lsmlen;int ret;/* -* Names will either be in the legacy form containing -* no periods (".") or they will be the LSM name followed -* by the legacy suffix. "current" or "selinux.current" -* The exception is "context", which gets all of the LSMs. -* -* Legacy names are handled by the presenting LSM. -* Suffixed names are handled by the named LSM. +* Target LSM will be either NULL or looked up by name. Names with +* a NULL LSM (legacy) are handled by the presenting LSM. The +* exception is "context", which gets all of the LSMs. */ if (strcmp (name,"context" ) ==0 ) { +char *lsmname; +int lsmlen; +security_task_getsecid (p, &secid); - ret =security_secid_to_secctx (&secid, &lsm, &lsmlen, &sop); + ret =security_secid_to_secctx (&secid, &lsmname, &lsmlen, &sop);if (ret ==0 ) { - *value =kstrdup (lsm,GFP_KERNEL ); + *value =kstrdup (lsmname,GFP_KERNEL );if (*value ==NULL ) ret = -ENOMEM ;else ret =strlen (*value); -security_release_secctx (lsm, lsmlen, sop); +security_release_secctx (lsmname, lsmlen, sop); }return ret; } -if (present_ops && !strchr (name,'.' )) -return present_getprocattr (p, name, value); - -for_each_hook (sop, getprocattr) { - lsm = sop->name; - lsmlen =strlen (lsm); -if (!strncmp (name, lsm, lsmlen) && name[lsmlen] =='.' ) -return sop->getprocattr (p, name + lsmlen +1 , value); +if (!lsm) { +if (present_ops) +return present_getprocattr (p, name, value); + }else { +for_each_hook (sop, getprocattr) { +if (!strcmp (lsm, sop->name)) +return sop->getprocattr (p, name, value); + } }return -EINVAL ; } -int security_setprocattr (struct task_struct *p,char *name,void *value, -size_t size) +int security_setprocattr (struct task_struct *p,const char *lsm,char *name, +void *value,size_t size) {struct security_operations *sop; -char *lsm; -int lsmlen;/* -* Names will either be in the legacy form containing -* no periods (".") or they will be the LSM name followed security/security.c void security_d_instantiate(struct dentry *dentry, struct inode *inode) · line 1951
Quoted 10 lines
security/security.c +2
-5-* by the legacy suffix. -* "current" or "selinux.current" -* -* Legacy names are handled by the presenting LSM. -* Suffixed names are handled by the named LSM. +* Target LSM will be either NULL or looked up by name. Names with +* a NULL LSM (legacy) are handled by the presenting LSM. The */ if (present_ops && !strchr (name,'.' ))return present_setprocattr (p, name, value, size);We'll want to loose the preceding two lines, and add some later.
security/security.c void security_d_instantiate(struct dentry *dentry, struct inode *inode)
Quoted 13 lines
security/security.c +6
-7-for_each_hook (sop, setprocattr) { - lsm = sop->name; - lsmlen =strlen (lsm); -if (!strncmp (name, lsm, lsmlen) && name[lsmlen] =='.' ) -return sop->setprocattr (p, name + lsmlen +1 , value, - size); +if (lsm) { +for_each_hook (sop, setprocattr) { +if (!strcmp (lsm, sop->name)) +return sop->setprocattr (p, name, value, + size); + } - }
Quoted 2 lines
+ } else if (
present_ops)
+ returnpresent_setprocattr(p, name, value, size);
Ah yes, this is better. Great!
-Kees
Quoted 4 lines
Quoted 3 lines
security/security.c +0
-0return -EINVAL ; }
Signature · 2 lines
Kees Cook Chrome OS Security
Casey Schaufler
maintainerQuoted 13 lines · Kees Cook
Quoted 12 lines · Casey Schaufler
Quoted 11 lines · Kees Cook
Quoted 4 lines · Casey Schaufler
The
/proc/*/attrinterfaces are given to one LSM. This can be done by settingCONFIG_SECURITY_PRESENT. Additional interfaces have been created in/proc/*/attrso that each LSM has its own named interfaces. The name of the presenting LSM can be read fromFor me, this is one problem that was bothering me, but it was a cosmetic one that I'd mentioned before: I really disliked the
/proc/$pid/attrinterface being named "$lsm.$file". I feel it's important to build directories in attr/ for each LSM. So, I spent time to figure out a way to do this. This patch changes the interface to/proc/$pid/attr/$lsm/$fileinstead, which I feel has a much more appealing organizational structure.
Quoted 5 lines
Quoted 2 lines
I will confess that the reason I went with <lsm>.current instead of <lsm>/current was that the former was easier to implement.
Yeah, that's totally fine. It wasn't very obvious (to me) how to implement this initially, so no problem at all. I'm glad there was something more than bug fixes I could contribute to this series. :)
Oh dear. I'm rebasing for 3.12 and the macros don't generate compiling code any longer. It seems that, among other things, readdir is no longer a member of file_operations.
Quoted 319 lines
Quoted 77 lines
Quoted 77 lines
-Kees
---
Subject: [PATCH] LSM: use subdirectories for LSM attr filesInstead of filling the
/proc/$pid/attr/directory with every LSM's needed attr files, insert a directory entry for each LSM which contains the needed files.Signed-off-by Kees Cook <[email protected]>--- fs/proc/base.c | 95 ++++++++++++++++++++++++++++++++++++---------- fs/proc/internal.h | 1 + include/linux/security.h | 11 +++--- security/security.c | 67 ++++++++++++++------------------ 4 files changed, 112 insertions(+), 62 deletions(-)fs/proc/base.c +28
-2@@ -138,6 +138,10 @@ struct pid_entry {NOD (NAME , (S_IFREG |(MODE )), \NULL , &proc_single_file_operations, \ { .proc_show = show } ) +#define ATTR (LSM ,NAME ,MODE ) \ + NOD(NAME, (S_IFREG|(MODE)), \ + NULL, &proc_pid_attr_operations, \ + { .lsm = LSM } )/* * Count the number of hardlinks for the pid_entry table, excluding the . @@ -2292,7 +2296,7 @@ static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,if (!task)return -ESRCH ; - length =security_getprocattr (task, + length =security_getprocattr (task,PROC_I (inode)->op.lsm, (char *)file->f_path.dentry->d_name.name, &p);put_task_struct (task);@@ -2335,7 +2339,7 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,if (length <0 ) goto out_free; - length =security_setprocattr (task, + length =security_setprocattr (task,PROC_I (inode)->op.lsm, (char *)file->f_path.dentry->d_name.name, (void *)page, count);mutex_unlock (&task->signal->cred_guard_mutex);@@ -2353,29 +2357,82 @@ static const struct file_operations proc_pid_attr_operations = { .llseek = generic_file_llseek, }; +#define LSM_DIR_OPS (LSM ) \ +static int proc_##LSM##_attr_dir_readdir(struct file * filp, \ + void * dirent, filldir_t filldir) \ +{ \ + return proc_pident_readdir(filp, dirent, filldir, \ + LSM##_attr_dir_stuff, \ + ARRAY_SIZE(LSM##_attr_dir_stuff)); \ +} \ +\ +static const struct file_operations proc_##LSM##_attr_dir_ops = { \ + .read = generic_read_dir, \ + .readdir = proc_##LSM##_attr_dir_readdir, \ + .llseek = default_llseek, \ +}; \ +\ +static struct dentry *proc_##LSM##_attr_dir_lookup(struct inode *dir, \ + struct dentry *dentry, unsigned int flags) \ +{ \ + return proc_pident_lookup(dir, dentry, \ + LSM##_attr_dir_stuff, \ + ARRAY_SIZE(LSM##_attr_dir_stuff)); \ +} \Quoted 8 lines
fs/proc/base.c static const struct file_operations proc_pid_attr_operations = { · line 2387
Quoted 6 lines
fs/proc/base.c +6
-0+\ +static const struct inode_operations proc_##LSM##_attr_dir_inode_ops = { \ + .lookup = proc_##LSM##_attr_dir_lookup, \ + .getattr = pid_getattr, \ + .setattr = proc_setattr, \ +};That's one hell of a macro you got there, Kees. I'm not saying it's bad, but it is quite the mouthful.
Heh, yeah. And this is the reduced version! I haven't found a good way to make this smaller yet.
Quoted 23 lines
Quoted 23 lines
fs/proc/base.c +23
-0+ +#ifdef CONFIG_SECURITY_SELINUX +static const struct pid_entry selinux_attr_dir_stuff[] = { +ATTR ("selinux" ,"current" ,S_IRUGO |S_IWUGO ), +ATTR ("selinux" ,"prev" ,S_IRUGO ), +ATTR ("selinux" ,"exec" ,S_IRUGO |S_IWUGO ), +ATTR ("selinux" ,"fscreate" ,S_IRUGO |S_IWUGO ), +ATTR ("selinux" ,"keycreate" ,S_IRUGO |S_IWUGO ), +ATTR ("selinux" ,"sockcreate" ,S_IRUGO |S_IWUGO ), +}; +LSM_DIR_OPS (selinux); +#endif + +#ifdef CONFIG_SECURITY_SMACK +static const struct pid_entry smack_attr_dir_stuff[] = { +ATTR ("smack" ,"current" ,S_IRUGO |S_IWUGO ), +}; +LSM_DIR_OPS (smack); +#endif + +#ifdef CONFIG_SECURITY_APPARMOR +static const struct pid_entry apparmor_attr_dir_stuff[] = { + ATTR("apparmor", "current", S_IRUGO|S_IWUGO),Quoted 8 lines
fs/proc/base.c static const struct file_operations proc_pid_attr_operations = { · line 2416
Quoted 6 lines
fs/proc/base.c +6
-0+ATTR ("apparmor" ,"prev" ,S_IRUGO ), +ATTR ("apparmor" ,"exec" ,S_IRUGO |S_IWUGO ), +}; +LSM_DIR_OPS (apparmor); +#endif +%s/dir_stuff/dir_entries/g
It doesn't have to be "entries", but "stuff" is horribly non-descriptive.Using "entries" is fine by me. I was modeling it entirely after the existing code (see "
attr_dir_stuff" below).Quoted 189 lines
Quoted 163 lines
fs/proc/base.c +13
-17static const struct pid_entry attr_dir_stuff[] = { -REG ("current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("prev" ,S_IRUGO , proc_pid_attr_operations), -REG ("exec" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("fscreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("keycreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("sockcreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("context" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +ATTR (NULL ,"current" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"prev" ,S_IRUGO ), +ATTR (NULL ,"exec" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"fscreate" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"keycreate" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"sockcreate" ,S_IRUGO |S_IWUGO ), +ATTR (NULL ,"context" ,S_IRUGO |S_IWUGO ), #ifdef CONFIG_SECURITY_SELINUX -REG ("selinux.current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("selinux.prev" ,S_IRUGO , proc_pid_attr_operations), -REG ("selinux.exec" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("selinux.fscreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("selinux.keycreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("selinux.sockcreate" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +DIR ("selinux" ,S_IRUGO |S_IXUGO , + proc_selinux_attr_dir_inode_ops, proc_selinux_attr_dir_ops), #endif #ifdef CONFIG_SECURITY_SMACK -REG ("smack.current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +DIR ("smack" ,S_IRUGO |S_IXUGO , + proc_smack_attr_dir_inode_ops, proc_smack_attr_dir_ops), #endif #ifdef CONFIG_SECURITY_APPARMOR -REG ("apparmor.current" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), -REG ("apparmor.prev" ,S_IRUGO , proc_pid_attr_operations), -REG ("apparmor.exec" ,S_IRUGO |S_IWUGO , proc_pid_attr_operations), +DIR ("apparmor" ,S_IRUGO |S_IXUGO , + proc_apparmor_attr_dir_inode_ops, proc_apparmor_attr_dir_ops), #endif };fs/proc/internal.h +1
-0@@ -56,6 +56,7 @@ union proc_op {int (*proc_show)(struct seq_file *m,struct pid_namespace *ns,struct pid *pid,struct task_struct *task); +const char *lsm; };struct proc_inode {include/linux/security.h +6
-5@@ -2115,9 +2115,10 @@ int security_sem_semctl(struct sem_array *sma, int cmd);int security_sem_semop (struct sem_array *sma,struct sembuf *sops,unsigned nsops,int alter);void security_d_instantiate (struct dentry *dentry,struct inode *inode); -int security_getprocattr (struct task_struct *p,char *name,char **value); -int security_setprocattr (struct task_struct *p,char *name,void *value, -size_t size); +int security_getprocattr (struct task_struct *p,const char *lsm,char *name, +char **value); +int security_setprocattr (struct task_struct *p,const char *lsm,char *name, +void *value,size_t size);int security_netlink_send (struct sock *sk,struct sk_buff *skb);int security_secid_to_secctx (struct secids *secid,char **secdata,u32 *seclen,struct security_operations **secops);@@ -2801,8 +2802,8 @@ static inline void security_d_instantiate(struct dentry *dentry, struct inode *inode) { } -static inline int security_getprocattr (struct task_struct *p,char *name, -char **value) +static inline int security_getprocattr (struct task_struct *p,char *lsm, +char *name,char **value) {return -EINVAL ; }security/security.c +21
-27@@ -1897,74 +1897,65 @@ void security_d_instantiate(struct dentry *dentry, struct inode *inode) }EXPORT_SYMBOL (security_d_instantiate); -int security_getprocattr (struct task_struct *p,char *name,char **value) +int security_getprocattr (struct task_struct *p,const char *lsm,char *name, +char **value) {struct security_operations *sop =NULL ;struct secids secid; -char *lsm; -int lsmlen;int ret;/* -* Names will either be in the legacy form containing -* no periods (".") or they will be the LSM name followed -* by the legacy suffix. "current" or "selinux.current" -* The exception is "context", which gets all of the LSMs. -* -* Legacy names are handled by the presenting LSM. -* Suffixed names are handled by the named LSM. +* Target LSM will be either NULL or looked up by name. Names with +* a NULL LSM (legacy) are handled by the presenting LSM. The +* exception is "context", which gets all of the LSMs. */ if (strcmp (name,"context" ) ==0 ) { +char *lsmname; +int lsmlen; +security_task_getsecid (p, &secid); - ret =security_secid_to_secctx (&secid, &lsm, &lsmlen, &sop); + ret =security_secid_to_secctx (&secid, &lsmname, &lsmlen, &sop);if (ret ==0 ) { - *value =kstrdup (lsm,GFP_KERNEL ); + *value =kstrdup (lsmname,GFP_KERNEL );if (*value ==NULL ) ret = -ENOMEM ;else ret =strlen (*value); -security_release_secctx (lsm, lsmlen, sop); +security_release_secctx (lsmname, lsmlen, sop); }return ret; } -if (present_ops && !strchr (name,'.' )) -return present_getprocattr (p, name, value); - -for_each_hook (sop, getprocattr) { - lsm = sop->name; - lsmlen =strlen (lsm); -if (!strncmp (name, lsm, lsmlen) && name[lsmlen] =='.' ) -return sop->getprocattr (p, name + lsmlen +1 , value); +if (!lsm) { +if (present_ops) +return present_getprocattr (p, name, value); + }else { +for_each_hook (sop, getprocattr) { +if (!strcmp (lsm, sop->name)) +return sop->getprocattr (p, name, value); + } }return -EINVAL ; } -int security_setprocattr (struct task_struct *p,char *name,void *value, -size_t size) +int security_setprocattr (struct task_struct *p,const char *lsm,char *name, +void *value,size_t size) {struct security_operations *sop; -char *lsm; -int lsmlen;/* -* Names will either be in the legacy form containing -* no periods (".") or they will be the LSM name followed security/security.c void security_d_instantiate(struct dentry *dentry, struct inode *inode) · line 1951
Quoted 10 lines
security/security.c +2
-5-* by the legacy suffix. -* "current" or "selinux.current" -* -* Legacy names are handled by the presenting LSM. -* Suffixed names are handled by the named LSM. +* Target LSM will be either NULL or looked up by name. Names with +* a NULL LSM (legacy) are handled by the presenting LSM. The */ if (present_ops && !strchr (name,'.' ))return present_setprocattr (p, name, value, size);We'll want to loose the preceding two lines, and add some later.
security/security.c void security_d_instantiate(struct dentry *dentry, struct inode *inode)
Quoted 13 lines
security/security.c +6
-7-for_each_hook (sop, setprocattr) { - lsm = sop->name; - lsmlen =strlen (lsm); -if (!strncmp (name, lsm, lsmlen) && name[lsmlen] =='.' ) -return sop->setprocattr (p, name + lsmlen +1 , value, - size); +if (lsm) { +for_each_hook (sop, setprocattr) { +if (!strcmp (lsm, sop->name)) +return sop->setprocattr (p, name, value, + size); + } - }Quoted 2 lines
+ } else if (
present_ops)
+ returnpresent_setprocattr(p, name, value, size);Ah yes, this is better. Great!
-Kees
Quoted 2 lines
Quoted 2 lines
security/security.c +0
-0return -EINVAL ; }
Quoted 16 lines · Casey Schaufler
Quoted 15 lines · Kees Cook
Quoted 14 lines · Casey Schaufler
Quoted 11 lines · Kees Cook
Quoted 4 lines · Casey Schaufler
The
/proc/*/attrinterfaces are given to one LSM. This can be done by settingCONFIG_SECURITY_PRESENT. Additional interfaces have been created in/proc/*/attrso that each LSM has its own named interfaces. The name of the presenting LSM can be read fromFor me, this is one problem that was bothering me, but it was a cosmetic one that I'd mentioned before: I really disliked the
/proc/$pid/attrinterface being named "$lsm.$file". I feel it's important to build directories in attr/ for each LSM. So, I spent time to figure out a way to do this. This patch changes the interface to/proc/$pid/attr/$lsm/$fileinstead, which I feel has a much more appealing organizational structure.I will confess that the reason I went with <lsm>.current instead of <lsm>/current was that the former was easier to implement.
Quoted 7 lines
Quoted 3 lines
Yeah, that's totally fine. It wasn't very obvious (to me) how to implement this initially, so no problem at all. I'm glad there was something more than bug fixes I could contribute to this series. :)
Oh dear. I'm rebasing for 3.12 and the macros don't generate compiling code any longer. It seems that, among other things, readdir is no longer a member of
file_operations.
Agh. I will take a look.
-Kees
Signature · 2 lines
Kees Cook Chrome OS Security
Quoted 16 lines · Casey Schaufler
Quoted 15 lines · Kees Cook
Quoted 14 lines · Casey Schaufler
Quoted 11 lines · Kees Cook
Quoted 4 lines · Casey Schaufler
The
/proc/*/attrinterfaces are given to one LSM. This can be done by settingCONFIG_SECURITY_PRESENT. Additional interfaces have been created in/proc/*/attrso that each LSM has its own named interfaces. The name of the presenting LSM can be read fromFor me, this is one problem that was bothering me, but it was a cosmetic one that I'd mentioned before: I really disliked the
/proc/$pid/attrinterface being named "$lsm.$file". I feel it's important to build directories in attr/ for each LSM. So, I spent time to figure out a way to do this. This patch changes the interface to/proc/$pid/attr/$lsm/$fileinstead, which I feel has a much more appealing organizational structure.I will confess that the reason I went with <lsm>.current instead of <lsm>/current was that the former was easier to implement.
Quoted 7 lines
Quoted 3 lines
Yeah, that's totally fine. It wasn't very obvious (to me) how to implement this initially, so no problem at all. I'm glad there was something more than bug fixes I could contribute to this series. :)
Oh dear. I'm rebasing for 3.12 and the macros don't generate compiling code any longer. It seems that, among other things, readdir is no longer a member of
file_operations.
Looks like f0c3b5093addc8bfe9fe3a5b01acb7ec7969eafa is what touched fs/proc/base.c and it should just need a few tweaks from "readdir" becoming "iterate", and the prototype changing.
So it should just require bump the macros a little. Let's see if gmail eats my paste...
fs/proc/base.c +4 -4
@@ -2358,17 +2358,17 @@ static const struct file_operations proc_pid_attr_operat };#define LSM_DIR_OPS (LSM ) \ -static int proc_##LSM##_attr_dir_readdir(struct file * filp, \ - void * dirent, filldir_t filldir) \ +static int proc_##LSM##_attr_dir_iterate(struct file * filp, \ + struct dir_context *ctx) \ { \ - return proc_pident_readdir(filp, dirent, filldir, \ + return proc_pident_readdir(filp, ctx, \ LSM##_attr_dir_stuff, \ ARRAY_SIZE(LSM##_attr_dir_stuff)); \ } \ \ static const struct file_operations proc_##LSM##_attr_dir_ops = { \ .read = generic_read_dir, \ - .readdir = proc_##LSM##_attr_dir_readdir, \ + .iterate = proc_##LSM##_attr_dir_iterate, \ .llseek = default_llseek, \ }; \ \
Do you have the rest of the series already ported to 3.12?
-Kees
Signature · 2 lines
Kees Cook Chrome OS Security
Casey Schaufler
maintainerQuoted 58 lines · Kees Cook
Quoted 14 lines · Casey Schaufler
Quoted 13 lines · Kees Cook
Quoted 12 lines · Casey Schaufler
Quoted 11 lines · Kees Cook
Quoted 4 lines · Casey Schaufler
The
/proc/*/attrinterfaces are given to one LSM. This can be done by settingCONFIG_SECURITY_PRESENT. Additional interfaces have been created in/proc/*/attrso that each LSM has its own named interfaces. The name of the presenting LSM can be read fromFor me, this is one problem that was bothering me, but it was a cosmetic one that I'd mentioned before: I really disliked the
/proc/$pid/attrinterface being named "$lsm.$file". I feel it's important to build directories in attr/ for each LSM. So, I spent time to figure out a way to do this. This patch changes the interface to/proc/$pid/attr/$lsm/$fileinstead, which I feel has a much more appealing organizational structure.Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
I will confess that the reason I went with <lsm>.current instead of <lsm>/current was that the former was easier to implement.
Yeah, that's totally fine. It wasn't very obvious (to me) how to implement this initially, so no problem at all. I'm glad there was something more than bug fixes I could contribute to this series. :)
Oh dear. I'm rebasing for 3.12 and the macros don't generate compiling code any longer. It seems that, among other things, readdir is no longer a member of
file_operations.Looks like
f0c3b5093addc8bfe9fe3a5b01acb7ec7969eafais what touchedfs/proc/base.cand it should just need a few tweaks from "readdir" becoming "iterate", and the prototype changing.So it should just require bump the macros a little. Let's see if gmail eats my paste...
fs/proc/base.c +4
-4@@ -2358,17 +2358,17 @@ static const struct file_operations proc_pid_attr_operat };#define LSM_DIR_OPS (LSM ) \ -static int proc_##LSM##_attr_dir_readdir(struct file * filp, \ - void * dirent, filldir_t filldir) \ +static int proc_##LSM##_attr_dir_iterate(struct file * filp, \ + struct dir_context *ctx) \ { \ - return proc_pident_readdir(filp, dirent, filldir, \ + return proc_pident_readdir(filp, ctx, \ LSM##_attr_dir_stuff, \ ARRAY_SIZE(LSM##_attr_dir_stuff)); \ } \ \ static const struct file_operations proc_##LSM##_attr_dir_ops = { \ .read = generic_read_dir, \ - .readdir = proc_##LSM##_attr_dir_readdir, \ + .iterate = proc_##LSM##_attr_dir_iterate, \ .llseek = default_llseek, \ }; \ \
Quoted 4 lines
Do you have the rest of the series already ported to 3.12?
-Kees
Yes, but I did it last week before my holiday started, and have not updated since. I will become active again upon my return. I hope to have the 3.12 version posted before the Security Summit.
--
This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to [email protected] with the words "unsubscribe selinux" without quotes as the message.