From 5309bc27a02375a717dafab7444c58cd78e3ce18 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Mon, 21 Dec 2009 11:29:54 +0000 Subject: [PATCH] Handle adjtimex being called in adjtime mode correctly. Closes #219538. Validate the constant field with ADJ_TAI is used in an adjtimex call. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@10969 --- coregrind/m_syswrap/syswrap-linux.c | 23 ++++++++++++++--------- include/vki/vki-linux.h | 3 +++ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index c8c44aab64..a8ef616e6a 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -623,18 +623,23 @@ PRE(sys_adjtimex) PRE_REG_READ1(long, "adjtimex", struct timex *, buf); PRE_MEM_READ( "adjtimex(timex->modes)", ARG1, sizeof(tx->modes)); -#define ADJX(bit,field) \ - if (tx->modes & bit) \ +#define ADJX(bits,field) \ + if (tx->modes & (bits)) \ PRE_MEM_READ( "adjtimex(timex->"#field")", \ (Addr)&tx->field, sizeof(tx->field)) - ADJX(VKI_ADJ_OFFSET, offset); - ADJX(VKI_ADJ_FREQUENCY, freq); - ADJX(VKI_ADJ_MAXERROR, maxerror); - ADJX(VKI_ADJ_ESTERROR, esterror); - ADJX(VKI_ADJ_STATUS, status); - ADJX(VKI_ADJ_TIMECONST, constant); - ADJX(VKI_ADJ_TICK, tick); + if (tx->modes & VKI_ADJ_ADJTIME) { + if (!(tx->modes & VKI_ADJ_OFFSET_READONLY)) + PRE_MEM_READ( "adjtimex(timex->offset)", (Addr)&tx->offset, sizeof(tx->offset)); + } else { + ADJX(VKI_ADJ_OFFSET, offset); + ADJX(VKI_ADJ_FREQUENCY, freq); + ADJX(VKI_ADJ_MAXERROR, maxerror); + ADJX(VKI_ADJ_ESTERROR, esterror); + ADJX(VKI_ADJ_STATUS, status); + ADJX(VKI_ADJ_TIMECONST|VKI_ADJ_TAI, constant); + ADJX(VKI_ADJ_TICK, tick); + } #undef ADJX PRE_MEM_WRITE( "adjtimex(timex)", ARG1, sizeof(struct vki_timex)); diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h index 073227152f..c906a39b3f 100644 --- a/include/vki/vki-linux.h +++ b/include/vki/vki-linux.h @@ -283,8 +283,11 @@ struct vki_timex { #define VKI_ADJ_ESTERROR 0x0008 /* estimated time error */ #define VKI_ADJ_STATUS 0x0010 /* clock status */ #define VKI_ADJ_TIMECONST 0x0020 /* pll time constant */ +#define VKI_ADJ_TAI 0x0080 /* set TAI offset */ #define VKI_ADJ_TICK 0x4000 /* tick value */ +#define VKI_ADJ_ADJTIME 0x8000 /* switch between adjtime/adjtimex modes */ //#define VKI_ADJ_OFFSET_SINGLESHOT 0x8001 /* old-fashioned adjtime */ +#define VKI_ADJ_OFFSET_READONLY 0x2000 /* read-only adjtime */ //---------------------------------------------------------------------- // From linux-2.6.8.1/include/linux/times.h -- 2.47.2