Loading security/smack/Kconfig +12 −0 Original line number Original line Diff line number Diff line Loading @@ -28,3 +28,15 @@ config SECURITY_SMACK_BRINGUP access rule set once the behavior is well understood. access rule set once the behavior is well understood. This is a superior mechanism to the oft abused This is a superior mechanism to the oft abused "permissive" mode of other systems. "permissive" mode of other systems. If you are unsure how to answer this question, answer N. config SECURITY_SMACK_NETFILTER bool "Packet marking using secmarks for netfilter" depends on SECURITY_SMACK depends on NETWORK_SECMARK depends on NETFILTER default n help This enables security marking of network packets using Smack labels. If you are unsure how to answer this question, answer N. security/smack/Makefile +1 −0 Original line number Original line Diff line number Diff line Loading @@ -5,3 +5,4 @@ obj-$(CONFIG_SECURITY_SMACK) := smack.o obj-$(CONFIG_SECURITY_SMACK) := smack.o smack-y := smack_lsm.o smack_access.o smackfs.o smack-y := smack_lsm.o smack_access.o smackfs.o smack-$(CONFIG_NETFILTER) += smack_netfilter.o security/smack/smack.h +11 −0 Original line number Original line Diff line number Diff line Loading @@ -248,6 +248,7 @@ struct smack_known *smk_find_entry(const char *); /* /* * Shared data. * Shared data. */ */ extern int smack_enabled; extern int smack_cipso_direct; extern int smack_cipso_direct; extern int smack_cipso_mapped; extern int smack_cipso_mapped; extern struct smack_known *smack_net_ambient; extern struct smack_known *smack_net_ambient; Loading Loading @@ -298,6 +299,16 @@ static inline struct smack_known *smk_of_task(const struct task_smack *tsp) return tsp->smk_task; return tsp->smk_task; } } static inline struct smack_known *smk_of_task_struct(const struct task_struct *t) { struct smack_known *skp; rcu_read_lock(); skp = smk_of_task(__task_cred(t)->security); rcu_read_unlock(); return skp; } /* /* * Present a pointer to the forked smack label entry in an task blob. * Present a pointer to the forked smack label entry in an task blob. */ */ Loading security/smack/smack_lsm.c +147 −52 Original line number Original line Diff line number Diff line Loading @@ -43,8 +43,6 @@ #include <linux/binfmts.h> #include <linux/binfmts.h> #include "smack.h" #include "smack.h" #define task_security(task) (task_cred_xxx((task), security)) #define TRANS_TRUE "TRUE" #define TRANS_TRUE "TRUE" #define TRANS_TRUE_SIZE 4 #define TRANS_TRUE_SIZE 4 Loading @@ -52,8 +50,11 @@ #define SMK_RECEIVING 1 #define SMK_RECEIVING 1 #define SMK_SENDING 2 #define SMK_SENDING 2 #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) LIST_HEAD(smk_ipv6_port_list); LIST_HEAD(smk_ipv6_port_list); #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ static struct kmem_cache *smack_inode_cache; static struct kmem_cache *smack_inode_cache; int smack_enabled; #ifdef CONFIG_SECURITY_SMACK_BRINGUP #ifdef CONFIG_SECURITY_SMACK_BRINGUP static void smk_bu_mode(int mode, char *s) static void smk_bu_mode(int mode, char *s) Loading Loading @@ -120,7 +121,7 @@ static int smk_bu_current(char *note, struct smack_known *oskp, static int smk_bu_task(struct task_struct *otp, int mode, int rc) static int smk_bu_task(struct task_struct *otp, int mode, int rc) { { struct task_smack *tsp = current_security(); struct task_smack *tsp = current_security(); struct task_smack *otsp = task_security(otp); struct smack_known *smk_task = smk_of_task_struct(otp); char acc[SMK_NUM_ACCESS_TYPE + 1]; char acc[SMK_NUM_ACCESS_TYPE + 1]; if (rc <= 0) if (rc <= 0) Loading @@ -128,7 +129,7 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc) smk_bu_mode(mode, acc); smk_bu_mode(mode, acc); pr_info("Smack Bringup: (%s %s %s) %s to %s\n", pr_info("Smack Bringup: (%s %s %s) %s to %s\n", tsp->smk_task->smk_known, otsp->smk_task->smk_known, acc, tsp->smk_task->smk_known, smk_task->smk_known, acc, current->comm, otp->comm); current->comm, otp->comm); return 0; return 0; } } Loading Loading @@ -160,7 +161,7 @@ static int smk_bu_file(struct file *file, int mode, int rc) { { struct task_smack *tsp = current_security(); struct task_smack *tsp = current_security(); struct smack_known *sskp = tsp->smk_task; struct smack_known *sskp = tsp->smk_task; struct inode *inode = file->f_inode; struct inode *inode = file_inode(file); char acc[SMK_NUM_ACCESS_TYPE + 1]; char acc[SMK_NUM_ACCESS_TYPE + 1]; if (rc <= 0) if (rc <= 0) Loading @@ -168,7 +169,7 @@ static int smk_bu_file(struct file *file, int mode, int rc) smk_bu_mode(mode, acc); smk_bu_mode(mode, acc); pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n", pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n", sskp->smk_known, (char *)file->f_security, acc, sskp->smk_known, smk_of_inode(inode)->smk_known, acc, inode->i_sb->s_id, inode->i_ino, file, inode->i_sb->s_id, inode->i_ino, file, current->comm); current->comm); return 0; return 0; Loading Loading @@ -202,6 +203,7 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file, /** /** * smk_fetch - Fetch the smack label from a file. * smk_fetch - Fetch the smack label from a file. * @name: type of the label (attribute) * @ip: a pointer to the inode * @ip: a pointer to the inode * @dp: a pointer to the dentry * @dp: a pointer to the dentry * * Loading Loading @@ -254,7 +256,9 @@ struct inode_smack *new_inode_smack(struct smack_known *skp) /** /** * new_task_smack - allocate a task security blob * new_task_smack - allocate a task security blob * @smack: a pointer to the Smack label to use in the blob * @task: a pointer to the Smack label for the running task * @forked: a pointer to the Smack label for the forked task * @gfp: type of the memory for the allocation * * * Returns the new blob or NULL if there's no memory available * Returns the new blob or NULL if there's no memory available */ */ Loading @@ -277,8 +281,9 @@ static struct task_smack *new_task_smack(struct smack_known *task, /** /** * smk_copy_rules - copy a rule set * smk_copy_rules - copy a rule set * @nhead - new rules header pointer * @nhead: new rules header pointer * @ohead - old rules header pointer * @ohead: old rules header pointer * @gfp: type of the memory for the allocation * * * Returns 0 on success, -ENOMEM on error * Returns 0 on success, -ENOMEM on error */ */ Loading Loading @@ -345,7 +350,8 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, saip = &ad; saip = &ad; } } tsp = task_security(tracer); rcu_read_lock(); tsp = __task_cred(tracer)->security; tracer_known = smk_of_task(tsp); tracer_known = smk_of_task(tsp); if ((mode & PTRACE_MODE_ATTACH) && if ((mode & PTRACE_MODE_ATTACH) && Loading @@ -365,11 +371,14 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, tracee_known->smk_known, tracee_known->smk_known, 0, rc, saip); 0, rc, saip); rcu_read_unlock(); return rc; return rc; } } /* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */ /* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */ rc = smk_tskacc(tsp, tracee_known, smk_ptrace_mode(mode), saip); rc = smk_tskacc(tsp, tracee_known, smk_ptrace_mode(mode), saip); rcu_read_unlock(); return rc; return rc; } } Loading @@ -396,7 +405,7 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) if (rc != 0) if (rc != 0) return rc; return rc; skp = smk_of_task(task_security(ctp)); skp = smk_of_task_struct(ctp); rc = smk_ptrace_rule_check(current, skp, mode, __func__); rc = smk_ptrace_rule_check(current, skp, mode, __func__); return rc; return rc; Loading Loading @@ -796,7 +805,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, if (name) if (name) *name = XATTR_SMACK_SUFFIX; *name = XATTR_SMACK_SUFFIX; if (value) { if (value && len) { rcu_read_lock(); rcu_read_lock(); may = smk_access_entry(skp->smk_known, dsp->smk_known, may = smk_access_entry(skp->smk_known, dsp->smk_known, &skp->smk_rules); &skp->smk_rules); Loading @@ -817,10 +826,9 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, *value = kstrdup(isp->smk_known, GFP_NOFS); *value = kstrdup(isp->smk_known, GFP_NOFS); if (*value == NULL) if (*value == NULL) return -ENOMEM; return -ENOMEM; } if (len) *len = strlen(isp->smk_known); *len = strlen(isp->smk_known); } return 0; return 0; } } Loading Loading @@ -1344,6 +1352,9 @@ static int smack_file_permission(struct file *file, int mask) * The security blob for a file is a pointer to the master * The security blob for a file is a pointer to the master * label list, so no allocation is done. * label list, so no allocation is done. * * * f_security is the owner security information. It * isn't used on file access checks, it's for send_sigio. * * Returns 0 * Returns 0 */ */ static int smack_file_alloc_security(struct file *file) static int smack_file_alloc_security(struct file *file) Loading Loading @@ -1381,17 +1392,18 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd, { { int rc = 0; int rc = 0; struct smk_audit_info ad; struct smk_audit_info ad; struct inode *inode = file_inode(file); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); smk_ad_setfield_u_fs_path(&ad, file->f_path); if (_IOC_DIR(cmd) & _IOC_WRITE) { if (_IOC_DIR(cmd) & _IOC_WRITE) { rc = smk_curacc(file->f_security, MAY_WRITE, &ad); rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad); rc = smk_bu_file(file, MAY_WRITE, rc); rc = smk_bu_file(file, MAY_WRITE, rc); } } if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) { if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) { rc = smk_curacc(file->f_security, MAY_READ, &ad); rc = smk_curacc(smk_of_inode(inode), MAY_READ, &ad); rc = smk_bu_file(file, MAY_READ, rc); rc = smk_bu_file(file, MAY_READ, rc); } } Loading @@ -1409,10 +1421,11 @@ static int smack_file_lock(struct file *file, unsigned int cmd) { { struct smk_audit_info ad; struct smk_audit_info ad; int rc; int rc; struct inode *inode = file_inode(file); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); smk_ad_setfield_u_fs_path(&ad, file->f_path); rc = smk_curacc(file->f_security, MAY_LOCK, &ad); rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad); rc = smk_bu_file(file, MAY_LOCK, rc); rc = smk_bu_file(file, MAY_LOCK, rc); return rc; return rc; } } Loading @@ -1434,7 +1447,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, { { struct smk_audit_info ad; struct smk_audit_info ad; int rc = 0; int rc = 0; struct inode *inode = file_inode(file); switch (cmd) { switch (cmd) { case F_GETLK: case F_GETLK: Loading @@ -1443,14 +1456,14 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, case F_SETLKW: case F_SETLKW: smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); smk_ad_setfield_u_fs_path(&ad, file->f_path); rc = smk_curacc(file->f_security, MAY_LOCK, &ad); rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad); rc = smk_bu_file(file, MAY_LOCK, rc); rc = smk_bu_file(file, MAY_LOCK, rc); break; break; case F_SETOWN: case F_SETOWN: case F_SETSIG: case F_SETSIG: smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); smk_ad_setfield_u_fs_path(&ad, file->f_path); rc = smk_curacc(file->f_security, MAY_WRITE, &ad); rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad); rc = smk_bu_file(file, MAY_WRITE, rc); rc = smk_bu_file(file, MAY_WRITE, rc); break; break; default: default: Loading Loading @@ -1568,14 +1581,10 @@ static int smack_mmap_file(struct file *file, * smack_file_set_fowner - set the file security blob value * smack_file_set_fowner - set the file security blob value * @file: object in question * @file: object in question * * * Returns 0 * Further research may be required on this one. */ */ static void smack_file_set_fowner(struct file *file) static void smack_file_set_fowner(struct file *file) { { struct smack_known *skp = smk_of_current(); file->f_security = smk_of_current(); file->f_security = skp; } } /** /** Loading Loading @@ -1627,6 +1636,7 @@ static int smack_file_receive(struct file *file) int rc; int rc; int may = 0; int may = 0; struct smk_audit_info ad; struct smk_audit_info ad; struct inode *inode = file_inode(file); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); smk_ad_setfield_u_fs_path(&ad, file->f_path); Loading @@ -1638,7 +1648,7 @@ static int smack_file_receive(struct file *file) if (file->f_mode & FMODE_WRITE) if (file->f_mode & FMODE_WRITE) may |= MAY_WRITE; may |= MAY_WRITE; rc = smk_curacc(file->f_security, may, &ad); rc = smk_curacc(smk_of_inode(inode), may, &ad); rc = smk_bu_file(file, may, rc); rc = smk_bu_file(file, may, rc); return rc; return rc; } } Loading @@ -1658,21 +1668,17 @@ static int smack_file_receive(struct file *file) static int smack_file_open(struct file *file, const struct cred *cred) static int smack_file_open(struct file *file, const struct cred *cred) { { struct task_smack *tsp = cred->security; struct task_smack *tsp = cred->security; struct inode_smack *isp = file_inode(file)->i_security; struct inode *inode = file_inode(file); struct smk_audit_info ad; struct smk_audit_info ad; int rc; int rc; if (smack_privileged(CAP_MAC_OVERRIDE)) { if (smack_privileged(CAP_MAC_OVERRIDE)) file->f_security = isp->smk_inode; return 0; return 0; } smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); smk_ad_setfield_u_fs_path(&ad, file->f_path); rc = smk_access(tsp->smk_task, isp->smk_inode, MAY_READ, &ad); rc = smk_access(tsp->smk_task, smk_of_inode(inode), MAY_READ, &ad); rc = smk_bu_credfile(cred, file, MAY_READ, rc); rc = smk_bu_credfile(cred, file, MAY_READ, rc); if (rc == 0) file->f_security = isp->smk_inode; return rc; return rc; } } Loading Loading @@ -1826,7 +1832,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access, const char *caller) const char *caller) { { struct smk_audit_info ad; struct smk_audit_info ad; struct smack_known *skp = smk_of_task(task_security(p)); struct smack_known *skp = smk_of_task_struct(p); int rc; int rc; smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK); smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK); Loading Loading @@ -1879,7 +1885,7 @@ static int smack_task_getsid(struct task_struct *p) */ */ static void smack_task_getsecid(struct task_struct *p, u32 *secid) static void smack_task_getsecid(struct task_struct *p, u32 *secid) { { struct smack_known *skp = smk_of_task(task_security(p)); struct smack_known *skp = smk_of_task_struct(p); *secid = skp->smk_secid; *secid = skp->smk_secid; } } Loading Loading @@ -1986,7 +1992,7 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, { { struct smk_audit_info ad; struct smk_audit_info ad; struct smack_known *skp; struct smack_known *skp; struct smack_known *tkp = smk_of_task(task_security(p)); struct smack_known *tkp = smk_of_task_struct(p); int rc; int rc; smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); Loading Loading @@ -2040,7 +2046,7 @@ static int smack_task_wait(struct task_struct *p) static void smack_task_to_inode(struct task_struct *p, struct inode *inode) static void smack_task_to_inode(struct task_struct *p, struct inode *inode) { { struct inode_smack *isp = inode->i_security; struct inode_smack *isp = inode->i_security; struct smack_known *skp = smk_of_task(task_security(p)); struct smack_known *skp = smk_of_task_struct(p); isp->smk_inode = skp; isp->smk_inode = skp; } } Loading Loading @@ -2212,6 +2218,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) return smack_netlabel(sk, sk_lbl); return smack_netlabel(sk, sk_lbl); } } #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) /** /** * smk_ipv6_port_label - Smack port access table management * smk_ipv6_port_label - Smack port access table management * @sock: socket * @sock: socket Loading Loading @@ -2361,6 +2368,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, rc = smk_bu_note("IPv6 port check", skp, object, MAY_WRITE, rc); rc = smk_bu_note("IPv6 port check", skp, object, MAY_WRITE, rc); return rc; return rc; } } #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ /** /** * smack_inode_setsecurity - set smack xattrs * smack_inode_setsecurity - set smack xattrs Loading Loading @@ -2421,8 +2429,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, } else } else return -EOPNOTSUPP; return -EOPNOTSUPP; #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) if (sock->sk->sk_family == PF_INET6) if (sock->sk->sk_family == PF_INET6) smk_ipv6_port_label(sock, NULL); smk_ipv6_port_label(sock, NULL); #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ return 0; return 0; } } Loading Loading @@ -2450,6 +2460,7 @@ static int smack_socket_post_create(struct socket *sock, int family, return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); } } #ifndef CONFIG_SECURITY_SMACK_NETFILTER /** /** * smack_socket_bind - record port binding information. * smack_socket_bind - record port binding information. * @sock: the socket * @sock: the socket Loading @@ -2463,11 +2474,14 @@ static int smack_socket_post_create(struct socket *sock, int family, static int smack_socket_bind(struct socket *sock, struct sockaddr *address, static int smack_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) int addrlen) { { #if IS_ENABLED(CONFIG_IPV6) if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) smk_ipv6_port_label(sock, address); smk_ipv6_port_label(sock, address); #endif return 0; return 0; } } #endif /* !CONFIG_SECURITY_SMACK_NETFILTER */ /** /** * smack_socket_connect - connect access check * smack_socket_connect - connect access check Loading Loading @@ -2496,8 +2510,10 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, case PF_INET6: case PF_INET6: if (addrlen < sizeof(struct sockaddr_in6)) if (addrlen < sizeof(struct sockaddr_in6)) return -EINVAL; return -EINVAL; #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap, rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap, SMK_CONNECTING); SMK_CONNECTING); #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ break; break; } } return rc; return rc; Loading Loading @@ -3033,7 +3049,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) * of the superblock. * of the superblock. */ */ if (opt_dentry->d_parent == opt_dentry) { if (opt_dentry->d_parent == opt_dentry) { if (sbp->s_magic == CGROUP_SUPER_MAGIC) { switch (sbp->s_magic) { case CGROUP_SUPER_MAGIC: /* /* * The cgroup filesystem is never mounted, * The cgroup filesystem is never mounted, * so there's no opportunity to set the mount * so there's no opportunity to set the mount Loading @@ -3041,8 +3058,19 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) */ */ sbsp->smk_root = &smack_known_star; sbsp->smk_root = &smack_known_star; sbsp->smk_default = &smack_known_star; sbsp->smk_default = &smack_known_star; } isp->smk_inode = sbsp->smk_root; isp->smk_inode = sbsp->smk_root; break; case TMPFS_MAGIC: /* * What about shmem/tmpfs anonymous files with dentry * obtained from d_alloc_pseudo()? */ isp->smk_inode = smk_of_current(); break; default: isp->smk_inode = sbsp->smk_root; break; } isp->smk_flags |= SMK_INODE_INSTANT; isp->smk_flags |= SMK_INODE_INSTANT; goto unlockandout; goto unlockandout; } } Loading Loading @@ -3200,7 +3228,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) */ */ static int smack_getprocattr(struct task_struct *p, char *name, char **value) static int smack_getprocattr(struct task_struct *p, char *name, char **value) { { struct smack_known *skp = smk_of_task(task_security(p)); struct smack_known *skp = smk_of_task_struct(p); char *cp; char *cp; int slen; int slen; Loading Loading @@ -3297,7 +3325,7 @@ static int smack_unix_stream_connect(struct sock *sock, if (!smack_privileged(CAP_MAC_OVERRIDE)) { if (!smack_privileged(CAP_MAC_OVERRIDE)) { skp = ssp->smk_out; skp = ssp->smk_out; okp = osp->smk_out; okp = osp->smk_in; #ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); smk_ad_setfield_u_net_sk(&ad, other); smk_ad_setfield_u_net_sk(&ad, other); Loading @@ -3305,7 +3333,9 @@ static int smack_unix_stream_connect(struct sock *sock, rc = smk_access(skp, okp, MAY_WRITE, &ad); rc = smk_access(skp, okp, MAY_WRITE, &ad); rc = smk_bu_note("UDS connect", skp, okp, MAY_WRITE, rc); rc = smk_bu_note("UDS connect", skp, okp, MAY_WRITE, rc); if (rc == 0) { if (rc == 0) { rc = smk_access(okp, skp, MAY_WRITE, NULL); okp = osp->smk_out; skp = ssp->smk_in; rc = smk_access(okp, skp, MAY_WRITE, &ad); rc = smk_bu_note("UDS connect", okp, skp, rc = smk_bu_note("UDS connect", okp, skp, MAY_WRITE, rc); MAY_WRITE, rc); } } Loading Loading @@ -3366,7 +3396,9 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size) int size) { { struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ int rc = 0; int rc = 0; /* /* Loading @@ -3380,7 +3412,9 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, rc = smack_netlabel_send(sock->sk, sip); rc = smack_netlabel_send(sock->sk, sip); break; break; case AF_INET6: case AF_INET6: #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING); rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING); #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ break; break; } } return rc; return rc; Loading Loading @@ -3471,6 +3505,7 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, return smack_net_ambient; return smack_net_ambient; } } #if IS_ENABLED(CONFIG_IPV6) static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) { { u8 nexthdr; u8 nexthdr; Loading Loading @@ -3517,6 +3552,7 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) } } return proto; return proto; } } #endif /* CONFIG_IPV6 */ /** /** * smack_socket_sock_rcv_skb - Smack packet delivery access check * smack_socket_sock_rcv_skb - Smack packet delivery access check Loading @@ -3529,15 +3565,30 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) { { struct netlbl_lsm_secattr secattr; struct netlbl_lsm_secattr secattr; struct socket_smack *ssp = sk->sk_security; struct socket_smack *ssp = sk->sk_security; struct smack_known *skp; struct smack_known *skp = NULL; struct sockaddr_in6 sadd; int rc = 0; int rc = 0; struct smk_audit_info ad; struct smk_audit_info ad; #ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT struct lsm_network_audit net; struct lsm_network_audit net; #endif #endif #if IS_ENABLED(CONFIG_IPV6) struct sockaddr_in6 sadd; int proto; #endif /* CONFIG_IPV6 */ switch (sk->sk_family) { switch (sk->sk_family) { case PF_INET: case PF_INET: #ifdef CONFIG_SECURITY_SMACK_NETFILTER /* * If there is a secmark use it rather than the CIPSO label. * If there is no secmark fall back to CIPSO. * The secmark is assumed to reflect policy better. */ if (skb && skb->secmark != 0) { skp = smack_from_secid(skb->secmark); goto access_check; } #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ /* /* * Translate what netlabel gave us. * Translate what netlabel gave us. */ */ Loading @@ -3551,6 +3602,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) netlbl_secattr_destroy(&secattr); netlbl_secattr_destroy(&secattr); #ifdef CONFIG_SECURITY_SMACK_NETFILTER access_check: #endif #ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); ad.a.u.net->family = sk->sk_family; ad.a.u.net->family = sk->sk_family; Loading @@ -3569,14 +3623,32 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) if (rc != 0) if (rc != 0) netlbl_skbuff_err(skb, rc, 0); netlbl_skbuff_err(skb, rc, 0); break; break; #if IS_ENABLED(CONFIG_IPV6) case PF_INET6: case PF_INET6: rc = smk_skb_to_addr_ipv6(skb, &sadd); proto = smk_skb_to_addr_ipv6(skb, &sadd); if (rc == IPPROTO_UDP || rc == IPPROTO_TCP) if (proto != IPPROTO_UDP && proto != IPPROTO_TCP) rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); break; #ifdef CONFIG_SECURITY_SMACK_NETFILTER if (skb && skb->secmark != 0) skp = smack_from_secid(skb->secmark); else else rc = 0; skp = smack_net_ambient; #ifdef CONFIG_AUDIT smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); ad.a.u.net->family = sk->sk_family; ad.a.u.net->netif = skb->skb_iif; ipv6_skb_to_auditdata(skb, &ad.a, NULL); #endif /* CONFIG_AUDIT */ rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); rc = smk_bu_note("IPv6 delivery", skp, ssp->smk_in, MAY_WRITE, rc); #else /* CONFIG_SECURITY_SMACK_NETFILTER */ rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ break; break; #endif /* CONFIG_IPV6 */ } } return rc; return rc; } } Loading Loading @@ -3638,16 +3710,25 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, if (skb != NULL) { if (skb != NULL) { if (skb->protocol == htons(ETH_P_IP)) if (skb->protocol == htons(ETH_P_IP)) family = PF_INET; family = PF_INET; #if IS_ENABLED(CONFIG_IPV6) else if (skb->protocol == htons(ETH_P_IPV6)) else if (skb->protocol == htons(ETH_P_IPV6)) family = PF_INET6; family = PF_INET6; #endif /* CONFIG_IPV6 */ } } if (family == PF_UNSPEC && sock != NULL) if (family == PF_UNSPEC && sock != NULL) family = sock->sk->sk_family; family = sock->sk->sk_family; if (family == PF_UNIX) { switch (family) { case PF_UNIX: ssp = sock->sk->sk_security; ssp = sock->sk->sk_security; s = ssp->smk_out->smk_secid; s = ssp->smk_out->smk_secid; } else if (family == PF_INET || family == PF_INET6) { break; case PF_INET: #ifdef CONFIG_SECURITY_SMACK_NETFILTER s = skb->secmark; if (s != 0) break; #endif /* /* * Translate what netlabel gave us. * Translate what netlabel gave us. */ */ Loading @@ -3660,6 +3741,14 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, s = skp->smk_secid; s = skp->smk_secid; } } netlbl_secattr_destroy(&secattr); netlbl_secattr_destroy(&secattr); break; #if IS_ENABLED(CONFIG_IPV6) case PF_INET6: #ifdef CONFIG_SECURITY_SMACK_NETFILTER s = skb->secmark; #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ break; #endif /* CONFIG_IPV6 */ } } *secid = s; *secid = s; if (s == 0) if (s == 0) Loading Loading @@ -3715,6 +3804,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, struct lsm_network_audit net; struct lsm_network_audit net; #endif #endif #if IS_ENABLED(CONFIG_IPV6) if (family == PF_INET6) { if (family == PF_INET6) { /* /* * Handle mapped IPv4 packets arriving * Handle mapped IPv4 packets arriving Loading @@ -3726,6 +3816,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, else else return 0; return 0; } } #endif /* CONFIG_IPV6 */ netlbl_secattr_init(&secattr); netlbl_secattr_init(&secattr); rc = netlbl_skbuff_getattr(skb, family, &secattr); rc = netlbl_skbuff_getattr(skb, family, &secattr); Loading Loading @@ -3834,11 +3925,11 @@ static void smack_key_free(struct key *key) key->security = NULL; key->security = NULL; } } /* /** * smack_key_permission - Smack access on a key * smack_key_permission - Smack access on a key * @key_ref: gets to the object * @key_ref: gets to the object * @cred: the credentials to use * @cred: the credentials to use * @perm: unused * @perm: requested key permissions * * * Return 0 if the task has read and write to the object, * Return 0 if the task has read and write to the object, * an error code otherwise * an error code otherwise Loading Loading @@ -4184,7 +4275,9 @@ struct security_operations smack_ops = { .unix_may_send = smack_unix_may_send, .unix_may_send = smack_unix_may_send, .socket_post_create = smack_socket_post_create, .socket_post_create = smack_socket_post_create, #ifndef CONFIG_SECURITY_SMACK_NETFILTER .socket_bind = smack_socket_bind, .socket_bind = smack_socket_bind, #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ .socket_connect = smack_socket_connect, .socket_connect = smack_socket_connect, .socket_sendmsg = smack_socket_sendmsg, .socket_sendmsg = smack_socket_sendmsg, .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, Loading Loading @@ -4265,6 +4358,8 @@ static __init int smack_init(void) if (!security_module_enable(&smack_ops)) if (!security_module_enable(&smack_ops)) return 0; return 0; smack_enabled = 1; smack_inode_cache = KMEM_CACHE(inode_smack, 0); smack_inode_cache = KMEM_CACHE(inode_smack, 0); if (!smack_inode_cache) if (!smack_inode_cache) return -ENOMEM; return -ENOMEM; Loading security/smack/smack_netfilter.c 0 → 100644 +96 −0 Original line number Original line Diff line number Diff line /* * Simplified MAC Kernel (smack) security module * * This file contains the Smack netfilter implementation * * Author: * Casey Schaufler <casey@schaufler-ca.com> * * Copyright (C) 2014 Casey Schaufler <casey@schaufler-ca.com> * Copyright (C) 2014 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation. */ #include <linux/netfilter_ipv4.h> #include <linux/netfilter_ipv6.h> #include <linux/netdevice.h> #include "smack.h" #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) static unsigned int smack_ipv6_output(const struct nf_hook_ops *ops, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct socket_smack *ssp; struct smack_known *skp; if (skb && skb->sk && skb->sk->sk_security) { ssp = skb->sk->sk_security; skp = ssp->smk_out; skb->secmark = skp->smk_secid; } return NF_ACCEPT; } #endif /* IPV6 */ static unsigned int smack_ipv4_output(const struct nf_hook_ops *ops, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct socket_smack *ssp; struct smack_known *skp; if (skb && skb->sk && skb->sk->sk_security) { ssp = skb->sk->sk_security; skp = ssp->smk_out; skb->secmark = skp->smk_secid; } return NF_ACCEPT; } static struct nf_hook_ops smack_nf_ops[] = { { .hook = smack_ipv4_output, .owner = THIS_MODULE, .pf = NFPROTO_IPV4, .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP_PRI_SELINUX_FIRST, }, #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) { .hook = smack_ipv6_output, .owner = THIS_MODULE, .pf = NFPROTO_IPV6, .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP6_PRI_SELINUX_FIRST, }, #endif /* IPV6 */ }; static int __init smack_nf_ip_init(void) { int err; if (smack_enabled == 0) return 0; printk(KERN_DEBUG "Smack: Registering netfilter hooks\n"); err = nf_register_hooks(smack_nf_ops, ARRAY_SIZE(smack_nf_ops)); if (err) pr_info("Smack: nf_register_hooks: error %d\n", err); return 0; } __initcall(smack_nf_ip_init); Loading
security/smack/Kconfig +12 −0 Original line number Original line Diff line number Diff line Loading @@ -28,3 +28,15 @@ config SECURITY_SMACK_BRINGUP access rule set once the behavior is well understood. access rule set once the behavior is well understood. This is a superior mechanism to the oft abused This is a superior mechanism to the oft abused "permissive" mode of other systems. "permissive" mode of other systems. If you are unsure how to answer this question, answer N. config SECURITY_SMACK_NETFILTER bool "Packet marking using secmarks for netfilter" depends on SECURITY_SMACK depends on NETWORK_SECMARK depends on NETFILTER default n help This enables security marking of network packets using Smack labels. If you are unsure how to answer this question, answer N.
security/smack/Makefile +1 −0 Original line number Original line Diff line number Diff line Loading @@ -5,3 +5,4 @@ obj-$(CONFIG_SECURITY_SMACK) := smack.o obj-$(CONFIG_SECURITY_SMACK) := smack.o smack-y := smack_lsm.o smack_access.o smackfs.o smack-y := smack_lsm.o smack_access.o smackfs.o smack-$(CONFIG_NETFILTER) += smack_netfilter.o
security/smack/smack.h +11 −0 Original line number Original line Diff line number Diff line Loading @@ -248,6 +248,7 @@ struct smack_known *smk_find_entry(const char *); /* /* * Shared data. * Shared data. */ */ extern int smack_enabled; extern int smack_cipso_direct; extern int smack_cipso_direct; extern int smack_cipso_mapped; extern int smack_cipso_mapped; extern struct smack_known *smack_net_ambient; extern struct smack_known *smack_net_ambient; Loading Loading @@ -298,6 +299,16 @@ static inline struct smack_known *smk_of_task(const struct task_smack *tsp) return tsp->smk_task; return tsp->smk_task; } } static inline struct smack_known *smk_of_task_struct(const struct task_struct *t) { struct smack_known *skp; rcu_read_lock(); skp = smk_of_task(__task_cred(t)->security); rcu_read_unlock(); return skp; } /* /* * Present a pointer to the forked smack label entry in an task blob. * Present a pointer to the forked smack label entry in an task blob. */ */ Loading
security/smack/smack_lsm.c +147 −52 Original line number Original line Diff line number Diff line Loading @@ -43,8 +43,6 @@ #include <linux/binfmts.h> #include <linux/binfmts.h> #include "smack.h" #include "smack.h" #define task_security(task) (task_cred_xxx((task), security)) #define TRANS_TRUE "TRUE" #define TRANS_TRUE "TRUE" #define TRANS_TRUE_SIZE 4 #define TRANS_TRUE_SIZE 4 Loading @@ -52,8 +50,11 @@ #define SMK_RECEIVING 1 #define SMK_RECEIVING 1 #define SMK_SENDING 2 #define SMK_SENDING 2 #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) LIST_HEAD(smk_ipv6_port_list); LIST_HEAD(smk_ipv6_port_list); #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ static struct kmem_cache *smack_inode_cache; static struct kmem_cache *smack_inode_cache; int smack_enabled; #ifdef CONFIG_SECURITY_SMACK_BRINGUP #ifdef CONFIG_SECURITY_SMACK_BRINGUP static void smk_bu_mode(int mode, char *s) static void smk_bu_mode(int mode, char *s) Loading Loading @@ -120,7 +121,7 @@ static int smk_bu_current(char *note, struct smack_known *oskp, static int smk_bu_task(struct task_struct *otp, int mode, int rc) static int smk_bu_task(struct task_struct *otp, int mode, int rc) { { struct task_smack *tsp = current_security(); struct task_smack *tsp = current_security(); struct task_smack *otsp = task_security(otp); struct smack_known *smk_task = smk_of_task_struct(otp); char acc[SMK_NUM_ACCESS_TYPE + 1]; char acc[SMK_NUM_ACCESS_TYPE + 1]; if (rc <= 0) if (rc <= 0) Loading @@ -128,7 +129,7 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc) smk_bu_mode(mode, acc); smk_bu_mode(mode, acc); pr_info("Smack Bringup: (%s %s %s) %s to %s\n", pr_info("Smack Bringup: (%s %s %s) %s to %s\n", tsp->smk_task->smk_known, otsp->smk_task->smk_known, acc, tsp->smk_task->smk_known, smk_task->smk_known, acc, current->comm, otp->comm); current->comm, otp->comm); return 0; return 0; } } Loading Loading @@ -160,7 +161,7 @@ static int smk_bu_file(struct file *file, int mode, int rc) { { struct task_smack *tsp = current_security(); struct task_smack *tsp = current_security(); struct smack_known *sskp = tsp->smk_task; struct smack_known *sskp = tsp->smk_task; struct inode *inode = file->f_inode; struct inode *inode = file_inode(file); char acc[SMK_NUM_ACCESS_TYPE + 1]; char acc[SMK_NUM_ACCESS_TYPE + 1]; if (rc <= 0) if (rc <= 0) Loading @@ -168,7 +169,7 @@ static int smk_bu_file(struct file *file, int mode, int rc) smk_bu_mode(mode, acc); smk_bu_mode(mode, acc); pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n", pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n", sskp->smk_known, (char *)file->f_security, acc, sskp->smk_known, smk_of_inode(inode)->smk_known, acc, inode->i_sb->s_id, inode->i_ino, file, inode->i_sb->s_id, inode->i_ino, file, current->comm); current->comm); return 0; return 0; Loading Loading @@ -202,6 +203,7 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file, /** /** * smk_fetch - Fetch the smack label from a file. * smk_fetch - Fetch the smack label from a file. * @name: type of the label (attribute) * @ip: a pointer to the inode * @ip: a pointer to the inode * @dp: a pointer to the dentry * @dp: a pointer to the dentry * * Loading Loading @@ -254,7 +256,9 @@ struct inode_smack *new_inode_smack(struct smack_known *skp) /** /** * new_task_smack - allocate a task security blob * new_task_smack - allocate a task security blob * @smack: a pointer to the Smack label to use in the blob * @task: a pointer to the Smack label for the running task * @forked: a pointer to the Smack label for the forked task * @gfp: type of the memory for the allocation * * * Returns the new blob or NULL if there's no memory available * Returns the new blob or NULL if there's no memory available */ */ Loading @@ -277,8 +281,9 @@ static struct task_smack *new_task_smack(struct smack_known *task, /** /** * smk_copy_rules - copy a rule set * smk_copy_rules - copy a rule set * @nhead - new rules header pointer * @nhead: new rules header pointer * @ohead - old rules header pointer * @ohead: old rules header pointer * @gfp: type of the memory for the allocation * * * Returns 0 on success, -ENOMEM on error * Returns 0 on success, -ENOMEM on error */ */ Loading Loading @@ -345,7 +350,8 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, saip = &ad; saip = &ad; } } tsp = task_security(tracer); rcu_read_lock(); tsp = __task_cred(tracer)->security; tracer_known = smk_of_task(tsp); tracer_known = smk_of_task(tsp); if ((mode & PTRACE_MODE_ATTACH) && if ((mode & PTRACE_MODE_ATTACH) && Loading @@ -365,11 +371,14 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, tracee_known->smk_known, tracee_known->smk_known, 0, rc, saip); 0, rc, saip); rcu_read_unlock(); return rc; return rc; } } /* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */ /* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */ rc = smk_tskacc(tsp, tracee_known, smk_ptrace_mode(mode), saip); rc = smk_tskacc(tsp, tracee_known, smk_ptrace_mode(mode), saip); rcu_read_unlock(); return rc; return rc; } } Loading @@ -396,7 +405,7 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) if (rc != 0) if (rc != 0) return rc; return rc; skp = smk_of_task(task_security(ctp)); skp = smk_of_task_struct(ctp); rc = smk_ptrace_rule_check(current, skp, mode, __func__); rc = smk_ptrace_rule_check(current, skp, mode, __func__); return rc; return rc; Loading Loading @@ -796,7 +805,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, if (name) if (name) *name = XATTR_SMACK_SUFFIX; *name = XATTR_SMACK_SUFFIX; if (value) { if (value && len) { rcu_read_lock(); rcu_read_lock(); may = smk_access_entry(skp->smk_known, dsp->smk_known, may = smk_access_entry(skp->smk_known, dsp->smk_known, &skp->smk_rules); &skp->smk_rules); Loading @@ -817,10 +826,9 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, *value = kstrdup(isp->smk_known, GFP_NOFS); *value = kstrdup(isp->smk_known, GFP_NOFS); if (*value == NULL) if (*value == NULL) return -ENOMEM; return -ENOMEM; } if (len) *len = strlen(isp->smk_known); *len = strlen(isp->smk_known); } return 0; return 0; } } Loading Loading @@ -1344,6 +1352,9 @@ static int smack_file_permission(struct file *file, int mask) * The security blob for a file is a pointer to the master * The security blob for a file is a pointer to the master * label list, so no allocation is done. * label list, so no allocation is done. * * * f_security is the owner security information. It * isn't used on file access checks, it's for send_sigio. * * Returns 0 * Returns 0 */ */ static int smack_file_alloc_security(struct file *file) static int smack_file_alloc_security(struct file *file) Loading Loading @@ -1381,17 +1392,18 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd, { { int rc = 0; int rc = 0; struct smk_audit_info ad; struct smk_audit_info ad; struct inode *inode = file_inode(file); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); smk_ad_setfield_u_fs_path(&ad, file->f_path); if (_IOC_DIR(cmd) & _IOC_WRITE) { if (_IOC_DIR(cmd) & _IOC_WRITE) { rc = smk_curacc(file->f_security, MAY_WRITE, &ad); rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad); rc = smk_bu_file(file, MAY_WRITE, rc); rc = smk_bu_file(file, MAY_WRITE, rc); } } if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) { if (rc == 0 && (_IOC_DIR(cmd) & _IOC_READ)) { rc = smk_curacc(file->f_security, MAY_READ, &ad); rc = smk_curacc(smk_of_inode(inode), MAY_READ, &ad); rc = smk_bu_file(file, MAY_READ, rc); rc = smk_bu_file(file, MAY_READ, rc); } } Loading @@ -1409,10 +1421,11 @@ static int smack_file_lock(struct file *file, unsigned int cmd) { { struct smk_audit_info ad; struct smk_audit_info ad; int rc; int rc; struct inode *inode = file_inode(file); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); smk_ad_setfield_u_fs_path(&ad, file->f_path); rc = smk_curacc(file->f_security, MAY_LOCK, &ad); rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad); rc = smk_bu_file(file, MAY_LOCK, rc); rc = smk_bu_file(file, MAY_LOCK, rc); return rc; return rc; } } Loading @@ -1434,7 +1447,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, { { struct smk_audit_info ad; struct smk_audit_info ad; int rc = 0; int rc = 0; struct inode *inode = file_inode(file); switch (cmd) { switch (cmd) { case F_GETLK: case F_GETLK: Loading @@ -1443,14 +1456,14 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, case F_SETLKW: case F_SETLKW: smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); smk_ad_setfield_u_fs_path(&ad, file->f_path); rc = smk_curacc(file->f_security, MAY_LOCK, &ad); rc = smk_curacc(smk_of_inode(inode), MAY_LOCK, &ad); rc = smk_bu_file(file, MAY_LOCK, rc); rc = smk_bu_file(file, MAY_LOCK, rc); break; break; case F_SETOWN: case F_SETOWN: case F_SETSIG: case F_SETSIG: smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); smk_ad_setfield_u_fs_path(&ad, file->f_path); rc = smk_curacc(file->f_security, MAY_WRITE, &ad); rc = smk_curacc(smk_of_inode(inode), MAY_WRITE, &ad); rc = smk_bu_file(file, MAY_WRITE, rc); rc = smk_bu_file(file, MAY_WRITE, rc); break; break; default: default: Loading Loading @@ -1568,14 +1581,10 @@ static int smack_mmap_file(struct file *file, * smack_file_set_fowner - set the file security blob value * smack_file_set_fowner - set the file security blob value * @file: object in question * @file: object in question * * * Returns 0 * Further research may be required on this one. */ */ static void smack_file_set_fowner(struct file *file) static void smack_file_set_fowner(struct file *file) { { struct smack_known *skp = smk_of_current(); file->f_security = smk_of_current(); file->f_security = skp; } } /** /** Loading Loading @@ -1627,6 +1636,7 @@ static int smack_file_receive(struct file *file) int rc; int rc; int may = 0; int may = 0; struct smk_audit_info ad; struct smk_audit_info ad; struct inode *inode = file_inode(file); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); smk_ad_setfield_u_fs_path(&ad, file->f_path); Loading @@ -1638,7 +1648,7 @@ static int smack_file_receive(struct file *file) if (file->f_mode & FMODE_WRITE) if (file->f_mode & FMODE_WRITE) may |= MAY_WRITE; may |= MAY_WRITE; rc = smk_curacc(file->f_security, may, &ad); rc = smk_curacc(smk_of_inode(inode), may, &ad); rc = smk_bu_file(file, may, rc); rc = smk_bu_file(file, may, rc); return rc; return rc; } } Loading @@ -1658,21 +1668,17 @@ static int smack_file_receive(struct file *file) static int smack_file_open(struct file *file, const struct cred *cred) static int smack_file_open(struct file *file, const struct cred *cred) { { struct task_smack *tsp = cred->security; struct task_smack *tsp = cred->security; struct inode_smack *isp = file_inode(file)->i_security; struct inode *inode = file_inode(file); struct smk_audit_info ad; struct smk_audit_info ad; int rc; int rc; if (smack_privileged(CAP_MAC_OVERRIDE)) { if (smack_privileged(CAP_MAC_OVERRIDE)) file->f_security = isp->smk_inode; return 0; return 0; } smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); smk_ad_setfield_u_fs_path(&ad, file->f_path); rc = smk_access(tsp->smk_task, isp->smk_inode, MAY_READ, &ad); rc = smk_access(tsp->smk_task, smk_of_inode(inode), MAY_READ, &ad); rc = smk_bu_credfile(cred, file, MAY_READ, rc); rc = smk_bu_credfile(cred, file, MAY_READ, rc); if (rc == 0) file->f_security = isp->smk_inode; return rc; return rc; } } Loading Loading @@ -1826,7 +1832,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access, const char *caller) const char *caller) { { struct smk_audit_info ad; struct smk_audit_info ad; struct smack_known *skp = smk_of_task(task_security(p)); struct smack_known *skp = smk_of_task_struct(p); int rc; int rc; smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK); smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK); Loading Loading @@ -1879,7 +1885,7 @@ static int smack_task_getsid(struct task_struct *p) */ */ static void smack_task_getsecid(struct task_struct *p, u32 *secid) static void smack_task_getsecid(struct task_struct *p, u32 *secid) { { struct smack_known *skp = smk_of_task(task_security(p)); struct smack_known *skp = smk_of_task_struct(p); *secid = skp->smk_secid; *secid = skp->smk_secid; } } Loading Loading @@ -1986,7 +1992,7 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, { { struct smk_audit_info ad; struct smk_audit_info ad; struct smack_known *skp; struct smack_known *skp; struct smack_known *tkp = smk_of_task(task_security(p)); struct smack_known *tkp = smk_of_task_struct(p); int rc; int rc; smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); Loading Loading @@ -2040,7 +2046,7 @@ static int smack_task_wait(struct task_struct *p) static void smack_task_to_inode(struct task_struct *p, struct inode *inode) static void smack_task_to_inode(struct task_struct *p, struct inode *inode) { { struct inode_smack *isp = inode->i_security; struct inode_smack *isp = inode->i_security; struct smack_known *skp = smk_of_task(task_security(p)); struct smack_known *skp = smk_of_task_struct(p); isp->smk_inode = skp; isp->smk_inode = skp; } } Loading Loading @@ -2212,6 +2218,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) return smack_netlabel(sk, sk_lbl); return smack_netlabel(sk, sk_lbl); } } #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) /** /** * smk_ipv6_port_label - Smack port access table management * smk_ipv6_port_label - Smack port access table management * @sock: socket * @sock: socket Loading Loading @@ -2361,6 +2368,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, rc = smk_bu_note("IPv6 port check", skp, object, MAY_WRITE, rc); rc = smk_bu_note("IPv6 port check", skp, object, MAY_WRITE, rc); return rc; return rc; } } #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ /** /** * smack_inode_setsecurity - set smack xattrs * smack_inode_setsecurity - set smack xattrs Loading Loading @@ -2421,8 +2429,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, } else } else return -EOPNOTSUPP; return -EOPNOTSUPP; #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) if (sock->sk->sk_family == PF_INET6) if (sock->sk->sk_family == PF_INET6) smk_ipv6_port_label(sock, NULL); smk_ipv6_port_label(sock, NULL); #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ return 0; return 0; } } Loading Loading @@ -2450,6 +2460,7 @@ static int smack_socket_post_create(struct socket *sock, int family, return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); } } #ifndef CONFIG_SECURITY_SMACK_NETFILTER /** /** * smack_socket_bind - record port binding information. * smack_socket_bind - record port binding information. * @sock: the socket * @sock: the socket Loading @@ -2463,11 +2474,14 @@ static int smack_socket_post_create(struct socket *sock, int family, static int smack_socket_bind(struct socket *sock, struct sockaddr *address, static int smack_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) int addrlen) { { #if IS_ENABLED(CONFIG_IPV6) if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) smk_ipv6_port_label(sock, address); smk_ipv6_port_label(sock, address); #endif return 0; return 0; } } #endif /* !CONFIG_SECURITY_SMACK_NETFILTER */ /** /** * smack_socket_connect - connect access check * smack_socket_connect - connect access check Loading Loading @@ -2496,8 +2510,10 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, case PF_INET6: case PF_INET6: if (addrlen < sizeof(struct sockaddr_in6)) if (addrlen < sizeof(struct sockaddr_in6)) return -EINVAL; return -EINVAL; #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap, rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap, SMK_CONNECTING); SMK_CONNECTING); #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ break; break; } } return rc; return rc; Loading Loading @@ -3033,7 +3049,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) * of the superblock. * of the superblock. */ */ if (opt_dentry->d_parent == opt_dentry) { if (opt_dentry->d_parent == opt_dentry) { if (sbp->s_magic == CGROUP_SUPER_MAGIC) { switch (sbp->s_magic) { case CGROUP_SUPER_MAGIC: /* /* * The cgroup filesystem is never mounted, * The cgroup filesystem is never mounted, * so there's no opportunity to set the mount * so there's no opportunity to set the mount Loading @@ -3041,8 +3058,19 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) */ */ sbsp->smk_root = &smack_known_star; sbsp->smk_root = &smack_known_star; sbsp->smk_default = &smack_known_star; sbsp->smk_default = &smack_known_star; } isp->smk_inode = sbsp->smk_root; isp->smk_inode = sbsp->smk_root; break; case TMPFS_MAGIC: /* * What about shmem/tmpfs anonymous files with dentry * obtained from d_alloc_pseudo()? */ isp->smk_inode = smk_of_current(); break; default: isp->smk_inode = sbsp->smk_root; break; } isp->smk_flags |= SMK_INODE_INSTANT; isp->smk_flags |= SMK_INODE_INSTANT; goto unlockandout; goto unlockandout; } } Loading Loading @@ -3200,7 +3228,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) */ */ static int smack_getprocattr(struct task_struct *p, char *name, char **value) static int smack_getprocattr(struct task_struct *p, char *name, char **value) { { struct smack_known *skp = smk_of_task(task_security(p)); struct smack_known *skp = smk_of_task_struct(p); char *cp; char *cp; int slen; int slen; Loading Loading @@ -3297,7 +3325,7 @@ static int smack_unix_stream_connect(struct sock *sock, if (!smack_privileged(CAP_MAC_OVERRIDE)) { if (!smack_privileged(CAP_MAC_OVERRIDE)) { skp = ssp->smk_out; skp = ssp->smk_out; okp = osp->smk_out; okp = osp->smk_in; #ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); smk_ad_setfield_u_net_sk(&ad, other); smk_ad_setfield_u_net_sk(&ad, other); Loading @@ -3305,7 +3333,9 @@ static int smack_unix_stream_connect(struct sock *sock, rc = smk_access(skp, okp, MAY_WRITE, &ad); rc = smk_access(skp, okp, MAY_WRITE, &ad); rc = smk_bu_note("UDS connect", skp, okp, MAY_WRITE, rc); rc = smk_bu_note("UDS connect", skp, okp, MAY_WRITE, rc); if (rc == 0) { if (rc == 0) { rc = smk_access(okp, skp, MAY_WRITE, NULL); okp = osp->smk_out; skp = ssp->smk_in; rc = smk_access(okp, skp, MAY_WRITE, &ad); rc = smk_bu_note("UDS connect", okp, skp, rc = smk_bu_note("UDS connect", okp, skp, MAY_WRITE, rc); MAY_WRITE, rc); } } Loading Loading @@ -3366,7 +3396,9 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size) int size) { { struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ int rc = 0; int rc = 0; /* /* Loading @@ -3380,7 +3412,9 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, rc = smack_netlabel_send(sock->sk, sip); rc = smack_netlabel_send(sock->sk, sip); break; break; case AF_INET6: case AF_INET6: #if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING); rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING); #endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ break; break; } } return rc; return rc; Loading Loading @@ -3471,6 +3505,7 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, return smack_net_ambient; return smack_net_ambient; } } #if IS_ENABLED(CONFIG_IPV6) static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) { { u8 nexthdr; u8 nexthdr; Loading Loading @@ -3517,6 +3552,7 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) } } return proto; return proto; } } #endif /* CONFIG_IPV6 */ /** /** * smack_socket_sock_rcv_skb - Smack packet delivery access check * smack_socket_sock_rcv_skb - Smack packet delivery access check Loading @@ -3529,15 +3565,30 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) { { struct netlbl_lsm_secattr secattr; struct netlbl_lsm_secattr secattr; struct socket_smack *ssp = sk->sk_security; struct socket_smack *ssp = sk->sk_security; struct smack_known *skp; struct smack_known *skp = NULL; struct sockaddr_in6 sadd; int rc = 0; int rc = 0; struct smk_audit_info ad; struct smk_audit_info ad; #ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT struct lsm_network_audit net; struct lsm_network_audit net; #endif #endif #if IS_ENABLED(CONFIG_IPV6) struct sockaddr_in6 sadd; int proto; #endif /* CONFIG_IPV6 */ switch (sk->sk_family) { switch (sk->sk_family) { case PF_INET: case PF_INET: #ifdef CONFIG_SECURITY_SMACK_NETFILTER /* * If there is a secmark use it rather than the CIPSO label. * If there is no secmark fall back to CIPSO. * The secmark is assumed to reflect policy better. */ if (skb && skb->secmark != 0) { skp = smack_from_secid(skb->secmark); goto access_check; } #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ /* /* * Translate what netlabel gave us. * Translate what netlabel gave us. */ */ Loading @@ -3551,6 +3602,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) netlbl_secattr_destroy(&secattr); netlbl_secattr_destroy(&secattr); #ifdef CONFIG_SECURITY_SMACK_NETFILTER access_check: #endif #ifdef CONFIG_AUDIT #ifdef CONFIG_AUDIT smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); ad.a.u.net->family = sk->sk_family; ad.a.u.net->family = sk->sk_family; Loading @@ -3569,14 +3623,32 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) if (rc != 0) if (rc != 0) netlbl_skbuff_err(skb, rc, 0); netlbl_skbuff_err(skb, rc, 0); break; break; #if IS_ENABLED(CONFIG_IPV6) case PF_INET6: case PF_INET6: rc = smk_skb_to_addr_ipv6(skb, &sadd); proto = smk_skb_to_addr_ipv6(skb, &sadd); if (rc == IPPROTO_UDP || rc == IPPROTO_TCP) if (proto != IPPROTO_UDP && proto != IPPROTO_TCP) rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); break; #ifdef CONFIG_SECURITY_SMACK_NETFILTER if (skb && skb->secmark != 0) skp = smack_from_secid(skb->secmark); else else rc = 0; skp = smack_net_ambient; #ifdef CONFIG_AUDIT smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); ad.a.u.net->family = sk->sk_family; ad.a.u.net->netif = skb->skb_iif; ipv6_skb_to_auditdata(skb, &ad.a, NULL); #endif /* CONFIG_AUDIT */ rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); rc = smk_bu_note("IPv6 delivery", skp, ssp->smk_in, MAY_WRITE, rc); #else /* CONFIG_SECURITY_SMACK_NETFILTER */ rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ break; break; #endif /* CONFIG_IPV6 */ } } return rc; return rc; } } Loading Loading @@ -3638,16 +3710,25 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, if (skb != NULL) { if (skb != NULL) { if (skb->protocol == htons(ETH_P_IP)) if (skb->protocol == htons(ETH_P_IP)) family = PF_INET; family = PF_INET; #if IS_ENABLED(CONFIG_IPV6) else if (skb->protocol == htons(ETH_P_IPV6)) else if (skb->protocol == htons(ETH_P_IPV6)) family = PF_INET6; family = PF_INET6; #endif /* CONFIG_IPV6 */ } } if (family == PF_UNSPEC && sock != NULL) if (family == PF_UNSPEC && sock != NULL) family = sock->sk->sk_family; family = sock->sk->sk_family; if (family == PF_UNIX) { switch (family) { case PF_UNIX: ssp = sock->sk->sk_security; ssp = sock->sk->sk_security; s = ssp->smk_out->smk_secid; s = ssp->smk_out->smk_secid; } else if (family == PF_INET || family == PF_INET6) { break; case PF_INET: #ifdef CONFIG_SECURITY_SMACK_NETFILTER s = skb->secmark; if (s != 0) break; #endif /* /* * Translate what netlabel gave us. * Translate what netlabel gave us. */ */ Loading @@ -3660,6 +3741,14 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, s = skp->smk_secid; s = skp->smk_secid; } } netlbl_secattr_destroy(&secattr); netlbl_secattr_destroy(&secattr); break; #if IS_ENABLED(CONFIG_IPV6) case PF_INET6: #ifdef CONFIG_SECURITY_SMACK_NETFILTER s = skb->secmark; #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ break; #endif /* CONFIG_IPV6 */ } } *secid = s; *secid = s; if (s == 0) if (s == 0) Loading Loading @@ -3715,6 +3804,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, struct lsm_network_audit net; struct lsm_network_audit net; #endif #endif #if IS_ENABLED(CONFIG_IPV6) if (family == PF_INET6) { if (family == PF_INET6) { /* /* * Handle mapped IPv4 packets arriving * Handle mapped IPv4 packets arriving Loading @@ -3726,6 +3816,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, else else return 0; return 0; } } #endif /* CONFIG_IPV6 */ netlbl_secattr_init(&secattr); netlbl_secattr_init(&secattr); rc = netlbl_skbuff_getattr(skb, family, &secattr); rc = netlbl_skbuff_getattr(skb, family, &secattr); Loading Loading @@ -3834,11 +3925,11 @@ static void smack_key_free(struct key *key) key->security = NULL; key->security = NULL; } } /* /** * smack_key_permission - Smack access on a key * smack_key_permission - Smack access on a key * @key_ref: gets to the object * @key_ref: gets to the object * @cred: the credentials to use * @cred: the credentials to use * @perm: unused * @perm: requested key permissions * * * Return 0 if the task has read and write to the object, * Return 0 if the task has read and write to the object, * an error code otherwise * an error code otherwise Loading Loading @@ -4184,7 +4275,9 @@ struct security_operations smack_ops = { .unix_may_send = smack_unix_may_send, .unix_may_send = smack_unix_may_send, .socket_post_create = smack_socket_post_create, .socket_post_create = smack_socket_post_create, #ifndef CONFIG_SECURITY_SMACK_NETFILTER .socket_bind = smack_socket_bind, .socket_bind = smack_socket_bind, #endif /* CONFIG_SECURITY_SMACK_NETFILTER */ .socket_connect = smack_socket_connect, .socket_connect = smack_socket_connect, .socket_sendmsg = smack_socket_sendmsg, .socket_sendmsg = smack_socket_sendmsg, .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, Loading Loading @@ -4265,6 +4358,8 @@ static __init int smack_init(void) if (!security_module_enable(&smack_ops)) if (!security_module_enable(&smack_ops)) return 0; return 0; smack_enabled = 1; smack_inode_cache = KMEM_CACHE(inode_smack, 0); smack_inode_cache = KMEM_CACHE(inode_smack, 0); if (!smack_inode_cache) if (!smack_inode_cache) return -ENOMEM; return -ENOMEM; Loading
security/smack/smack_netfilter.c 0 → 100644 +96 −0 Original line number Original line Diff line number Diff line /* * Simplified MAC Kernel (smack) security module * * This file contains the Smack netfilter implementation * * Author: * Casey Schaufler <casey@schaufler-ca.com> * * Copyright (C) 2014 Casey Schaufler <casey@schaufler-ca.com> * Copyright (C) 2014 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, * as published by the Free Software Foundation. */ #include <linux/netfilter_ipv4.h> #include <linux/netfilter_ipv6.h> #include <linux/netdevice.h> #include "smack.h" #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) static unsigned int smack_ipv6_output(const struct nf_hook_ops *ops, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct socket_smack *ssp; struct smack_known *skp; if (skb && skb->sk && skb->sk->sk_security) { ssp = skb->sk->sk_security; skp = ssp->smk_out; skb->secmark = skp->smk_secid; } return NF_ACCEPT; } #endif /* IPV6 */ static unsigned int smack_ipv4_output(const struct nf_hook_ops *ops, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct socket_smack *ssp; struct smack_known *skp; if (skb && skb->sk && skb->sk->sk_security) { ssp = skb->sk->sk_security; skp = ssp->smk_out; skb->secmark = skp->smk_secid; } return NF_ACCEPT; } static struct nf_hook_ops smack_nf_ops[] = { { .hook = smack_ipv4_output, .owner = THIS_MODULE, .pf = NFPROTO_IPV4, .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP_PRI_SELINUX_FIRST, }, #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) { .hook = smack_ipv6_output, .owner = THIS_MODULE, .pf = NFPROTO_IPV6, .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP6_PRI_SELINUX_FIRST, }, #endif /* IPV6 */ }; static int __init smack_nf_ip_init(void) { int err; if (smack_enabled == 0) return 0; printk(KERN_DEBUG "Smack: Registering netfilter hooks\n"); err = nf_register_hooks(smack_nf_ops, ARRAY_SIZE(smack_nf_ops)); if (err) pr_info("Smack: nf_register_hooks: error %d\n", err); return 0; } __initcall(smack_nf_ip_init);