1/*- 2 * Copyright (c) 1997-2000 Doug Rabson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * |
26 * $FreeBSD: head/sys/kern/kern_linker.c 82749 2001-09-01 19:04:37Z dillon $ |
27 */ 28 29#include "opt_ddb.h" 30 31#include <sys/param.h> 32#include <sys/kernel.h> 33#include <sys/systm.h> 34#include <sys/malloc.h> 35#include <sys/sysproto.h> 36#include <sys/sysent.h> 37#include <sys/proc.h> 38#include <sys/lock.h> |
39#include <sys/mutex.h> |
40#include <sys/module.h> 41#include <sys/linker.h> 42#include <sys/fcntl.h> 43#include <sys/libkern.h> 44#include <sys/namei.h> 45#include <sys/vnode.h> 46#include <sys/sysctl.h> 47 --- 640 unchanged lines hidden (view full) --- 688 return ENOENT; 689} 690 691#endif 692 693/* 694 * Syscalls. 695 */ |
696/* 697 * MPSAFE 698 */ |
699int 700kldload(struct proc* p, struct kldload_args* uap) 701{ |
702 char *pathname = NULL; 703 char *realpath = NULL; |
704 const char *filename; 705 linker_file_t lf; 706 int error = 0; 707 708 p->p_retval[0] = -1; 709 710 if (securelevel > 0) /* redundant, but that's OK */ 711 return EPERM; 712 |
713 mtx_lock(&Giant); 714 |
715 if ((error = suser(p)) != 0) |
716 goto out; |
717 |
718 pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 719 if ((error = copyinstr(SCARG(uap, file), pathname, MAXPATHLEN, NULL)) != 0) 720 goto out; 721 722 realpath = linker_search_path(pathname); 723 if (realpath == NULL) { 724 error = ENOENT; 725 goto out; --- 11 unchanged lines hidden (view full) --- 737 lf->userrefs++; 738 p->p_retval[0] = lf->id; 739 740out: 741 if (pathname) 742 free(pathname, M_TEMP); 743 if (realpath) 744 free(realpath, M_LINKER); |
745 mtx_unlock(&Giant); 746 return (error); |
747} 748 |
749/* 750 * MPSAFE 751 */ |
752int 753kldunload(struct proc* p, struct kldunload_args* uap) 754{ 755 linker_file_t lf; 756 int error = 0; 757 758 if (securelevel > 0) /* redundant, but that's OK */ 759 return EPERM; 760 |
761 mtx_lock(&Giant); 762 |
763 if ((error = suser(p)) != 0) |
764 goto out; |
765 766 lf = linker_find_file_by_id(SCARG(uap, fileid)); 767 if (lf) { 768 KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs)); 769 if (lf->userrefs == 0) { 770 printf("kldunload: attempt to unload file that was loaded by the kernel\n"); 771 error = EBUSY; 772 goto out; 773 } 774 lf->userrefs--; 775 error = linker_file_unload(lf); 776 if (error) 777 lf->userrefs++; |
778 } else { |
779 error = ENOENT; |
780 } |
781out: |
782 mtx_unlock(&Giant); 783 return (error); |
784} 785 |
786/* 787 * MPSAFE 788 */ |
789int 790kldfind(struct proc* p, struct kldfind_args* uap) 791{ 792 char* pathname; 793 const char *filename; 794 linker_file_t lf; 795 int error = 0; 796 |
797 mtx_lock(&Giant); 798 |
799 p->p_retval[0] = -1; 800 801 pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 802 if ((error = copyinstr(SCARG(uap, file), pathname, MAXPATHLEN, NULL)) != 0) 803 goto out; 804 805 filename = linker_basename(pathname); 806 807 lf = linker_find_file_by_name(filename); 808 if (lf) 809 p->p_retval[0] = lf->id; 810 else 811 error = ENOENT; 812 813out: 814 if (pathname) 815 free(pathname, M_TEMP); |
816 mtx_unlock(&Giant); 817 return (error); |
818} 819 |
820/* 821 * MPSAFE 822 */ |
823int 824kldnext(struct proc* p, struct kldnext_args* uap) 825{ 826 linker_file_t lf; 827 int error = 0; 828 |
829 mtx_lock(&Giant); 830 |
831 if (SCARG(uap, fileid) == 0) { 832 if (TAILQ_FIRST(&linker_files)) 833 p->p_retval[0] = TAILQ_FIRST(&linker_files)->id; 834 else 835 p->p_retval[0] = 0; |
836 goto out; |
837 } 838 839 lf = linker_find_file_by_id(SCARG(uap, fileid)); 840 if (lf) { 841 if (TAILQ_NEXT(lf, link)) 842 p->p_retval[0] = TAILQ_NEXT(lf, link)->id; 843 else 844 p->p_retval[0] = 0; |
845 } else { |
846 error = ENOENT; |
847 } 848out: 849 mtx_unlock(&Giant); 850 return (error); |
851} 852 |
853/* 854 * MPSAFE 855 */ |
856int 857kldstat(struct proc* p, struct kldstat_args* uap) 858{ 859 linker_file_t lf; 860 int error = 0; 861 int version; 862 struct kld_file_stat* stat; 863 int namelen; 864 |
865 mtx_lock(&Giant); 866 |
867 lf = linker_find_file_by_id(SCARG(uap, fileid)); 868 if (!lf) { 869 error = ENOENT; 870 goto out; 871 } 872 873 stat = SCARG(uap, stat); 874 --- 19 unchanged lines hidden (view full) --- 894 if ((error = copyout(&lf->address, &stat->address, sizeof(caddr_t))) != 0) 895 goto out; 896 if ((error = copyout(&lf->size, &stat->size, sizeof(size_t))) != 0) 897 goto out; 898 899 p->p_retval[0] = 0; 900 901out: |
902 mtx_unlock(&Giant); 903 return (error); |
904} 905 |
906/* 907 * MPSAFE 908 */ |
909int 910kldfirstmod(struct proc* p, struct kldfirstmod_args* uap) 911{ 912 linker_file_t lf; 913 int error = 0; 914 |
915 mtx_lock(&Giant); |
916 lf = linker_find_file_by_id(SCARG(uap, fileid)); 917 if (lf) { 918 if (TAILQ_FIRST(&lf->modules)) 919 p->p_retval[0] = module_getid(TAILQ_FIRST(&lf->modules)); 920 else 921 p->p_retval[0] = 0; |
922 } else { |
923 error = ENOENT; |
924 } 925 mtx_unlock(&Giant); 926 return (error); |
927} 928 |
929/* 930 * MPSAFE 931 */ |
932int 933kldsym(struct proc *p, struct kldsym_args *uap) 934{ 935 char *symstr = NULL; 936 c_linker_sym_t sym; 937 linker_symval_t symval; 938 linker_file_t lf; 939 struct kld_sym_lookup lookup; 940 int error = 0; 941 |
942 mtx_lock(&Giant); 943 |
944 if ((error = copyin(SCARG(uap, data), &lookup, sizeof(lookup))) != 0) 945 goto out; 946 if (lookup.version != sizeof(lookup) || SCARG(uap, cmd) != KLDSYM_LOOKUP) { 947 error = EINVAL; 948 goto out; 949 } 950 951 symstr = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); --- 24 unchanged lines hidden (view full) --- 976 } 977 } 978 if (!lf) 979 error = ENOENT; 980 } 981out: 982 if (symstr) 983 free(symstr, M_TEMP); |
984 mtx_unlock(&Giant); 985 return (error); |
986} 987 988/* 989 * Preloaded module support 990 */ 991 992static modlist_t 993modlist_lookup(const char *name, int ver) --- 497 unchanged lines hidden --- |