#include <linux/string.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/version.h>
#include <linux/syscalls.h>
#include <linux/file.h>
#include <rsbac/types.h>
#include <rsbac/aci.h>
#include <rsbac/error.h>
#include <rsbac/rkmem.h>
#include <rsbac/debug.h>
#include <rsbac/helpers.h>
#include <rsbac/getname.h>
#include <rsbac/network.h>
#include <rsbac/jail.h>
#include <asm/uaccess.h>
Go to the source code of this file.
Functions | |
int | rsbac_jail_sys_jail (rsbac_version_t version, char *path, rsbac_jail_ip_t ip, rsbac_jail_flags_t flags, rsbac_cap_vector_t max_caps, rsbac_jail_scd_vector_t scd_get, rsbac_jail_scd_vector_t scd_modify) |
Variables | |
static rsbac_jail_id_t | next_id = 1 |
int rsbac_jail_sys_jail | ( | rsbac_version_t | version, | |
char * | path, | |||
rsbac_jail_ip_t | ip, | |||
rsbac_jail_flags_t | flags, | |||
rsbac_cap_vector_t | max_caps, | |||
rsbac_jail_scd_vector_t | scd_get, | |||
rsbac_jail_scd_vector_t | scd_modify | |||
) |
Definition at line 52 of file jail_syscalls.c.
References A_jail_flags, A_jail_id, A_jail_ip, A_jail_max_caps, A_jail_parent, A_jail_scd_get, A_jail_scd_modify, JAIL_allow_parent_ipc, rsbac_attribute_value_t::jail_flags, rsbac_attribute_value_t::jail_id, rsbac_attribute_value_t::jail_ip, rsbac_attribute_value_t::jail_max_caps, rsbac_attribute_value_t::jail_parent, rsbac_attribute_value_t::jail_scd_get, rsbac_attribute_value_t::jail_scd_modify, JAIL_this_is_syslog, next_id, rsbac_target_id_t::process, RSBAC_EEXISTS, RSBAC_EINVALIDVERSION, RSBAC_EREADFAILED, RSBAC_EWRITEFAILED, rsbac_get_attr, rsbac_get_full_path(), rsbac_jail_exists(), rsbac_jail_syslog_jail_id, RSBAC_JAIL_VERSION, rsbac_kfree(), rsbac_kmalloc(), RSBAC_MAXNAMELEN, rsbac_printk(), rsbac_set_attr, SW_JAIL, T_PROCESS, and TRUE.
Referenced by sys_rsbac(), and sys_rsbac_jail().
00059 { 00060 union rsbac_target_id_t i_tid; 00061 union rsbac_attribute_value_t i_attr_val1; 00062 int err = 0; 00063 int chk_addr_ret; 00064 rsbac_jail_id_t parent = 0; 00065 00066 if(version != RSBAC_JAIL_VERSION) 00067 return -RSBAC_EINVALIDVERSION; 00068 chk_addr_ret = inet_addr_type(ip); 00069 if (ip != INADDR_ANY && 00070 chk_addr_ret != RTN_LOCAL && 00071 chk_addr_ret != RTN_MULTICAST && 00072 chk_addr_ret != RTN_BROADCAST) 00073 return -EADDRNOTAVAIL; 00074 00075 /* Get jail_id for this process */ 00076 i_tid.process = current->pid; 00077 if (rsbac_get_attr(SW_JAIL, 00078 T_PROCESS, 00079 i_tid, 00080 A_jail_id, 00081 &i_attr_val1, 00082 TRUE)) 00083 { 00084 rsbac_ds_get_error("rsbac_jail_sys_jail()", A_jail_id); 00085 return(-RSBAC_EREADFAILED); 00086 } 00087 if(i_attr_val1.jail_id) 00088 { /* this process is already in a jail -> limit ip and flags */ 00089 parent = i_attr_val1.jail_id; 00090 if (rsbac_get_attr(SW_JAIL, 00091 T_PROCESS, 00092 i_tid, 00093 A_jail_flags, 00094 &i_attr_val1, 00095 TRUE)) 00096 { 00097 rsbac_ds_get_error("rsbac_jail_sys_jail()", A_jail_flags); 00098 return(-RSBAC_EREADFAILED); 00099 } 00100 flags &= i_attr_val1.jail_flags | JAIL_allow_parent_ipc; 00101 if (rsbac_get_attr(SW_JAIL, 00102 T_PROCESS, 00103 i_tid, 00104 A_jail_scd_get, 00105 &i_attr_val1, 00106 TRUE)) 00107 { 00108 rsbac_ds_get_error("rsbac_jail_sys_jail()", A_jail_scd_get); 00109 return(-RSBAC_EREADFAILED); 00110 } 00111 scd_get &= i_attr_val1.jail_scd_get; 00112 if (rsbac_get_attr(SW_JAIL, 00113 T_PROCESS, 00114 i_tid, 00115 A_jail_scd_modify, 00116 &i_attr_val1, 00117 TRUE)) 00118 { 00119 rsbac_ds_get_error("rsbac_jail_sys_jail()", A_jail_scd_modify); 00120 return(-RSBAC_EREADFAILED); 00121 } 00122 scd_modify &= i_attr_val1.jail_scd_modify; 00123 if (rsbac_get_attr(SW_JAIL, 00124 T_PROCESS, 00125 i_tid, 00126 A_jail_ip, 00127 &i_attr_val1, 00128 TRUE)) 00129 { 00130 rsbac_ds_get_error("rsbac_jail_sys_jail()", A_jail_ip); 00131 return(-RSBAC_EREADFAILED); 00132 } 00133 if(i_attr_val1.jail_ip) 00134 ip = i_attr_val1.jail_ip; 00135 if (rsbac_get_attr(SW_JAIL, 00136 T_PROCESS, 00137 i_tid, 00138 A_jail_max_caps, 00139 &i_attr_val1, 00140 TRUE)) 00141 { 00142 rsbac_ds_get_error("rsbac_jail_sys_jail()", A_jail_max_caps); 00143 return(-RSBAC_EREADFAILED); 00144 } 00145 max_caps &= i_attr_val1.jail_max_caps; 00146 } 00147 00148 /* check syslog id */ 00149 if(flags & JAIL_this_is_syslog) { 00150 if( rsbac_jail_syslog_jail_id 00151 && rsbac_jail_exists(rsbac_jail_syslog_jail_id) 00152 ) 00153 return -RSBAC_EEXISTS; 00154 } 00155 00156 if(path) 00157 { 00158 mm_segment_t oldfs; 00159 struct file * file; 00160 struct files_struct *files = current->files; 00161 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 00162 struct fdtable *fdt; 00163 #endif 00164 int fd; 00165 00166 err = sys_chroot(path); 00167 if(err) 00168 return err; 00169 /* Set current user space to kernel space, because sys_chdir() takes name */ 00170 /* from user space */ 00171 oldfs = get_fs(); 00172 set_fs(KERNEL_DS); 00173 err = sys_chdir("/"); 00174 /* Set current user space back to user space */ 00175 set_fs(oldfs); 00176 00177 restart: 00178 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 00179 rcu_read_lock(); 00180 fdt = files_fdtable(files); 00181 for(fd=0; fd < fdt->max_fds; fd++) 00182 { 00183 file = fcheck(fd); 00184 #else 00185 read_lock(&files->file_lock); 00186 for(fd=0; fd < files->max_fds; fd++) 00187 { 00188 file = files->fd[fd]; 00189 #endif 00190 if( file 00191 && file->f_dentry 00192 && file->f_dentry->d_inode 00193 && S_ISDIR(file->f_dentry->d_inode->i_mode) 00194 ) 00195 { 00196 char * filename; 00197 00198 #ifdef CONFIG_RSBAC_LOG_FULL_PATH 00199 filename = rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN + 4); 00200 if(filename) 00201 rsbac_get_full_path(file->f_dentry, filename, CONFIG_RSBAC_MAX_PATH_LEN); 00202 #else 00203 filename = rsbac_kmalloc(RSBAC_MAXNAMELEN + 4); 00204 if(filename) 00205 rsbac_get_full_path(file->f_dentry, filename, RSBAC_MAXNAMELEN); 00206 #endif 00207 00208 rsbac_printk(KERN_INFO 00209 "rsbac_jail_sys_jail(): avoid possible chroot breakout by closing open dir fd %u, inode %u, device %02u:%02u, path %s\n", 00210 fd, 00211 file->f_dentry->d_inode->i_ino, 00212 MAJOR(file->f_dentry->d_sb->s_dev), 00213 MINOR(file->f_dentry->d_sb->s_dev), 00214 filename); 00215 if(filename) 00216 rsbac_kfree(filename); 00217 00218 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 00219 rcu_read_unlock(); 00220 #else 00221 read_unlock(&files->file_lock); 00222 #endif 00223 sys_close(fd); 00224 goto restart; 00225 } 00226 } 00227 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 00228 rcu_read_unlock(); 00229 #else 00230 read_unlock(&files->file_lock); 00231 #endif 00232 } 00233 00234 /* Set jail_id for this process */ 00235 i_attr_val1.jail_id = next_id++; 00236 if (rsbac_set_attr(SW_JAIL, 00237 T_PROCESS, 00238 i_tid, 00239 A_jail_id, 00240 i_attr_val1)) 00241 { 00242 rsbac_ds_set_error("rsbac_jail_sys_jail()", A_jail_id); 00243 return(-RSBAC_EWRITEFAILED); 00244 } 00245 if(flags & JAIL_this_is_syslog) { 00246 rsbac_jail_syslog_jail_id = i_attr_val1.jail_id; 00247 } 00248 /* Set jail_parent for this process */ 00249 i_attr_val1.jail_parent = parent; 00250 if (rsbac_set_attr(SW_JAIL, T_PROCESS, i_tid, A_jail_parent, i_attr_val1)) { 00251 rsbac_ds_set_error("rsbac_jail_sys_jail()", A_jail_parent); 00252 return (-RSBAC_EWRITEFAILED); 00253 } 00254 /* Set jail_ip for this process */ 00255 i_attr_val1.jail_ip = ip; 00256 if (rsbac_set_attr(SW_JAIL, 00257 T_PROCESS, 00258 i_tid, 00259 A_jail_ip, 00260 i_attr_val1)) 00261 { 00262 rsbac_ds_set_error("rsbac_jail_sys_jail()", A_jail_ip); 00263 return(-RSBAC_EWRITEFAILED); 00264 } 00265 /* Set jail_flags for this process */ 00266 i_attr_val1.jail_flags = flags; 00267 if (rsbac_set_attr(SW_JAIL, 00268 T_PROCESS, 00269 i_tid, 00270 A_jail_flags, 00271 i_attr_val1)) 00272 { 00273 rsbac_ds_set_error("rsbac_jail_sys_jail()", A_jail_flags); 00274 return(-RSBAC_EWRITEFAILED); 00275 } 00276 /* Set jail_max_caps for this process */ 00277 i_attr_val1.jail_max_caps = max_caps; 00278 if (rsbac_set_attr(SW_JAIL, 00279 T_PROCESS, 00280 i_tid, 00281 A_jail_max_caps, 00282 i_attr_val1)) 00283 { 00284 rsbac_ds_set_error("rsbac_jail_sys_jail()", A_jail_max_caps); 00285 return(-RSBAC_EWRITEFAILED); 00286 } 00287 /* Set jail_scd_get for this process */ 00288 i_attr_val1.jail_scd_get = scd_get; 00289 if (rsbac_set_attr(SW_JAIL, 00290 T_PROCESS, 00291 i_tid, 00292 A_jail_scd_get, 00293 i_attr_val1)) 00294 { 00295 rsbac_ds_set_error("rsbac_jail_sys_jail()", A_jail_scd_get); 00296 return(-RSBAC_EWRITEFAILED); 00297 } 00298 /* Set jail_scd_modify for this process */ 00299 i_attr_val1.jail_scd_modify = scd_modify; 00300 if (rsbac_set_attr(SW_JAIL, 00301 T_PROCESS, 00302 i_tid, 00303 A_jail_scd_modify, 00304 i_attr_val1)) 00305 { 00306 rsbac_ds_set_error("rsbac_jail_sys_jail()", A_jail_scd_modify); 00307 return(-RSBAC_EWRITEFAILED); 00308 } 00309 return err; 00310 }
rsbac_jail_id_t next_id = 1 [static] |