diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-12 10:13:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-12 10:13:55 -0400 |
commit | 5e40d331bd72447197f26525f21711c4a265b6a6 (patch) | |
tree | cfbf5efba46b0c5c5b3c8149395f721eab839945 /security/smack/smack_lsm.c | |
parent | d0ca47575ab3b41bb7f0fe5feec13c6cddb2913a (diff) | |
parent | 594081ee7145cc30a3977cb4e218f81213b63dc5 (diff) | |
download | linux-5e40d331bd72447197f26525f21711c4a265b6a6.tar.gz linux-5e40d331bd72447197f26525f21711c4a265b6a6.tar.bz2 linux-5e40d331bd72447197f26525f21711c4a265b6a6.zip |
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security
Pull security subsystem updates from James Morris.
Mostly ima, selinux, smack and key handling updates.
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: (65 commits)
integrity: do zero padding of the key id
KEYS: output last portion of fingerprint in /proc/keys
KEYS: strip 'id:' from ca_keyid
KEYS: use swapped SKID for performing partial matching
KEYS: Restore partial ID matching functionality for asymmetric keys
X.509: If available, use the raw subjKeyId to form the key description
KEYS: handle error code encoded in pointer
selinux: normalize audit log formatting
selinux: cleanup error reporting in selinux_nlmsg_perm()
KEYS: Check hex2bin()'s return when generating an asymmetric key ID
ima: detect violations for mmaped files
ima: fix race condition on ima_rdwr_violation_check and process_measurement
ima: added ima_policy_flag variable
ima: return an error code from ima_add_boot_aggregate()
ima: provide 'ima_appraise=log' kernel option
ima: move keyring initialization to ima_init()
PKCS#7: Handle PKCS#7 messages that contain no X.509 certs
PKCS#7: Better handling of unsupported crypto
KEYS: Overhaul key identification when searching for asymmetric keys
KEYS: Implement binary asymmetric key ID handling
...
Diffstat (limited to 'security/smack/smack_lsm.c')
-rw-r--r-- | security/smack/smack_lsm.c | 545 |
1 files changed, 388 insertions, 157 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 69e5635d89e5..d515ec25ae9f 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -54,6 +54,151 @@ LIST_HEAD(smk_ipv6_port_list); +#ifdef CONFIG_SECURITY_SMACK_BRINGUP +static void smk_bu_mode(int mode, char *s) +{ + int i = 0; + + if (mode & MAY_READ) + s[i++] = 'r'; + if (mode & MAY_WRITE) + s[i++] = 'w'; + if (mode & MAY_EXEC) + s[i++] = 'x'; + if (mode & MAY_APPEND) + s[i++] = 'a'; + if (mode & MAY_TRANSMUTE) + s[i++] = 't'; + if (mode & MAY_LOCK) + s[i++] = 'l'; + if (i == 0) + s[i++] = '-'; + s[i] = '\0'; +} +#endif + +#ifdef CONFIG_SECURITY_SMACK_BRINGUP +static int smk_bu_note(char *note, struct smack_known *sskp, + struct smack_known *oskp, int mode, int rc) +{ + char acc[SMK_NUM_ACCESS_TYPE + 1]; + + if (rc <= 0) + return rc; + + smk_bu_mode(mode, acc); + pr_info("Smack Bringup: (%s %s %s) %s\n", + sskp->smk_known, oskp->smk_known, acc, note); + return 0; +} +#else +#define smk_bu_note(note, sskp, oskp, mode, RC) (RC) +#endif + +#ifdef CONFIG_SECURITY_SMACK_BRINGUP +static int smk_bu_current(char *note, struct smack_known *oskp, + int mode, int rc) +{ + struct task_smack *tsp = current_security(); + char acc[SMK_NUM_ACCESS_TYPE + 1]; + + if (rc <= 0) + return rc; + + smk_bu_mode(mode, acc); + pr_info("Smack Bringup: (%s %s %s) %s %s\n", + tsp->smk_task->smk_known, oskp->smk_known, + acc, current->comm, note); + return 0; +} +#else +#define smk_bu_current(note, oskp, mode, RC) (RC) +#endif + +#ifdef CONFIG_SECURITY_SMACK_BRINGUP +static int smk_bu_task(struct task_struct *otp, int mode, int rc) +{ + struct task_smack *tsp = current_security(); + struct task_smack *otsp = task_security(otp); + char acc[SMK_NUM_ACCESS_TYPE + 1]; + + if (rc <= 0) + return rc; + + smk_bu_mode(mode, acc); + pr_info("Smack Bringup: (%s %s %s) %s to %s\n", + tsp->smk_task->smk_known, otsp->smk_task->smk_known, acc, + current->comm, otp->comm); + return 0; +} +#else +#define smk_bu_task(otp, mode, RC) (RC) +#endif + +#ifdef CONFIG_SECURITY_SMACK_BRINGUP +static int smk_bu_inode(struct inode *inode, int mode, int rc) +{ + struct task_smack *tsp = current_security(); + char acc[SMK_NUM_ACCESS_TYPE + 1]; + + if (rc <= 0) + return rc; + + smk_bu_mode(mode, acc); + pr_info("Smack Bringup: (%s %s %s) inode=(%s %ld) %s\n", + tsp->smk_task->smk_known, smk_of_inode(inode)->smk_known, acc, + inode->i_sb->s_id, inode->i_ino, current->comm); + return 0; +} +#else +#define smk_bu_inode(inode, mode, RC) (RC) +#endif + +#ifdef CONFIG_SECURITY_SMACK_BRINGUP +static int smk_bu_file(struct file *file, int mode, int rc) +{ + struct task_smack *tsp = current_security(); + struct smack_known *sskp = tsp->smk_task; + struct inode *inode = file->f_inode; + char acc[SMK_NUM_ACCESS_TYPE + 1]; + + if (rc <= 0) + return rc; + + smk_bu_mode(mode, acc); + pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %s) %s\n", + sskp->smk_known, (char *)file->f_security, acc, + inode->i_sb->s_id, inode->i_ino, file->f_dentry->d_name.name, + current->comm); + return 0; +} +#else +#define smk_bu_file(file, mode, RC) (RC) +#endif + +#ifdef CONFIG_SECURITY_SMACK_BRINGUP +static int smk_bu_credfile(const struct cred *cred, struct file *file, + int mode, int rc) +{ + struct task_smack *tsp = cred->security; + struct smack_known *sskp = tsp->smk_task; + struct inode *inode = file->f_inode; + char acc[SMK_NUM_ACCESS_TYPE + 1]; + + if (rc <= 0) + return rc; + + smk_bu_mode(mode, acc); + pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %s) %s\n", + sskp->smk_known, smk_of_inode(inode)->smk_known, acc, + inode->i_sb->s_id, inode->i_ino, file->f_dentry->d_name.name, + current->comm); + return 0; +} +#else +#define smk_bu_credfile(cred, file, mode, RC) (RC) +#endif + /** * smk_fetch - Fetch the smack label from a file. * @ip: a pointer to the inode @@ -87,11 +232,11 @@ static struct smack_known *smk_fetch(const char *name, struct inode *ip, /** * new_inode_smack - allocate an inode security blob - * @smack: a pointer to the Smack label to use in the blob + * @skp: a pointer to the Smack label entry to use in the blob * * Returns the new blob or NULL if there's no memory available */ -struct inode_smack *new_inode_smack(char *smack) +struct inode_smack *new_inode_smack(struct smack_known *skp) { struct inode_smack *isp; @@ -99,7 +244,7 @@ struct inode_smack *new_inode_smack(char *smack) if (isp == NULL) return NULL; - isp->smk_inode = smack; + isp->smk_inode = skp; isp->smk_flags = 0; mutex_init(&isp->smk_lock); @@ -178,20 +323,20 @@ static inline unsigned int smk_ptrace_mode(unsigned int mode) /** * smk_ptrace_rule_check - helper for ptrace access * @tracer: tracer process - * @tracee_label: label of the process that's about to be traced, - * the pointer must originate from smack structures + * @tracee_known: label entry of the process that's about to be traced * @mode: ptrace attachment mode (PTRACE_MODE_*) * @func: name of the function that called us, used for audit * * Returns 0 on access granted, -error on error */ -static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label, +static int smk_ptrace_rule_check(struct task_struct *tracer, + struct smack_known *tracee_known, unsigned int mode, const char *func) { int rc; struct smk_audit_info ad, *saip = NULL; struct task_smack *tsp; - struct smack_known *skp; + struct smack_known *tracer_known; if ((mode & PTRACE_MODE_NOAUDIT) == 0) { smk_ad_init(&ad, func, LSM_AUDIT_DATA_TASK); @@ -200,12 +345,12 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label, } tsp = task_security(tracer); - skp = smk_of_task(tsp); + tracer_known = smk_of_task(tsp); if ((mode & PTRACE_MODE_ATTACH) && (smack_ptrace_rule == SMACK_PTRACE_EXACT || smack_ptrace_rule == SMACK_PTRACE_DRACONIAN)) { - if (skp->smk_known == tracee_label) + if (tracer_known->smk_known == tracee_known->smk_known) rc = 0; else if (smack_ptrace_rule == SMACK_PTRACE_DRACONIAN) rc = -EACCES; @@ -215,13 +360,15 @@ static int smk_ptrace_rule_check(struct task_struct *tracer, char *tracee_label, rc = -EACCES; if (saip) - smack_log(skp->smk_known, tracee_label, 0, rc, saip); + smack_log(tracer_known->smk_known, + tracee_known->smk_known, + 0, rc, saip); return rc; } /* In case of rule==SMACK_PTRACE_DEFAULT or mode==PTRACE_MODE_READ */ - rc = smk_tskacc(tsp, tracee_label, smk_ptrace_mode(mode), saip); + rc = smk_tskacc(tsp, tracee_known, smk_ptrace_mode(mode), saip); return rc; } @@ -250,7 +397,7 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) skp = smk_of_task(task_security(ctp)); - rc = smk_ptrace_rule_check(current, skp->smk_known, mode, __func__); + rc = smk_ptrace_rule_check(current, skp, mode, __func__); return rc; } @@ -273,8 +420,7 @@ static int smack_ptrace_traceme(struct task_struct *ptp) skp = smk_of_task(current_security()); - rc = smk_ptrace_rule_check(ptp, skp->smk_known, - PTRACE_MODE_ATTACH, __func__); + rc = smk_ptrace_rule_check(ptp, skp, PTRACE_MODE_ATTACH, __func__); return rc; } @@ -318,10 +464,10 @@ static int smack_sb_alloc_security(struct super_block *sb) if (sbsp == NULL) return -ENOMEM; - sbsp->smk_root = smack_known_floor.smk_known; - sbsp->smk_default = smack_known_floor.smk_known; - sbsp->smk_floor = smack_known_floor.smk_known; - sbsp->smk_hat = smack_known_hat.smk_known; + sbsp->smk_root = &smack_known_floor; + sbsp->smk_default = &smack_known_floor; + sbsp->smk_floor = &smack_known_floor; + sbsp->smk_hat = &smack_known_hat; /* * smk_initialized will be zero from kzalloc. */ @@ -405,7 +551,6 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) struct smack_known *skp; char *op; char *commap; - char *nsp; int transmute = 0; int specified = 0; @@ -421,38 +566,38 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) { op += strlen(SMK_FSHAT); - nsp = smk_import(op, 0); - if (nsp != NULL) { - sp->smk_hat = nsp; + skp = smk_import_entry(op, 0); + if (skp != NULL) { + sp->smk_hat = skp; specified = 1; } } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 0) { op += strlen(SMK_FSFLOOR); - nsp = smk_import(op, 0); - if (nsp != NULL) { - sp->smk_floor = nsp; + skp = smk_import_entry(op, 0); + if (skp != NULL) { + sp->smk_floor = skp; specified = 1; } } else if (strncmp(op, SMK_FSDEFAULT, strlen(SMK_FSDEFAULT)) == 0) { op += strlen(SMK_FSDEFAULT); - nsp = smk_import(op, 0); - if (nsp != NULL) { - sp->smk_default = nsp; + skp = smk_import_entry(op, 0); + if (skp != NULL) { + sp->smk_default = skp; specified = 1; } } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) { op += strlen(SMK_FSROOT); - nsp = smk_import(op, 0); - if (nsp != NULL) { - sp->smk_root = nsp; + skp = smk_import_entry(op, 0); + if (skp != NULL) { + sp->smk_root = skp; specified = 1; } } else if (strncmp(op, SMK_FSTRANS, strlen(SMK_FSTRANS)) == 0) { op += strlen(SMK_FSTRANS); - nsp = smk_import(op, 0); - if (nsp != NULL) { - sp->smk_root = nsp; + skp = smk_import_entry(op, 0); + if (skp != NULL) { + sp->smk_root = skp; transmute = 1; specified = 1; } @@ -469,8 +614,8 @@ static int smack_sb_kern_mount(struct super_block *sb, int flags, void *data) * Unprivileged mounts get root and default from the caller. */ skp = smk_of_current(); - sp->smk_root = skp->smk_known; - sp->smk_default = skp->smk_known; + sp->smk_root = skp; + sp->smk_default = skp; } /* * Initialize the root inode. @@ -507,6 +652,7 @@ static int smack_sb_statfs(struct dentry *dentry) smk_ad_setfield_u_fs_path_dentry(&ad, dentry); rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad); + rc = smk_bu_current("statfs", sbp->smk_floor, MAY_READ, rc); return rc; } @@ -546,7 +692,7 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm) tracer = ptrace_parent(current); if (likely(tracer != NULL)) rc = smk_ptrace_rule_check(tracer, - isp->smk_task->smk_known, + isp->smk_task, PTRACE_MODE_ATTACH, __func__); rcu_read_unlock(); @@ -607,7 +753,7 @@ static int smack_inode_alloc_security(struct inode *inode) { struct smack_known *skp = smk_of_current(); - inode->i_security = new_inode_smack(skp->smk_known); + inode->i_security = new_inode_smack(skp); if (inode->i_security == NULL) return -ENOMEM; return 0; @@ -627,8 +773,8 @@ static void smack_inode_free_security(struct inode *inode) /** * smack_inode_init_security - copy out the smack from an inode - * @inode: the inode - * @dir: unused + * @inode: the newly created inode + * @dir: containing directory object * @qstr: unused * @name: where to put the attribute name * @value: where to put the attribute value @@ -642,8 +788,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, { struct inode_smack *issp = inode->i_security; struct smack_known *skp = smk_of_current(); - char *isp = smk_of_inode(inode); - char *dsp = smk_of_inode(dir); + struct smack_known *isp = smk_of_inode(inode); + struct smack_known *dsp = smk_of_inode(dir); int may; if (name) @@ -651,7 +797,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, if (value) { rcu_read_lock(); - may = smk_access_entry(skp->smk_known, dsp, &skp->smk_rules); + may = smk_access_entry(skp->smk_known, dsp->smk_known, + &skp->smk_rules); rcu_read_unlock(); /* @@ -666,13 +813,13 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, issp->smk_flags |= SMK_INODE_CHANGED; } - *value = kstrdup(isp, GFP_NOFS); + *value = kstrdup(isp->smk_known, GFP_NOFS); if (*value == NULL) return -ENOMEM; } if (len) - *len = strlen(isp) + 1; + *len = strlen(isp->smk_known); return 0; } @@ -688,7 +835,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) { - char *isp; + struct smack_known *isp; struct smk_audit_info ad; int rc; @@ -697,11 +844,13 @@ static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, isp = smk_of_inode(old_dentry->d_inode); rc = smk_curacc(isp, MAY_WRITE, &ad); + rc = smk_bu_inode(old_dentry->d_inode, MAY_WRITE, rc); if (rc == 0 && new_dentry->d_inode != NULL) { isp = smk_of_inode(new_dentry->d_inode); smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry); rc = smk_curacc(isp, MAY_WRITE, &ad); + rc = smk_bu_inode(new_dentry->d_inode, MAY_WRITE, rc); } return rc; @@ -728,6 +877,7 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) * You need write access to the thing you're unlinking */ rc = smk_curacc(smk_of_inode(ip), MAY_WRITE, &ad); + rc = smk_bu_inode(ip, MAY_WRITE, rc); if (rc == 0) { /* * You also need write access to the containing directory @@ -735,6 +885,7 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE); smk_ad_setfield_u_fs_inode(&ad, dir); rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad); + rc = smk_bu_inode(dir, MAY_WRITE, rc); } return rc; } @@ -759,6 +910,7 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) * You need write access to the thing you're removing */ rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); + rc = smk_bu_inode(dentry->d_inode, MAY_WRITE, rc); if (rc == 0) { /* * You also need write access to the containing directory @@ -766,6 +918,7 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE); smk_ad_setfield_u_fs_inode(&ad, dir); rc = smk_curacc(smk_of_inode(dir), MAY_WRITE, &ad); + rc = smk_bu_inode(dir, MAY_WRITE, rc); } return rc; @@ -773,10 +926,10 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) /** * smack_inode_rename - Smack check on rename - * @old_inode: the old directory - * @old_dentry: unused - * @new_inode: the new directory - * @new_dentry: unused + * @old_inode: unused + * @old_dentry: the old object + * @new_inode: unused + * @new_dentry: the new object * * Read and write access is required on both the old and * new directories. @@ -789,7 +942,7 @@ static int smack_inode_rename(struct inode *old_inode, struct dentry *new_dentry) { int rc; - char *isp; + struct smack_known *isp; struct smk_audit_info ad; smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); @@ -797,11 +950,13 @@ static int smack_inode_rename(struct inode *old_inode, isp = smk_of_inode(old_dentry->d_inode); rc = smk_curacc(isp, MAY_READWRITE, &ad); + rc = smk_bu_inode(old_dentry->d_inode, MAY_READWRITE, rc); if (rc == 0 && new_dentry->d_inode != NULL) { isp = smk_of_inode(new_dentry->d_inode); smk_ad_setfield_u_fs_path_dentry(&ad, new_dentry); rc = smk_curacc(isp, MAY_READWRITE, &ad); + rc = smk_bu_inode(new_dentry->d_inode, MAY_READWRITE, rc); } return rc; } @@ -819,6 +974,7 @@ static int smack_inode_permission(struct inode *inode, int mask) { struct smk_audit_info ad; int no_block = mask & MAY_NOT_BLOCK; + int rc; mask &= (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND); /* @@ -832,7 +988,9 @@ static int smack_inode_permission(struct inode *inode, int mask) return -ECHILD; smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE); smk_ad_setfield_u_fs_inode(&ad, inode); - return smk_curacc(smk_of_inode(inode), mask, &ad); + rc = smk_curacc(smk_of_inode(inode), mask, &ad); + rc = smk_bu_inode(inode, mask, rc); + return rc; } /** @@ -845,6 +1003,8 @@ static int smack_inode_permission(struct inode *inode, int mask) static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) { struct smk_audit_info ad; + int rc; + /* * Need to allow for clearing the setuid bit. */ @@ -853,12 +1013,14 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); - return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); + rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); + rc = smk_bu_inode(dentry->d_inode, MAY_WRITE, rc); + return rc; } /** * smack_inode_getattr - Smack check for getting attributes - * @mnt: unused + * @mnt: vfsmount of the object * @dentry: the object * * Returns 0 if access is permitted, an error code otherwise @@ -867,21 +1029,24 @@ static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) { struct smk_audit_info ad; struct path path; + int rc; path.dentry = dentry; path.mnt = mnt; smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, path); - return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); + rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); + rc = smk_bu_inode(dentry->d_inode, MAY_READ, rc); + return rc; } /** * smack_inode_setxattr - Smack check for setting xattrs * @dentry: the object * @name: name of the attribute - * @value: unused - * @size: unused + * @value: value of the attribute + * @size: size of the value * @flags: unused * * This protects the Smack attribute explicitly. @@ -923,7 +1088,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, rc = -EPERM; if (rc == 0 && check_import) { - skp = smk_import_entry(value, size); + skp = size ? smk_import_entry(value, size) : NULL; if (skp == NULL || (check_star && (skp == &smack_known_star || skp == &smack_known_web))) rc = -EINVAL; @@ -932,8 +1097,10 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); - if (rc == 0) + if (rc == 0) { rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); + rc = smk_bu_inode(dentry->d_inode, MAY_WRITE, rc); + } return rc; } @@ -963,9 +1130,9 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, if (strcmp(name, XATTR_NAME_SMACK) == 0) { skp = smk_import_entry(value, size); if (skp != NULL) - isp->smk_inode = skp->smk_known; + isp->smk_inode = skp; else - isp->smk_inode = smack_known_invalid.smk_known; + isp->smk_inode = &smack_known_invalid; } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) { skp = smk_import_entry(value, size); if (skp != NULL) @@ -993,11 +1160,14 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, static int smack_inode_getxattr(struct dentry *dentry, const char *name) { struct smk_audit_info ad; + int rc; smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY); smk_ad_setfield_u_fs_path_dentry(&ad, dentry); - return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); + rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); + rc = smk_bu_inode(dentry->d_inode, MAY_READ, rc); + return rc; } /** @@ -1033,6 +1203,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) smk_ad_setfield_u_fs_path_dentry(&ad, dentry); rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); + rc = smk_bu_inode(dentry->d_inode, MAY_WRITE, rc); if (rc != 0) return rc; @@ -1070,14 +1241,14 @@ static int smack_inode_getsecurity(const struct inode *inode, struct socket *sock; struct super_block *sbp; struct inode *ip = (struct inode *)inode; - char *isp; + struct smack_known *isp; int ilen; int rc = 0; if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { isp = smk_of_inode(inode); - ilen = strlen(isp) + 1; - *buffer = isp; + ilen = strlen(isp->smk_known); + *buffer = isp->smk_known; return ilen; } @@ -1095,15 +1266,15 @@ static int smack_inode_getsecurity(const struct inode *inode, ssp = sock->sk->sk_security; if (strcmp(name, XATTR_SMACK_IPIN) == 0) - isp = ssp->smk_in->smk_known; + isp = ssp->smk_in; else if (strcmp(name, XATTR_SMACK_IPOUT) == 0) - isp = ssp->smk_out->smk_known; + isp = ssp->smk_out; else return -EOPNOTSUPP; - ilen = strlen(isp) + 1; + ilen = strlen(isp->smk_known); if (rc == 0) { - *buffer = isp; + *buffer = isp->smk_known; rc = ilen; } @@ -1122,13 +1293,12 @@ static int smack_inode_getsecurity(const struct inode *inode, static int smack_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) { - int len = strlen(XATTR_NAME_SMACK); + int len = sizeof(XATTR_NAME_SMACK); - if (buffer != NULL && len <= buffer_size) { + if (buffer != NULL && len <= buffer_size) memcpy(buffer, XATTR_NAME_SMACK, len); - return len; - } - return -EINVAL; + + return len; } /** @@ -1140,7 +1310,7 @@ static void smack_inode_getsecid(const struct inode *inode, u32 *secid) { struct inode_smack *isp = inode->i_security; - *secid = smack_to_secid(isp->smk_inode); + *secid = isp->smk_inode->smk_secid; } /* @@ -1179,7 +1349,7 @@ static int smack_file_alloc_security(struct file *file) { struct smack_known *skp = smk_of_current(); - file->f_security = skp->smk_known; + file->f_security = skp; return 0; } @@ -1214,11 +1384,15 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd, smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_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_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_bu_file(file, MAY_READ, rc); + } return rc; } @@ -1233,10 +1407,13 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd, static int smack_file_lock(struct file *file, unsigned int cmd) { struct smk_audit_info ad; + int rc; smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); - return smk_curacc(file->f_security, MAY_LOCK, &ad); + rc = smk_curacc(file->f_security, MAY_LOCK, &ad); + rc = smk_bu_file(file, MAY_LOCK, rc); + return rc; } /** @@ -1266,12 +1443,14 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd, smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); rc = smk_curacc(file->f_security, MAY_LOCK, &ad); + rc = smk_bu_file(file, MAY_LOCK, rc); break; case F_SETOWN: case F_SETSIG: smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH); smk_ad_setfield_u_fs_path(&ad, file->f_path); rc = smk_curacc(file->f_security, MAY_WRITE, &ad); + rc = smk_bu_file(file, MAY_WRITE, rc); break; default: break; @@ -1298,7 +1477,7 @@ static int smack_mmap_file(struct file *file, struct smack_known *mkp; struct smack_rule *srp; struct task_smack *tsp; - char *osmack; + struct smack_known *okp; struct inode_smack *isp; int may; int mmay; @@ -1324,18 +1503,19 @@ static int smack_mmap_file(struct file *file, * to that rule's object label. */ list_for_each_entry_rcu(srp, &skp->smk_rules, list) { - osmack = srp->smk_object; + okp = srp->smk_object; /* * Matching labels always allows access. */ - if (mkp->smk_known == osmack) + if (mkp->smk_known == okp->smk_known) continue; /* * If there is a matching local rule take * that into account as well. */ - may = smk_access_entry(srp->smk_subject->smk_known, osmack, - &tsp->smk_rules); + may = smk_access_entry(srp->smk_subject->smk_known, + okp->smk_known, + &tsp->smk_rules); if (may == -ENOENT) may = srp->smk_access; else @@ -1352,8 +1532,8 @@ static int smack_mmap_file(struct file *file, * If there isn't one a SMACK64MMAP subject * can't have as much access as current. */ - mmay = smk_access_entry(mkp->smk_known, osmack, - &mkp->smk_rules); + mmay = smk_access_entry(mkp->smk_known, okp->smk_known, + &mkp->smk_rules); if (mmay == -ENOENT) { rc = -EACCES; break; @@ -1362,8 +1542,8 @@ static int smack_mmap_file(struct file *file, * If there is a local entry it modifies the * potential access, too. */ - tmay = smk_access_entry(mkp->smk_known, osmack, - &tsp->smk_rules); + tmay = smk_access_entry(mkp->smk_known, okp->smk_known, + &tsp->smk_rules); if (tmay != -ENOENT) mmay &= tmay; @@ -1394,7 +1574,7 @@ static void smack_file_set_fowner(struct file *file) { struct smack_known *skp = smk_of_current(); - file->f_security = skp->smk_known; + file->f_security = skp; } /** @@ -1423,14 +1603,15 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, file = container_of(fown, struct file, f_owner); /* we don't log here as rc can be overriden */ - skp = smk_find_entry(file->f_security); - rc = smk_access(skp, tkp->smk_known, MAY_WRITE, NULL); + skp = file->f_security; + rc = smk_access(skp, tkp, MAY_WRITE, NULL); + rc = smk_bu_note("sigiotask", skp, tkp, MAY_WRITE, rc); if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE)) rc = 0; smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); smk_ad_setfield_u_tsk(&ad, tsk); - smack_log(file->f_security, tkp->smk_known, MAY_WRITE, rc, &ad); + smack_log(skp->smk_known, tkp->smk_known, MAY_WRITE, rc, &ad); return rc; } @@ -1442,6 +1623,7 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, */ static int smack_file_receive(struct file *file) { + int rc; int may = 0; struct smk_audit_info ad; @@ -1455,7 +1637,9 @@ static int smack_file_receive(struct file *file) if (file->f_mode & FMODE_WRITE) may |= MAY_WRITE; - return smk_curacc(file->f_security, may, &ad); + rc = smk_curacc(file->f_security, may, &ad); + rc = smk_bu_file(file, may, rc); + return rc; } /** @@ -1477,12 +1661,15 @@ static int smack_file_open(struct file *file, const struct cred *cred) struct smk_audit_info ad; int rc; - if (smack_privileged(CAP_MAC_OVERRIDE)) + if (smack_privileged(CAP_MAC_OVERRIDE)) { + file->f_security = isp->smk_inode; return 0; + } smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_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_bu_credfile(cred, file, MAY_READ, rc); if (rc == 0) file->f_security = isp->smk_inode; @@ -1621,7 +1808,7 @@ static int smack_kernel_create_files_as(struct cred *new, struct inode_smack *isp = inode->i_security; struct task_smack *tsp = new->security; - tsp->smk_forked = smk_find_entry(isp->smk_inode); + tsp->smk_forked = isp->smk_inode; tsp->smk_task = tsp->smk_forked; return 0; } @@ -1639,10 +1826,13 @@ static int smk_curacc_on_task(struct task_struct *p, int access, { struct smk_audit_info ad; struct smack_known *skp = smk_of_task(task_security(p)); + int rc; smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK); smk_ad_setfield_u_tsk(&ad, p); - return smk_curacc(skp->smk_known, access, &ad); + rc = smk_curacc(skp, access, &ad); + rc = smk_bu_task(p, access, rc); + return rc; } /** @@ -1796,6 +1986,7 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, struct smk_audit_info ad; struct smack_known *skp; struct smack_known *tkp = smk_of_task(task_security(p)); + int rc; smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); smk_ad_setfield_u_tsk(&ad, p); @@ -1803,15 +1994,20 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info, * Sending a signal requires that the sender * can write the receiver. */ - if (secid == 0) - return smk_curacc(tkp->smk_known, MAY_WRITE, &ad); + if (secid == 0) { + rc = smk_curacc(tkp, MAY_WRITE, &ad); + rc = smk_bu_task(p, MAY_WRITE, rc); + return rc; + } /* * If the secid isn't 0 we're dealing with some USB IO * specific behavior. This is not clean. For one thing * we can't take privilege into account. */ skp = smack_from_secid(secid); - return smk_access(skp, tkp->smk_known, MAY_WRITE, &ad); + rc = smk_access(skp, tkp, MAY_WRITE, &ad); + rc = smk_bu_note("USB signal", skp, tkp, MAY_WRITE, rc); + return rc; } /** @@ -1845,7 +2041,7 @@ static void smack_task_to_inode(struct task_struct *p, struct inode *inode) struct inode_smack *isp = inode->i_security; struct smack_known *skp = smk_of_task(task_security(p)); - isp->smk_inode = skp->smk_known; + isp->smk_inode = skp; } /* @@ -1903,7 +2099,7 @@ static void smack_sk_free_security(struct sock *sk) * * Returns the label of the far end or NULL if it's not special. */ -static char *smack_host_label(struct sockaddr_in *sip) +static struct smack_known *smack_host_label(struct sockaddr_in *sip) { struct smk_netlbladdr *snp; struct in_addr *siap = &sip->sin_addr; @@ -1920,7 +2116,7 @@ static char *smack_host_label(struct sockaddr_in *sip) if ((&snp->smk_host.sin_addr)->s_addr == (siap->s_addr & (&snp->smk_mask)->s_addr)) { /* we have found the special CIPSO option */ - if (snp->smk_label == smack_cipso_option) + if (snp->smk_label == &smack_cipso_option) return NULL; return snp->smk_label; } @@ -1985,13 +2181,13 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) struct smack_known *skp; int rc; int sk_lbl; - char *hostsp; + struct smack_known *hkp; struct socket_smack *ssp = sk->sk_security; struct smk_audit_info ad; rcu_read_lock(); - hostsp = smack_host_label(sap); - if (hostsp != NULL) { + hkp = smack_host_label(sap); + if (hkp != NULL) { #ifdef CONFIG_AUDIT struct lsm_network_audit net; @@ -2002,7 +2198,8 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) #endif sk_lbl = SMACK_UNLABELED_SOCKET; skp = ssp->smk_out; - rc = smk_access(skp, hostsp, MAY_WRITE, &ad); + rc = smk_access(skp, hkp, MAY_WRITE, &ad); + rc = smk_bu_note("IPv4 host check", skp, hkp, MAY_WRITE, rc); } else { sk_lbl = SMACK_CIPSO_SOCKET; rc = 0; @@ -2103,18 +2300,19 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, struct socket_smack *ssp = sk->sk_security; struct smack_known *skp; unsigned short port = 0; - char *object; + struct smack_known *object; struct smk_audit_info ad; + int rc; #ifdef CONFIG_AUDIT struct lsm_network_audit net; #endif if (act == SMK_RECEIVING) { skp = smack_net_ambient; - object = ssp->smk_in->smk_known; + object = ssp->smk_in; } else { skp = ssp->smk_out; - object = smack_net_ambient->smk_known; + object = smack_net_ambient; } /* @@ -2141,7 +2339,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address, list_for_each_entry(spp, &smk_ipv6_port_list, list) { if (spp->smk_port != port) continue; - object = spp->smk_in->smk_known; + object = spp->smk_in; if (act == SMK_CONNECTING) ssp->smk_packet = spp->smk_out; break; @@ -2158,7 +2356,9 @@ auditout: else ad.a.u.net->v6info.daddr = address->sin6_addr; #endif - return smk_access(skp, object, MAY_WRITE, &ad); + rc = smk_access(skp, object, MAY_WRITE, &ad); + rc = smk_bu_note("IPv6 port check", skp, object, MAY_WRITE, rc); + return rc; } /** @@ -2190,7 +2390,7 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, return -EINVAL; if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { - nsp->smk_inode = skp->smk_known; + nsp->smk_inode = skp; nsp->smk_flags |= SMK_INODE_INSTANT; return 0; } @@ -2332,7 +2532,7 @@ static int smack_msg_msg_alloc_security(struct msg_msg *msg) { struct smack_known *skp = smk_of_current(); - msg->security = skp->smk_known; + msg->security = skp; return 0; } @@ -2353,9 +2553,9 @@ static void smack_msg_msg_free_security(struct msg_msg *msg) * * Returns a pointer to the smack value */ -static char *smack_of_shm(struct shmid_kernel *shp) +static struct smack_known *smack_of_shm(struct shmid_kernel *shp) { - return (char *)shp->shm_perm.security; + return (struct smack_known *)shp->shm_perm.security; } /** @@ -2369,7 +2569,7 @@ static int smack_shm_alloc_security(struct shmid_kernel *shp) struct kern_ipc_perm *isp = &shp->shm_perm; struct smack_known *skp = smk_of_current(); - isp->security = skp->smk_known; + isp->security = skp; return 0; } @@ -2395,14 +2595,17 @@ static void smack_shm_free_security(struct shmid_kernel *shp) */ static int smk_curacc_shm(struct shmid_kernel *shp, int access) { - char *ssp = smack_of_shm(shp); + struct smack_known *ssp = smack_of_shm(shp); struct smk_audit_info ad; + int rc; #ifdef CONFIG_AUDIT smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); ad.a.u.ipc_id = shp->shm_perm.id; #endif - return smk_curacc(ssp, access, &ad); + rc = smk_curacc(ssp, access, &ad); + rc = smk_bu_current("shm", ssp, access, rc); + return rc; } /** @@ -2477,9 +2680,9 @@ static int smack_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, * * Returns a pointer to the smack value */ -static char *smack_of_sem(struct sem_array *sma) +static struct smack_known *smack_of_sem(struct sem_array *sma) { - return (char *)sma->sem_perm.security; + return (struct smack_known *)sma->sem_perm.security; } /** @@ -2493,7 +2696,7 @@ static int smack_sem_alloc_security(struct sem_array *sma) struct kern_ipc_perm *isp = &sma->sem_perm; struct smack_known *skp = smk_of_current(); - isp->security = skp->smk_known; + isp->security = skp; return 0; } @@ -2519,14 +2722,17 @@ static void smack_sem_free_security(struct sem_array *sma) */ static int smk_curacc_sem(struct sem_array *sma, int access) { - char *ssp = smack_of_sem(sma); + struct smack_known *ssp = smack_of_sem(sma); struct smk_audit_info ad; + int rc; #ifdef CONFIG_AUDIT smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); ad.a.u.ipc_id = sma->sem_perm.id; #endif - return smk_curacc(ssp, access, &ad); + rc = smk_curacc(ssp, access, &ad); + rc = smk_bu_current("sem", ssp, access, rc); + return rc; } /** @@ -2612,7 +2818,7 @@ static int smack_msg_queue_alloc_security(struct msg_queue *msq) struct kern_ipc_perm *kisp = &msq->q_perm; struct smack_known *skp = smk_of_current(); - kisp->security = skp->smk_known; + kisp->security = skp; return 0; } @@ -2633,11 +2839,11 @@ static void smack_msg_queue_free_security(struct msg_queue *msq) * smack_of_msq - the smack pointer for the msq * @msq: the object * - * Returns a pointer to the smack value + * Returns a pointer to the smack label entry */ -static char *smack_of_msq(struct msg_queue *msq) +static struct smack_known *smack_of_msq(struct msg_queue *msq) { - return (char *)msq->q_perm.security; + return (struct smack_known *)msq->q_perm.security; } /** @@ -2649,14 +2855,17 @@ static char *smack_of_msq(struct msg_queue *msq) */ static int smk_curacc_msq(struct msg_queue *msq, int access) { - char *msp = smack_of_msq(msq); + struct smack_known *msp = smack_of_msq(msq); struct smk_audit_info ad; + int rc; #ifdef CONFIG_AUDIT smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); ad.a.u.ipc_id = msq->q_perm.id; #endif - return smk_curacc(msp, access, &ad); + rc = smk_curacc(msp, access, &ad); + rc = smk_bu_current("msq", msp, access, rc); + return rc; } /** @@ -2749,15 +2958,18 @@ static int smack_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, */ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) { - char *isp = ipp->security; + struct smack_known *iskp = ipp->security; int may = smack_flags_to_may(flag); struct smk_audit_info ad; + int rc; #ifdef CONFIG_AUDIT smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_IPC); ad.a.u.ipc_id = ipp->id; #endif - return smk_curacc(isp, may, &ad); + rc = smk_curacc(iskp, may, &ad); + rc = smk_bu_current("svipc", iskp, may, rc); + return rc; } /** @@ -2767,9 +2979,9 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) */ static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid) { - char *smack = ipp->security; + struct smack_known *iskp = ipp->security; - *secid = smack_to_secid(smack); + *secid = iskp->smk_secid; } /** @@ -2786,7 +2998,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) struct inode_smack *isp; struct smack_known *skp; struct smack_known *ckp = smk_of_current(); - char *final; + struct smack_known *final; char trattr[TRANS_TRUE_SIZE]; int transflag = 0; int rc; @@ -2826,8 +3038,8 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) * so there's no opportunity to set the mount * options. */ - sbsp->smk_root = smack_known_star.smk_known; - sbsp->smk_default = smack_known_star.smk_known; + sbsp->smk_root = &smack_known_star; + sbsp->smk_default = &smack_known_star; } isp->smk_inode = sbsp->smk_root; isp->smk_flags |= SMK_INODE_INSTANT; @@ -2857,7 +3069,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) * * Cgroupfs is special */ - final = smack_known_star.smk_known; + final = &smack_known_star; break; case DEVPTS_SUPER_MAGIC: /* @@ -2865,7 +3077,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) * Programs that change smack have to treat the * pty with respect. */ - final = ckp->smk_known; + final = ckp; break; case PROC_SUPER_MAGIC: /* @@ -2879,7 +3091,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) * but watch out, because they're volitile, * getting recreated on every reboot. */ - final = smack_known_star.smk_known; + final = &smack_known_star; /* * No break. * @@ -2898,7 +3110,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) * UNIX domain sockets use lower level socket data. */ if (S_ISSOCK(inode->i_mode)) { - final = smack_known_star.smk_known; + final = &smack_known_star; break; } /* @@ -2915,7 +3127,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) dp = dget(opt_dentry); skp = smk_fetch(XATTR_NAME_SMACK, inode, dp); if (skp != NULL) - final = skp->smk_known; + final = skp; /* * Transmuting directory @@ -2964,7 +3176,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) } if (final == NULL) - isp->smk_inode = ckp->smk_known; + isp->smk_inode = ckp; else isp->smk_inode = final; @@ -3089,9 +3301,13 @@ static int smack_unix_stream_connect(struct sock *sock, smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); smk_ad_setfield_u_net_sk(&ad, other); #endif - rc = smk_access(skp, okp->smk_known, MAY_WRITE, &ad); - if (rc == 0) - rc = smk_access(okp, okp->smk_known, MAY_WRITE, NULL); + rc = smk_access(skp, okp, MAY_WRITE, &ad); + rc = smk_bu_note("UDS connect", skp, okp, MAY_WRITE, rc); + if (rc == 0) { + rc = smk_access(okp, skp, MAY_WRITE, NULL); + rc = smk_bu_note("UDS connect", okp, skp, + MAY_WRITE, rc); + } } /* @@ -3117,8 +3333,8 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) { struct socket_smack *ssp = sock->sk->sk_security; struct socket_smack *osp = other->sk->sk_security; - struct smack_known *skp; struct smk_audit_info ad; + int rc; #ifdef CONFIG_AUDIT struct lsm_network_audit net; @@ -3130,8 +3346,9 @@ static int smack_unix_may_send(struct socket *sock, struct socket *other) if (smack_privileged(CAP_MAC_OVERRIDE)) return 0; - skp = ssp->smk_out; - return smk_access(skp, osp->smk_in->smk_known, MAY_WRITE, &ad); + rc = smk_access(ssp->smk_out, osp->smk_in, MAY_WRITE, &ad); + rc = smk_bu_note("UDS send", ssp->smk_out, osp->smk_in, MAY_WRITE, rc); + return rc; } /** @@ -3345,7 +3562,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) * This is the simplist possible security model * for networking. */ - rc = smk_access(skp, ssp->smk_in->smk_known, MAY_WRITE, &ad); + rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); + rc = smk_bu_note("IPv4 delivery", skp, ssp->smk_in, + MAY_WRITE, rc); if (rc != 0) netlbl_skbuff_err(skb, rc, 0); break; @@ -3488,7 +3707,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, struct netlbl_lsm_secattr secattr; struct sockaddr_in addr; struct iphdr *hdr; - char *hsp; + struct smack_known *hskp; int rc; struct smk_audit_info ad; #ifdef CONFIG_AUDIT @@ -3525,7 +3744,8 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, * Receiving a packet requires that the other end be able to write * here. Read access is not required. */ - rc = smk_access(skp, ssp->smk_in->smk_known, MAY_WRITE, &ad); + rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); + rc = smk_bu_note("IPv4 connect", skp, ssp->smk_in, MAY_WRITE, rc); if (rc != 0) return rc; @@ -3543,10 +3763,10 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, hdr = ip_hdr(skb); addr.sin_addr.s_addr = hdr->saddr; rcu_read_lock(); - hsp = smack_host_label(&addr); + hskp = smack_host_label(&addr); rcu_read_unlock(); - if (hsp == NULL) + if (hskp == NULL) rc = netlbl_req_setattr(req, &skp->smk_netlabel); else netlbl_req_delattr(req); @@ -3598,7 +3818,7 @@ static int smack_key_alloc(struct key *key, const struct cred *cred, { struct smack_known *skp = smk_of_task(cred->security); - key->security = skp->smk_known; + key->security = skp; return 0; } @@ -3629,6 +3849,7 @@ static int smack_key_permission(key_ref_t key_ref, struct smk_audit_info ad; struct smack_known *tkp = smk_of_task(cred->security); int request = 0; + int rc; keyp = key_ref_to_ptr(key_ref); if (keyp == NULL) @@ -3653,7 +3874,9 @@ static int smack_key_permission(key_ref_t key_ref, request = MAY_READ; if (perm & (KEY_NEED_WRITE | KEY_NEED_LINK | KEY_NEED_SETATTR)) request = MAY_WRITE; - return smk_access(tkp, keyp->security, request, &ad); + rc = smk_access(tkp, keyp->security, request, &ad); + rc = smk_bu_note("key access", tkp, keyp->security, request, rc); + return rc; } #endif /* CONFIG_KEYS */ @@ -3684,6 +3907,7 @@ static int smack_key_permission(key_ref_t key_ref, */ static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) { + struct smack_known *skp; char **rule = (char **)vrule; *rule = NULL; @@ -3693,7 +3917,9 @@ static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule) if (op != Audit_equal && op != Audit_not_equal) return -EINVAL; - *rule = smk_import(rulestr, 0); + skp = smk_import_entry(rulestr, 0); + if (skp) + *rule = skp->smk_known; return 0; } @@ -3812,7 +4038,12 @@ static int smack_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) */ static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) { - *secid = smack_to_secid(secdata); + struct smack_known *skp = smk_find_entry(secdata); + + if (skp) + *secid = skp->smk_secid; + else + *secid = 0; return 0; } |