aboutsummaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorAlex Elder <elder@inktank.com>2013-04-19 15:34:50 -0500
committerSage Weil <sage@inktank.com>2013-05-01 21:19:17 -0700
commitc3f56102f28d90946171ae51753bd417b003fd42 (patch)
tree7c96c0c4818fa655c6ba4fe61e7de2f1b6915a6a /include/linux
parentb587398a4ff6520753f9a58da294c80ee22443a5 (diff)
libceph: validate timespec conversions
A ceph timespec contains 32-bit unsigned values for its seconds and nanoseconds components. For a standard timespec, both fields are signed, and the seconds field is almost surely 64 bits. Add some explicit casts so the fact that this conversion is taking place is obvious. Also trip a bug if we ever try to put out of range (negative or too big) values into a ceph timespec. Signed-off-by: Alex Elder <elder@inktank.com> Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/ceph/decode.h13
1 files changed, 9 insertions, 4 deletions
diff --git a/include/linux/ceph/decode.h b/include/linux/ceph/decode.h
index 9575a52e011..379f7150899 100644
--- a/include/linux/ceph/decode.h
+++ b/include/linux/ceph/decode.h
@@ -154,14 +154,19 @@ bad:
static inline void ceph_decode_timespec(struct timespec *ts,
const struct ceph_timespec *tv)
{
- ts->tv_sec = le32_to_cpu(tv->tv_sec);
- ts->tv_nsec = le32_to_cpu(tv->tv_nsec);
+ ts->tv_sec = (__kernel_time_t)le32_to_cpu(tv->tv_sec);
+ ts->tv_nsec = (long)le32_to_cpu(tv->tv_nsec);
}
static inline void ceph_encode_timespec(struct ceph_timespec *tv,
const struct timespec *ts)
{
- tv->tv_sec = cpu_to_le32(ts->tv_sec);
- tv->tv_nsec = cpu_to_le32(ts->tv_nsec);
+ BUG_ON(ts->tv_sec < 0);
+ BUG_ON(ts->tv_sec > (__kernel_time_t)U32_MAX);
+ BUG_ON(ts->tv_nsec < 0);
+ BUG_ON(ts->tv_nsec > (long)U32_MAX);
+
+ tv->tv_sec = cpu_to_le32((u32)ts->tv_sec);
+ tv->tv_nsec = cpu_to_le32((u32)ts->tv_nsec);
}
/*