[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