1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-15 10:17:20 +00:00

Provide compat32 shims for kldstat(2).

Requested and tested by:	jpaetzel
MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2011-03-30 14:46:12 +00:00
parent af47829540
commit 8666550972
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=220158
5 changed files with 80 additions and 25 deletions

View File

@ -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_ */

View File

@ -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));
}

View File

@ -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, \

View File

@ -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

View File

@ -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);