Deleted Added
full compact
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 ---