00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00032
00033
00034 static rsbac_jail_id_t next_id = 1;
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
extern long sys_chroot(
const char * filename);
00045
extern long sys_chdir(
const char * filename);
00046
00047
00048
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
00083
if (i_attr_val1.
system_role ==
SR_user)
00084
return(-EPERM);
00085
#endif
00086
00087
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 {
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
00148
00149 oldfs = get_fs();
00150 set_fs(KERNEL_DS);
00151 err =
sys_chdir(
"/");
00152
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
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
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
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
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