@@ -65,6 +65,7 @@ static DEFINE_MUTEX(sel_mutex);
65
65
/* global data for booleans */
66
66
static struct dentry * bool_dir = NULL ;
67
67
static int bool_num = 0 ;
68
+ static char * * bool_pending_names ;
68
69
static int * bool_pending_values = NULL ;
69
70
70
71
/* global data for classes */
@@ -832,11 +833,16 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
832
833
ssize_t length ;
833
834
ssize_t ret ;
834
835
int cur_enforcing ;
835
- struct inode * inode ;
836
+ struct inode * inode = filep -> f_path .dentry -> d_inode ;
837
+ unsigned index = inode -> i_ino & SEL_INO_MASK ;
838
+ const char * name = filep -> f_path .dentry -> d_name .name ;
836
839
837
840
mutex_lock (& sel_mutex );
838
841
839
- ret = - EFAULT ;
842
+ if (index >= bool_num || strcmp (name , bool_pending_names [index ])) {
843
+ ret = - EINVAL ;
844
+ goto out ;
845
+ }
840
846
841
847
if (count > PAGE_SIZE ) {
842
848
ret = - EINVAL ;
@@ -847,15 +853,13 @@ static ssize_t sel_read_bool(struct file *filep, char __user *buf,
847
853
goto out ;
848
854
}
849
855
850
- inode = filep -> f_path .dentry -> d_inode ;
851
- cur_enforcing = security_get_bool_value (inode -> i_ino & SEL_INO_MASK );
856
+ cur_enforcing = security_get_bool_value (index );
852
857
if (cur_enforcing < 0 ) {
853
858
ret = cur_enforcing ;
854
859
goto out ;
855
860
}
856
-
857
861
length = scnprintf (page , PAGE_SIZE , "%d %d" , cur_enforcing ,
858
- bool_pending_values [inode -> i_ino & SEL_INO_MASK ]);
862
+ bool_pending_values [index ]);
859
863
ret = simple_read_from_buffer (buf , count , ppos , page , length );
860
864
out :
861
865
mutex_unlock (& sel_mutex );
@@ -868,22 +872,31 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
868
872
size_t count , loff_t * ppos )
869
873
{
870
874
char * page = NULL ;
871
- ssize_t length = - EFAULT ;
875
+ ssize_t length ;
872
876
int new_value ;
873
- struct inode * inode ;
877
+ struct inode * inode = filep -> f_path .dentry -> d_inode ;
878
+ unsigned index = inode -> i_ino & SEL_INO_MASK ;
879
+ const char * name = filep -> f_path .dentry -> d_name .name ;
874
880
875
881
mutex_lock (& sel_mutex );
876
882
877
883
length = task_has_security (current , SECURITY__SETBOOL );
878
884
if (length )
879
885
goto out ;
880
886
887
+ if (index >= bool_num || strcmp (name , bool_pending_names [index ])) {
888
+ length = - EINVAL ;
889
+ goto out ;
890
+ }
891
+
881
892
if (count >= PAGE_SIZE ) {
882
893
length = - ENOMEM ;
883
894
goto out ;
884
895
}
896
+
885
897
if (* ppos != 0 ) {
886
898
/* No partial writes. */
899
+ length = - EINVAL ;
887
900
goto out ;
888
901
}
889
902
page = (char * )get_zeroed_page (GFP_KERNEL );
@@ -892,6 +905,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
892
905
goto out ;
893
906
}
894
907
908
+ length = - EFAULT ;
895
909
if (copy_from_user (page , buf , count ))
896
910
goto out ;
897
911
@@ -902,8 +916,7 @@ static ssize_t sel_write_bool(struct file *filep, const char __user *buf,
902
916
if (new_value )
903
917
new_value = 1 ;
904
918
905
- inode = filep -> f_path .dentry -> d_inode ;
906
- bool_pending_values [inode -> i_ino & SEL_INO_MASK ] = new_value ;
919
+ bool_pending_values [index ] = new_value ;
907
920
length = count ;
908
921
909
922
out :
@@ -923,7 +936,7 @@ static ssize_t sel_commit_bools_write(struct file *filep,
923
936
size_t count , loff_t * ppos )
924
937
{
925
938
char * page = NULL ;
926
- ssize_t length = - EFAULT ;
939
+ ssize_t length ;
927
940
int new_value ;
928
941
929
942
mutex_lock (& sel_mutex );
@@ -946,6 +959,7 @@ static ssize_t sel_commit_bools_write(struct file *filep,
946
959
goto out ;
947
960
}
948
961
962
+ length = - EFAULT ;
949
963
if (copy_from_user (page , buf , count ))
950
964
goto out ;
951
965
@@ -1010,7 +1024,9 @@ static int sel_make_bools(void)
1010
1024
u32 sid ;
1011
1025
1012
1026
/* remove any existing files */
1027
+ kfree (bool_pending_names );
1013
1028
kfree (bool_pending_values );
1029
+ bool_pending_names = NULL ;
1014
1030
bool_pending_values = NULL ;
1015
1031
1016
1032
sel_remove_entries (dir );
@@ -1052,16 +1068,17 @@ static int sel_make_bools(void)
1052
1068
d_add (dentry , inode );
1053
1069
}
1054
1070
bool_num = num ;
1071
+ bool_pending_names = names ;
1055
1072
bool_pending_values = values ;
1056
1073
out :
1057
1074
free_page ((unsigned long )page );
1075
+ return ret ;
1076
+ err :
1058
1077
if (names ) {
1059
1078
for (i = 0 ; i < num ; i ++ )
1060
1079
kfree (names [i ]);
1061
1080
kfree (names );
1062
1081
}
1063
- return ret ;
1064
- err :
1065
1082
kfree (values );
1066
1083
sel_remove_entries (dir );
1067
1084
ret = - ENOMEM ;
0 commit comments