| @@ -2981,7 +2981,7 @@ static int module_sig_check(struct load_info *info, int flags) · 2980 unmodified lines |
| 2981 | 2981 | } |
| 2982 | 2982 | |
| 2983 | 2983 | if (is_module_sig_enforced()) { |
| 2984 | | − pr_notice("%s: loading of %s is rejected\n", info->name, reason); |
| 2984 | + pr_notice("Loading of %s is rejected\n", reason); |
| 2985 | 2985 | return -EKEYREJECTED; |
| 2986 | 2986 | } |
| 2987 | 2987 | |
| @@ -2994,9 +2994,33 @@ static int module_sig_check(struct load_info *info, int flags) · 6 unmodified lines |
| 2994 | 2994 | } |
| 2995 | 2995 | #endif /* !CONFIG_MODULE_SIG */ |
| 2996 | 2996 | |
| 2997 | | −/* Sanity checks against invalid binaries, wrong arch, weird elf version. */ |
| 2998 | | −static int elf_header_check(struct load_info *info) |
| 2997 | +static int validate_section_offset(struct load_info *info, Elf_Shdr *shdr) |
| 2999 | 2998 | { |
| 2999 | + unsigned long secend; |
| 3000 | + |
| 3001 | + /* |
| 3002 | + * Check for both overflow and offset/size being |
| 3003 | + * too large. |
| 3004 | + */ |
| 3005 | + secend = shdr->sh_offset + shdr->sh_size; |
| 3006 | + if (secend < shdr->sh_offset || secend > info->len) |
| 3007 | + return -ENOEXEC; |
| 3008 | + |
| 3009 | + return 0; |
| 3010 | +} |
| 3011 | + |
| 3012 | +/* |
| 3013 | + * Sanity checks against invalid binaries, wrong arch, weird elf version. |
| 3014 | + * |
| 3015 | + * Also do basic validity checks against section offsets and sizes, the |
| 3016 | + * section name string table, and the indices used for it (sh_name). |
| 3017 | + */ |
| 3018 | +static int elf_validity_check(struct load_info *info) |
| 3019 | +{ |
| 3020 | + unsigned int i; |
| 3021 | + Elf_Shdr *shdr, *strhdr; |
| 3022 | + int err; |
| 3023 | + |
| 3000 | 3024 | if (info->len < sizeof(*(info->hdr))) |
| 3001 | 3025 | return -ENOEXEC; |
| 3002 | 3026 | |
| @@ -3006,11 +3030,78 @@ static int elf_header_check(struct load_info *info) · 3 unmodified lines |
| 3006 | 3030 | || info->hdr->e_shentsize != sizeof(Elf_Shdr)) |
| 3007 | 3031 | return -ENOEXEC; |
| 3008 | 3032 | |
| 3033 | + /* |
| 3034 | + * e_shnum is 16 bits, and sizeof(Elf_Shdr) is |
| 3035 | + * known and small. So e_shnum * sizeof(Elf_Shdr) |
| 3036 | + * will not overflow unsigned long on any platform. |
| 3037 | + */ |
| 3009 | 3038 | if (info->hdr->e_shoff >= info->len |
| 3010 | 3039 | || (info->hdr->e_shnum * sizeof(Elf_Shdr) > |
| 3011 | 3040 | info->len - info->hdr->e_shoff)) |
| 3012 | 3041 | return -ENOEXEC; |
| 3013 | 3042 | |
| 3043 | + info->sechdrs = (void *)info->hdr + info->hdr->e_shoff; |
| 3044 | + |
| 3045 | + /* |
| 3046 | + * Verify if the section name table index is valid. |
| 3047 | + */ |
| 3048 | + if (info->hdr->e_shstrndx == SHN_UNDEF |
| 3049 | + || info->hdr->e_shstrndx >= info->hdr->e_shnum) |
| 3050 | + return -ENOEXEC; |
| 3051 | + |
| 3052 | + strhdr = &info->sechdrs[info->hdr->e_shstrndx]; |
| 3053 | + err = validate_section_offset(info, strhdr); |
| 3054 | + if (err < 0) |
| 3055 | + return err; |
| 3056 | + |
| 3057 | + /* |
| 3058 | + * The section name table must be NUL-terminated, as required |
| 3059 | + * by the spec. This makes strcmp and pr_* calls that access |
| 3060 | + * strings in the section safe. |
| 3061 | + */ |
| 3062 | + info->secstrings = (void *)info->hdr + strhdr->sh_offset; |
| 3063 | + if (info->secstrings[strhdr->sh_size - 1] != '\0') |
| 3064 | + return -ENOEXEC; |
| 3065 | + |
| 3066 | + /* |
| 3067 | + * The code assumes that section 0 has a length of zero and |
| 3068 | + * an addr of zero, so check for it. |
| 3069 | + */ |
| 3070 | + if (info->sechdrs[0].sh_type != SHT_NULL |
| 3071 | + || info->sechdrs[0].sh_size != 0 |
| 3072 | + || info->sechdrs[0].sh_addr != 0) |
| 3073 | + return -ENOEXEC; |
| 3074 | + |
| 3075 | + for (i = 1; i < info->hdr->e_shnum; i++) { |
| 3076 | + shdr = &info->sechdrs[i]; |
| 3077 | + switch (shdr->sh_type) { |
| 3078 | + case SHT_NULL: |
| 3079 | + case SHT_NOBITS: |
| 3080 | + continue; |
| 3081 | + case SHT_SYMTAB: |
| 3082 | + if (shdr->sh_link == SHN_UNDEF |
| 3083 | + || shdr->sh_link >= info->hdr->e_shnum) |
| 3084 | + return -ENOEXEC; |
| 3085 | + fallthrough; |
| 3086 | + default: |
| 3087 | + err = validate_section_offset(info, shdr); |
| 3088 | + if (err < 0) { |
| 3089 | + pr_err("Invalid ELF section in module (section %u type %u)\n", |
| 3090 | + i, shdr->sh_type); |
| 3091 | + return err; |
| 3092 | + } |
| 3093 | + |
| 3094 | + if (shdr->sh_flags & SHF_ALLOC) { |
| 3095 | + if (shdr->sh_name >= strhdr->sh_size) { |
| 3096 | + pr_err("Invalid ELF section name in module (section %u type %u)\n", |
| 3097 | + i, shdr->sh_type); |
| 3098 | + return -ENOEXEC; |
| 3099 | + } |
| 3100 | + } |
| 3101 | + break; |
| 3102 | + } |
| 3103 | + } |
| 3104 | + |
| 3014 | 3105 | return 0; |
| 3015 | 3106 | } |
| 3016 | 3107 | |
| @@ -3112,11 +3203,6 @@ static int rewrite_section_headers(struct load_info *info, int flags) · 95 unmodified lines |
| 3112 | 3203 | |
| 3113 | 3204 | for (i = 1; i < info->hdr->e_shnum; i++) { |
| 3114 | 3205 | Elf_Shdr *shdr = &info->sechdrs[i]; |
| 3115 | | − if (shdr->sh_type != SHT_NOBITS |
| 3116 | | − && info->len < shdr->sh_offset + shdr->sh_size) { |
| 3117 | | − pr_err("Module len %lu truncated\n", info->len); |
| 3118 | | − return -ENOEXEC; |
| 3119 | | − } |
| 3120 | 3206 | |
| 3121 | 3207 | /* |
| 3122 | 3208 | * Mark all sections sh_addr with their address in the |
| @@ -3150,11 +3236,6 @@ static int setup_load_info(struct load_info *info, int flags) · 27 unmodified lines |
| 3150 | 3236 | { |
| 3151 | 3237 | unsigned int i; |
| 3152 | 3238 | |
| 3153 | | − /* Set up the convenience variables */ |
| 3154 | | − info->sechdrs = (void *)info->hdr + info->hdr->e_shoff; |
| 3155 | | − info->secstrings = (void *)info->hdr |
| 3156 | | − + info->sechdrs[info->hdr->e_shstrndx].sh_offset; |
| 3157 | | − |
| 3158 | 3239 | /* Try to find a name early so we can log errors with a module name */ |
| 3159 | 3240 | info->index.info = find_sec(info, ".modinfo"); |
| 3160 | 3241 | if (info->index.info) |
| @@ -3911,26 +3992,50 @@ static int load_module(struct load_info *info, const char __user *uargs, · 750 unmodified lines |
| 3911 | 3992 | long err = 0; |
| 3912 | 3993 | char *after_dashes; |
| 3913 | 3994 | |
| 3914 | | − err = elf_header_check(info); |
| 3995 | + /* |
| 3996 | + * Do the signature check (if any) first. All that |
| 3997 | + * the signature check needs is info->len, it does |
| 3998 | + * not need any of the section info. That can be |
| 3999 | + * set up later. This will minimize the chances |
| 4000 | + * of a corrupt module causing problems before |
| 4001 | + * we even get to the signature check. |
| 4002 | + * |
| 4003 | + * The check will also adjust info->len by stripping |
| 4004 | + * off the sig length at the end of the module, making |
| 4005 | + * checks against info->len more correct. |
| 4006 | + */ |
| 4007 | + err = module_sig_check(info, flags); |
| 4008 | + if (err) |
| 4009 | + goto free_copy; |
| 4010 | + |
| 4011 | + /* |
| 4012 | + * Do basic sanity checks against the ELF header and |
| 4013 | + * sections. |
| 4014 | + */ |
| 4015 | + err = elf_validity_check(info); |
| 3915 | 4016 | if (err) { |
| 3916 | | − pr_err("Module has invalid ELF header\n"); |
| 4017 | + pr_err("Module has invalid ELF structures\n"); |
| 3917 | 4018 | goto free_copy; |
| 3918 | 4019 | } |
| 3919 | 4020 | |
| 4021 | + /* |
| 4022 | + * Everything checks out, so set up the section info |
| 4023 | + * in the info structure. |
| 4024 | + */ |
| 3920 | 4025 | err = setup_load_info(info, flags); |
| 3921 | 4026 | if (err) |
| 3922 | 4027 | goto free_copy; |
| 3923 | 4028 | |
| 4029 | + /* |
| 4030 | + * Now that we know we have the correct module name, check |
| 4031 | + * if it's blacklisted. |
| 4032 | + */ |
| 3924 | 4033 | if (blacklisted(info->name)) { |
| 3925 | 4034 | err = -EPERM; |
| 3926 | 4035 | pr_err("Module %s is blacklisted\n", info->name); |
| 3927 | 4036 | goto free_copy; |
| 3928 | 4037 | } |
| 3929 | 4038 | |
| 3930 | | − err = module_sig_check(info, flags); |
| 3931 | | − if (err) |
| 3932 | | − goto free_copy; |
| 3933 | | − |
| 3934 | 4039 | err = rewrite_section_headers(info, flags); |
| 3935 | 4040 | if (err) |
| 3936 | 4041 | goto free_copy; |