Deleted Added
sdiff udiff text old ( 81937 ) new ( 82749 )
full compact
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 ---