@@ -116,6 +116,106 @@ bool checkGarbageRatio(group_data *grp_data){
116116
117117
118118
119+
120+ /** @brief Test if the current process is the owner of a group
121+ *
122+ * @param[in] grp_data A group main structure
123+ *
124+ * @note This function is thread-safe
125+ *
126+ * @retval true if the current process is the owner
127+ * @retval false if the current process is not the owner
128+ */
129+ bool isOwner (group_data * grp_data ){
130+ uid_t current_owner ;
131+ bool ret ;
132+
133+ down_read (& grp_data -> owner_lock );
134+
135+ current_owner = grp_data -> owner ;
136+ printk (KERN_DEBUG "Current owner: %d" , current_owner );
137+ printk (KERN_DEBUG "Current user: %d" , current_uid ().val );
138+ if (current_uid ().val == current_owner ){
139+ ret = true;
140+ }else {
141+ ret = false;
142+ }
143+
144+ up_read (& grp_data -> owner_lock );
145+
146+ return ret ;
147+ }
148+
149+
150+ /**
151+ * @brief Change the current owner of a group
152+ *
153+ * @note If strict mode is enabled, only the owner of a group can call
154+ * this function.
155+ *
156+ * @retval 0 on success
157+ * @retval -1 if the current process is not authorized
158+ *
159+ */
160+ int changeOwner (group_data * grp_data , uid_t new_owner ){
161+
162+ uid_t current_owner ;
163+ int ret ;
164+ bool allowed = false;
165+
166+ //If strict mode is disabled anyone can call this function
167+ if (grp_data -> flags .strict_mode == 0 )
168+ allowed = true;
169+
170+
171+ down_write (& grp_data -> owner_lock );
172+
173+ current_owner = grp_data -> owner ;
174+
175+ if (allowed || current_uid ().val == current_owner ){
176+ grp_data -> owner = new_owner ;
177+ ret = 0 ;
178+ }else {
179+ ret = -1 ;
180+ }
181+
182+ up_write (& grp_data -> owner_lock );
183+
184+ if (ret == 0 ){
185+ printk (KERN_DEBUG "New Owner UID: %u" , new_owner );
186+ printk (KERN_DEBUG "Current owner UID: %u" , current_owner );
187+ }
188+
189+
190+ return ret ;
191+ }
192+
193+
194+ /**
195+ * @brief Change group's 'strict' security flag
196+ *
197+ * @param[in] grp_data A group structure where the flag should be set
198+ * @param[in] enabled True if the flag must be enabled, false otherwise
199+ *
200+ * @retval 0 On success
201+ * @retval -1 If the current process is unauthorized
202+ */
203+ int setStrictMode (group_data * grp_data , const bool enabled ){
204+
205+ if (isOwner (grp_data )){
206+ printk (KERN_DEBUG "Authorized to change strict mode to %d" , enabled );
207+ if (enabled )
208+ grp_data -> flags .strict_mode = 1 ;
209+ else
210+ grp_data -> flags .strict_mode = 0 ;
211+
212+ return 0 ;
213+ }
214+
215+ return -1 ;
216+ }
217+
218+
119219/**
120220 * @brief Initialize group_data participants' structures
121221 *
@@ -203,20 +303,8 @@ int registerGroupDevice(group_data *grp_data, const struct device* parent){
203303
204304 printk (KERN_DEBUG "Device Major/Minor correctly allocated" );
205305
206- /*
207- name_len = strnlen(device_name, DEVICE_NAME_SIZE);
208-
209- grp_data->descriptor.group_name = kmalloc(sizeof(char)*name_len, GFP_KERNEL);
210- if(!grp_data->descriptor.group_name){
211- ret = ALLOC_ERR;
212- goto cleanup_region;
213- }
214306
215-
216- strncpy(grp_data->descriptor.group_name, device_name, name_len);
217- */
218307
219- //TODO: test parent behaviour
220308 grp_data -> dev = device_create (group_device_class , parent , grp_data -> deviceID , NULL , device_name );
221309
222310 if (IS_ERR (grp_data -> dev )){
@@ -239,7 +327,6 @@ int registerGroupDevice(group_data *grp_data, const struct device* parent){
239327 }
240328
241329
242-
243330 #ifndef DISABLE_THREAD_BARRIER
244331 //Initialize Wait Queue
245332 init_waitqueue_head (& grp_data -> barrier_queue );
@@ -668,6 +755,9 @@ void awakeBarrier(group_data *grp_data){
668755 * -IOCTL_REVOKE_DELAYED_MESSAGES: revoke delay on all queued messages
669756 * -IOCTL_SLEEP_ON_BARRIER: The invoking thread will sleep until other thread awake the sleep queue
670757 * -IOCTL_AWAKE_BARRIER: Awake the sleep queue
758+ * -IOCTL_GET_GROUP_DESC: Write a group descriptor into the provided pointer
759+ * -IOCTL_SET_STRICT_MODE: Set the strict mode flag
760+ * -IOCTL_CHANGE_OWNER: Change the owner of the group
671761 *
672762 * @retval 0 on success
673763 * @retval -1 on error
@@ -678,6 +768,8 @@ long int groupIoctl(struct file *filep, unsigned int ioctl_num, unsigned long io
678768 long delay = 0 ;
679769 group_t * user_descriptor ;
680770 group_data * grp_data ;
771+ bool flag ;
772+ uid_t new_owner ;
681773
682774
683775 switch (ioctl_num ){
@@ -726,12 +818,40 @@ long int groupIoctl(struct file *filep, unsigned int ioctl_num, unsigned long io
726818 user_descriptor = (group_t * )ioctl_param ;
727819
728820 if ((ret = copy_group_t_to_user (user_descriptor , & grp_data -> descriptor )) < 0 ){
729- printk ("\nUnable to retrieve group's data" );
821+ printk (KERN_ERR "Unable to retrieve group's data" );
730822 break ;
731823 }
732824
733825 ret = 0 ;
734826 break ;
827+
828+ case IOCTL_SET_STRICT_MODE :
829+ grp_data = (group_data * ) filep -> private_data ;
830+
831+ flag = (bool )ioctl_param ;
832+
833+ if (setStrictMode (grp_data , flag ) < 0 ){
834+ printk (KERN_WARNING "Unable set strict mode: unauthorized" );
835+ ret = -1 ;
836+ }else
837+ ret = 0 ;
838+
839+
840+ break ;
841+
842+ case IOCTL_CHANGE_OWNER :
843+ grp_data = (group_data * ) filep -> private_data ;
844+
845+ new_owner = (uid_t )ioctl_param ;
846+
847+ if (changeOwner (grp_data , new_owner ) < 0 ){
848+ printk (KERN_WARNING "Unable to change owner: unauthorized" );
849+ ret = -1 ;
850+ }else
851+ ret = 0 ;
852+
853+ break ;
854+
735855 default :
736856 printk (KERN_INFO "Invalid IOCTL command provided: \n\tioctl_num=%u\n\tparam: %lu" , ioctl_num , ioctl_param );
737857 ret = INVALID_IOCTL_COMMAND ;
@@ -743,9 +863,6 @@ long int groupIoctl(struct file *filep, unsigned int ioctl_num, unsigned long io
743863
744864
745865
746-
747-
748-
749866/**
750867 * @brief Copy a 'group_t' structure to kernel space
751868 *
0 commit comments