summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2011-03-30 14:46:12 +0000
committerkib <kib@FreeBSD.org>2011-03-30 14:46:12 +0000
commit5c02dd1e9add6c29db896cf655430f442997109b (patch)
treef653afa54410b6fb98e6f9a19020b6fd180a3ab9
parente27ebee43a59badd94d03f57ed93a881ff12a516 (diff)
downloadFreeBSD-src-5c02dd1e9add6c29db896cf655430f442997109b.zip
FreeBSD-src-5c02dd1e9add6c29db896cf655430f442997109b.tar.gz
Provide compat32 shims for kldstat(2).
Requested and tested by: jpaetzel MFC after: 1 week
-rw-r--r--sys/compat/freebsd32/freebsd32.h19
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c27
-rw-r--r--sys/compat/freebsd32/syscalls.master4
-rw-r--r--sys/kern/kern_linker.c53
-rw-r--r--sys/sys/syscallsubr.h2
5 files changed, 80 insertions, 25 deletions
diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h
index e04d202..560db72 100644
--- a/sys/compat/freebsd32/freebsd32.h
+++ b/sys/compat/freebsd32/freebsd32.h
@@ -336,4 +336,23 @@ struct kinfo_proc32 {
int ki_tdflags;
};
+struct kld32_file_stat_1 {
+ int version; /* set to sizeof(struct kld_file_stat_1) */
+ char name[MAXPATHLEN];
+ int refs;
+ int id;
+ uint32_t address; /* load address */
+ uint32_t size; /* size in bytes */
+};
+
+struct kld32_file_stat {
+ int version; /* set to sizeof(struct kld_file_stat) */
+ char name[MAXPATHLEN];
+ int refs;
+ int id;
+ uint32_t address; /* load address */
+ uint32_t size; /* size in bytes */
+ char pathname[MAXPATHLEN];
+};
+
#endif /* !_COMPAT_FREEBSD32_FREEBSD32_H_ */
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index cf3af87..e751147 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/jail.h>
#include <sys/kernel.h>
#include <sys/limits.h>
+#include <sys/linker.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/file.h> /* Must come after sys/malloc.h */
@@ -2669,3 +2670,29 @@ freebsd32_copyout_strings(struct image_params *imgp)
return ((register_t *)stack_base);
}
+int
+freebsd32_kldstat(struct thread *td, struct freebsd32_kldstat_args *uap)
+{
+ struct kld_file_stat stat;
+ struct kld32_file_stat stat32;
+ int error, version;
+
+ if ((error = copyin(&uap->stat->version, &version, sizeof(version)))
+ != 0)
+ return (error);
+ if (version != sizeof(struct kld32_file_stat_1) &&
+ version != sizeof(struct kld32_file_stat))
+ return (EINVAL);
+
+ error = kern_kldstat(td, uap->fileid, &stat);
+ if (error != 0)
+ return (error);
+
+ bcopy(&stat.name[0], &stat32.name[0], sizeof(stat.name));
+ CP(stat, stat32, refs);
+ CP(stat, stat32, id);
+ PTROUT_CP(stat, stat32, address);
+ CP(stat, stat32, size);
+ bcopy(&stat.pathname[0], &stat32.pathname[0], sizeof(stat.pathname));
+ return (copyout(&stat32, uap->stat, version));
+}
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
index 26c0f6e..31a67b6 100644
--- a/sys/compat/freebsd32/syscalls.master
+++ b/sys/compat/freebsd32/syscalls.master
@@ -533,8 +533,8 @@
305 AUE_MODUNLOAD NOPROTO { int kldunload(int fileid); }
306 AUE_NULL NOPROTO { int kldfind(const char *file); }
307 AUE_NULL NOPROTO { int kldnext(int fileid); }
-308 AUE_NULL NOPROTO { int kldstat(int fileid, \
- struct kld_file_stat* stat); }
+308 AUE_NULL STD { int freebsd32_kldstat(int fileid, \
+ struct kld32_file_stat* stat); }
309 AUE_NULL NOPROTO { int kldfirstmod(int fileid); }
310 AUE_GETSID NOPROTO { int getsid(pid_t pid); }
311 AUE_SETRESUID NOPROTO { int setresuid(uid_t ruid, uid_t euid, \
diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c
index e4837d1..86a14ae 100644
--- a/sys/kern/kern_linker.c
+++ b/sys/kern/kern_linker.c
@@ -1201,29 +1201,39 @@ int
kldstat(struct thread *td, struct kldstat_args *uap)
{
struct kld_file_stat stat;
- linker_file_t lf;
- int error, namelen, version, version_num;
+ int error, version;
/*
* Check the version of the user's structure.
*/
- if ((error = copyin(&uap->stat->version, &version, sizeof(version))) != 0)
+ if ((error = copyin(&uap->stat->version, &version, sizeof(version)))
+ != 0)
return (error);
- if (version == sizeof(struct kld_file_stat_1))
- version_num = 1;
- else if (version == sizeof(struct kld_file_stat))
- version_num = 2;
- else
+ if (version != sizeof(struct kld_file_stat_1) &&
+ version != sizeof(struct kld_file_stat))
return (EINVAL);
+ error = kern_kldstat(td, uap->fileid, &stat);
+ if (error != 0)
+ return (error);
+ return (copyout(&stat, uap->stat, version));
+}
+
+int
+kern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat)
+{
+ linker_file_t lf;
+ int namelen;
#ifdef MAC
+ int error;
+
error = mac_kld_check_stat(td->td_ucred);
if (error)
return (error);
#endif
KLD_LOCK();
- lf = linker_find_file_by_id(uap->fileid);
+ lf = linker_find_file_by_id(fileid);
if (lf == NULL) {
KLD_UNLOCK();
return (ENOENT);
@@ -1233,23 +1243,20 @@ kldstat(struct thread *td, struct kldstat_args *uap)
namelen = strlen(lf->filename) + 1;
if (namelen > MAXPATHLEN)
namelen = MAXPATHLEN;
- bcopy(lf->filename, &stat.name[0], namelen);
- stat.refs = lf->refs;
- stat.id = lf->id;
- stat.address = lf->address;
- stat.size = lf->size;
- if (version_num > 1) {
- /* Version 2 fields: */
- namelen = strlen(lf->pathname) + 1;
- if (namelen > MAXPATHLEN)
- namelen = MAXPATHLEN;
- bcopy(lf->pathname, &stat.pathname[0], namelen);
- }
+ bcopy(lf->filename, &stat->name[0], namelen);
+ stat->refs = lf->refs;
+ stat->id = lf->id;
+ stat->address = lf->address;
+ stat->size = lf->size;
+ /* Version 2 fields: */
+ namelen = strlen(lf->pathname) + 1;
+ if (namelen > MAXPATHLEN)
+ namelen = MAXPATHLEN;
+ bcopy(lf->pathname, &stat->pathname[0], namelen);
KLD_UNLOCK();
td->td_retval[0] = 0;
-
- return (copyout(&stat, uap->stat, version));
+ return (0);
}
int
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
index 7524cf5..d400633 100644
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -48,6 +48,7 @@ struct sockaddr;
struct stat;
struct kevent;
struct kevent_copyops;
+struct kld_file_stat;
struct ksiginfo;
struct sendfile_args;
struct thr_param;
@@ -113,6 +114,7 @@ int kern_jail_set(struct thread *td, struct uio *options, int flags);
int kern_kevent(struct thread *td, int fd, int nchanges, int nevents,
struct kevent_copyops *k_ops, const struct timespec *timeout);
int kern_kldload(struct thread *td, const char *file, int *fileid);
+int kern_kldstat(struct thread *td, int fileid, struct kld_file_stat *stat);
int kern_kldunload(struct thread *td, int fileid, int flags);
int kern_lchown(struct thread *td, char *path, enum uio_seg pathseg,
int uid, int gid);
OpenPOWER on IntegriCloud