| 880 | } |
| 881 | |
| 882 | static int |
| 883 | __elfN(enforce_limits)(struct image_params *imgp, const Elf_Ehdr *hdr, |
| 884 | const Elf_Phdr *phdr, u_long et_dyn_addr) |
| 885 | { |
| 886 | struct vmspace *vmspace; |
| 887 | const char *err_str; |
| 888 | u_long text_size, data_size, total_size, text_addr, data_addr; |
| 889 | u_long seg_size, seg_addr; |
| 890 | int i; |
| 891 | |
| 892 | err_str = NULL; |
| 893 | text_size = data_size = total_size = text_addr = data_addr = 0; |
| 894 | |
| 895 | for (i = 0; i < hdr->e_phnum; i++) { |
| 896 | if (phdr[i].p_type != PT_LOAD || phdr[i].p_memsz == 0) |
| 897 | continue; |
| 898 | |
| 899 | seg_addr = trunc_page(phdr[i].p_vaddr + et_dyn_addr); |
| 900 | seg_size = round_page(phdr[i].p_memsz + |
| 901 | phdr[i].p_vaddr + et_dyn_addr - seg_addr); |
| 902 | |
| 903 | /* |
| 904 | * Make the largest executable segment the official |
| 905 | * text segment and all others data. |
| 906 | * |
| 907 | * Note that obreak() assumes that data_addr + data_size == end |
| 908 | * of data load area, and the ELF file format expects segments |
| 909 | * to be sorted by address. If multiple data segments exist, |
| 910 | * the last one will be used. |
| 911 | */ |
| 912 | |
| 913 | if ((phdr[i].p_flags & PF_X) != 0 && text_size < seg_size) { |
| 914 | text_size = seg_size; |
| 915 | text_addr = seg_addr; |
| 916 | } else { |
| 917 | data_size = seg_size; |
| 918 | data_addr = seg_addr; |
| 919 | } |
| 920 | total_size += seg_size; |
| 921 | } |
| 922 | |
| 923 | if (data_addr == 0 && data_size == 0) { |
| 924 | data_addr = text_addr; |
| 925 | data_size = text_size; |
| 926 | } |
| 927 | |
| 928 | /* |
| 929 | * Check limits. It should be safe to check the |
| 930 | * limits after loading the segments since we do |
| 931 | * not actually fault in all the segments pages. |
| 932 | */ |
| 933 | PROC_LOCK(imgp->proc); |
| 934 | if (data_size > lim_cur_proc(imgp->proc, RLIMIT_DATA)) |
| 935 | err_str = "Data segment size exceeds process limit"; |
| 936 | else if (text_size > maxtsiz) |
| 937 | err_str = "Text segment size exceeds system limit"; |
| 938 | else if (total_size > lim_cur_proc(imgp->proc, RLIMIT_VMEM)) |
| 939 | err_str = "Total segment size exceeds process limit"; |
nothing calls this directly
no test coverage detected