Add COMPAT_50 and COMPAT_NETBSD32 compatibility code for rnd(4)
ioctl commands. Tested with "rndctl -ls" using an old 32-bit version of rndctl(8) (built for NetBSD-5.99.56/i386) and a new 64-bit kernel (NetBSD-5.99.59/amd64).
This commit is contained in:
parent
7c0101b055
commit
381a814261
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.47 2011/08/11 21:23:09 jmcneill Exp $
|
||||
# $NetBSD: Makefile,v 1.48 2011/12/19 21:53:52 apb Exp $
|
||||
|
||||
LIB= compat
|
||||
NOPIC= # defined
|
||||
@ -40,9 +40,9 @@ SRCS+= kern_time_30.c vfs_syscalls_30.c uipc_syscalls_30.c
|
||||
SRCS+= vfs_syscalls_40.c uipc_syscalls_40.c
|
||||
|
||||
# Compatibility code for NetBSD 5.0
|
||||
SRCS+= kern_time_50.c kern_select_50.c rtsock_50.c sysv_msg_50.c \
|
||||
sysv_sem_50.c sysv_shm_50.c vfs_syscalls_50.c uipc_syscalls_50.c \
|
||||
sysv_ipc_50.c
|
||||
SRCS+= kern_time_50.c kern_select_50.c rndpseudo_50.c rtsock_50.c \
|
||||
sysv_ipc_50.c sysv_msg_50.c sysv_sem_50.c sysv_shm_50.c \
|
||||
vfs_syscalls_50.c uipc_syscalls_50.c
|
||||
|
||||
# really, all machines where sizeof(int) != sizeof(long) (LP64)
|
||||
.if (${MACHINE_ARCH} != "alpha" && ${MACHINE_ARCH} != "sparc64" \
|
||||
|
182
sys/compat/common/rndpseudo_50.c
Normal file
182
sys/compat/common/rndpseudo_50.c
Normal file
@ -0,0 +1,182 @@
|
||||
/* $NetBSD: rndpseudo_50.c,v 1.1 2011/12/19 21:53:52 apb Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Michael Graff <explorer@flame.org> and Thor Lancelot Simon.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rndpseudo_50.c,v 1.1 2011/12/19 21:53:52 apb Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_compat_netbsd.h"
|
||||
#include "opt_compat_netbsd32.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/file.h>
|
||||
|
||||
#include <sys/rnd.h>
|
||||
#include <compat/sys/rnd.h>
|
||||
|
||||
/*
|
||||
* Convert from rndsource_t to rndsource50_t, for the results from
|
||||
* RNDGETNUM50 and RNDGETNAME50.
|
||||
*/
|
||||
static void
|
||||
rndsource_to_rndsource50(rndsource_t *r, rndsource50_t *r50)
|
||||
{
|
||||
memset(r50, 0, sizeof(*r50));
|
||||
strlcpy(r50->name, r->name, sizeof(r50->name));
|
||||
r50->total = r->total;
|
||||
r50->type = r->type;
|
||||
r50->flags = r->flags;
|
||||
}
|
||||
|
||||
#ifdef COMPAT_NETBSD32
|
||||
/*
|
||||
* Convert from rndsource_t to rndsource50_32_t, for the results from
|
||||
* RNDGETNUM50_32 and RNDGETNAME50_32.
|
||||
*/
|
||||
static void
|
||||
rndsource_to_rndsource50_32(rndsource_t *r, rndsource50_32_t *r50_32)
|
||||
{
|
||||
memset(r50_32, 0, sizeof(*r50_32));
|
||||
strlcpy(r50_32->name, r->name, sizeof(r50_32->name));
|
||||
r50_32->total = r->total;
|
||||
r50_32->type = r->type;
|
||||
r50_32->flags = r->flags;
|
||||
}
|
||||
#endif /* COMPAT_NETBSD32 */
|
||||
|
||||
/*
|
||||
* COMPAT_50 handling for rnd_ioctl. This is called from rnd_ioctl.
|
||||
*
|
||||
* It also handles the case of (COMPAT_50 && COMPAT_NETBSD32).
|
||||
*/
|
||||
int
|
||||
compat_50_rnd_ioctl(struct file *fp, u_long cmd, void *addr)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case RNDGETSRCNUM50:
|
||||
{
|
||||
rndstat_t rstbuf = {.start = 0};
|
||||
rndstat50_t *rst50 = (rndstat50_t *)addr;
|
||||
int count;
|
||||
|
||||
if (rst50->count > RND_MAXSTATCOUNT50)
|
||||
return EINVAL;
|
||||
|
||||
rstbuf.start = rst50->start;
|
||||
rstbuf.count = rst50->count;
|
||||
|
||||
ret = (fp->f_ops->fo_ioctl)(fp, RNDGETSRCNUM, &rstbuf);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
for (count = 0; count < rst50->count; count++) {
|
||||
rndsource_to_rndsource50(&rstbuf.source[count],
|
||||
&rst50->source[count]);
|
||||
}
|
||||
rst50->count = rstbuf.count;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef COMPAT_NETBSD32
|
||||
case RNDGETSRCNUM50_32:
|
||||
{
|
||||
rndstat_t rstbuf = {.start = 0};
|
||||
rndstat50_32_t *rst50_32 = (rndstat50_32_t *)addr;
|
||||
int count;
|
||||
|
||||
if (rst50_32->count > RND_MAXSTATCOUNT50)
|
||||
return (EINVAL);
|
||||
|
||||
rstbuf.start = rst50_32->start;
|
||||
rstbuf.count = rst50_32->count;
|
||||
|
||||
ret = (fp->f_ops->fo_ioctl)(fp, RNDGETSRCNUM, &rstbuf);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
for (count = 0; count < rst50_32->count; count++) {
|
||||
rndsource_to_rndsource50_32(&rstbuf.source[count],
|
||||
&rst50_32->source[count]);
|
||||
}
|
||||
rst50_32->count = rstbuf.count;
|
||||
|
||||
break;
|
||||
}
|
||||
#endif /* COMPAT_NETBSD32 */
|
||||
|
||||
case RNDGETSRCNAME50:
|
||||
{
|
||||
rndstat_name_t rstnmbuf = {.name[0] = 0};
|
||||
rndstat_name50_t *rstnm50;
|
||||
rstnm50 = (rndstat_name50_t *)addr;
|
||||
|
||||
strlcpy(rstnmbuf.name, rstnm50->name, sizeof(rstnmbuf.name));
|
||||
|
||||
ret = (fp->f_ops->fo_ioctl)(fp, RNDGETSRCNAME, &rstnmbuf);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
rndsource_to_rndsource50(&rstnmbuf.source, &rstnm50->source);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef COMPAT_NETBSD32
|
||||
case RNDGETSRCNAME50_32:
|
||||
{
|
||||
rndstat_name_t rstnmbuf = {.name[0] = 0};
|
||||
rndstat_name50_32_t *rstnm50_32;
|
||||
rstnm50_32 = (rndstat_name50_32_t *)addr;
|
||||
|
||||
strlcpy(rstnmbuf.name, rstnm50_32->name, sizeof(rstnmbuf.name));
|
||||
|
||||
ret = (fp->f_ops->fo_ioctl)(fp, RNDGETSRCNAME, &rstnmbuf);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
rndsource_to_rndsource50_32(&rstnmbuf.source,
|
||||
&rstnm50_32->source);
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
default:
|
||||
return ENOTTY;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
154
sys/compat/sys/rnd.h
Normal file
154
sys/compat/sys/rnd.h
Normal file
@ -0,0 +1,154 @@
|
||||
/* $NetBSD: rnd.h,v 1.1 2011/12/19 21:53:52 apb Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997,2011 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Michael Graff <explorer@flame.org>. This code uses ideas and
|
||||
* algorithms from the Linux driver written by Ted Ts'o.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _COMPAT_SYS_RND_H_
|
||||
#define _COMPAT_SYS_RND_H_
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_compat_netbsd.h"
|
||||
#include "opt_compat_netbsd32.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#ifdef COMPAT_NETBSD32
|
||||
#include <compat/netbsd32/netbsd32.h>
|
||||
#endif /* COMPAT_NETBSD32 */
|
||||
|
||||
#include <sys/rnd.h>
|
||||
|
||||
#ifdef COMPAT_50
|
||||
|
||||
/*
|
||||
* NetBSD-5 used "void *state" in the rndsource_t struct. rndsource_t
|
||||
* was used in rnstat_t and rnstat_name_t, which were used by
|
||||
* the NetBSD-5 RNDGETSRCNUM and RNDGETSRCNAME ioctls.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Sanitized random source view for userspace. */
|
||||
typedef struct {
|
||||
char name[16]; /* device name */
|
||||
uint32_t unused_time; /* was: last time recorded */
|
||||
uint32_t unused_delta; /* was: last delta value */
|
||||
uint32_t unused_delta2; /* was: last delta2 value */
|
||||
uint32_t total; /* entropy from this source */
|
||||
uint32_t type; /* type */
|
||||
uint32_t flags; /* flags */
|
||||
void *unused_state; /* was: internal state */
|
||||
} rndsource50_t;
|
||||
|
||||
#ifdef COMPAT_NETBSD32
|
||||
typedef struct {
|
||||
char name[16]; /* device name */
|
||||
uint32_t unused_time; /* was: last time recorded */
|
||||
uint32_t unused_delta; /* was: last delta value */
|
||||
uint32_t unused_delta2; /* was: last delta2 value */
|
||||
uint32_t total; /* entropy from this source */
|
||||
uint32_t type; /* type */
|
||||
uint32_t flags; /* flags */
|
||||
netbsd32_voidp unused_state; /* was: internal state */
|
||||
} rndsource50_32_t;
|
||||
#endif /* COMPAT_NETBSD32 */
|
||||
|
||||
/*
|
||||
* NetBSD-5 defined RND_MAXSTATCOUNT as 10. We define RND_MAXSTATCOUNT50
|
||||
* here, and check that the native RND_MAXSTATCOUNT is not smaller.
|
||||
*/
|
||||
#define RND_MAXSTATCOUNT50 10 /* 10 sources at once max */
|
||||
#if (RND_MAXSTATCOUNT50 > RND_MAXSTATCOUNT)
|
||||
#error "RND_MAXSTATCOUNT50 is too large"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* return "count" random entries, starting at "start"
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t start;
|
||||
uint32_t count;
|
||||
rndsource50_t source[RND_MAXSTATCOUNT50];
|
||||
} rndstat50_t;
|
||||
|
||||
#ifdef COMPAT_NETBSD32
|
||||
typedef struct {
|
||||
uint32_t start;
|
||||
uint32_t count;
|
||||
rndsource50_32_t source[RND_MAXSTATCOUNT50];
|
||||
} rndstat50_32_t;
|
||||
#endif /* COMPAT_NETBSD32 */
|
||||
|
||||
/*
|
||||
* return information on a specific source by name
|
||||
*/
|
||||
typedef struct {
|
||||
char name[16];
|
||||
rndsource50_t source;
|
||||
} rndstat_name50_t;
|
||||
|
||||
#ifdef COMPAT_NETBSD32
|
||||
typedef struct {
|
||||
char name[16];
|
||||
rndsource50_32_t source;
|
||||
} rndstat_name50_32_t;
|
||||
#endif /* COMPAT_NETBSD32 */
|
||||
|
||||
/*
|
||||
* NetBSD-5 defined RND_POOLWORDS as 128. In NetBSD-6, the value
|
||||
* exposed to userland via the rnddata_t type was renamed to
|
||||
* RND_SAVEWORDS. As long as RND_SAVEWORDS remains equal to 128, then
|
||||
* rnddata_t (used by ioctl RNDADDATA), and rndpoolstat_t (used by ioctl
|
||||
* RNDGETPOOLSTAT) remain ABI compatible without any extra effort, even
|
||||
* though the declarations in the source code have changed.
|
||||
*/
|
||||
#if (RND_SAVEWORDS != 128)
|
||||
#error "RND_SAVEWORDS must be 128 for NetBSD-5 compatibility"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compatibility with NetBSD-5 ioctls.
|
||||
*/
|
||||
#ifdef _KERNEL
|
||||
int compat_50_rnd_ioctl(struct file *, u_long, void *);
|
||||
#endif
|
||||
|
||||
#define RNDGETSRCNUM50 _IOWR('R', 102, rndstat50_t)
|
||||
#define RNDGETSRCNAME50 _IOWR('R', 103, rndstat_name50_t)
|
||||
|
||||
#ifdef COMPAT_NETBSD32
|
||||
#define RNDGETSRCNUM50_32 _IOWR('R', 102, rndstat50_32_t)
|
||||
#define RNDGETSRCNAME50_32 _IOWR('R', 103, rndstat_name50_32_t)
|
||||
#endif /* COMPAT_NETBSD32 */
|
||||
|
||||
#endif /* COMPAT_50 */
|
||||
|
||||
#endif /* !_COMPAT_SYS_RND_H_ */
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: rndpseudo.c,v 1.3 2011/12/19 21:44:08 apb Exp $ */
|
||||
/* $NetBSD: rndpseudo.c,v 1.4 2011/12/19 21:53:52 apb Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
|
||||
@ -30,7 +30,11 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.3 2011/12/19 21:44:08 apb Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.4 2011/12/19 21:53:52 apb Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_compat_netbsd.h"
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
@ -46,13 +50,17 @@ __KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.3 2011/12/19 21:44:08 apb Exp $");
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/rnd.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/pool.h>
|
||||
#include <sys/kauth.h>
|
||||
#include <sys/cprng.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <sys/rnd.h>
|
||||
#ifdef COMPAT_50
|
||||
#include <compat/sys/rnd.h>
|
||||
#endif
|
||||
|
||||
#include <dev/rnd_private.h>
|
||||
|
||||
#if defined(__HAVE_CPU_COUNTER) && !defined(_RUMPKERNEL) /* XXX: bad pooka */
|
||||
@ -428,7 +436,11 @@ rnd_ioctl(struct file *fp, u_long cmd, void *addr)
|
||||
break;
|
||||
|
||||
default:
|
||||
return (ENOTTY);
|
||||
#ifdef COMPAT_50
|
||||
return compat_50_rnd_ioctl(fp, cmd, addr);
|
||||
#else
|
||||
return ENOTTY;
|
||||
#endif
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
@ -597,7 +609,7 @@ rnd_ioctl(struct file *fp, u_long cmd, void *addr)
|
||||
break;
|
||||
|
||||
default:
|
||||
return (ENOTTY);
|
||||
return ENOTTY;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
|
Loading…
Reference in New Issue
Block a user