/daten/src/linux-2.4.27-rsbac-v1.2.3/rsbac/adf/jail/jail_syscalls.c

Go to the documentation of this file.
00001 /*************************************************** */ 00002 /* Rule Set Based Access Control */ 00003 /* Implementation of the Access Control Decision */ 00004 /* Facility (ADF) - JAIL module */ 00005 /* File: rsbac/adf/jail/syscalls.c */ 00006 /* */ 00007 /* Author and (c) 1999-2004: Amon Ott <ao@rsbac.org> */ 00008 /* */ 00009 /* Last modified: 27/Apr/2004 */ 00010 /*************************************************** */ 00011 00012 #include <linux/string.h> 00013 #include <linux/sched.h> 00014 #include <linux/errno.h> 00015 #include <linux/version.h> 00016 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 00017 #include <linux/syscalls.h> 00018 #include <linux/file.h> 00019 #endif 00020 #include <rsbac/types.h> 00021 #include <rsbac/aci.h> 00022 #include <rsbac/error.h> 00023 #include <rsbac/rkmem.h> 00024 #include <rsbac/debug.h> 00025 #include <rsbac/helpers.h> 00026 #include <rsbac/getname.h> 00027 #include <rsbac/network.h> 00028 #include <asm/uaccess.h> 00029 00030 /************************************************* */ 00031 /* Global Variables */ 00032 /************************************************* */ 00033 00034 static rsbac_jail_id_t next_id = 1; 00035 00036 /************************************************* */ 00037 /* Internal Help functions */ 00038 /************************************************* */ 00039 00040 /************************************************* */ 00041 /* Externally visible functions */ 00042 /************************************************* */ 00043 00044 extern long sys_chroot(const char * filename); 00045 extern long sys_chdir(const char * filename); 00046 00047 /* Create a jail for current process */ 00048 /* Note: It is allowed to create jails within jails, but with restrictions */ 00049 int rsbac_jail_sys_jail(rsbac_version_t version, 00050 char * path, 00051 rsbac_jail_ip_t ip, 00052 rsbac_jail_flags_t flags, 00053 rsbac_cap_vector_t max_caps) 00054 { 00055 union rsbac_target_id_t i_tid; 00056 union rsbac_attribute_value_t i_attr_val1; 00057 int err = 0; 00058 int chk_addr_ret; 00059 00060 if(version != RSBAC_JAIL_VERSION) 00061 return -RSBAC_EINVALIDVERSION; 00062 chk_addr_ret = inet_addr_type(ip); 00063 if (ip != INADDR_ANY && 00064 chk_addr_ret != RTN_LOCAL && 00065 chk_addr_ret != RTN_MULTICAST && 00066 chk_addr_ret != RTN_BROADCAST) 00067 return -EADDRNOTAVAIL; 00068 00069 #if 0 00070 err = rsbac_get_owner(&i_tid.user); 00071 if(err) 00072 return err; 00073 if (rsbac_get_attr(JAIL, 00074 T_USER, 00075 i_tid, 00076 A_jail_role, 00077 &i_attr_val1, 00078 TRUE)) 00079 { 00080 rsbac_ds_get_error("rsbac_jail_sys_jail()", A_jail_role); 00081 } 00082 /* if user role, then deny */ 00083 if (i_attr_val1.system_role == SR_user) 00084 return(-EPERM); 00085 #endif 00086 00087 /* Get jail_id for this process */ 00088 i_tid.process = current->pid; 00089 if (rsbac_get_attr(JAIL, 00090 T_PROCESS, 00091 i_tid, 00092 A_jail_id, 00093 &i_attr_val1, 00094 TRUE)) 00095 { 00096 rsbac_ds_get_error("rsbac_jail_sys_jail()", A_jail_id); 00097 return(-RSBAC_EREADFAILED); 00098 } 00099 if(i_attr_val1.jail_id) 00100 { /* this process is already in a jail -> limit ip and flags */ 00101 if (rsbac_get_attr(JAIL, 00102 T_PROCESS, 00103 i_tid, 00104 A_jail_flags, 00105 &i_attr_val1, 00106 TRUE)) 00107 { 00108 rsbac_ds_get_error("rsbac_jail_sys_jail()", A_jail_flags); 00109 return(-RSBAC_EREADFAILED); 00110 } 00111 flags &= i_attr_val1.jail_flags; 00112 if (rsbac_get_attr(JAIL, 00113 T_PROCESS, 00114 i_tid, 00115 A_jail_ip, 00116 &i_attr_val1, 00117 TRUE)) 00118 { 00119 rsbac_ds_get_error("rsbac_jail_sys_jail()", A_jail_ip); 00120 return(-RSBAC_EREADFAILED); 00121 } 00122 if(i_attr_val1.jail_ip) 00123 ip = i_attr_val1.jail_ip; 00124 if (rsbac_get_attr(JAIL, 00125 T_PROCESS, 00126 i_tid, 00127 A_jail_max_caps, 00128 &i_attr_val1, 00129 TRUE)) 00130 { 00131 rsbac_ds_get_error("rsbac_jail_sys_jail()", A_jail_max_caps); 00132 return(-RSBAC_EREADFAILED); 00133 } 00134 max_caps &= i_attr_val1.jail_max_caps; 00135 } 00136 00137 if(path) 00138 { 00139 mm_segment_t oldfs; 00140 struct file * file; 00141 struct files_struct *files = current->files; 00142 int fd; 00143 00144 err = sys_chroot(path); 00145 if(err) 00146 return err; 00147 /* Set current user space to kernel space, because sys_chdir() takes name */ 00148 /* from user space */ 00149 oldfs = get_fs(); 00150 set_fs(KERNEL_DS); 00151 err = sys_chdir("/"); 00152 /* Set current user space back to user space */ 00153 set_fs(oldfs); 00154 00155 restart: 00156 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 00157 spin_lock(&files->file_lock); 00158 #else 00159 read_lock(&files->file_lock); 00160 #endif 00161 for(fd=0; fd < files->max_fds; fd++) 00162 { 00163 file = files->fd[fd]; 00164 if( file 00165 && file->f_dentry 00166 && file->f_dentry->d_inode 00167 && S_ISDIR(file->f_dentry->d_inode->i_mode) 00168 ) 00169 { 00170 char * filename; 00171 00172 #ifdef CONFIG_RSBAC_LOG_FULL_PATH 00173 filename = rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN + 4); 00174 if(filename) 00175 rsbac_get_full_path(file->f_dentry, filename, CONFIG_RSBAC_MAX_PATH_LEN); 00176 #else 00177 filename = rsbac_kmalloc(RSBAC_MAXNAMELEN + 4); 00178 if(filename) 00179 rsbac_get_full_path(file->f_dentry, filename, RSBAC_MAXNAMELEN); 00180 #endif 00181 00182 #ifdef CONFIG_RSBAC_RMSG 00183 rsbac_printk(KERN_INFO 00184 "rsbac_jail_sys_jail(): avoid possible chroot breakout by closing open dir fd %u, inode %u, device %02u:%02u, path %s\n", 00185 fd, 00186 file->f_dentry->d_inode->i_ino, 00187 MAJOR(file->f_dentry->d_sb->s_dev), 00188 MINOR(file->f_dentry->d_sb->s_dev), 00189 filename); 00190 #endif 00191 #ifdef CONFIG_RSBAC_RMSG_NOSYSLOG 00192 if (!rsbac_nosyslog) 00193 #endif 00194 printk(KERN_INFO 00195 "rsbac_jail_sys_jail(): avoid possible chroot breakout by closing open dir fd %u, inode %lu, device %02u:%02u, path %s\n", 00196 fd, 00197 file->f_dentry->d_inode->i_ino, 00198 MAJOR(file->f_dentry->d_sb->s_dev), 00199 MINOR(file->f_dentry->d_sb->s_dev), 00200 filename); 00201 if(filename) 00202 rsbac_kfree(filename); 00203 00204 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 00205 spin_unlock(&files->file_lock); 00206 #else 00207 read_unlock(&files->file_lock); 00208 #endif 00209 sys_close(fd); 00210 goto restart; 00211 } 00212 } 00213 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) 00214 spin_unlock(&files->file_lock); 00215 #else 00216 read_unlock(&files->file_lock); 00217 #endif 00218 } 00219 00220 /* Set jail_id for this process */ 00221 i_attr_val1.jail_id = next_id++; 00222 if (rsbac_set_attr(JAIL, 00223 T_PROCESS, 00224 i_tid, 00225 A_jail_id, 00226 i_attr_val1)) 00227 { 00228 rsbac_ds_set_error("rsbac_jail_sys_jail()", A_jail_id); 00229 return(-RSBAC_EWRITEFAILED); 00230 } 00231 /* Set jail_ip for this process */ 00232 i_attr_val1.jail_ip = ip; 00233 if (rsbac_set_attr(JAIL, 00234 T_PROCESS, 00235 i_tid, 00236 A_jail_ip, 00237 i_attr_val1)) 00238 { 00239 rsbac_ds_set_error("rsbac_jail_sys_jail()", A_jail_ip); 00240 return(-RSBAC_EWRITEFAILED); 00241 } 00242 /* Set jail_flags for this process */ 00243 i_attr_val1.jail_flags = flags; 00244 if (rsbac_set_attr(JAIL, 00245 T_PROCESS, 00246 i_tid, 00247 A_jail_flags, 00248 i_attr_val1)) 00249 { 00250 rsbac_ds_set_error("rsbac_jail_sys_jail()", A_jail_flags); 00251 return(-RSBAC_EWRITEFAILED); 00252 } 00253 /* Set jail_max_caps for this process */ 00254 i_attr_val1.jail_max_caps = max_caps; 00255 if (rsbac_set_attr(JAIL, 00256 T_PROCESS, 00257 i_tid, 00258 A_jail_max_caps, 00259 i_attr_val1)) 00260 { 00261 rsbac_ds_set_error("rsbac_jail_sys_jail()", A_jail_flags); 00262 return(-RSBAC_EWRITEFAILED); 00263 } 00264 return err; 00265 } 00266 00267 /* end of rsbac/adf/jail/syscalls.c */

Generated on Tue Aug 31 10:05:23 2004 for RSBAC by doxygen 1.3.8