aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/compat.c')
-rw-r--r--fs/compat.c105
1 files changed, 89 insertions, 16 deletions
diff --git a/fs/compat.c b/fs/compat.c
index 55efdfebdf5a..1c859dae758f 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -51,6 +51,7 @@
51#include <linux/poll.h> 51#include <linux/poll.h>
52#include <linux/mm.h> 52#include <linux/mm.h>
53#include <linux/eventpoll.h> 53#include <linux/eventpoll.h>
54#include <linux/fs_struct.h>
54 55
55#include <asm/uaccess.h> 56#include <asm/uaccess.h>
56#include <asm/mmu_context.h> 57#include <asm/mmu_context.h>
@@ -1195,16 +1196,12 @@ out:
1195 return ret; 1196 return ret;
1196} 1197}
1197 1198
1198asmlinkage ssize_t 1199static size_t compat_readv(struct file *file,
1199compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, unsigned long vlen) 1200 const struct compat_iovec __user *vec,
1201 unsigned long vlen, loff_t *pos)
1200{ 1202{
1201 struct file *file;
1202 ssize_t ret = -EBADF; 1203 ssize_t ret = -EBADF;
1203 1204
1204 file = fget(fd);
1205 if (!file)
1206 return -EBADF;
1207
1208 if (!(file->f_mode & FMODE_READ)) 1205 if (!(file->f_mode & FMODE_READ))
1209 goto out; 1206 goto out;
1210 1207
@@ -1212,25 +1209,56 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, unsign
1212 if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read)) 1209 if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read))
1213 goto out; 1210 goto out;
1214 1211
1215 ret = compat_do_readv_writev(READ, file, vec, vlen, &file->f_pos); 1212 ret = compat_do_readv_writev(READ, file, vec, vlen, pos);
1216 1213
1217out: 1214out:
1218 if (ret > 0) 1215 if (ret > 0)
1219 add_rchar(current, ret); 1216 add_rchar(current, ret);
1220 inc_syscr(current); 1217 inc_syscr(current);
1221 fput(file);
1222 return ret; 1218 return ret;
1223} 1219}
1224 1220
1225asmlinkage ssize_t 1221asmlinkage ssize_t
1226compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, unsigned long vlen) 1222compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec,
1223 unsigned long vlen)
1227{ 1224{
1228 struct file *file; 1225 struct file *file;
1229 ssize_t ret = -EBADF; 1226 int fput_needed;
1227 ssize_t ret;
1230 1228
1231 file = fget(fd); 1229 file = fget_light(fd, &fput_needed);
1232 if (!file) 1230 if (!file)
1233 return -EBADF; 1231 return -EBADF;
1232 ret = compat_readv(file, vec, vlen, &file->f_pos);
1233 fput_light(file, fput_needed);
1234 return ret;
1235}
1236
1237asmlinkage ssize_t
1238compat_sys_preadv(unsigned long fd, const struct compat_iovec __user *vec,
1239 unsigned long vlen, u32 pos_high, u32 pos_low)
1240{
1241 loff_t pos = ((loff_t)pos_high << 32) | pos_low;
1242 struct file *file;
1243 int fput_needed;
1244 ssize_t ret;
1245
1246 if (pos < 0)
1247 return -EINVAL;
1248 file = fget_light(fd, &fput_needed);
1249 if (!file)
1250 return -EBADF;
1251 ret = compat_readv(file, vec, vlen, &pos);
1252 fput_light(file, fput_needed);
1253 return ret;
1254}
1255
1256static size_t compat_writev(struct file *file,
1257 const struct compat_iovec __user *vec,
1258 unsigned long vlen, loff_t *pos)
1259{
1260 ssize_t ret = -EBADF;
1261
1234 if (!(file->f_mode & FMODE_WRITE)) 1262 if (!(file->f_mode & FMODE_WRITE))
1235 goto out; 1263 goto out;
1236 1264
@@ -1238,13 +1266,47 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, unsig
1238 if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write)) 1266 if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write))
1239 goto out; 1267 goto out;
1240 1268
1241 ret = compat_do_readv_writev(WRITE, file, vec, vlen, &file->f_pos); 1269 ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos);
1242 1270
1243out: 1271out:
1244 if (ret > 0) 1272 if (ret > 0)
1245 add_wchar(current, ret); 1273 add_wchar(current, ret);
1246 inc_syscw(current); 1274 inc_syscw(current);
1247 fput(file); 1275 return ret;
1276}
1277
1278asmlinkage ssize_t
1279compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec,
1280 unsigned long vlen)
1281{
1282 struct file *file;
1283 int fput_needed;
1284 ssize_t ret;
1285
1286 file = fget_light(fd, &fput_needed);
1287 if (!file)
1288 return -EBADF;
1289 ret = compat_writev(file, vec, vlen, &file->f_pos);
1290 fput_light(file, fput_needed);
1291 return ret;
1292}
1293
1294asmlinkage ssize_t
1295compat_sys_pwritev(unsigned long fd, const struct compat_iovec __user *vec,
1296 unsigned long vlen, u32 pos_high, u32 pos_low)
1297{
1298 loff_t pos = ((loff_t)pos_high << 32) | pos_low;
1299 struct file *file;
1300 int fput_needed;
1301 ssize_t ret;
1302
1303 if (pos < 0)
1304 return -EINVAL;
1305 file = fget_light(fd, &fput_needed);
1306 if (!file)
1307 return -EBADF;
1308 ret = compat_writev(file, vec, vlen, &pos);
1309 fput_light(file, fput_needed);
1248 return ret; 1310 return ret;
1249} 1311}
1250 1312
@@ -1441,12 +1503,15 @@ int compat_do_execve(char * filename,
1441 bprm->cred = prepare_exec_creds(); 1503 bprm->cred = prepare_exec_creds();
1442 if (!bprm->cred) 1504 if (!bprm->cred)
1443 goto out_unlock; 1505 goto out_unlock;
1444 check_unsafe_exec(bprm); 1506
1507 retval = check_unsafe_exec(bprm);
1508 if (retval)
1509 goto out_unlock;
1445 1510
1446 file = open_exec(filename); 1511 file = open_exec(filename);
1447 retval = PTR_ERR(file); 1512 retval = PTR_ERR(file);
1448 if (IS_ERR(file)) 1513 if (IS_ERR(file))
1449 goto out_unlock; 1514 goto out_unmark;
1450 1515
1451 sched_exec(); 1516 sched_exec();
1452 1517
@@ -1488,6 +1553,9 @@ int compat_do_execve(char * filename,
1488 goto out; 1553 goto out;
1489 1554
1490 /* execve succeeded */ 1555 /* execve succeeded */
1556 write_lock(&current->fs->lock);
1557 current->fs->in_exec = 0;
1558 write_unlock(&current->fs->lock);
1491 current->in_execve = 0; 1559 current->in_execve = 0;
1492 mutex_unlock(&current->cred_exec_mutex); 1560 mutex_unlock(&current->cred_exec_mutex);
1493 acct_update_integrals(current); 1561 acct_update_integrals(current);
@@ -1506,6 +1574,11 @@ out_file:
1506 fput(bprm->file); 1574 fput(bprm->file);
1507 } 1575 }
1508 1576
1577out_unmark:
1578 write_lock(&current->fs->lock);
1579 current->fs->in_exec = 0;
1580 write_unlock(&current->fs->lock);
1581
1509out_unlock: 1582out_unlock:
1510 current->in_execve = 0; 1583 current->in_execve = 0;
1511 mutex_unlock(&current->cred_exec_mutex); 1584 mutex_unlock(&current->cred_exec_mutex);