Smack: Repair processing of fcntl

Al Viro pointed out that the processing of fcntl done
by Smack appeared poorly designed. He was right. There
are three things that required change. Most obviously,
the list of commands that really imply writing is limited
to those involving file locking and signal handling.
The initialization if the file security blob was
incomplete, requiring use of a heretofore unused LSM hook.
Finally, the audit information coming from a helper
masked the identity of the LSM hook. This patch corrects
all three of these defects.

This is targeted for the smack-next tree pending comments.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
This commit is contained in:
Casey Schaufler 2011-09-19 12:41:42 -07:00 committed by Casey Schaufler
parent 272cd7a8c6
commit 531f1d453e

View file

@ -1091,36 +1091,31 @@ static int smack_file_lock(struct file *file, unsigned int cmd)
* @cmd: what action to check * @cmd: what action to check
* @arg: unused * @arg: unused
* *
* Generally these operations are harmless.
* File locking operations present an obvious mechanism
* for passing information, so they require write access.
*
* Returns 0 if current has access, error code otherwise * Returns 0 if current has access, error code otherwise
*/ */
static int smack_file_fcntl(struct file *file, unsigned int cmd, static int smack_file_fcntl(struct file *file, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
struct smk_audit_info ad; struct smk_audit_info ad;
int rc; int rc = 0;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
smk_ad_setfield_u_fs_path(&ad, file->f_path);
switch (cmd) { switch (cmd) {
case F_DUPFD:
case F_GETFD:
case F_GETFL:
case F_GETLK: case F_GETLK:
case F_GETOWN:
case F_GETSIG:
rc = smk_curacc(file->f_security, MAY_READ, &ad);
break;
case F_SETFD:
case F_SETFL:
case F_SETLK: case F_SETLK:
case F_SETLKW: case F_SETLKW:
case F_SETOWN: case F_SETOWN:
case F_SETSIG: 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_curacc(file->f_security, MAY_WRITE, &ad);
break; break;
default: default:
rc = smk_curacc(file->f_security, MAY_READWRITE, &ad); break;
} }
return rc; return rc;
@ -1314,6 +1309,24 @@ static int smack_file_receive(struct file *file)
return smk_curacc(file->f_security, may, &ad); return smk_curacc(file->f_security, may, &ad);
} }
/**
* smack_dentry_open - Smack dentry open processing
* @file: the object
* @cred: unused
*
* Set the security blob in the file structure.
*
* Returns 0
*/
static int smack_dentry_open(struct file *file, const struct cred *cred)
{
struct inode_smack *isp = file->f_path.dentry->d_inode->i_security;
file->f_security = isp->smk_inode;
return 0;
}
/* /*
* Task hooks * Task hooks
*/ */
@ -1454,15 +1467,17 @@ static int smack_kernel_create_files_as(struct cred *new,
/** /**
* smk_curacc_on_task - helper to log task related access * smk_curacc_on_task - helper to log task related access
* @p: the task object * @p: the task object
* @access : the access requested * @access: the access requested
* @caller: name of the calling function for audit
* *
* Return 0 if access is permitted * Return 0 if access is permitted
*/ */
static int smk_curacc_on_task(struct task_struct *p, int access) static int smk_curacc_on_task(struct task_struct *p, int access,
const char *caller)
{ {
struct smk_audit_info ad; struct smk_audit_info ad;
smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_TASK); smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
smk_ad_setfield_u_tsk(&ad, p); smk_ad_setfield_u_tsk(&ad, p);
return smk_curacc(smk_of_task(task_security(p)), access, &ad); return smk_curacc(smk_of_task(task_security(p)), access, &ad);
} }
@ -1476,7 +1491,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access)
*/ */
static int smack_task_setpgid(struct task_struct *p, pid_t pgid) static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
{ {
return smk_curacc_on_task(p, MAY_WRITE); return smk_curacc_on_task(p, MAY_WRITE, __func__);
} }
/** /**
@ -1487,7 +1502,7 @@ static int smack_task_setpgid(struct task_struct *p, pid_t pgid)
*/ */
static int smack_task_getpgid(struct task_struct *p) static int smack_task_getpgid(struct task_struct *p)
{ {
return smk_curacc_on_task(p, MAY_READ); return smk_curacc_on_task(p, MAY_READ, __func__);
} }
/** /**
@ -1498,7 +1513,7 @@ static int smack_task_getpgid(struct task_struct *p)
*/ */
static int smack_task_getsid(struct task_struct *p) static int smack_task_getsid(struct task_struct *p)
{ {
return smk_curacc_on_task(p, MAY_READ); return smk_curacc_on_task(p, MAY_READ, __func__);
} }
/** /**
@ -1526,7 +1541,7 @@ static int smack_task_setnice(struct task_struct *p, int nice)
rc = cap_task_setnice(p, nice); rc = cap_task_setnice(p, nice);
if (rc == 0) if (rc == 0)
rc = smk_curacc_on_task(p, MAY_WRITE); rc = smk_curacc_on_task(p, MAY_WRITE, __func__);
return rc; return rc;
} }
@ -1543,7 +1558,7 @@ static int smack_task_setioprio(struct task_struct *p, int ioprio)
rc = cap_task_setioprio(p, ioprio); rc = cap_task_setioprio(p, ioprio);
if (rc == 0) if (rc == 0)
rc = smk_curacc_on_task(p, MAY_WRITE); rc = smk_curacc_on_task(p, MAY_WRITE, __func__);
return rc; return rc;
} }
@ -1555,7 +1570,7 @@ static int smack_task_setioprio(struct task_struct *p, int ioprio)
*/ */
static int smack_task_getioprio(struct task_struct *p) static int smack_task_getioprio(struct task_struct *p)
{ {
return smk_curacc_on_task(p, MAY_READ); return smk_curacc_on_task(p, MAY_READ, __func__);
} }
/** /**
@ -1572,7 +1587,7 @@ static int smack_task_setscheduler(struct task_struct *p)
rc = cap_task_setscheduler(p); rc = cap_task_setscheduler(p);
if (rc == 0) if (rc == 0)
rc = smk_curacc_on_task(p, MAY_WRITE); rc = smk_curacc_on_task(p, MAY_WRITE, __func__);
return rc; return rc;
} }
@ -1584,7 +1599,7 @@ static int smack_task_setscheduler(struct task_struct *p)
*/ */
static int smack_task_getscheduler(struct task_struct *p) static int smack_task_getscheduler(struct task_struct *p)
{ {
return smk_curacc_on_task(p, MAY_READ); return smk_curacc_on_task(p, MAY_READ, __func__);
} }
/** /**
@ -1595,7 +1610,7 @@ static int smack_task_getscheduler(struct task_struct *p)
*/ */
static int smack_task_movememory(struct task_struct *p) static int smack_task_movememory(struct task_struct *p)
{ {
return smk_curacc_on_task(p, MAY_WRITE); return smk_curacc_on_task(p, MAY_WRITE, __func__);
} }
/** /**
@ -3468,6 +3483,8 @@ struct security_operations smack_ops = {
.file_send_sigiotask = smack_file_send_sigiotask, .file_send_sigiotask = smack_file_send_sigiotask,
.file_receive = smack_file_receive, .file_receive = smack_file_receive,
.dentry_open = smack_dentry_open,
.cred_alloc_blank = smack_cred_alloc_blank, .cred_alloc_blank = smack_cred_alloc_blank,
.cred_free = smack_cred_free, .cred_free = smack_cred_free,
.cred_prepare = smack_cred_prepare, .cred_prepare = smack_cred_prepare,