aboutsummaryrefslogtreecommitdiffstats
path: root/security/smack/smackfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/smack/smackfs.c')
-rw-r--r--security/smack/smackfs.c66
1 files changed, 22 insertions, 44 deletions
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index 358c92c1a153..cfae8afcc262 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -74,17 +74,25 @@ struct smk_list_entry *smack_list;
74#define SEQ_READ_FINISHED 1 74#define SEQ_READ_FINISHED 1
75 75
76/* 76/*
77 * Disable concurrent writing open() operations
78 */
79static struct semaphore smack_write_sem;
80
81/*
82 * Values for parsing cipso rules 77 * Values for parsing cipso rules
83 * SMK_DIGITLEN: Length of a digit field in a rule. 78 * SMK_DIGITLEN: Length of a digit field in a rule.
84 * SMK_CIPSOMEN: Minimum possible cipso rule length. 79 * SMK_CIPSOMIN: Minimum possible cipso rule length.
80 * SMK_CIPSOMAX: Maximum possible cipso rule length.
85 */ 81 */
86#define SMK_DIGITLEN 4 82#define SMK_DIGITLEN 4
87#define SMK_CIPSOMIN (SMK_MAXLEN + 2 * SMK_DIGITLEN) 83#define SMK_CIPSOMIN (SMK_LABELLEN + 2 * SMK_DIGITLEN)
84#define SMK_CIPSOMAX (SMK_CIPSOMIN + SMACK_CIPSO_MAXCATNUM * SMK_DIGITLEN)
85
86/*
87 * Values for parsing MAC rules
88 * SMK_ACCESS: Maximum possible combination of access permissions
89 * SMK_ACCESSLEN: Maximum length for a rule access field
90 * SMK_LOADLEN: Smack rule length
91 */
92#define SMK_ACCESS "rwxa"
93#define SMK_ACCESSLEN (sizeof(SMK_ACCESS) - 1)
94#define SMK_LOADLEN (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSLEN)
95
88 96
89/* 97/*
90 * Seq_file read operations for /smack/load 98 * Seq_file read operations for /smack/load
@@ -155,32 +163,7 @@ static struct seq_operations load_seq_ops = {
155 */ 163 */
156static int smk_open_load(struct inode *inode, struct file *file) 164static int smk_open_load(struct inode *inode, struct file *file)
157{ 165{
158 if ((file->f_flags & O_ACCMODE) == O_RDONLY) 166 return seq_open(file, &load_seq_ops);
159 return seq_open(file, &load_seq_ops);
160
161 if (down_interruptible(&smack_write_sem))
162 return -ERESTARTSYS;
163
164 return 0;
165}
166
167/**
168 * smk_release_load - release() for /smack/load
169 * @inode: inode structure representing file
170 * @file: "load" file pointer
171 *
172 * For a reading session, use the seq_file release
173 * implementation.
174 * Otherwise, we are at the end of a writing session so
175 * clean everything up.
176 */
177static int smk_release_load(struct inode *inode, struct file *file)
178{
179 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
180 return seq_release(inode, file);
181
182 up(&smack_write_sem);
183 return 0;
184} 167}
185 168
186/** 169/**
@@ -229,14 +212,10 @@ static void smk_set_access(struct smack_rule *srp)
229 * The format is exactly: 212 * The format is exactly:
230 * char subject[SMK_LABELLEN] 213 * char subject[SMK_LABELLEN]
231 * char object[SMK_LABELLEN] 214 * char object[SMK_LABELLEN]
232 * char access[SMK_ACCESSKINDS] 215 * char access[SMK_ACCESSLEN]
233 *
234 * Anything following is commentary and ignored.
235 * 216 *
236 * writes must be SMK_LABELLEN+SMK_LABELLEN+4 bytes. 217 * writes must be SMK_LABELLEN+SMK_LABELLEN+SMK_ACCESSLEN bytes.
237 */ 218 */
238#define MINIMUM_LOAD (SMK_LABELLEN + SMK_LABELLEN + SMK_ACCESSKINDS)
239
240static ssize_t smk_write_load(struct file *file, const char __user *buf, 219static ssize_t smk_write_load(struct file *file, const char __user *buf,
241 size_t count, loff_t *ppos) 220 size_t count, loff_t *ppos)
242{ 221{
@@ -253,7 +232,7 @@ static ssize_t smk_write_load(struct file *file, const char __user *buf,
253 return -EPERM; 232 return -EPERM;
254 if (*ppos != 0) 233 if (*ppos != 0)
255 return -EINVAL; 234 return -EINVAL;
256 if (count < MINIMUM_LOAD) 235 if (count != SMK_LOADLEN)
257 return -EINVAL; 236 return -EINVAL;
258 237
259 data = kzalloc(count, GFP_KERNEL); 238 data = kzalloc(count, GFP_KERNEL);
@@ -332,7 +311,7 @@ static const struct file_operations smk_load_ops = {
332 .read = seq_read, 311 .read = seq_read,
333 .llseek = seq_lseek, 312 .llseek = seq_lseek,
334 .write = smk_write_load, 313 .write = smk_write_load,
335 .release = smk_release_load, 314 .release = seq_release,
336}; 315};
337 316
338/** 317/**
@@ -513,7 +492,7 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
513 return -EPERM; 492 return -EPERM;
514 if (*ppos != 0) 493 if (*ppos != 0)
515 return -EINVAL; 494 return -EINVAL;
516 if (count <= SMK_CIPSOMIN) 495 if (count < SMK_CIPSOMIN || count > SMK_CIPSOMAX)
517 return -EINVAL; 496 return -EINVAL;
518 497
519 data = kzalloc(count + 1, GFP_KERNEL); 498 data = kzalloc(count + 1, GFP_KERNEL);
@@ -547,7 +526,7 @@ static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
547 if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM) 526 if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM)
548 goto out; 527 goto out;
549 528
550 if (count <= (SMK_CIPSOMIN + catlen * SMK_DIGITLEN)) 529 if (count != (SMK_CIPSOMIN + catlen * SMK_DIGITLEN))
551 goto out; 530 goto out;
552 531
553 memset(mapcatset, 0, sizeof(mapcatset)); 532 memset(mapcatset, 0, sizeof(mapcatset));
@@ -1002,7 +981,6 @@ static int __init init_smk_fs(void)
1002 } 981 }
1003 } 982 }
1004 983
1005 sema_init(&smack_write_sem, 1);
1006 smk_cipso_doi(); 984 smk_cipso_doi();
1007 smk_unlbl_ambient(NULL); 985 smk_unlbl_ambient(NULL);
1008 986