diff options
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 36 |
1 files changed, 27 insertions, 9 deletions
@@ -850,15 +850,25 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size, | |||
850 | if (ret) | 850 | if (ret) |
851 | return ret; | 851 | return ret; |
852 | 852 | ||
853 | ret = deny_write_access(file); | ||
854 | if (ret) | ||
855 | return ret; | ||
856 | |||
853 | i_size = i_size_read(file_inode(file)); | 857 | i_size = i_size_read(file_inode(file)); |
854 | if (max_size > 0 && i_size > max_size) | 858 | if (max_size > 0 && i_size > max_size) { |
855 | return -EFBIG; | 859 | ret = -EFBIG; |
856 | if (i_size <= 0) | 860 | goto out; |
857 | return -EINVAL; | 861 | } |
862 | if (i_size <= 0) { | ||
863 | ret = -EINVAL; | ||
864 | goto out; | ||
865 | } | ||
858 | 866 | ||
859 | *buf = vmalloc(i_size); | 867 | *buf = vmalloc(i_size); |
860 | if (!*buf) | 868 | if (!*buf) { |
861 | return -ENOMEM; | 869 | ret = -ENOMEM; |
870 | goto out; | ||
871 | } | ||
862 | 872 | ||
863 | pos = 0; | 873 | pos = 0; |
864 | while (pos < i_size) { | 874 | while (pos < i_size) { |
@@ -876,18 +886,21 @@ int kernel_read_file(struct file *file, void **buf, loff_t *size, | |||
876 | 886 | ||
877 | if (pos != i_size) { | 887 | if (pos != i_size) { |
878 | ret = -EIO; | 888 | ret = -EIO; |
879 | goto out; | 889 | goto out_free; |
880 | } | 890 | } |
881 | 891 | ||
882 | ret = security_kernel_post_read_file(file, *buf, i_size, id); | 892 | ret = security_kernel_post_read_file(file, *buf, i_size, id); |
883 | if (!ret) | 893 | if (!ret) |
884 | *size = pos; | 894 | *size = pos; |
885 | 895 | ||
886 | out: | 896 | out_free: |
887 | if (ret < 0) { | 897 | if (ret < 0) { |
888 | vfree(*buf); | 898 | vfree(*buf); |
889 | *buf = NULL; | 899 | *buf = NULL; |
890 | } | 900 | } |
901 | |||
902 | out: | ||
903 | allow_write_access(file); | ||
891 | return ret; | 904 | return ret; |
892 | } | 905 | } |
893 | EXPORT_SYMBOL_GPL(kernel_read_file); | 906 | EXPORT_SYMBOL_GPL(kernel_read_file); |
@@ -1387,7 +1400,12 @@ static void bprm_fill_uid(struct linux_binprm *bprm) | |||
1387 | kuid_t uid; | 1400 | kuid_t uid; |
1388 | kgid_t gid; | 1401 | kgid_t gid; |
1389 | 1402 | ||
1390 | /* clear any previous set[ug]id data from a previous binary */ | 1403 | /* |
1404 | * Since this can be called multiple times (via prepare_binprm), | ||
1405 | * we must clear any previous work done when setting set[ug]id | ||
1406 | * bits from any earlier bprm->file uses (for example when run | ||
1407 | * first for a setuid script then again for its interpreter). | ||
1408 | */ | ||
1391 | bprm->cred->euid = current_euid(); | 1409 | bprm->cred->euid = current_euid(); |
1392 | bprm->cred->egid = current_egid(); | 1410 | bprm->cred->egid = current_egid(); |
1393 | 1411 | ||