1 // SPDX-License-Identifier: GPL-2.0 << 2 /********************************************* 1 /****************************************************************************/ 3 /* 2 /* 4 * linux/fs/binfmt_flat.c 3 * linux/fs/binfmt_flat.c 5 * 4 * 6 * Copyright (C) 2000-2003 David McCullou 5 * Copyright (C) 2000-2003 David McCullough <davidm@snapgear.com> 7 * Copyright (C) 2002 Greg Ungerer <gerg@ 6 * Copyright (C) 2002 Greg Ungerer <gerg@snapgear.com> 8 * Copyright (C) 2002 SnapGear, by Paul D 7 * Copyright (C) 2002 SnapGear, by Paul Dale <pauli@snapgear.com> 9 * Copyright (C) 2000, 2001 Lineo, by Dav 8 * Copyright (C) 2000, 2001 Lineo, by David McCullough <davidm@lineo.com> 10 * based heavily on: 9 * based heavily on: 11 * 10 * 12 * linux/fs/binfmt_aout.c: 11 * linux/fs/binfmt_aout.c: 13 * Copyright (C) 1991, 1992, 1996 Linus 12 * Copyright (C) 1991, 1992, 1996 Linus Torvalds 14 * linux/fs/binfmt_flat.c for 2.0 kernel 13 * linux/fs/binfmt_flat.c for 2.0 kernel 15 * Copyright (C) 1998 Kenneth Albano 14 * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com> 16 * JAN/99 -- coded full program relocatio 15 * JAN/99 -- coded full program relocation (gerg@snapgear.com) 17 */ 16 */ 18 17 19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fm !! 18 #include <linux/module.h> 20 << 21 #include <linux/kernel.h> 19 #include <linux/kernel.h> 22 #include <linux/sched.h> 20 #include <linux/sched.h> 23 #include <linux/sched/task_stack.h> << 24 #include <linux/mm.h> 21 #include <linux/mm.h> 25 #include <linux/mman.h> 22 #include <linux/mman.h> 26 #include <linux/errno.h> 23 #include <linux/errno.h> 27 #include <linux/signal.h> 24 #include <linux/signal.h> 28 #include <linux/string.h> 25 #include <linux/string.h> 29 #include <linux/fs.h> 26 #include <linux/fs.h> 30 #include <linux/file.h> 27 #include <linux/file.h> >> 28 #include <linux/stat.h> >> 29 #include <linux/fcntl.h> 31 #include <linux/ptrace.h> 30 #include <linux/ptrace.h> 32 #include <linux/user.h> 31 #include <linux/user.h> 33 #include <linux/slab.h> 32 #include <linux/slab.h> 34 #include <linux/binfmts.h> 33 #include <linux/binfmts.h> 35 #include <linux/personality.h> 34 #include <linux/personality.h> 36 #include <linux/init.h> 35 #include <linux/init.h> 37 #include <linux/flat.h> 36 #include <linux/flat.h> 38 #include <linux/uaccess.h> !! 37 #include <linux/syscalls.h> 39 #include <linux/vmalloc.h> << 40 38 41 #include <asm/byteorder.h> 39 #include <asm/byteorder.h> 42 #include <linux/unaligned.h> !! 40 #include <asm/system.h> >> 41 #include <asm/uaccess.h> >> 42 #include <asm/unaligned.h> 43 #include <asm/cacheflush.h> 43 #include <asm/cacheflush.h> 44 #include <asm/page.h> 44 #include <asm/page.h> 45 #include <asm/flat.h> << 46 << 47 #ifndef flat_get_relocate_addr << 48 #define flat_get_relocate_addr(rel) (rel) << 49 #endif << 50 45 51 /********************************************* 46 /****************************************************************************/ 52 47 53 /* !! 48 #if 0 54 * User data (data section and bss) needs to b !! 49 #define DEBUG 1 55 * We pick 0x20 here because it is the max val !! 50 #endif 56 * used in producing FLAT files, and because i !! 51 57 * enough to make all the gcc alignment relate !! 52 #ifdef DEBUG 58 */ !! 53 #define DBG_FLT(a...) printk(a) 59 #define FLAT_DATA_ALIGN (0x20) !! 54 #else >> 55 #define DBG_FLT(a...) >> 56 #endif 60 57 61 /* 58 /* 62 * User data (stack) also needs to be aligned. !! 59 * User data (stack, data section and bss) needs to be aligned 63 * Here we can be a bit looser than the data s !! 60 * for the same reasons as SLAB memory is, and to the same amount. 64 * needs to only meet arch ABI requirements. !! 61 * Avoid duplicating architecture specific code by using the same >> 62 * macro as with SLAB allocation: 65 */ 63 */ 66 #define FLAT_STACK_ALIGN max_t(unsigned !! 64 #ifdef ARCH_SLAB_MINALIGN >> 65 #define FLAT_DATA_ALIGN (ARCH_SLAB_MINALIGN) >> 66 #else >> 67 #define FLAT_DATA_ALIGN (sizeof(void *)) >> 68 #endif 67 69 68 #define RELOC_FAILED 0xff00ff01 /* Rel 70 #define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */ 69 #define UNLOADED_LIB 0x7ff000ff /* Pla 71 #define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */ 70 72 71 #define MAX_SHARED_LIBS (1) << 72 << 73 #ifdef CONFIG_BINFMT_FLAT_NO_DATA_START_OFFSET << 74 #define DATA_START_OFFSET_WORDS (0) << 75 #define MAX_SHARED_LIBS_UPDATE (0) << 76 #else << 77 #define DATA_START_OFFSET_WORDS (MAX_S << 78 #define MAX_SHARED_LIBS_UPDATE (MAX_S << 79 #endif << 80 << 81 struct lib_info { 73 struct lib_info { 82 struct { 74 struct { 83 unsigned long start_code; 75 unsigned long start_code; /* Start of text segment */ 84 unsigned long start_data; 76 unsigned long start_data; /* Start of data segment */ 85 unsigned long start_brk; 77 unsigned long start_brk; /* End of data segment */ 86 unsigned long text_len; 78 unsigned long text_len; /* Length of text segment */ 87 unsigned long entry; 79 unsigned long entry; /* Start address for this module */ 88 unsigned long build_date; 80 unsigned long build_date; /* When this one was compiled */ 89 bool loaded; !! 81 short loaded; /* Has this library been loaded? */ 90 } lib_list[MAX_SHARED_LIBS]; 82 } lib_list[MAX_SHARED_LIBS]; 91 }; 83 }; 92 84 93 static int load_flat_binary(struct linux_binpr !! 85 #ifdef CONFIG_BINFMT_SHARED_FLAT >> 86 static int load_flat_shared_library(int id, struct lib_info *p); >> 87 #endif >> 88 >> 89 static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs); >> 90 static int flat_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit); 94 91 95 static struct linux_binfmt flat_format = { 92 static struct linux_binfmt flat_format = { 96 .module = THIS_MODULE, 93 .module = THIS_MODULE, 97 .load_binary = load_flat_binary, 94 .load_binary = load_flat_binary, >> 95 .core_dump = flat_core_dump, >> 96 .min_coredump = PAGE_SIZE 98 }; 97 }; 99 98 >> 99 /****************************************************************************/ >> 100 /* >> 101 * Routine writes a core dump image in the current directory. >> 102 * Currently only a stub-function. >> 103 */ >> 104 >> 105 static int flat_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit) >> 106 { >> 107 printk("Process %s:%d received signr %d and should have core dumped\n", >> 108 current->comm, current->pid, (int) signr); >> 109 return(1); >> 110 } 100 111 101 /********************************************* 112 /****************************************************************************/ 102 /* 113 /* 103 * create_flat_tables() parses the env- and ar 114 * create_flat_tables() parses the env- and arg-strings in new user 104 * memory and creates the pointer tables from 115 * memory and creates the pointer tables from them, and puts their 105 * addresses on the "stack", recording the new !! 116 * addresses on the "stack", returning the new stack pointer value. 106 */ 117 */ 107 118 108 static int create_flat_tables(struct linux_bin !! 119 static unsigned long create_flat_tables( >> 120 unsigned long pp, >> 121 struct linux_binprm * bprm) 109 { 122 { 110 char __user *p; !! 123 unsigned long *argv,*envp; 111 unsigned long __user *sp; !! 124 unsigned long * sp; 112 long i, len; !! 125 char * p = (char*)pp; 113 !! 126 int argc = bprm->argc; 114 p = (char __user *)arg_start; !! 127 int envc = bprm->envc; 115 sp = (unsigned long __user *)current-> !! 128 char uninitialized_var(dummy); 116 !! 129 117 sp -= bprm->envc + 1; !! 130 sp = (unsigned long *)p; 118 sp -= bprm->argc + 1; !! 131 sp -= (envc + argc + 2) + 1 + (flat_argvp_envp_on_stack() ? 2 : 0); 119 if (IS_ENABLED(CONFIG_BINFMT_FLAT_ARGV !! 132 sp = (unsigned long *) ((unsigned long)sp & -FLAT_DATA_ALIGN); 120 sp -= 2; /* argvp + envp */ !! 133 argv = sp + 1 + (flat_argvp_envp_on_stack() ? 2 : 0); 121 sp -= 1; /* &argc */ !! 134 envp = argv + (argc + 1); 122 !! 135 123 current->mm->start_stack = (unsigned l !! 136 if (flat_argvp_envp_on_stack()) { 124 sp = (unsigned long __user *)current-> !! 137 put_user((unsigned long) envp, sp + 2); 125 !! 138 put_user((unsigned long) argv, sp + 1); 126 if (put_user(bprm->argc, sp++)) !! 139 } 127 return -EFAULT; !! 140 128 if (IS_ENABLED(CONFIG_BINFMT_FLAT_ARGV !! 141 put_user(argc, sp); 129 unsigned long argv, envp; !! 142 current->mm->arg_start = (unsigned long) p; 130 argv = (unsigned long)(sp + 2) !! 143 while (argc-->0) { 131 envp = (unsigned long)(sp + 2 !! 144 put_user((unsigned long) p, argv++); 132 if (put_user(argv, sp++) || pu !! 145 do { 133 return -EFAULT; !! 146 get_user(dummy, p); p++; 134 } !! 147 } while (dummy); 135 !! 148 } 136 current->mm->arg_start = (unsigned lon !! 149 put_user((unsigned long) NULL, argv); 137 for (i = bprm->argc; i > 0; i--) { !! 150 current->mm->arg_end = current->mm->env_start = (unsigned long) p; 138 if (put_user((unsigned long)p, !! 151 while (envc-->0) { 139 return -EFAULT; !! 152 put_user((unsigned long)p, envp); envp++; 140 len = strnlen_user(p, MAX_ARG_ !! 153 do { 141 if (!len || len > MAX_ARG_STRL !! 154 get_user(dummy, p); p++; 142 return -EINVAL; !! 155 } while (dummy); 143 p += len; !! 156 } 144 } !! 157 put_user((unsigned long) NULL, envp); 145 if (put_user(0, sp++)) !! 158 current->mm->env_end = (unsigned long) p; 146 return -EFAULT; !! 159 return (unsigned long)sp; 147 current->mm->arg_end = (unsigned long) << 148 << 149 current->mm->env_start = (unsigned lon << 150 for (i = bprm->envc; i > 0; i--) { << 151 if (put_user((unsigned long)p, << 152 return -EFAULT; << 153 len = strnlen_user(p, MAX_ARG_ << 154 if (!len || len > MAX_ARG_STRL << 155 return -EINVAL; << 156 p += len; << 157 } << 158 if (put_user(0, sp++)) << 159 return -EFAULT; << 160 current->mm->env_end = (unsigned long) << 161 << 162 return 0; << 163 } 160 } 164 161 165 /********************************************* 162 /****************************************************************************/ 166 163 167 #ifdef CONFIG_BINFMT_ZFLAT 164 #ifdef CONFIG_BINFMT_ZFLAT 168 165 169 #include <linux/zlib.h> 166 #include <linux/zlib.h> 170 167 171 #define LBUFSIZE 4000 168 #define LBUFSIZE 4000 172 169 173 /* gzip flag byte */ 170 /* gzip flag byte */ 174 #define ASCII_FLAG 0x01 /* bit 0 set: file p 171 #define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */ 175 #define CONTINUATION 0x02 /* bit 1 set: contin 172 #define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */ 176 #define EXTRA_FIELD 0x04 /* bit 2 set: extra 173 #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ 177 #define ORIG_NAME 0x08 /* bit 3 set: origin 174 #define ORIG_NAME 0x08 /* bit 3 set: original file name present */ 178 #define COMMENT 0x10 /* bit 4 set: file c 175 #define COMMENT 0x10 /* bit 4 set: file comment present */ 179 #define ENCRYPTED 0x20 /* bit 5 set: file i 176 #define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */ 180 #define RESERVED 0xC0 /* bit 6,7: reserv 177 #define RESERVED 0xC0 /* bit 6,7: reserved */ 181 178 182 static int decompress_exec(struct linux_binprm !! 179 static int decompress_exec( 183 long len, int fd) !! 180 struct linux_binprm *bprm, >> 181 unsigned long offset, >> 182 char *dst, >> 183 long len, >> 184 int fd) 184 { 185 { 185 unsigned char *buf; 186 unsigned char *buf; 186 z_stream strm; 187 z_stream strm; >> 188 loff_t fpos; 187 int ret, retval; 189 int ret, retval; 188 190 189 pr_debug("decompress_exec(offset=%llx, !! 191 DBG_FLT("decompress_exec(offset=%x,buf=%x,len=%x)\n",(int)offset, (int)dst, (int)len); 190 192 191 memset(&strm, 0, sizeof(strm)); 193 memset(&strm, 0, sizeof(strm)); 192 strm.workspace = kmalloc(zlib_inflate_ 194 strm.workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); 193 if (!strm.workspace) !! 195 if (strm.workspace == NULL) { >> 196 DBG_FLT("binfmt_flat: no memory for decompress workspace\n"); 194 return -ENOMEM; 197 return -ENOMEM; 195 !! 198 } 196 buf = kmalloc(LBUFSIZE, GFP_KERNEL); 199 buf = kmalloc(LBUFSIZE, GFP_KERNEL); 197 if (!buf) { !! 200 if (buf == NULL) { >> 201 DBG_FLT("binfmt_flat: no memory for read buffer\n"); 198 retval = -ENOMEM; 202 retval = -ENOMEM; 199 goto out_free; 203 goto out_free; 200 } 204 } 201 205 202 /* Read in first chunk of data and par 206 /* Read in first chunk of data and parse gzip header. */ 203 ret = kernel_read(bprm->file, buf, LBU !! 207 fpos = offset; >> 208 ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos); 204 209 205 strm.next_in = buf; 210 strm.next_in = buf; 206 strm.avail_in = ret; 211 strm.avail_in = ret; 207 strm.total_in = 0; 212 strm.total_in = 0; 208 213 209 retval = -ENOEXEC; 214 retval = -ENOEXEC; 210 215 211 /* Check minimum size -- gzip header * 216 /* Check minimum size -- gzip header */ 212 if (ret < 10) { 217 if (ret < 10) { 213 pr_debug("file too small?\n"); !! 218 DBG_FLT("binfmt_flat: file too small?\n"); 214 goto out_free_buf; 219 goto out_free_buf; 215 } 220 } 216 221 217 /* Check gzip magic number */ 222 /* Check gzip magic number */ 218 if ((buf[0] != 037) || ((buf[1] != 021 223 if ((buf[0] != 037) || ((buf[1] != 0213) && (buf[1] != 0236))) { 219 pr_debug("unknown compression !! 224 DBG_FLT("binfmt_flat: unknown compression magic?\n"); 220 goto out_free_buf; 225 goto out_free_buf; 221 } 226 } 222 227 223 /* Check gzip method */ 228 /* Check gzip method */ 224 if (buf[2] != 8) { 229 if (buf[2] != 8) { 225 pr_debug("unknown compression !! 230 DBG_FLT("binfmt_flat: unknown compression method?\n"); 226 goto out_free_buf; 231 goto out_free_buf; 227 } 232 } 228 /* Check gzip flags */ 233 /* Check gzip flags */ 229 if ((buf[3] & ENCRYPTED) || (buf[3] & 234 if ((buf[3] & ENCRYPTED) || (buf[3] & CONTINUATION) || 230 (buf[3] & RESERVED)) { 235 (buf[3] & RESERVED)) { 231 pr_debug("unknown flags?\n"); !! 236 DBG_FLT("binfmt_flat: unknown flags?\n"); 232 goto out_free_buf; 237 goto out_free_buf; 233 } 238 } 234 239 235 ret = 10; 240 ret = 10; 236 if (buf[3] & EXTRA_FIELD) { 241 if (buf[3] & EXTRA_FIELD) { 237 ret += 2 + buf[10] + (buf[11] 242 ret += 2 + buf[10] + (buf[11] << 8); 238 if (unlikely(ret >= LBUFSIZE)) !! 243 if (unlikely(LBUFSIZE <= ret)) { 239 pr_debug("buffer overf !! 244 DBG_FLT("binfmt_flat: buffer overflow (EXTRA)?\n"); 240 goto out_free_buf; 245 goto out_free_buf; 241 } 246 } 242 } 247 } 243 if (buf[3] & ORIG_NAME) { 248 if (buf[3] & ORIG_NAME) { 244 while (ret < LBUFSIZE && buf[r 249 while (ret < LBUFSIZE && buf[ret++] != 0) 245 ; 250 ; 246 if (unlikely(ret == LBUFSIZE)) !! 251 if (unlikely(LBUFSIZE == ret)) { 247 pr_debug("buffer overf !! 252 DBG_FLT("binfmt_flat: buffer overflow (ORIG_NAME)?\n"); 248 goto out_free_buf; 253 goto out_free_buf; 249 } 254 } 250 } 255 } 251 if (buf[3] & COMMENT) { 256 if (buf[3] & COMMENT) { 252 while (ret < LBUFSIZE && buf[r 257 while (ret < LBUFSIZE && buf[ret++] != 0) 253 ; 258 ; 254 if (unlikely(ret == LBUFSIZE)) !! 259 if (unlikely(LBUFSIZE == ret)) { 255 pr_debug("buffer overf !! 260 DBG_FLT("binfmt_flat: buffer overflow (COMMENT)?\n"); 256 goto out_free_buf; 261 goto out_free_buf; 257 } 262 } 258 } 263 } 259 264 260 strm.next_in += ret; 265 strm.next_in += ret; 261 strm.avail_in -= ret; 266 strm.avail_in -= ret; 262 267 263 strm.next_out = dst; 268 strm.next_out = dst; 264 strm.avail_out = len; 269 strm.avail_out = len; 265 strm.total_out = 0; 270 strm.total_out = 0; 266 271 267 if (zlib_inflateInit2(&strm, -MAX_WBIT 272 if (zlib_inflateInit2(&strm, -MAX_WBITS) != Z_OK) { 268 pr_debug("zlib init failed?\n" !! 273 DBG_FLT("binfmt_flat: zlib init failed?\n"); 269 goto out_free_buf; 274 goto out_free_buf; 270 } 275 } 271 276 272 while ((ret = zlib_inflate(&strm, Z_NO 277 while ((ret = zlib_inflate(&strm, Z_NO_FLUSH)) == Z_OK) { 273 ret = kernel_read(bprm->file, !! 278 ret = bprm->file->f_op->read(bprm->file, buf, LBUFSIZE, &fpos); 274 if (ret <= 0) 279 if (ret <= 0) 275 break; 280 break; 276 len -= ret; 281 len -= ret; 277 282 278 strm.next_in = buf; 283 strm.next_in = buf; 279 strm.avail_in = ret; 284 strm.avail_in = ret; 280 strm.total_in = 0; 285 strm.total_in = 0; 281 } 286 } 282 287 283 if (ret < 0) { 288 if (ret < 0) { 284 pr_debug("decompression failed !! 289 DBG_FLT("binfmt_flat: decompression failed (%d), %s\n", 285 ret, strm.msg); 290 ret, strm.msg); 286 goto out_zlib; 291 goto out_zlib; 287 } 292 } 288 293 289 retval = 0; 294 retval = 0; 290 out_zlib: 295 out_zlib: 291 zlib_inflateEnd(&strm); 296 zlib_inflateEnd(&strm); 292 out_free_buf: 297 out_free_buf: 293 kfree(buf); 298 kfree(buf); 294 out_free: 299 out_free: 295 kfree(strm.workspace); 300 kfree(strm.workspace); 296 return retval; 301 return retval; 297 } 302 } 298 303 299 #endif /* CONFIG_BINFMT_ZFLAT */ 304 #endif /* CONFIG_BINFMT_ZFLAT */ 300 305 301 /********************************************* 306 /****************************************************************************/ 302 307 303 static unsigned long 308 static unsigned long 304 calc_reloc(unsigned long r, struct lib_info *p !! 309 calc_reloc(unsigned long r, struct lib_info *p, int curid, int internalp) 305 { 310 { 306 unsigned long addr; 311 unsigned long addr; >> 312 int id; 307 unsigned long start_brk; 313 unsigned long start_brk; 308 unsigned long start_data; 314 unsigned long start_data; 309 unsigned long text_len; 315 unsigned long text_len; 310 unsigned long start_code; 316 unsigned long start_code; 311 317 312 start_brk = p->lib_list[0].start_brk; !! 318 #ifdef CONFIG_BINFMT_SHARED_FLAT 313 start_data = p->lib_list[0].start_data !! 319 if (r == 0) 314 start_code = p->lib_list[0].start_code !! 320 id = curid; /* Relocs of 0 are always self referring */ 315 text_len = p->lib_list[0].text_len; !! 321 else { 316 !! 322 id = (r >> 24) & 0xff; /* Find ID for this reloc */ 317 if (r > start_brk - start_data + text_ !! 323 r &= 0x00ffffff; /* Trim ID off here */ 318 pr_err("reloc outside program !! 324 } 319 r, start_brk-start_data !! 325 if (id >= MAX_SHARED_LIBS) { >> 326 printk("BINFMT_FLAT: reference 0x%x to shared library %d", >> 327 (unsigned) r, id); >> 328 goto failed; >> 329 } >> 330 if (curid != id) { >> 331 if (internalp) { >> 332 printk("BINFMT_FLAT: reloc address 0x%x not in same module " >> 333 "(%d != %d)", (unsigned) r, curid, id); >> 334 goto failed; >> 335 } else if ( ! p->lib_list[id].loaded && >> 336 IS_ERR_VALUE(load_flat_shared_library(id, p))) { >> 337 printk("BINFMT_FLAT: failed to load library %d", id); >> 338 goto failed; >> 339 } >> 340 /* Check versioning information (i.e. time stamps) */ >> 341 if (p->lib_list[id].build_date && p->lib_list[curid].build_date && >> 342 p->lib_list[curid].build_date < p->lib_list[id].build_date) { >> 343 printk("BINFMT_FLAT: library %d is younger than %d", id, curid); >> 344 goto failed; >> 345 } >> 346 } >> 347 #else >> 348 id = 0; >> 349 #endif >> 350 >> 351 start_brk = p->lib_list[id].start_brk; >> 352 start_data = p->lib_list[id].start_data; >> 353 start_code = p->lib_list[id].start_code; >> 354 text_len = p->lib_list[id].text_len; >> 355 >> 356 if (!flat_reloc_valid(r, start_brk - start_data + text_len)) { >> 357 printk("BINFMT_FLAT: reloc outside program 0x%x (0 - 0x%x/0x%x)", >> 358 (int) r,(int)(start_brk-start_code),(int)text_len); 320 goto failed; 359 goto failed; 321 } 360 } 322 361 323 if (r < text_len) 362 if (r < text_len) /* In text segment */ 324 addr = r + start_code; 363 addr = r + start_code; 325 else 364 else /* In data segment */ 326 addr = r - text_len + start_da 365 addr = r - text_len + start_data; 327 366 328 /* Range checked already above so doin 367 /* Range checked already above so doing the range tests is redundant...*/ 329 return addr; !! 368 return(addr); 330 369 331 failed: 370 failed: 332 pr_cont(", killing %s!\n", current->co !! 371 printk(", killing %s!\n", current->comm); 333 send_sig(SIGSEGV, current, 0); 372 send_sig(SIGSEGV, current, 0); 334 373 335 return RELOC_FAILED; 374 return RELOC_FAILED; 336 } 375 } 337 376 338 /********************************************* 377 /****************************************************************************/ 339 378 340 #ifdef CONFIG_BINFMT_FLAT_OLD !! 379 void old_reloc(unsigned long rl) 341 static void old_reloc(unsigned long rl) << 342 { 380 { 343 static const char *segment[] = { "TEXT !! 381 #ifdef DEBUG >> 382 char *segment[] = { "TEXT", "DATA", "BSS", "*UNKNOWN*" }; >> 383 #endif 344 flat_v2_reloc_t r; 384 flat_v2_reloc_t r; 345 unsigned long __user *ptr; !! 385 unsigned long *ptr; 346 unsigned long val; !! 386 347 << 348 r.value = rl; 387 r.value = rl; 349 #if defined(CONFIG_COLDFIRE) 388 #if defined(CONFIG_COLDFIRE) 350 ptr = (unsigned long __user *)(current !! 389 ptr = (unsigned long *) (current->mm->start_code + r.reloc.offset); 351 #else 390 #else 352 ptr = (unsigned long __user *)(current !! 391 ptr = (unsigned long *) (current->mm->start_data + r.reloc.offset); 353 #endif 392 #endif 354 get_user(val, ptr); << 355 << 356 pr_debug("Relocation of variable at DA << 357 "(address %p, currently %lx) << 358 r.reloc.offset, ptr, val, seg << 359 393 >> 394 #ifdef DEBUG >> 395 printk("Relocation of variable at DATASEG+%x " >> 396 "(address %p, currently %x) into segment %s\n", >> 397 r.reloc.offset, ptr, (int)*ptr, segment[r.reloc.type]); >> 398 #endif >> 399 360 switch (r.reloc.type) { 400 switch (r.reloc.type) { 361 case OLD_FLAT_RELOC_TYPE_TEXT: 401 case OLD_FLAT_RELOC_TYPE_TEXT: 362 val += current->mm->start_code !! 402 *ptr += current->mm->start_code; 363 break; 403 break; 364 case OLD_FLAT_RELOC_TYPE_DATA: 404 case OLD_FLAT_RELOC_TYPE_DATA: 365 val += current->mm->start_data !! 405 *ptr += current->mm->start_data; 366 break; 406 break; 367 case OLD_FLAT_RELOC_TYPE_BSS: 407 case OLD_FLAT_RELOC_TYPE_BSS: 368 val += current->mm->end_data; !! 408 *ptr += current->mm->end_data; 369 break; 409 break; 370 default: 410 default: 371 pr_err("Unknown relocation typ !! 411 printk("BINFMT_FLAT: Unknown relocation type=%x\n", r.reloc.type); 372 break; 412 break; 373 } 413 } 374 put_user(val, ptr); << 375 414 376 pr_debug("Relocation became %lx\n", va !! 415 #ifdef DEBUG 377 } !! 416 printk("Relocation became %x\n", (int)*ptr); 378 #endif /* CONFIG_BINFMT_FLAT_OLD */ !! 417 #endif >> 418 } 379 419 380 /********************************************* 420 /****************************************************************************/ 381 421 382 static inline u32 __user *skip_got_header(u32 !! 422 static int load_flat_file(struct linux_binprm * bprm, >> 423 struct lib_info *libinfo, int id, unsigned long *extra_stack) 383 { 424 { 384 if (IS_ENABLED(CONFIG_RISCV)) { !! 425 struct flat_hdr * hdr; 385 /* !! 426 unsigned long textpos = 0, datapos = 0, result; 386 * RISC-V has a 16 byte GOT PL !! 427 unsigned long realdatastart = 0; 387 * and 8 byte GOT PLT header f !! 428 unsigned long text_len, data_len, bss_len, stack_len, flags; 388 * Skip the whole GOT PLT head !! 429 unsigned long len, memp = 0; 389 * for the dynamic linker (ld. !! 430 unsigned long memp_size, extra, rlim; 390 */ !! 431 unsigned long *reloc = 0, *rp; 391 u32 rp_val0, rp_val1; !! 432 struct inode *inode; 392 !! 433 int i, rev, relocs = 0; 393 if (get_user(rp_val0, rp)) << 394 return rp; << 395 if (get_user(rp_val1, rp + 1)) << 396 return rp; << 397 << 398 if (rp_val0 == 0xffffffff && r << 399 rp += 4; << 400 else if (rp_val0 == 0xffffffff << 401 rp += 2; << 402 } << 403 return rp; << 404 } << 405 << 406 static int load_flat_file(struct linux_binprm << 407 struct lib_info *libinfo, unsi << 408 { << 409 struct flat_hdr *hdr; << 410 unsigned long textpos, datapos, realda << 411 u32 text_len, data_len, bss_len, stack << 412 unsigned long len, memp, memp_size, ex << 413 __be32 __user *reloc; << 414 u32 __user *rp; << 415 int i, rev, relocs; << 416 loff_t fpos; 434 loff_t fpos; 417 unsigned long start_code, end_code; 435 unsigned long start_code, end_code; 418 ssize_t result; << 419 int ret; 436 int ret; 420 437 421 hdr = ((struct flat_hdr *) bprm->buf); 438 hdr = ((struct flat_hdr *) bprm->buf); /* exec-header */ >> 439 inode = bprm->file->f_path.dentry->d_inode; 422 440 423 text_len = ntohl(hdr->data_start); 441 text_len = ntohl(hdr->data_start); 424 data_len = ntohl(hdr->data_end) - nto 442 data_len = ntohl(hdr->data_end) - ntohl(hdr->data_start); 425 bss_len = ntohl(hdr->bss_end) - ntoh 443 bss_len = ntohl(hdr->bss_end) - ntohl(hdr->data_end); 426 stack_len = ntohl(hdr->stack_size); 444 stack_len = ntohl(hdr->stack_size); 427 if (extra_stack) { 445 if (extra_stack) { 428 stack_len += *extra_stack; 446 stack_len += *extra_stack; 429 *extra_stack = stack_len; 447 *extra_stack = stack_len; 430 } 448 } 431 relocs = ntohl(hdr->reloc_count); 449 relocs = ntohl(hdr->reloc_count); 432 flags = ntohl(hdr->flags); 450 flags = ntohl(hdr->flags); 433 rev = ntohl(hdr->rev); 451 rev = ntohl(hdr->rev); 434 full_data = data_len + relocs * sizeof << 435 452 436 if (strncmp(hdr->magic, "bFLT", 4)) { 453 if (strncmp(hdr->magic, "bFLT", 4)) { 437 /* 454 /* 438 * Previously, here was a prin 455 * Previously, here was a printk to tell people 439 * "BINFMT_FLAT: bad header 456 * "BINFMT_FLAT: bad header magic". 440 * But for the kernel which al 457 * But for the kernel which also use ELF FD-PIC format, this 441 * error message is confusing. 458 * error message is confusing. 442 * because a lot of people do 459 * because a lot of people do not manage to produce good 443 */ 460 */ 444 ret = -ENOEXEC; 461 ret = -ENOEXEC; 445 goto err; 462 goto err; 446 } 463 } 447 464 448 if (flags & FLAT_FLAG_KTRACE) 465 if (flags & FLAT_FLAG_KTRACE) 449 pr_info("Loading file: %s\n", !! 466 printk("BINFMT_FLAT: Loading file: %s\n", bprm->filename); 450 467 451 #ifdef CONFIG_BINFMT_FLAT_OLD << 452 if (rev != FLAT_VERSION && rev != OLD_ 468 if (rev != FLAT_VERSION && rev != OLD_FLAT_VERSION) { 453 pr_err("bad flat file version !! 469 printk("BINFMT_FLAT: bad flat file version 0x%x (supported " 454 rev, FLAT_VERSION, OLD_ !! 470 "0x%lx and 0x%lx)\n", >> 471 rev, FLAT_VERSION, OLD_FLAT_VERSION); >> 472 ret = -ENOEXEC; >> 473 goto err; >> 474 } >> 475 >> 476 /* Don't allow old format executables to use shared libraries */ >> 477 if (rev == OLD_FLAT_VERSION && id != 0) { >> 478 printk("BINFMT_FLAT: shared libraries are not available before rev 0x%x\n", >> 479 (int) FLAT_VERSION); 455 ret = -ENOEXEC; 480 ret = -ENOEXEC; 456 goto err; 481 goto err; 457 } 482 } 458 483 459 /* 484 /* 460 * fix up the flags for the older form 485 * fix up the flags for the older format, there were all kinds 461 * of endian hacks, this only works f 486 * of endian hacks, this only works for the simple cases 462 */ 487 */ 463 if (rev == OLD_FLAT_VERSION && !! 488 if (rev == OLD_FLAT_VERSION && flat_old_ram_flag(flags)) 464 (flags || IS_ENABLED(CONFIG_BINFMT_ << 465 flags = FLAT_FLAG_RAM; 489 flags = FLAT_FLAG_RAM; 466 490 467 #else /* CONFIG_BINFMT_FLAT_OLD */ << 468 if (rev != FLAT_VERSION) { << 469 pr_err("bad flat file version << 470 rev, FLAT_VERSION); << 471 ret = -ENOEXEC; << 472 goto err; << 473 } << 474 #endif /* !CONFIG_BINFMT_FLAT_OLD */ << 475 << 476 /* << 477 * Make sure the header params are san << 478 * 28 bits (256 MB) is way more than r << 479 * If some top bits are set we have pr << 480 */ << 481 if ((text_len | data_len | bss_len | s << 482 pr_err("bad header\n"); << 483 ret = -ENOEXEC; << 484 goto err; << 485 } << 486 << 487 #ifndef CONFIG_BINFMT_ZFLAT 491 #ifndef CONFIG_BINFMT_ZFLAT 488 if (flags & (FLAT_FLAG_GZIP|FLAT_FLAG_ 492 if (flags & (FLAT_FLAG_GZIP|FLAT_FLAG_GZDATA)) { 489 pr_err("Support for ZFLAT exec !! 493 printk("Support for ZFLAT executables is not enabled.\n"); 490 ret = -ENOEXEC; 494 ret = -ENOEXEC; 491 goto err; 495 goto err; 492 } 496 } 493 #endif 497 #endif 494 498 495 /* 499 /* 496 * Check initial limits. This avoids l 500 * Check initial limits. This avoids letting people circumvent 497 * size limits imposed on them by crea 501 * size limits imposed on them by creating programs with large 498 * arrays in the data or bss. 502 * arrays in the data or bss. 499 */ 503 */ 500 rlim = rlimit(RLIMIT_DATA); !! 504 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; 501 if (rlim >= RLIM_INFINITY) 505 if (rlim >= RLIM_INFINITY) 502 rlim = ~0; 506 rlim = ~0; 503 if (data_len + bss_len > rlim) { 507 if (data_len + bss_len > rlim) { 504 ret = -ENOMEM; 508 ret = -ENOMEM; 505 goto err; 509 goto err; 506 } 510 } 507 511 508 /* Flush all traces of the currently r 512 /* Flush all traces of the currently running executable */ 509 ret = begin_new_exec(bprm); !! 513 if (id == 0) { 510 if (ret) !! 514 result = flush_old_exec(bprm); 511 goto err; !! 515 if (result) { >> 516 ret = result; >> 517 goto err; >> 518 } 512 519 513 /* OK, This is the point of no return !! 520 /* OK, This is the point of no return */ 514 set_personality(PER_LINUX_32BIT); !! 521 set_personality(PER_LINUX_32BIT); 515 setup_new_exec(bprm); !! 522 setup_new_exec(bprm); >> 523 } 516 524 517 /* 525 /* 518 * calculate the extra space we need t 526 * calculate the extra space we need to map in 519 */ 527 */ 520 extra = max_t(unsigned long, bss_len + 528 extra = max_t(unsigned long, bss_len + stack_len, 521 relocs * sizeof(unsign 529 relocs * sizeof(unsigned long)); 522 530 523 /* 531 /* 524 * there are a couple of cases here, 532 * there are a couple of cases here, the separate code/data 525 * case, and then the fully copied to 533 * case, and then the fully copied to RAM case which lumps 526 * it all together. 534 * it all together. 527 */ 535 */ 528 if (!IS_ENABLED(CONFIG_MMU) && !(flags !! 536 if ((flags & (FLAT_FLAG_RAM|FLAT_FLAG_GZIP)) == 0) { 529 /* 537 /* 530 * this should give us a ROM p 538 * this should give us a ROM ptr, but if it doesn't we don't 531 * really care 539 * really care 532 */ 540 */ 533 pr_debug("ROM mapping of file !! 541 DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); 534 542 535 textpos = vm_mmap(bprm->file, !! 543 down_write(¤t->mm->mmap_sem); 536 MAP_PRIVATE, !! 544 textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, >> 545 MAP_PRIVATE|MAP_EXECUTABLE, 0); >> 546 up_write(¤t->mm->mmap_sem); 537 if (!textpos || IS_ERR_VALUE(t 547 if (!textpos || IS_ERR_VALUE(textpos)) { 538 ret = textpos; << 539 if (!textpos) 548 if (!textpos) 540 ret = -ENOMEM; !! 549 textpos = (unsigned long) -ENOMEM; 541 pr_err("Unable to mmap !! 550 printk("Unable to mmap process text, errno %d\n", (int)-textpos); >> 551 ret = textpos; 542 goto err; 552 goto err; 543 } 553 } 544 554 545 len = data_len + extra + !! 555 len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); 546 DATA_START_OFFSET_WORD << 547 len = PAGE_ALIGN(len); 556 len = PAGE_ALIGN(len); 548 realdatastart = vm_mmap(NULL, !! 557 down_write(¤t->mm->mmap_sem); >> 558 realdatastart = do_mmap(0, 0, len, 549 PROT_READ|PROT_WRITE|P 559 PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); >> 560 up_write(¤t->mm->mmap_sem); 550 561 551 if (realdatastart == 0 || IS_E 562 if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) { 552 ret = realdatastart; << 553 if (!realdatastart) 563 if (!realdatastart) 554 ret = -ENOMEM; !! 564 realdatastart = (unsigned long) -ENOMEM; 555 pr_err("Unable to allo !! 565 printk("Unable to allocate RAM for process data, errno %d\n", 556 "errno %d\n", r !! 566 (int)-realdatastart); 557 vm_munmap(textpos, tex !! 567 do_munmap(current->mm, textpos, text_len); >> 568 ret = realdatastart; 558 goto err; 569 goto err; 559 } 570 } 560 datapos = ALIGN(realdatastart 571 datapos = ALIGN(realdatastart + 561 DATA_START_OFF !! 572 MAX_SHARED_LIBS * sizeof(unsigned long), 562 FLAT_DATA_ALIG 573 FLAT_DATA_ALIGN); 563 574 564 pr_debug("Allocated data+bss+s !! 575 DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n", 565 data_len + bss_len + !! 576 (int)(data_len + bss_len + stack_len), (int)datapos); 566 577 567 fpos = ntohl(hdr->data_start); 578 fpos = ntohl(hdr->data_start); 568 #ifdef CONFIG_BINFMT_ZFLAT 579 #ifdef CONFIG_BINFMT_ZFLAT 569 if (flags & FLAT_FLAG_GZDATA) 580 if (flags & FLAT_FLAG_GZDATA) { 570 result = decompress_ex !! 581 result = decompress_exec(bprm, fpos, (char *) datapos, 571 !! 582 data_len + (relocs * sizeof(unsigned long)), 0); 572 } else 583 } else 573 #endif 584 #endif 574 { 585 { 575 result = read_code(bpr !! 586 result = bprm->file->f_op->read(bprm->file, (char *) datapos, 576 full_d !! 587 data_len + (relocs * sizeof(unsigned long)), &fpos); 577 } 588 } 578 if (IS_ERR_VALUE(result)) { 589 if (IS_ERR_VALUE(result)) { >> 590 printk("Unable to read data+bss, errno %d\n", (int)-result); >> 591 do_munmap(current->mm, textpos, text_len); >> 592 do_munmap(current->mm, realdatastart, data_len + extra); 579 ret = result; 593 ret = result; 580 pr_err("Unable to read << 581 vm_munmap(textpos, tex << 582 vm_munmap(realdatastar << 583 goto err; 594 goto err; 584 } 595 } 585 596 586 reloc = (__be32 __user *) !! 597 reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len)); 587 (datapos + (ntohl(hdr- << 588 memp = realdatastart; 598 memp = realdatastart; 589 memp_size = len; 599 memp_size = len; 590 } else { 600 } else { 591 601 592 len = text_len + data_len + ex !! 602 len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); 593 DATA_START_OFFSET_WORD << 594 len = PAGE_ALIGN(len); 603 len = PAGE_ALIGN(len); 595 textpos = vm_mmap(NULL, 0, len !! 604 down_write(¤t->mm->mmap_sem); >> 605 textpos = do_mmap(0, 0, len, 596 PROT_READ | PROT_EXEC 606 PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); >> 607 up_write(¤t->mm->mmap_sem); 597 608 598 if (!textpos || IS_ERR_VALUE(t 609 if (!textpos || IS_ERR_VALUE(textpos)) { 599 ret = textpos; << 600 if (!textpos) 610 if (!textpos) 601 ret = -ENOMEM; !! 611 textpos = (unsigned long) -ENOMEM; 602 pr_err("Unable to allo !! 612 printk("Unable to allocate RAM for process text/data, errno %d\n", 603 "errno %d\n", r !! 613 (int)-textpos); >> 614 ret = textpos; 604 goto err; 615 goto err; 605 } 616 } 606 617 607 realdatastart = textpos + ntoh 618 realdatastart = textpos + ntohl(hdr->data_start); 608 datapos = ALIGN(realdatastart 619 datapos = ALIGN(realdatastart + 609 DATA_START_OFF !! 620 MAX_SHARED_LIBS * sizeof(unsigned long), 610 FLAT_DATA_ALIG 621 FLAT_DATA_ALIGN); 611 622 612 reloc = (__be32 __user *) !! 623 reloc = (unsigned long *) 613 (datapos + (ntohl(hdr- 624 (datapos + (ntohl(hdr->reloc_start) - text_len)); 614 memp = textpos; 625 memp = textpos; 615 memp_size = len; 626 memp_size = len; 616 #ifdef CONFIG_BINFMT_ZFLAT 627 #ifdef CONFIG_BINFMT_ZFLAT 617 /* 628 /* 618 * load it all in and treat it 629 * load it all in and treat it like a RAM load from now on 619 */ 630 */ 620 if (flags & FLAT_FLAG_GZIP) { 631 if (flags & FLAT_FLAG_GZIP) { 621 #ifndef CONFIG_MMU !! 632 result = decompress_exec(bprm, sizeof (struct flat_hdr), 622 result = decompress_ex !! 633 (((char *) textpos) + sizeof (struct flat_hdr)), 623 (((ch !! 634 (text_len + data_len + (relocs * sizeof(unsigned long)) 624 (text !! 635 - sizeof (struct flat_hdr)), 625 << 626 0); 636 0); 627 memmove((void *) datap 637 memmove((void *) datapos, (void *) realdatastart, 628 full_d !! 638 data_len + (relocs * sizeof(unsigned long))); 629 #else << 630 /* << 631 * This is used on MMU << 632 * Let's use a kernel << 633 */ << 634 long unz_text_len = te << 635 long unz_len = unz_tex << 636 char *unz_data = vmall << 637 if (!unz_data) { << 638 result = -ENOM << 639 } else { << 640 result = decom << 641 << 642 if (result == << 643 (copy_to_u << 644 << 645 copy_to_u << 646 << 647 result << 648 vfree(unz_data << 649 } << 650 #endif << 651 } else if (flags & FLAT_FLAG_G 639 } else if (flags & FLAT_FLAG_GZDATA) { 652 result = read_code(bpr !! 640 fpos = 0; 653 if (!IS_ERR_VALUE(resu !! 641 result = bprm->file->f_op->read(bprm->file, 654 #ifndef CONFIG_MMU !! 642 (char *) textpos, text_len, &fpos); >> 643 if (!IS_ERR_VALUE(result)) 655 result = decom 644 result = decompress_exec(bprm, text_len, (char *) datapos, 656 !! 645 data_len + (relocs * sizeof(unsigned long)), 0); 657 #else !! 646 } 658 char *unz_data !! 647 else 659 if (!unz_data) << 660 result << 661 } else { << 662 result << 663 << 664 if (re << 665 co << 666 << 667 << 668 vfree( << 669 } << 670 #endif 648 #endif 671 } << 672 } else << 673 #endif /* CONFIG_BINFMT_ZFLAT */ << 674 { 649 { 675 result = read_code(bpr !! 650 fpos = 0; 676 if (!IS_ERR_VALUE(resu !! 651 result = bprm->file->f_op->read(bprm->file, 677 result = read_ !! 652 (char *) textpos, text_len, &fpos); 678 !! 653 if (!IS_ERR_VALUE(result)) { 679 !! 654 fpos = ntohl(hdr->data_start); >> 655 result = bprm->file->f_op->read(bprm->file, (char *) datapos, >> 656 data_len + (relocs * sizeof(unsigned long)), &fpos); >> 657 } 680 } 658 } 681 if (IS_ERR_VALUE(result)) { 659 if (IS_ERR_VALUE(result)) { >> 660 printk("Unable to read code+data+bss, errno %d\n",(int)-result); >> 661 do_munmap(current->mm, textpos, text_len + data_len + extra + >> 662 MAX_SHARED_LIBS * sizeof(unsigned long)); 682 ret = result; 663 ret = result; 683 pr_err("Unable to read << 684 vm_munmap(textpos, tex << 685 DATA_START_O << 686 goto err; 664 goto err; 687 } 665 } 688 } 666 } 689 667 690 start_code = textpos + sizeof(struct f !! 668 if (flags & FLAT_FLAG_KTRACE) 691 end_code = textpos + text_len; !! 669 printk("Mapping is %x, Entry point is %x, data_start is %x\n", 692 text_len -= sizeof(struct flat_hdr); / !! 670 (int)textpos, 0x00ffffff&ntohl(hdr->entry), ntohl(hdr->data_start)); 693 671 694 /* The main program needs a little ext 672 /* The main program needs a little extra setup in the task structure */ 695 current->mm->start_code = start_code; !! 673 start_code = textpos + sizeof (struct flat_hdr); 696 current->mm->end_code = end_code; !! 674 end_code = textpos + text_len; 697 current->mm->start_data = datapos; !! 675 if (id == 0) { 698 current->mm->end_data = datapos + data !! 676 current->mm->start_code = start_code; 699 /* !! 677 current->mm->end_code = end_code; 700 * set up the brk stuff, uses any slac !! 678 current->mm->start_data = datapos; 701 * allocation. We put the brk after t !! 679 current->mm->end_data = datapos + data_len; 702 * and stack) like other platforms. !! 680 /* 703 * Userspace code relies on the stack !! 681 * set up the brk stuff, uses any slack left in data/bss/stack 704 * an address right at the end of a pa !! 682 * allocation. We put the brk after the bss (between the bss 705 */ !! 683 * and stack) like other platforms. 706 current->mm->start_brk = datapos + dat !! 684 * Userspace code relies on the stack pointer starting out at 707 current->mm->brk = (current->mm->start !! 685 * an address right at the end of a page. 708 #ifndef CONFIG_MMU !! 686 */ 709 current->mm->context.end_brk = memp + !! 687 current->mm->start_brk = datapos + data_len + bss_len; 710 #endif !! 688 current->mm->brk = (current->mm->start_brk + 3) & ~3; 711 !! 689 current->mm->context.end_brk = memp + memp_size - stack_len; 712 if (flags & FLAT_FLAG_KTRACE) { << 713 pr_info("Mapping is %lx, Entry << 714 textpos, 0x00ffffff&nt << 715 pr_info("%s %s: TEXT=%lx-%lx D << 716 "Load", bprm->filename << 717 start_code, end_code, << 718 datapos + data_len, (d << 719 } 690 } 720 691 721 /* Store the current module values int !! 692 if (flags & FLAT_FLAG_KTRACE) 722 libinfo->lib_list[0].start_code = star !! 693 printk("%s %s: TEXT=%x-%x DATA=%x-%x BSS=%x-%x\n", 723 libinfo->lib_list[0].start_data = data !! 694 id ? "Lib" : "Load", bprm->filename, 724 libinfo->lib_list[0].start_brk = datap !! 695 (int) start_code, (int) end_code, 725 libinfo->lib_list[0].text_len = text_l !! 696 (int) datapos, 726 libinfo->lib_list[0].loaded = 1; !! 697 (int) (datapos + data_len), 727 libinfo->lib_list[0].entry = (0x00ffff !! 698 (int) (datapos + data_len), 728 libinfo->lib_list[0].build_date = ntoh !! 699 (int) (((datapos + data_len + bss_len) + 3) & ~3)); >> 700 >> 701 text_len -= sizeof(struct flat_hdr); /* the real code len */ 729 702 >> 703 /* Store the current module values into the global library structure */ >> 704 libinfo->lib_list[id].start_code = start_code; >> 705 libinfo->lib_list[id].start_data = datapos; >> 706 libinfo->lib_list[id].start_brk = datapos + data_len + bss_len; >> 707 libinfo->lib_list[id].text_len = text_len; >> 708 libinfo->lib_list[id].loaded = 1; >> 709 libinfo->lib_list[id].entry = (0x00ffffff & ntohl(hdr->entry)) + textpos; >> 710 libinfo->lib_list[id].build_date = ntohl(hdr->build_date); >> 711 730 /* 712 /* 731 * We just load the allocations into s 713 * We just load the allocations into some temporary memory to 732 * help simplify all this mumbo jumbo 714 * help simplify all this mumbo jumbo 733 * 715 * 734 * We've got two different sections of 716 * We've got two different sections of relocation entries. 735 * The first is the GOT which resides !! 717 * The first is the GOT which resides at the begining of the data segment 736 * and is terminated with a -1. This 718 * and is terminated with a -1. This one can be relocated in place. 737 * The second is the extra relocation 719 * The second is the extra relocation entries tacked after the image's 738 * data segment. These require a littl 720 * data segment. These require a little more processing as the entry is 739 * really an offset into the image whi 721 * really an offset into the image which contains an offset into the 740 * image. 722 * image. 741 */ 723 */ 742 if (flags & FLAT_FLAG_GOTPIC) { 724 if (flags & FLAT_FLAG_GOTPIC) { 743 rp = skip_got_header((u32 __us !! 725 for (rp = (unsigned long *)datapos; *rp != 0xffffffff; rp++) { 744 for (; ; rp++) { !! 726 unsigned long addr; 745 u32 addr, rp_val; !! 727 if (*rp) { 746 if (get_user(rp_val, r !! 728 addr = calc_reloc(*rp, libinfo, id, 0); 747 return -EFAULT << 748 if (rp_val == 0xffffff << 749 break; << 750 if (rp_val) { << 751 addr = calc_re << 752 if (addr == RE 729 if (addr == RELOC_FAILED) { 753 ret = 730 ret = -ENOEXEC; 754 goto e 731 goto err; 755 } 732 } 756 if (put_user(a !! 733 *rp = addr; 757 return << 758 } 734 } 759 } 735 } 760 } 736 } 761 737 762 /* 738 /* 763 * Now run through the relocation entr 739 * Now run through the relocation entries. 764 * We've got to be careful here as C++ 740 * We've got to be careful here as C++ produces relocatable zero 765 * entries in the constructor and dest 741 * entries in the constructor and destructor tables which are then 766 * tested for being not zero (which wi 742 * tested for being not zero (which will always occur unless we're 767 * based from address zero). This cau 743 * based from address zero). This causes an endless loop as __start 768 * is at zero. The solution used is t 744 * is at zero. The solution used is to not relocate zero addresses. 769 * This has the negative side effect o 745 * This has the negative side effect of not allowing a global data 770 * reference to be statically initiali 746 * reference to be statically initialised to _stext (I've moved 771 * __start to address 4 so that is oka 747 * __start to address 4 so that is okay). 772 */ 748 */ 773 if (rev > OLD_FLAT_VERSION) { 749 if (rev > OLD_FLAT_VERSION) { 774 for (i = 0; i < relocs; i++) { !! 750 unsigned long persistent = 0; 775 u32 addr, relval; !! 751 for (i=0; i < relocs; i++) { 776 __be32 tmp; !! 752 unsigned long addr, relval; 777 !! 753 778 /* !! 754 /* Get the address of the pointer to be 779 * Get the address of !! 755 relocated (of course, the address has to be 780 * relocated (of cours !! 756 relocated first). */ 781 * relocated first). !! 757 relval = ntohl(reloc[i]); 782 */ !! 758 if (flat_set_persistent (relval, &persistent)) 783 if (get_user(tmp, relo !! 759 continue; 784 return -EFAULT << 785 relval = ntohl(tmp); << 786 addr = flat_get_reloca 760 addr = flat_get_relocate_addr(relval); 787 rp = (u32 __user *)cal !! 761 rp = (unsigned long *) calc_reloc(addr, libinfo, id, 1); 788 if (rp == (u32 __user !! 762 if (rp == (unsigned long *)RELOC_FAILED) { 789 ret = -ENOEXEC 763 ret = -ENOEXEC; 790 goto err; 764 goto err; 791 } 765 } 792 766 793 /* Get the pointer's v 767 /* Get the pointer's value. */ 794 ret = flat_get_addr_fr !! 768 addr = flat_get_addr_from_rp(rp, relval, flags, 795 if (unlikely(ret)) !! 769 &persistent); 796 goto err; << 797 << 798 if (addr != 0) { 770 if (addr != 0) { 799 /* 771 /* 800 * Do the relo 772 * Do the relocation. PIC relocs in the data section are 801 * already in 773 * already in target order 802 */ 774 */ 803 if ((flags & F !! 775 if ((flags & FLAT_FLAG_GOTPIC) == 0) 804 /* !! 776 addr = ntohl(addr); 805 * Meh !! 777 addr = calc_reloc(addr, libinfo, id, 0); 806 * byt << 807 */ << 808 addr = << 809 } << 810 addr = calc_re << 811 if (addr == RE 778 if (addr == RELOC_FAILED) { 812 ret = 779 ret = -ENOEXEC; 813 goto e 780 goto err; 814 } 781 } 815 782 816 /* Write back 783 /* Write back the relocated pointer. */ 817 ret = flat_put !! 784 flat_put_addr_at_rp(rp, addr, relval); 818 if (unlikely(r << 819 goto e << 820 } 785 } 821 } 786 } 822 #ifdef CONFIG_BINFMT_FLAT_OLD << 823 } else { 787 } else { 824 for (i = 0; i < relocs; i++) { !! 788 for (i=0; i < relocs; i++) 825 __be32 relval; !! 789 old_reloc(ntohl(reloc[i])); 826 if (get_user(relval, r << 827 return -EFAULT << 828 old_reloc(ntohl(relval << 829 } << 830 #endif /* CONFIG_BINFMT_FLAT_OLD */ << 831 } 790 } 832 !! 791 833 flush_icache_user_range(start_code, en !! 792 flush_icache_range(start_code, end_code); 834 793 835 /* zero the BSS, BRK and stack areas 794 /* zero the BSS, BRK and stack areas */ 836 if (clear_user((void __user *)(datapos !! 795 memset((void*)(datapos + data_len), 0, bss_len + 837 (memp + memp_size - sta !! 796 (memp + memp_size - stack_len - /* end brk */ 838 libinfo->lib_list[0].st !! 797 libinfo->lib_list[id].start_brk) + /* start brk */ 839 stack_len)) !! 798 stack_len); 840 return -EFAULT; << 841 799 842 return 0; 800 return 0; 843 err: 801 err: 844 return ret; 802 return ret; 845 } 803 } 846 804 847 805 848 /********************************************* 806 /****************************************************************************/ >> 807 #ifdef CONFIG_BINFMT_SHARED_FLAT >> 808 >> 809 /* >> 810 * Load a shared library into memory. The library gets its own data >> 811 * segment (including bss) but not argv/argc/environ. >> 812 */ >> 813 >> 814 static int load_flat_shared_library(int id, struct lib_info *libs) >> 815 { >> 816 struct linux_binprm bprm; >> 817 int res; >> 818 char buf[16]; >> 819 >> 820 /* Create the file name */ >> 821 sprintf(buf, "/lib/lib%d.so", id); >> 822 >> 823 /* Open the file up */ >> 824 bprm.filename = buf; >> 825 bprm.file = open_exec(bprm.filename); >> 826 res = PTR_ERR(bprm.file); >> 827 if (IS_ERR(bprm.file)) >> 828 return res; >> 829 >> 830 bprm.cred = prepare_exec_creds(); >> 831 res = -ENOMEM; >> 832 if (!bprm.cred) >> 833 goto out; >> 834 >> 835 res = prepare_binprm(&bprm); >> 836 >> 837 if (!IS_ERR_VALUE(res)) >> 838 res = load_flat_file(&bprm, libs, id, NULL); >> 839 >> 840 abort_creds(bprm.cred); >> 841 >> 842 out: >> 843 allow_write_access(bprm.file); >> 844 fput(bprm.file); >> 845 >> 846 return(res); >> 847 } >> 848 >> 849 #endif /* CONFIG_BINFMT_SHARED_FLAT */ >> 850 /****************************************************************************/ 849 851 850 /* 852 /* 851 * These are the functions used to load flat s 853 * These are the functions used to load flat style executables and shared 852 * libraries. There is no binary dependent co 854 * libraries. There is no binary dependent code anywhere else. 853 */ 855 */ 854 856 855 static int load_flat_binary(struct linux_binpr !! 857 static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs) 856 { 858 { 857 struct lib_info libinfo; 859 struct lib_info libinfo; 858 struct pt_regs *regs = current_pt_regs !! 860 unsigned long p = bprm->p; 859 unsigned long stack_len = 0; !! 861 unsigned long stack_len; 860 unsigned long start_addr; 862 unsigned long start_addr; >> 863 unsigned long *sp; 861 int res; 864 int res; 862 int i, j; 865 int i, j; 863 866 864 memset(&libinfo, 0, sizeof(libinfo)); 867 memset(&libinfo, 0, sizeof(libinfo)); 865 << 866 /* 868 /* 867 * We have to add the size of our argu 869 * We have to add the size of our arguments to our stack size 868 * otherwise it's too easy for users t 870 * otherwise it's too easy for users to create stack overflows 869 * by passing in a huge argument list. 871 * by passing in a huge argument list. And yes, we have to be 870 * pedantic and include space for the 872 * pedantic and include space for the argv/envp array as it may have 871 * a lot of entries. 873 * a lot of entries. 872 */ 874 */ 873 #ifndef CONFIG_MMU !! 875 #define TOP_OF_ARGS (PAGE_SIZE * MAX_ARG_PAGES - sizeof(void *)) 874 stack_len += PAGE_SIZE * MAX_ARG_PAGES !! 876 stack_len = TOP_OF_ARGS - bprm->p; /* the strings */ 875 #endif !! 877 stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */ 876 stack_len += (bprm->argc + 1) * sizeof !! 878 stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */ 877 stack_len += (bprm->envc + 1) * sizeof !! 879 stack_len += FLAT_DATA_ALIGN - 1; /* reserve for upcoming alignment */ 878 stack_len = ALIGN(stack_len, FLAT_STAC !! 880 879 !! 881 res = load_flat_file(bprm, &libinfo, 0, &stack_len); 880 res = load_flat_file(bprm, &libinfo, & !! 882 if (IS_ERR_VALUE(res)) 881 if (res < 0) << 882 return res; 883 return res; 883 !! 884 884 /* Update data segment pointers for al 885 /* Update data segment pointers for all libraries */ 885 for (i = 0; i < MAX_SHARED_LIBS_UPDATE !! 886 for (i=0; i<MAX_SHARED_LIBS; i++) 886 if (!libinfo.lib_list[i].loade !! 887 if (libinfo.lib_list[i].loaded) 887 continue; !! 888 for (j=0; j<MAX_SHARED_LIBS; j++) 888 for (j = 0; j < MAX_SHARED_LIB !! 889 (-(j+1))[(unsigned long *)(libinfo.lib_list[i].start_data)] = 889 unsigned long val = li !! 890 (libinfo.lib_list[j].loaded)? 890 libinfo.lib_li !! 891 libinfo.lib_list[j].start_data:UNLOADED_LIB; 891 unsigned long __user * !! 892 892 libinfo.lib_li !! 893 install_exec_creds(bprm); 893 p -= j + 1; !! 894 current->flags &= ~PF_FORKNOEXEC; 894 if (put_user(val, p)) << 895 return -EFAULT << 896 } << 897 } << 898 895 899 set_binfmt(&flat_format); 896 set_binfmt(&flat_format); 900 897 901 #ifdef CONFIG_MMU !! 898 p = ((current->mm->context.end_brk + stack_len + 3) & ~3) - 4; 902 res = setup_arg_pages(bprm, STACK_TOP, !! 899 DBG_FLT("p=%x\n", (int)p); 903 if (!res) << 904 res = create_flat_tables(bprm, << 905 #else << 906 /* Stash our initial stack pointer int << 907 current->mm->start_stack = << 908 ((current->mm->context.end_brk << 909 pr_debug("sp=%lx\n", current->mm->star << 910 << 911 /* copy the arg pages onto the stack * << 912 res = transfer_args_to_stack(bprm, &cu << 913 if (!res) << 914 res = create_flat_tables(bprm, << 915 #endif << 916 if (res) << 917 return res; << 918 900 >> 901 /* copy the arg pages onto the stack, this could be more efficient :-) */ >> 902 for (i = TOP_OF_ARGS - 1; i >= bprm->p; i--) >> 903 * (char *) --p = >> 904 ((char *) page_address(bprm->page[i/PAGE_SIZE]))[i % PAGE_SIZE]; >> 905 >> 906 sp = (unsigned long *) create_flat_tables(p, bprm); >> 907 919 /* Fake some return addresses to ensur 908 /* Fake some return addresses to ensure the call chain will 920 * initialise library in order for us. 909 * initialise library in order for us. We are required to call 921 * lib 1 first, then 2, ... and finall 910 * lib 1 first, then 2, ... and finally the main program (id 0). 922 */ 911 */ 923 start_addr = libinfo.lib_list[0].entry 912 start_addr = libinfo.lib_list[0].entry; 924 913 >> 914 #ifdef CONFIG_BINFMT_SHARED_FLAT >> 915 for (i = MAX_SHARED_LIBS-1; i>0; i--) { >> 916 if (libinfo.lib_list[i].loaded) { >> 917 /* Push previos first to call address */ >> 918 --sp; put_user(start_addr, sp); >> 919 start_addr = libinfo.lib_list[i].entry; >> 920 } >> 921 } >> 922 #endif >> 923 >> 924 /* Stash our initial stack pointer into the mm structure */ >> 925 current->mm->start_stack = (unsigned long )sp; >> 926 925 #ifdef FLAT_PLAT_INIT 927 #ifdef FLAT_PLAT_INIT 926 FLAT_PLAT_INIT(regs); 928 FLAT_PLAT_INIT(regs); 927 #endif 929 #endif 928 !! 930 DBG_FLT("start_thread(regs=0x%x, entry=0x%x, start_stack=0x%x)\n", 929 finalize_exec(bprm); !! 931 (int)regs, (int)start_addr, (int)current->mm->start_stack); 930 pr_debug("start_thread(regs=0x%p, entr !! 932 931 regs, start_addr, current->mm << 932 start_thread(regs, start_addr, current 933 start_thread(regs, start_addr, current->mm->start_stack); 933 934 934 return 0; 935 return 0; 935 } 936 } 936 937 937 /********************************************* 938 /****************************************************************************/ 938 939 939 static int __init init_flat_binfmt(void) 940 static int __init init_flat_binfmt(void) 940 { 941 { 941 register_binfmt(&flat_format); !! 942 return register_binfmt(&flat_format); 942 return 0; << 943 } 943 } >> 944 >> 945 /****************************************************************************/ >> 946 944 core_initcall(init_flat_binfmt); 947 core_initcall(init_flat_binfmt); 945 948 946 /********************************************* 949 /****************************************************************************/ 947 950
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.