[PATCH v2] Add support for /dev/[u]random ioctls

Dmitry V. Levin ldv at altlinux.org
Mon Nov 5 16:13:04 UTC 2018


On Mon, Nov 05, 2018 at 12:12:36PM +0000, Rasmus Villemoes wrote:
> * random_ioctl.c: New file.
> * Makefile.am (strace_SOURCES): Add it.
> * defs.h (DECL_IOCTL): Add random.
> * ioctl.c (ioctl_decode): Add 'R' case.
> * xlat/random_ioctl_cmds.in: New file.
> * tests/ioctl_random.c: New file.
> * tests/.gitignore: Add ioctl_random.
> * tests/pure_executables.list: Likewise.
> * tests/gen_tests.in (ioctl_random): New entry.
> 
> Signed-off-by: Rasmus Villemoes <rasmus.villemoes at prevas.dk>
> ---
> v2:
> * Use proper helpers for printing int* and struct fields
> * Add printing of buffer contents for RNDADDENTROPY
> * Add tests
> 
> Thanks for the feedback, Dmitry. For printing the buffer, I don't
> think PRINT_FIELD_STRN is appropriate, since buf is a flexible array
> member, not a(nother) pointer that needs to be followed. So I think
> computing the address of buf as I do here is the right thing to do (it
> passes the test, at least).

I must have misread the kernel, your approach looks correct.

>  Makefile.am                 |  1 +
>  defs.h                      |  1 +
>  ioctl.c                     |  2 ++
>  random_ioctl.c              | 56 +++++++++++++++++++++++++++++++++++++
>  tests/.gitignore            |  1 +
>  tests/gen_tests.in          |  1 +
>  tests/ioctl_random.c        | 47 +++++++++++++++++++++++++++++++
>  tests/pure_executables.list |  1 +
>  xlat/random_ioctl_cmds.in   |  6 ++++
>  9 files changed, 116 insertions(+)
>  create mode 100644 random_ioctl.c
>  create mode 100644 tests/ioctl_random.c
>  create mode 100644 xlat/random_ioctl_cmds.in

git am complains about trailing whitespace errors:
.git/rebase-apply/patch:101: trailing whitespace.
.git/rebase-apply/patch:113: trailing whitespace.
.git/rebase-apply/patch:178: trailing whitespace.
.git/rebase-apply/patch:202: new blank line at EOF.

> diff --git a/Makefile.am b/Makefile.am
> index 913d26a9..0680763e 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -267,6 +267,7 @@ strace_SOURCES =	\
>  	ptp.c		\
>  	ptrace.h	\
>  	quota.c		\
> +	random_ioctl.c	\
>  	readahead.c	\
>  	readlink.c	\
>  	reboot.c	\
> diff --git a/defs.h b/defs.h
> index 5ba95f53..b8d561aa 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -973,6 +973,7 @@ DECL_IOCTL(kvm);
>  DECL_IOCTL(nbd);
>  DECL_IOCTL(nsfs);
>  DECL_IOCTL(ptp);
> +DECL_IOCTL(random);
>  DECL_IOCTL(scsi);
>  DECL_IOCTL(term);
>  DECL_IOCTL(ubi);
> diff --git a/ioctl.c b/ioctl.c
> index 4c9e7db3..e7dd4c4e 100644
> --- a/ioctl.c
> +++ b/ioctl.c
> @@ -329,6 +329,8 @@ ioctl_decode(struct tcb *tcp)
>  		return inotify_ioctl(tcp, code, arg);
>  	case 0xab:
>  		return nbd_ioctl(tcp, code, arg);
> +	case 'R':
> +		return random_ioctl(tcp, code, arg);
>  	default:
>  		break;
>  	}
> diff --git a/random_ioctl.c b/random_ioctl.c
> new file mode 100644
> index 00000000..ce9773ed
> --- /dev/null
> +++ b/random_ioctl.c
> @@ -0,0 +1,56 @@
> +
> +#include "defs.h"
> +#include "print_fields.h"
> +
> +#include <linux/random.h>
> +
> +#define XLAT_MACROS_ONLY
> +# include "xlat/random_ioctl_cmds.h"
> +#undef XLAT_MACROS_ONLY
> +
> +/*
> + * RNDGETPOOL was removed in 2.6.9, so non-ancient kernels always
> + * return -EINVAL for that.
> + */
> +
> +int
> +random_ioctl(struct tcb *const tcp, const unsigned int code,
> +	   const kernel_ulong_t arg)
> +{
> +	struct rand_pool_info info;
> +	kernel_ulong_t buf;
> +
> +	switch (code) {
> +	case RNDGETENTCNT:
> +		if (entering(tcp))
> +			return 0;
> +		ATTRIBUTE_FALLTHROUGH;
> +	case RNDADDTOENTCNT:
> +		tprints(", ");
> +		printnum_int(tcp, arg, "%d");
> +		break;
> +		
> +	case RNDADDENTROPY:
> +		tprints(", ");
> +		if (!umove_or_printaddr(tcp, arg, &info)) {
> +			PRINT_FIELD_D("{", info, entropy_count);
> +			PRINT_FIELD_D(", ", info, buf_size);
> +			tprints(", buf=");
> +			buf = arg + offsetof(struct rand_pool_info, buf);
> +			printstrn(tcp, buf, info.buf_size);
> +			tprints("}");
> +		}
> +		break;
> +		
> +	/* ioctls with no parameters */
> +	case RNDZAPENTCNT:
> +	case RNDCLEARPOOL:
> +#ifdef RNDRESEEDCRNG /* only linux 4.17+ */
> +	case RNDRESEEDCRNG:
> +#endif

The version of the running kernel and the kernel headers version may
differ, this happens quite often e.g. in linux distributions.

I think we should rather add RNDRESEEDCRNG to xlat/random_ioctl_cmds.in
and decode it unconditionally.

> +		break;
> +	default:
> +		return RVAL_DECODED;
> +	}
> +	return RVAL_IOCTL_DECODED;
> +}
> diff --git a/tests/.gitignore b/tests/.gitignore
> index 577a1316..297319ef 100644
> --- a/tests/.gitignore
> +++ b/tests/.gitignore
> @@ -158,6 +158,7 @@ ioctl_nsfs
>  ioctl_perf
>  ioctl_perf-success
>  ioctl_ptp
> +ioctl_random
>  ioctl_rtc
>  ioctl_rtc-v
>  ioctl_scsi
> diff --git a/tests/gen_tests.in b/tests/gen_tests.in
> index cd63788d..f36cb62f 100644
> --- a/tests/gen_tests.in
> +++ b/tests/gen_tests.in
> @@ -150,6 +150,7 @@ ioctl_nbd	+ioctl.test -y
>  ioctl_nsfs	+ioctl.test -esignal=none
>  ioctl_perf	+ioctl.test
>  ioctl_ptp 	+ioctl.test
> +ioctl_random	+ioctl.test
>  ioctl_rtc	+ioctl.test
>  ioctl_rtc-v	+ioctl.test -v
>  ioctl_scsi	+ioctl.test
> diff --git a/tests/ioctl_random.c b/tests/ioctl_random.c
> new file mode 100644
> index 00000000..540b9c49
> --- /dev/null
> +++ b/tests/ioctl_random.c
> @@ -0,0 +1,47 @@
> +#include "tests.h"
> +
> +#include <stdio.h>
> +#include <string.h>
> +#include <sys/ioctl.h>
> +#include <linux/random.h>
> +
> +#define XLAT_MACROS_ONLY
> +# include "xlat/nbd_ioctl_cmds.h"
> +#undef XLAT_MACROS_ONLY
> +
> +#define RVAL_EBADF " = -1 EBADF (%m)\n"
> +
> +int
> +main(void)
> +{
> +	union {
> +		char c[sizeof(struct rand_pool_info) + 8];
> +		struct rand_pool_info info;
> +	} u;
> +	struct rand_pool_info *info = &u.info;
> +	int cnt = 6;
> +	
> +	memcpy(info->buf, "12345678", 8);
> +	info->buf_size = 8;
> +	info->entropy_count = 3;
> +
> +	ioctl(-1, RNDGETENTCNT, &cnt);
> +	printf("ioctl(-1, RNDGETENTCNT, %p)" RVAL_EBADF, &cnt);
> +	ioctl(-1, RNDADDTOENTCNT, &cnt);
> +	printf("ioctl(-1, RNDADDTOENTCNT, [6])" RVAL_EBADF);
> +	ioctl(-1, RNDADDENTROPY, info);
> +	printf("ioctl(-1, RNDADDENTROPY, {entropy_count=3, buf_size=8, buf=\"12345678\"})" RVAL_EBADF);
> +
> +	ioctl(-1, RNDZAPENTCNT);
> +	printf("ioctl(-1, RNDZAPENTCNT)" RVAL_EBADF);
> +	ioctl(-1, RNDCLEARPOOL);
> +	printf("ioctl(-1, RNDCLEARPOOL)" RVAL_EBADF);
> +#ifdef RNDRESEEDCRNG
> +	ioctl(-1, RNDRESEEDCRNG);
> +	printf("ioctl(-1, RNDRESEEDCRNG)" RVAL_EBADF);
> +#endif

If RNDRESEEDCRNG was added to xlat/random_ioctl_cmds.in,
we could use RNDRESEEDCRNG here unconditionally.


-- 
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20181105/7d5f1f50/attachment.bin>


More information about the Strace-devel mailing list