static int preload_this_library (struct linux_binprm *exe_bprm, char *lib_name) { int status; int old_fs = get_fs(); /* * If debugging then print "we have arrived" */ #ifdef COFF_DEBUG printk ("%s loading shared library %s\n", exe_bprm->filename, lib_name); #endif /* * Change the FS register to the proper kernel address space and attempt * to load the library. The library name is allocated from the kernel * pool. */ set_fs (get_ds ()); status = sys_uselib (lib_name); set_fs (old_fs); /* * Return the success/failure to the caller. */ return (status); }
/* * This procedure is called to load a library section. The various * libraries are loaded from the list given in the section data. */ static int coff_preload_shlib(struct linux_binprm *exe_bprm, COFF_SCNHDR *sect) { COFF_SLIBHD *phdr; char *buffer; long nbytes; int err = 0; /* * Fetch the size of the section. There must be * enough room for at least one entry. */ nbytes = (long)COFF_LONG(sect->s_size); if (nbytes < (long)COFF_SLIBSZ) return -ENOEXEC; if (!(buffer = kmalloc(nbytes, GFP_KERNEL))) { printk(KERN_WARNING "coff: unable to allocate shlib buffer\n"); return -ENOMEM; } err = kernel_read(exe_bprm->file, COFF_LONG(sect->s_scnptr), buffer, nbytes); if (err < 0) goto out; if (err != nbytes) goto enoexec; /* * Go through the list of libraries in the data area. */ phdr = (COFF_SLIBHD *)buffer; while (nbytes > (long)COFF_SLIBSZ) { int entry_size, header_size; mm_segment_t old_fs = get_fs(); entry_size = COFF_LONG(phdr->sl_entsz) * sizeof(long); header_size = COFF_LONG(phdr->sl_pathndx) * sizeof(long); /* * Validate the sizes of the various items. * I don't trust the linker!! */ if ((u_int)header_size >= (u_int)nbytes) goto enoexec; if ((u_int)entry_size <= (u_int)header_size) goto enoexec; if (entry_size <= 0) goto enoexec; set_fs(get_ds()); err = sys_uselib(&((char *)phdr)[header_size]); set_fs(old_fs); if (err < 0) goto out; /* * Point to the next library in the section data. */ nbytes -= entry_size; phdr = (COFF_SLIBHD *) & ((char *) phdr)[entry_size]; } out: kfree(buffer); return (err); enoexec: err = -ENOEXEC; goto out; }