kern_linker.c (81937) | kern_linker.c (82749) |
---|---|
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 * | 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 81937 2001-08-20 01:12:28Z dd $ | 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> | 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> |
|
39#include <sys/module.h> 40#include <sys/linker.h> 41#include <sys/fcntl.h> 42#include <sys/libkern.h> 43#include <sys/namei.h> 44#include <sys/vnode.h> 45#include <sys/sysctl.h> 46 --- 640 unchanged lines hidden (view full) --- 687 return ENOENT; 688} 689 690#endif 691 692/* 693 * Syscalls. 694 */ | 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 */ |
695 | 696/* 697 * MPSAFE 698 */ |
696int 697kldload(struct proc* p, struct kldload_args* uap) 698{ | 699int 700kldload(struct proc* p, struct kldload_args* uap) 701{ |
699 char* pathname, *realpath; | 702 char *pathname = NULL; 703 char *realpath = NULL; |
700 const char *filename; 701 linker_file_t lf; 702 int error = 0; 703 704 p->p_retval[0] = -1; 705 706 if (securelevel > 0) /* redundant, but that's OK */ 707 return EPERM; 708 | 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 |
|
709 if ((error = suser(p)) != 0) | 715 if ((error = suser(p)) != 0) |
710 return error; | 716 goto out; |
711 | 717 |
712 realpath = NULL; | |
713 pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 714 if ((error = copyinstr(SCARG(uap, file), pathname, MAXPATHLEN, NULL)) != 0) 715 goto out; 716 717 realpath = linker_search_path(pathname); 718 if (realpath == NULL) { 719 error = ENOENT; 720 goto out; --- 11 unchanged lines hidden (view full) --- 732 lf->userrefs++; 733 p->p_retval[0] = lf->id; 734 735out: 736 if (pathname) 737 free(pathname, M_TEMP); 738 if (realpath) 739 free(realpath, M_LINKER); | 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); |
740 return error; | 745 mtx_unlock(&Giant); 746 return (error); |
741} 742 | 747} 748 |
749/* 750 * MPSAFE 751 */ |
|
743int 744kldunload(struct proc* p, struct kldunload_args* uap) 745{ 746 linker_file_t lf; 747 int error = 0; 748 749 if (securelevel > 0) /* redundant, but that's OK */ 750 return EPERM; 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 |
|
752 if ((error = suser(p)) != 0) | 763 if ((error = suser(p)) != 0) |
753 return error; | 764 goto out; |
754 755 lf = linker_find_file_by_id(SCARG(uap, fileid)); 756 if (lf) { 757 KLD_DPF(FILE, ("kldunload: lf->userrefs=%d\n", lf->userrefs)); 758 if (lf->userrefs == 0) { 759 printf("kldunload: attempt to unload file that was loaded by the kernel\n"); 760 error = EBUSY; 761 goto out; 762 } 763 lf->userrefs--; 764 error = linker_file_unload(lf); 765 if (error) 766 lf->userrefs++; | 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++; |
767 } else | 778 } else { |
768 error = ENOENT; | 779 error = ENOENT; |
769 | 780 } |
770out: | 781out: |
771 return error; | 782 mtx_unlock(&Giant); 783 return (error); |
772} 773 | 784} 785 |
786/* 787 * MPSAFE 788 */ |
|
774int 775kldfind(struct proc* p, struct kldfind_args* uap) 776{ 777 char* pathname; 778 const char *filename; 779 linker_file_t lf; 780 int error = 0; 781 | 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 |
|
782 p->p_retval[0] = -1; 783 784 pathname = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 785 if ((error = copyinstr(SCARG(uap, file), pathname, MAXPATHLEN, NULL)) != 0) 786 goto out; 787 788 filename = linker_basename(pathname); 789 790 lf = linker_find_file_by_name(filename); 791 if (lf) 792 p->p_retval[0] = lf->id; 793 else 794 error = ENOENT; 795 796out: 797 if (pathname) 798 free(pathname, M_TEMP); | 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); |
799 return error; | 816 mtx_unlock(&Giant); 817 return (error); |
800} 801 | 818} 819 |
820/* 821 * MPSAFE 822 */ |
|
802int 803kldnext(struct proc* p, struct kldnext_args* uap) 804{ 805 linker_file_t lf; 806 int error = 0; 807 | 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 |
|
808 if (SCARG(uap, fileid) == 0) { 809 if (TAILQ_FIRST(&linker_files)) 810 p->p_retval[0] = TAILQ_FIRST(&linker_files)->id; 811 else 812 p->p_retval[0] = 0; | 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; |
813 return 0; | 836 goto out; |
814 } 815 816 lf = linker_find_file_by_id(SCARG(uap, fileid)); 817 if (lf) { 818 if (TAILQ_NEXT(lf, link)) 819 p->p_retval[0] = TAILQ_NEXT(lf, link)->id; 820 else 821 p->p_retval[0] = 0; | 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; |
822 } else | 845 } else { |
823 error = ENOENT; | 846 error = ENOENT; |
824 825 return error; | 847 } 848out: 849 mtx_unlock(&Giant); 850 return (error); |
826} 827 | 851} 852 |
853/* 854 * MPSAFE 855 */ |
|
828int 829kldstat(struct proc* p, struct kldstat_args* uap) 830{ 831 linker_file_t lf; 832 int error = 0; 833 int version; 834 struct kld_file_stat* stat; 835 int namelen; 836 | 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 |
|
837 lf = linker_find_file_by_id(SCARG(uap, fileid)); 838 if (!lf) { 839 error = ENOENT; 840 goto out; 841 } 842 843 stat = SCARG(uap, stat); 844 --- 19 unchanged lines hidden (view full) --- 864 if ((error = copyout(&lf->address, &stat->address, sizeof(caddr_t))) != 0) 865 goto out; 866 if ((error = copyout(&lf->size, &stat->size, sizeof(size_t))) != 0) 867 goto out; 868 869 p->p_retval[0] = 0; 870 871out: | 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: |
872 return error; | 902 mtx_unlock(&Giant); 903 return (error); |
873} 874 | 904} 905 |
906/* 907 * MPSAFE 908 */ |
|
875int 876kldfirstmod(struct proc* p, struct kldfirstmod_args* uap) 877{ 878 linker_file_t lf; 879 int error = 0; 880 | 909int 910kldfirstmod(struct proc* p, struct kldfirstmod_args* uap) 911{ 912 linker_file_t lf; 913 int error = 0; 914 |
915 mtx_lock(&Giant); |
|
881 lf = linker_find_file_by_id(SCARG(uap, fileid)); 882 if (lf) { 883 if (TAILQ_FIRST(&lf->modules)) 884 p->p_retval[0] = module_getid(TAILQ_FIRST(&lf->modules)); 885 else 886 p->p_retval[0] = 0; | 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; |
887 } else | 922 } else { |
888 error = ENOENT; | 923 error = ENOENT; |
889 890 return error; | 924 } 925 mtx_unlock(&Giant); 926 return (error); |
891} 892 | 927} 928 |
929/* 930 * MPSAFE 931 */ |
|
893int 894kldsym(struct proc *p, struct kldsym_args *uap) 895{ 896 char *symstr = NULL; 897 c_linker_sym_t sym; 898 linker_symval_t symval; 899 linker_file_t lf; 900 struct kld_sym_lookup lookup; 901 int error = 0; 902 | 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 |
|
903 if ((error = copyin(SCARG(uap, data), &lookup, sizeof(lookup))) != 0) 904 goto out; 905 if (lookup.version != sizeof(lookup) || SCARG(uap, cmd) != KLDSYM_LOOKUP) { 906 error = EINVAL; 907 goto out; 908 } 909 910 symstr = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); --- 24 unchanged lines hidden (view full) --- 935 } 936 } 937 if (!lf) 938 error = ENOENT; 939 } 940out: 941 if (symstr) 942 free(symstr, M_TEMP); | 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); |
943 return error; | 984 mtx_unlock(&Giant); 985 return (error); |
944} 945 946/* 947 * Preloaded module support 948 */ 949 950static modlist_t 951modlist_lookup(const char *name, int ver) --- 497 unchanged lines hidden --- | 986} 987 988/* 989 * Preloaded module support 990 */ 991 992static modlist_t 993modlist_lookup(const char *name, int ver) --- 497 unchanged lines hidden --- |