diff options
Diffstat (limited to 'security/smack/smack_lsm.c')
-rw-r--r-- | security/smack/smack_lsm.c | 143 |
1 files changed, 110 insertions, 33 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 2b5d6f72f67..93f5b0ce662 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -189,17 +189,10 @@ static void smack_sb_free_security(struct super_block *sb) * Copy the Smack specific mount options out of the mount * options list. */ -static int smack_sb_copy_data(struct file_system_type *type, void *orig, - void *smackopts) +static int smack_sb_copy_data(char *orig, char *smackopts) { char *cp, *commap, *otheropts, *dp; - /* Binary mount data: just copy */ - if (type->fs_flags & FS_BINARY_MOUNTDATA) { - copy_page(smackopts, orig); - return 0; - } - otheropts = (char *)get_zeroed_page(GFP_KERNEL); if (otheropts == NULL) return -ENOMEM; @@ -584,14 +577,20 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) static int smack_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags) { - if (!capable(CAP_MAC_ADMIN)) { - if (strcmp(name, XATTR_NAME_SMACK) == 0 || - strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || - strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) - return -EPERM; - } + int rc = 0; - return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); + if (strcmp(name, XATTR_NAME_SMACK) == 0 || + strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || + strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { + if (!capable(CAP_MAC_ADMIN)) + rc = -EPERM; + } else + rc = cap_inode_setxattr(dentry, name, value, size, flags); + + if (rc == 0) + rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); + + return rc; } /** @@ -658,10 +657,20 @@ static int smack_inode_getxattr(struct dentry *dentry, char *name) */ static int smack_inode_removexattr(struct dentry *dentry, char *name) { - if (strcmp(name, XATTR_NAME_SMACK) == 0 && !capable(CAP_MAC_ADMIN)) - return -EPERM; + int rc = 0; - return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); + if (strcmp(name, XATTR_NAME_SMACK) == 0 || + strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || + strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { + if (!capable(CAP_MAC_ADMIN)) + rc = -EPERM; + } else + rc = cap_inode_removexattr(dentry, name); + + if (rc == 0) + rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); + + return rc; } /** @@ -1016,7 +1025,12 @@ static void smack_task_getsecid(struct task_struct *p, u32 *secid) */ static int smack_task_setnice(struct task_struct *p, int nice) { - return smk_curacc(p->security, MAY_WRITE); + int rc; + + rc = cap_task_setnice(p, nice); + if (rc == 0) + rc = smk_curacc(p->security, MAY_WRITE); + return rc; } /** @@ -1028,7 +1042,12 @@ static int smack_task_setnice(struct task_struct *p, int nice) */ static int smack_task_setioprio(struct task_struct *p, int ioprio) { - return smk_curacc(p->security, MAY_WRITE); + int rc; + + rc = cap_task_setioprio(p, ioprio); + if (rc == 0) + rc = smk_curacc(p->security, MAY_WRITE); + return rc; } /** @@ -1053,7 +1072,12 @@ static int smack_task_getioprio(struct task_struct *p) static int smack_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp) { - return smk_curacc(p->security, MAY_WRITE); + int rc; + + rc = cap_task_setscheduler(p, policy, lp); + if (rc == 0) + rc = smk_curacc(p->security, MAY_WRITE); + return rc; } /** @@ -1251,9 +1275,8 @@ static void smack_to_secattr(char *smack, struct netlbl_lsm_secattr *nlsp) switch (smack_net_nltype) { case NETLBL_NLTYPE_CIPSOV4: - nlsp->domain = NULL; - nlsp->flags = NETLBL_SECATTR_DOMAIN; - nlsp->flags |= NETLBL_SECATTR_MLS_LVL; + nlsp->domain = smack; + nlsp->flags = NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL; rc = smack_to_cipso(smack, &cipso); if (rc == 0) { @@ -1282,15 +1305,14 @@ static int smack_netlabel(struct sock *sk) { struct socket_smack *ssp; struct netlbl_lsm_secattr secattr; - int rc = 0; + int rc; ssp = sk->sk_security; netlbl_secattr_init(&secattr); smack_to_secattr(ssp->smk_out, &secattr); - if (secattr.flags != NETLBL_SECATTR_NONE) - rc = netlbl_sock_setattr(sk, &secattr); - + rc = netlbl_sock_setattr(sk, &secattr); netlbl_secattr_destroy(&secattr); + return rc; } @@ -1313,6 +1335,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, struct inode_smack *nsp = inode->i_security; struct socket_smack *ssp; struct socket *sock; + int rc = 0; if (value == NULL || size > SMK_LABELLEN) return -EACCES; @@ -1341,7 +1364,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, ssp->smk_in = sp; else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) { ssp->smk_out = sp; - return smack_netlabel(sock->sk); + rc = smack_netlabel(sock->sk); + if (rc != 0) + printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", + __func__, -rc); } else return -EOPNOTSUPP; @@ -1477,7 +1503,7 @@ static int smack_shm_associate(struct shmid_kernel *shp, int shmflg) */ static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd) { - char *ssp = smack_of_shm(shp); + char *ssp; int may; switch (cmd) { @@ -1501,6 +1527,7 @@ static int smack_shm_shmctl(struct shmid_kernel *shp, int cmd) return -EINVAL; } + ssp = smack_of_shm(shp); return smk_curacc(ssp, may); } @@ -1585,7 +1612,7 @@ static int smack_sem_associate(struct sem_array *sma, int semflg) */ static int smack_sem_semctl(struct sem_array *sma, int cmd) { - char *ssp = smack_of_sem(sma); + char *ssp; int may; switch (cmd) { @@ -1614,6 +1641,7 @@ static int smack_sem_semctl(struct sem_array *sma, int cmd) return -EINVAL; } + ssp = smack_of_sem(sma); return smk_curacc(ssp, may); } @@ -1699,7 +1727,7 @@ static int smack_msg_queue_associate(struct msg_queue *msq, int msqflg) */ static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd) { - char *msp = smack_of_msq(msq); + char *msp; int may; switch (cmd) { @@ -1721,6 +1749,7 @@ static int smack_msg_queue_msgctl(struct msg_queue *msq, int cmd) return -EINVAL; } + msp = smack_of_msq(msq); return smk_curacc(msp, may); } @@ -1776,6 +1805,27 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) return smk_curacc(isp, may); } +/* module stacking operations */ + +/** + * smack_register_security - stack capability module + * @name: module name + * @ops: module operations - ignored + * + * Allow the capability module to register. + */ +static int smack_register_security(const char *name, + struct security_operations *ops) +{ + if (strcmp(name, "capability") != 0) + return -EINVAL; + + printk(KERN_INFO "%s: Registering secondary module %s\n", + __func__, name); + + return 0; +} + /** * smack_d_instantiate - Make sure the blob is correct on an inode * @opt_dentry: unused @@ -2214,6 +2264,9 @@ static void smack_sock_graft(struct sock *sk, struct socket *parent) ssp->smk_packet[0] = '\0'; rc = smack_netlabel(sk); + if (rc != 0) + printk(KERN_WARNING "Smack: \"%s\" netlbl error %d.\n", + __func__, -rc); } /** @@ -2346,6 +2399,20 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) } /* + * smack_secctx_to_secid - return the secid for a smack label + * @secdata: smack label + * @seclen: how long result is + * @secid: outgoing integer + * + * Exists for audit and networking code. + */ +static int smack_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) +{ + *secid = smack_to_secid(secdata); + return 0; +} + +/* * smack_release_secctx - don't do anything. * @key_ref: unused * @context: unused @@ -2357,7 +2424,9 @@ static void smack_release_secctx(char *secdata, u32 seclen) { } -static struct security_operations smack_ops = { +struct security_operations smack_ops = { + .name = "smack", + .ptrace = smack_ptrace, .capget = cap_capget, .capset_check = cap_capset_check, @@ -2393,6 +2462,8 @@ static struct security_operations smack_ops = { .inode_post_setxattr = smack_inode_post_setxattr, .inode_getxattr = smack_inode_getxattr, .inode_removexattr = smack_inode_removexattr, + .inode_need_killpriv = cap_inode_need_killpriv, + .inode_killpriv = cap_inode_killpriv, .inode_getsecurity = smack_inode_getsecurity, .inode_setsecurity = smack_inode_setsecurity, .inode_listsecurity = smack_inode_listsecurity, @@ -2452,6 +2523,8 @@ static struct security_operations smack_ops = { .netlink_send = cap_netlink_send, .netlink_recv = cap_netlink_recv, + .register_security = smack_register_security, + .d_instantiate = smack_d_instantiate, .getprocattr = smack_getprocattr, @@ -2475,6 +2548,7 @@ static struct security_operations smack_ops = { .key_permission = smack_key_permission, #endif /* CONFIG_KEYS */ .secid_to_secctx = smack_secid_to_secctx, + .secctx_to_secid = smack_secctx_to_secid, .release_secctx = smack_release_secctx, }; @@ -2485,6 +2559,9 @@ static struct security_operations smack_ops = { */ static __init int smack_init(void) { + if (!security_module_enable(&smack_ops)) + return 0; + printk(KERN_INFO "Smack: Initializing.\n"); /* |