5 |
* |
* |
6 |
* Copyright (C) 2005-2007 NTT DATA CORPORATION |
* Copyright (C) 2005-2007 NTT DATA CORPORATION |
7 |
* |
* |
8 |
* Version: 1.5.0 2007/09/20 |
* Version: 1.5.1-pre 2007/10/16 |
9 |
* |
* |
10 |
* This file is applicable to both 2.4.30 and 2.6.11 and later. |
* This file is applicable to both 2.4.30 and 2.6.11 and later. |
11 |
* See README.ccs for ChangeLog. |
* See README.ccs for ChangeLog. |
756 |
return retval; |
return retval; |
757 |
} |
} |
758 |
|
|
759 |
|
static int CheckEnviron(struct linux_binprm *bprm) |
760 |
|
{ |
761 |
|
char *arg_ptr = ccs_alloc(CCS_MAX_PATHNAME_LEN); |
762 |
|
int arg_len = 0; |
763 |
|
unsigned long pos = bprm->p; |
764 |
|
int i = pos / PAGE_SIZE, offset = pos % PAGE_SIZE; |
765 |
|
int argv_count = bprm->argc; |
766 |
|
int envp_count = bprm->envc; |
767 |
|
//printk("start %d %d\n", argv_count, envp_count); |
768 |
|
int error = -ENOMEM; |
769 |
|
if (!arg_ptr) goto out; |
770 |
|
if (!envp_count) { |
771 |
|
error = 0; |
772 |
|
goto out; |
773 |
|
} |
774 |
|
while (error == -ENOMEM) { |
775 |
|
struct page *page; |
776 |
|
const char *kaddr; |
777 |
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) && defined(CONFIG_MMU) |
778 |
|
if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0) goto out; |
779 |
|
#else |
780 |
|
page = bprm->page[i]; |
781 |
|
#endif |
782 |
|
/* Map */ |
783 |
|
kaddr = kmap(page); |
784 |
|
if (!kaddr) { /* Mapping failed. */ |
785 |
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) && defined(CONFIG_MMU) |
786 |
|
put_page(page); |
787 |
|
#endif |
788 |
|
goto out; |
789 |
|
} |
790 |
|
/* Read. */ |
791 |
|
while (argv_count && offset < PAGE_SIZE) { |
792 |
|
if (!kaddr[offset++]) argv_count--; |
793 |
|
} |
794 |
|
if (argv_count) goto unmap_page; |
795 |
|
while (offset < PAGE_SIZE) { |
796 |
|
const unsigned char c = kaddr[offset++]; |
797 |
|
if (arg_len < CCS_MAX_PATHNAME_LEN - 10) { |
798 |
|
if (c == '=') { |
799 |
|
arg_ptr[arg_len++] = '\0'; |
800 |
|
} else if (c == '\\') { |
801 |
|
arg_ptr[arg_len++] = '\\'; |
802 |
|
arg_ptr[arg_len++] = '\\'; |
803 |
|
} else if (c > ' ' && c < 127) { |
804 |
|
arg_ptr[arg_len++] = c; |
805 |
|
} else { |
806 |
|
arg_ptr[arg_len++] = '\\'; |
807 |
|
arg_ptr[arg_len++] = (c >> 6) + '0'; |
808 |
|
arg_ptr[arg_len++] = ((c >> 3) & 7) + '0'; |
809 |
|
arg_ptr[arg_len++] = (c & 7) + '0'; |
810 |
|
} |
811 |
|
} else { |
812 |
|
arg_ptr[arg_len] = '\0'; |
813 |
|
} |
814 |
|
if (c) continue; |
815 |
|
if (CheckEnvPerm(arg_ptr)) { |
816 |
|
error = -EPERM; |
817 |
|
break; |
818 |
|
} |
819 |
|
if (!--envp_count) { |
820 |
|
error = 0; |
821 |
|
break; |
822 |
|
} |
823 |
|
arg_len = 0; |
824 |
|
} |
825 |
|
unmap_page: |
826 |
|
/* Unmap. */ |
827 |
|
kunmap(page); |
828 |
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) && defined(CONFIG_MMU) |
829 |
|
put_page(page); |
830 |
|
pos += PAGE_SIZE - offset; |
831 |
|
#endif |
832 |
|
i++; |
833 |
|
offset = 0; |
834 |
|
} |
835 |
|
out: |
836 |
|
ccs_free(arg_ptr); |
837 |
|
if (error && !CheckCCSEnforce(CCS_TOMOYO_MAC_FOR_ENV)) error = 0; |
838 |
|
return error; |
839 |
|
} |
840 |
|
|
841 |
#endif |
#endif |
842 |
|
|
843 |
int search_binary_handler_with_transition(struct linux_binprm *bprm, struct pt_regs *regs) |
int search_binary_handler_with_transition(struct linux_binprm *bprm, struct pt_regs *regs) |
854 |
retval = 0; next_domain = prev_domain; |
retval = 0; next_domain = prev_domain; |
855 |
#endif |
#endif |
856 |
if (retval == 0) { |
if (retval == 0) { |
|
current->tomoyo_flags |= TOMOYO_CHECK_READ_FOR_OPEN_EXEC; |
|
857 |
current->domain_info = next_domain; |
current->domain_info = next_domain; |
858 |
retval = search_binary_handler(bprm, regs); |
#if defined(CONFIG_TOMOYO) |
859 |
if (retval < 0) current->domain_info = prev_domain; |
if (CheckCCSFlags(CCS_TOMOYO_MAC_FOR_ENV)) retval = CheckEnviron(bprm); |
860 |
|
#endif |
861 |
|
current->tomoyo_flags |= TOMOYO_CHECK_READ_FOR_OPEN_EXEC; |
862 |
|
if (!retval) retval = search_binary_handler(bprm, regs); |
863 |
current->tomoyo_flags &= ~TOMOYO_CHECK_READ_FOR_OPEN_EXEC; |
current->tomoyo_flags &= ~TOMOYO_CHECK_READ_FOR_OPEN_EXEC; |
864 |
|
if (retval < 0) current->domain_info = prev_domain; |
865 |
} |
} |
866 |
return retval; |
return retval; |
867 |
} |
} |