aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/selinuxfs.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-12 20:11:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-12 20:11:47 -0500
commit33caf82acf4dc420bf0f0136b886f7b27ecf90c5 (patch)
treeb24b0b5c8f257ae7db3b8df939821a0856869895 /security/selinux/selinuxfs.c
parentca9706a282943899981e83604f2ed13e88ce4239 (diff)
parentbbddca8e8fac07ece3938e03526b5d00fa791a4c (diff)
Merge branch 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull misc vfs updates from Al Viro: "All kinds of stuff. That probably should've been 5 or 6 separate branches, but by the time I'd realized how large and mixed that bag had become it had been too close to -final to play with rebasing. Some fs/namei.c cleanups there, memdup_user_nul() introduction and switching open-coded instances, burying long-dead code, whack-a-mole of various kinds, several new helpers for ->llseek(), assorted cleanups and fixes from various people, etc. One piece probably deserves special mention - Neil's lookup_one_len_unlocked(). Similar to lookup_one_len(), but gets called without ->i_mutex and tries to avoid ever taking it. That, of course, means that it's not useful for any directory modifications, but things like getting inode attributes in nfds readdirplus are fine with that. I really should've asked for moratorium on lookup-related changes this cycle, but since I hadn't done that early enough... I *am* asking for that for the coming cycle, though - I'm going to try and get conversion of i_mutex to rwsem with ->lookup() done under lock taken shared. There will be a patch closer to the end of the window, along the lines of the one Linus had posted last May - mechanical conversion of ->i_mutex accesses to inode_lock()/inode_unlock()/inode_trylock()/ inode_is_locked()/inode_lock_nested(). To quote Linus back then: ----- | This is an automated patch using | | sed 's/mutex_lock(&\(.*\)->i_mutex)/inode_lock(\1)/' | sed 's/mutex_unlock(&\(.*\)->i_mutex)/inode_unlock(\1)/' | sed 's/mutex_lock_nested(&\(.*\)->i_mutex,[ ]*I_MUTEX_\([A-Z0-9_]*\))/inode_lock_nested(\1, I_MUTEX_\2)/' | sed 's/mutex_is_locked(&\(.*\)->i_mutex)/inode_is_locked(\1)/' | sed 's/mutex_trylock(&\(.*\)->i_mutex)/inode_trylock(\1)/' | | with a very few manual fixups ----- I'm going to send that once the ->i_mutex-affecting stuff in -next gets mostly merged (or when Linus says he's about to stop taking merges)" * 'work.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (63 commits) nfsd: don't hold i_mutex over userspace upcalls fs:affs:Replace time_t with time64_t fs/9p: use fscache mutex rather than spinlock proc: add a reschedule point in proc_readfd_common() logfs: constify logfs_block_ops structures fcntl: allow to set O_DIRECT flag on pipe fs: __generic_file_splice_read retry lookup on AOP_TRUNCATED_PAGE fs: xattr: Use kvfree() [s390] page_to_phys() always returns a multiple of PAGE_SIZE nbd: use ->compat_ioctl() fs: use block_device name vsprintf helper lib/vsprintf: add %*pg format specifier fs: use gendisk->disk_name where possible poll: plug an unused argument to do_poll amdkfd: don't open-code memdup_user() cdrom: don't open-code memdup_user() rsxx: don't open-code memdup_user() mtip32xx: don't open-code memdup_user() [um] mconsole: don't open-code memdup_user_nul() [um] hostaudio: don't open-code memdup_user() ...
Diffstat (limited to 'security/selinux/selinuxfs.c')
-rw-r--r--security/selinux/selinuxfs.c114
1 files changed, 41 insertions, 73 deletions
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index c02da25d7b63..73c60baa90a4 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -147,23 +147,16 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
147 ssize_t length; 147 ssize_t length;
148 int new_value; 148 int new_value;
149 149
150 length = -ENOMEM;
151 if (count >= PAGE_SIZE) 150 if (count >= PAGE_SIZE)
152 goto out; 151 return -ENOMEM;
153 152
154 /* No partial writes. */ 153 /* No partial writes. */
155 length = -EINVAL;
156 if (*ppos != 0) 154 if (*ppos != 0)
157 goto out; 155 return -EINVAL;
158
159 length = -ENOMEM;
160 page = (char *)get_zeroed_page(GFP_KERNEL);
161 if (!page)
162 goto out;
163 156
164 length = -EFAULT; 157 page = memdup_user_nul(buf, count);
165 if (copy_from_user(page, buf, count)) 158 if (IS_ERR(page))
166 goto out; 159 return PTR_ERR(page);
167 160
168 length = -EINVAL; 161 length = -EINVAL;
169 if (sscanf(page, "%d", &new_value) != 1) 162 if (sscanf(page, "%d", &new_value) != 1)
@@ -186,7 +179,7 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
186 } 179 }
187 length = count; 180 length = count;
188out: 181out:
189 free_page((unsigned long) page); 182 kfree(page);
190 return length; 183 return length;
191} 184}
192#else 185#else
@@ -275,27 +268,20 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf,
275 size_t count, loff_t *ppos) 268 size_t count, loff_t *ppos)
276 269
277{ 270{
278 char *page = NULL; 271 char *page;
279 ssize_t length; 272 ssize_t length;
280 int new_value; 273 int new_value;
281 274
282 length = -ENOMEM;
283 if (count >= PAGE_SIZE) 275 if (count >= PAGE_SIZE)
284 goto out; 276 return -ENOMEM;
285 277
286 /* No partial writes. */ 278 /* No partial writes. */
287 length = -EINVAL;
288 if (*ppos != 0) 279 if (*ppos != 0)
289 goto out; 280 return -EINVAL;
290
291 length = -ENOMEM;
292 page = (char *)get_zeroed_page(GFP_KERNEL);
293 if (!page)
294 goto out;
295 281
296 length = -EFAULT; 282 page = memdup_user_nul(buf, count);
297 if (copy_from_user(page, buf, count)) 283 if (IS_ERR(page))
298 goto out; 284 return PTR_ERR(page);
299 285
300 length = -EINVAL; 286 length = -EINVAL;
301 if (sscanf(page, "%d", &new_value) != 1) 287 if (sscanf(page, "%d", &new_value) != 1)
@@ -313,7 +299,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf,
313 299
314 length = count; 300 length = count;
315out: 301out:
316 free_page((unsigned long) page); 302 kfree(page);
317 return length; 303 return length;
318} 304}
319#else 305#else
@@ -611,31 +597,24 @@ static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
611static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf, 597static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
612 size_t count, loff_t *ppos) 598 size_t count, loff_t *ppos)
613{ 599{
614 char *page = NULL; 600 char *page;
615 ssize_t length; 601 ssize_t length;
616 unsigned int new_value; 602 unsigned int new_value;
617 603
618 length = task_has_security(current, SECURITY__SETCHECKREQPROT); 604 length = task_has_security(current, SECURITY__SETCHECKREQPROT);
619 if (length) 605 if (length)
620 goto out; 606 return length;
621 607
622 length = -ENOMEM;
623 if (count >= PAGE_SIZE) 608 if (count >= PAGE_SIZE)
624 goto out; 609 return -ENOMEM;
625 610
626 /* No partial writes. */ 611 /* No partial writes. */
627 length = -EINVAL;
628 if (*ppos != 0) 612 if (*ppos != 0)
629 goto out; 613 return -EINVAL;
630
631 length = -ENOMEM;
632 page = (char *)get_zeroed_page(GFP_KERNEL);
633 if (!page)
634 goto out;
635 614
636 length = -EFAULT; 615 page = memdup_user_nul(buf, count);
637 if (copy_from_user(page, buf, count)) 616 if (IS_ERR(page))
638 goto out; 617 return PTR_ERR(page);
639 618
640 length = -EINVAL; 619 length = -EINVAL;
641 if (sscanf(page, "%u", &new_value) != 1) 620 if (sscanf(page, "%u", &new_value) != 1)
@@ -644,7 +623,7 @@ static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
644 selinux_checkreqprot = new_value ? 1 : 0; 623 selinux_checkreqprot = new_value ? 1 : 0;
645 length = count; 624 length = count;
646out: 625out:
647 free_page((unsigned long) page); 626 kfree(page);
648 return length; 627 return length;
649} 628}
650static const struct file_operations sel_checkreqprot_ops = { 629static const struct file_operations sel_checkreqprot_ops = {
@@ -1100,14 +1079,12 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
1100 if (*ppos != 0) 1079 if (*ppos != 0)
1101 goto out; 1080 goto out;
1102 1081
1103 length = -ENOMEM; 1082 page = memdup_user_nul(buf, count);
1104 page = (char *)get_zeroed_page(GFP_KERNEL); 1083 if (IS_ERR(page)) {
1105 if (!page) 1084 length = PTR_ERR(page);
1106 goto out; 1085 page = NULL;
1107
1108 length = -EFAULT;
1109 if (copy_from_user(page, buf, count))
1110 goto out; 1086 goto out;
1087 }
1111 1088
1112 length = -EINVAL; 1089 length = -EINVAL;
1113 if (sscanf(page, "%d", &new_value) != 1) 1090 if (sscanf(page, "%d", &new_value) != 1)
@@ -1121,7 +1098,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
1121 1098
1122out: 1099out:
1123 mutex_unlock(&sel_mutex); 1100 mutex_unlock(&sel_mutex);
1124 free_page((unsigned long) page); 1101 kfree(page);
1125 return length; 1102 return length;
1126} 1103}
1127 1104
@@ -1154,14 +1131,12 @@ static ssize_t sel_commit_bools_write(struct file *filep,
1154 if (*ppos != 0) 1131 if (*ppos != 0)
1155 goto out; 1132 goto out;
1156 1133
1157 length = -ENOMEM; 1134 page = memdup_user_nul(buf, count);
1158 page = (char *)get_zeroed_page(GFP_KERNEL); 1135 if (IS_ERR(page)) {
1159 if (!page) 1136 length = PTR_ERR(page);
1160 goto out; 1137 page = NULL;
1161
1162 length = -EFAULT;
1163 if (copy_from_user(page, buf, count))
1164 goto out; 1138 goto out;
1139 }
1165 1140
1166 length = -EINVAL; 1141 length = -EINVAL;
1167 if (sscanf(page, "%d", &new_value) != 1) 1142 if (sscanf(page, "%d", &new_value) != 1)
@@ -1176,7 +1151,7 @@ static ssize_t sel_commit_bools_write(struct file *filep,
1176 1151
1177out: 1152out:
1178 mutex_unlock(&sel_mutex); 1153 mutex_unlock(&sel_mutex);
1179 free_page((unsigned long) page); 1154 kfree(page);
1180 return length; 1155 return length;
1181} 1156}
1182 1157
@@ -1292,31 +1267,24 @@ static ssize_t sel_write_avc_cache_threshold(struct file *file,
1292 size_t count, loff_t *ppos) 1267 size_t count, loff_t *ppos)
1293 1268
1294{ 1269{
1295 char *page = NULL; 1270 char *page;
1296 ssize_t ret; 1271 ssize_t ret;
1297 int new_value; 1272 int new_value;
1298 1273
1299 ret = task_has_security(current, SECURITY__SETSECPARAM); 1274 ret = task_has_security(current, SECURITY__SETSECPARAM);
1300 if (ret) 1275 if (ret)
1301 goto out; 1276 return ret;
1302 1277
1303 ret = -ENOMEM;
1304 if (count >= PAGE_SIZE) 1278 if (count >= PAGE_SIZE)
1305 goto out; 1279 return -ENOMEM;
1306 1280
1307 /* No partial writes. */ 1281 /* No partial writes. */
1308 ret = -EINVAL;
1309 if (*ppos != 0) 1282 if (*ppos != 0)
1310 goto out; 1283 return -EINVAL;
1311
1312 ret = -ENOMEM;
1313 page = (char *)get_zeroed_page(GFP_KERNEL);
1314 if (!page)
1315 goto out;
1316 1284
1317 ret = -EFAULT; 1285 page = memdup_user_nul(buf, count);
1318 if (copy_from_user(page, buf, count)) 1286 if (IS_ERR(page))
1319 goto out; 1287 return PTR_ERR(page);
1320 1288
1321 ret = -EINVAL; 1289 ret = -EINVAL;
1322 if (sscanf(page, "%u", &new_value) != 1) 1290 if (sscanf(page, "%u", &new_value) != 1)
@@ -1326,7 +1294,7 @@ static ssize_t sel_write_avc_cache_threshold(struct file *file,
1326 1294
1327 ret = count; 1295 ret = count;
1328out: 1296out:
1329 free_page((unsigned long)page); 1297 kfree(page);
1330 return ret; 1298 return ret;
1331} 1299}
1332 1300