Skip to content

Commit 6b97f8f

Browse files
committed
Merge branch 'security' into develop
2 parents 92c55ed + 1a563e9 commit 6b97f8f

File tree

9 files changed

+406
-46
lines changed

9 files changed

+406
-46
lines changed

src/group_manager.c

Lines changed: 134 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*

src/group_manager.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <linux/idr.h>
1818
#include <linux/errno.h>
19+
#include <linux/cred.h> //For current_uid()
1920

2021

2122
#include "message.h"
@@ -66,6 +67,8 @@
6667

6768
#endif
6869

70+
#define IOCTL_SET_STRICT_MODE _IOW('Q', 101, bool)
71+
#define IOCTL_CHANGE_OWNER _IOW('Q', 102, uid_t)
6972

7073

7174

src/main_device.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,8 @@ __must_check int installGroup(const group_t new_group_descriptor){
408408
memset(&new_group->flags, 0, sizeof(g_flags_t)); //Reset all flags
409409

410410
new_group->descriptor = new_group_descriptor;
411-
new_group->owner = current->pid;
411+
new_group->owner = current_uid().val;
412+
init_rwsem(&new_group->owner_lock);
412413

413414

414415
printk(KERN_DEBUG "Group descriptor: [%s]", new_group->descriptor.group_name);

0 commit comments

Comments
 (0)