|
|
7c06a3 |
From d850a85b2374fe1b83779c0fc61463057eeca4ab Mon Sep 17 00:00:00 2001
|
|
|
7c06a3 |
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
|
|
|
7c06a3 |
Date: Mon, 24 Feb 2014 15:54:32 +0100
|
|
|
7c06a3 |
Subject: [PATCH] Prevent from grace period overflow in RPC transport
|
|
|
7c06a3 |
MIME-Version: 1.0
|
|
|
7c06a3 |
Content-Type: text/plain; charset=UTF-8
|
|
|
7c06a3 |
Content-Transfer-Encoding: 8bit
|
|
|
7c06a3 |
|
|
|
7c06a3 |
The RPC transports grace time as unsigned int, but the value stored
|
|
|
7c06a3 |
there and retrivedd from is treated as singed difference against current time.
|
|
|
7c06a3 |
|
|
|
7c06a3 |
This leads to overflow after expiring the grace time which is
|
|
|
7c06a3 |
presented as an enourmously large grace time instead of "none" in the
|
|
|
7c06a3 |
quota(1) output.
|
|
|
7c06a3 |
|
|
|
7c06a3 |
There also possible an overflow when the time difference is still
|
|
|
7c06a3 |
bigger than an int can represent.
|
|
|
7c06a3 |
|
|
|
7c06a3 |
This first issue is solved by explicit type cast to/from int32_t, the
|
|
|
7c06a3 |
second issue is fixes by limiting the value into int32_t range.
|
|
|
7c06a3 |
|
|
|
7c06a3 |
<https://sourceforge.net/p/linuxquota/bugs/115/>
|
|
|
7c06a3 |
|
|
|
7c06a3 |
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
|
|
7c06a3 |
Signed-off-by: Jan Kara <jack@suse.cz>
|
|
|
7c06a3 |
---
|
|
|
7c06a3 |
quotasys.c | 13 +++++++++++++
|
|
|
7c06a3 |
quotasys.h | 4 ++++
|
|
|
7c06a3 |
rquota_client.c | 10 ++++++----
|
|
|
7c06a3 |
rquota_server.c | 9 +++++----
|
|
|
7c06a3 |
4 files changed, 28 insertions(+), 8 deletions(-)
|
|
|
7c06a3 |
|
|
|
7c06a3 |
diff --git a/quotasys.c b/quotasys.c
|
|
|
7c06a3 |
index 120125a..a5737a8 100644
|
|
|
7c06a3 |
--- a/quotasys.c
|
|
|
7c06a3 |
+++ b/quotasys.c
|
|
|
7c06a3 |
@@ -23,6 +23,7 @@
|
|
|
7c06a3 |
#include <sys/types.h>
|
|
|
7c06a3 |
#include <sys/stat.h>
|
|
|
7c06a3 |
#include <sys/vfs.h>
|
|
|
7c06a3 |
+#include <stdint.h>
|
|
|
7c06a3 |
|
|
|
7c06a3 |
#include "pot.h"
|
|
|
7c06a3 |
#include "bylabel.h"
|
|
|
7c06a3 |
@@ -323,6 +324,18 @@ void difftime2str(time_t seconds, char *buf)
|
|
|
7c06a3 |
}
|
|
|
7c06a3 |
|
|
|
7c06a3 |
/*
|
|
|
7c06a3 |
+ * Round difference of two time_t values into int32_t
|
|
|
7c06a3 |
+ */
|
|
|
7c06a3 |
+int32_t difftime2net(time_t later, time_t sooner)
|
|
|
7c06a3 |
+{
|
|
|
7c06a3 |
+ if ((later - sooner) > INT32_MAX)
|
|
|
7c06a3 |
+ return INT32_MAX;
|
|
|
7c06a3 |
+ if ((later - sooner) < INT32_MIN)
|
|
|
7c06a3 |
+ return INT32_MIN;
|
|
|
7c06a3 |
+ return (later - sooner);
|
|
|
7c06a3 |
+}
|
|
|
7c06a3 |
+
|
|
|
7c06a3 |
+/*
|
|
|
7c06a3 |
* Convert time to printable form
|
|
|
7c06a3 |
*/
|
|
|
7c06a3 |
void time2str(time_t seconds, char *buf, int flags)
|
|
|
7c06a3 |
diff --git a/quotasys.h b/quotasys.h
|
|
|
7c06a3 |
index e79f8cd..d8d79fe 100644
|
|
|
7c06a3 |
--- a/quotasys.h
|
|
|
7c06a3 |
+++ b/quotasys.h
|
|
|
7c06a3 |
@@ -8,6 +8,7 @@
|
|
|
7c06a3 |
#define GUARD_QUOTASYS_H
|
|
|
7c06a3 |
|
|
|
7c06a3 |
#include <sys/types.h>
|
|
|
7c06a3 |
+#include <inttypes.h>
|
|
|
7c06a3 |
#include "mntopt.h"
|
|
|
7c06a3 |
#include "quota.h"
|
|
|
7c06a3 |
|
|
|
7c06a3 |
@@ -100,6 +101,9 @@ int util2kernfmt(int fmt);
|
|
|
7c06a3 |
/* Convert time difference between given time and current time to printable form */
|
|
|
7c06a3 |
void difftime2str(time_t, char *);
|
|
|
7c06a3 |
|
|
|
7c06a3 |
+/* Round difference of two time_t values into int32_t */
|
|
|
7c06a3 |
+int32_t difftime2net(time_t later, time_t sooner);
|
|
|
7c06a3 |
+
|
|
|
7c06a3 |
/* Convert time to printable form */
|
|
|
7c06a3 |
void time2str(time_t, char *, int);
|
|
|
7c06a3 |
|
|
|
7c06a3 |
diff --git a/rquota_client.c b/rquota_client.c
|
|
|
7c06a3 |
index e26e066..9d4055e 100644
|
|
|
7c06a3 |
--- a/rquota_client.c
|
|
|
7c06a3 |
+++ b/rquota_client.c
|
|
|
7c06a3 |
@@ -32,11 +32,13 @@
|
|
|
7c06a3 |
#include <string.h>
|
|
|
7c06a3 |
#include <signal.h>
|
|
|
7c06a3 |
#include <time.h>
|
|
|
7c06a3 |
+#include <stdint.h>
|
|
|
7c06a3 |
|
|
|
7c06a3 |
#include "mntopt.h"
|
|
|
7c06a3 |
#include "rquota.h"
|
|
|
7c06a3 |
#include "common.h"
|
|
|
7c06a3 |
#include "quotaio.h"
|
|
|
7c06a3 |
+#include "quotasys.h"
|
|
|
7c06a3 |
|
|
|
7c06a3 |
#if defined(RPC)
|
|
|
7c06a3 |
|
|
|
7c06a3 |
@@ -54,11 +56,11 @@ static inline void clinet2utildqblk(struct util_dqblk *u, struct rquota *n)
|
|
|
7c06a3 |
u->dqb_curspace = ((qsize_t)n->rq_curblocks) * n->rq_bsize;
|
|
|
7c06a3 |
time(&now;;
|
|
|
7c06a3 |
if (n->rq_btimeleft)
|
|
|
7c06a3 |
- u->dqb_btime = n->rq_btimeleft + now;
|
|
|
7c06a3 |
+ u->dqb_btime = (int32_t)n->rq_btimeleft + now;
|
|
|
7c06a3 |
else
|
|
|
7c06a3 |
u->dqb_btime = 0;
|
|
|
7c06a3 |
if (n->rq_ftimeleft)
|
|
|
7c06a3 |
- u->dqb_itime = n->rq_ftimeleft + now;
|
|
|
7c06a3 |
+ u->dqb_itime = (int32_t)n->rq_ftimeleft + now;
|
|
|
7c06a3 |
else
|
|
|
7c06a3 |
u->dqb_itime = 0;
|
|
|
7c06a3 |
}
|
|
|
7c06a3 |
@@ -76,11 +78,11 @@ static inline void cliutil2netdqblk(struct sq_dqblk *n, struct util_dqblk *u)
|
|
|
7c06a3 |
n->rq_curblocks = toqb(u->dqb_curspace);
|
|
|
7c06a3 |
n->rq_curfiles = u->dqb_curinodes;
|
|
|
7c06a3 |
if (u->dqb_btime)
|
|
|
7c06a3 |
- n->rq_btimeleft = u->dqb_btime - now;
|
|
|
7c06a3 |
+ n->rq_btimeleft = difftime2net(u->dqb_btime, now);
|
|
|
7c06a3 |
else
|
|
|
7c06a3 |
n->rq_btimeleft = 0;
|
|
|
7c06a3 |
if (u->dqb_itime)
|
|
|
7c06a3 |
- n->rq_ftimeleft = u->dqb_itime - now;
|
|
|
7c06a3 |
+ n->rq_ftimeleft = difftime2net(u->dqb_itime, now);
|
|
|
7c06a3 |
else
|
|
|
7c06a3 |
n->rq_ftimeleft = 0;
|
|
|
7c06a3 |
}
|
|
|
7c06a3 |
diff --git a/rquota_server.c b/rquota_server.c
|
|
|
7c06a3 |
index bf66e4d..09cf6ed 100644
|
|
|
7c06a3 |
--- a/rquota_server.c
|
|
|
7c06a3 |
+++ b/rquota_server.c
|
|
|
7c06a3 |
@@ -25,6 +25,7 @@
|
|
|
7c06a3 |
#include <stdio.h>
|
|
|
7c06a3 |
#include <syslog.h>
|
|
|
7c06a3 |
#include <time.h>
|
|
|
7c06a3 |
+#include <stdint.h>
|
|
|
7c06a3 |
|
|
|
7c06a3 |
#include "mntopt.h"
|
|
|
7c06a3 |
#include "quotaops.h"
|
|
|
7c06a3 |
@@ -82,11 +83,11 @@ static inline void servnet2utildqblk(struct util_dqblk *u, sq_dqblk * n)
|
|
|
7c06a3 |
u->dqb_curspace = ((qsize_t)n->rq_curblocks) << RPC_DQBLK_SIZE_BITS;
|
|
|
7c06a3 |
u->dqb_curinodes = n->rq_curfiles;
|
|
|
7c06a3 |
if (n->rq_btimeleft)
|
|
|
7c06a3 |
- u->dqb_btime = n->rq_btimeleft + now;
|
|
|
7c06a3 |
+ u->dqb_btime = (int32_t)n->rq_btimeleft + now;
|
|
|
7c06a3 |
else
|
|
|
7c06a3 |
u->dqb_btime = 0;
|
|
|
7c06a3 |
if (n->rq_ftimeleft)
|
|
|
7c06a3 |
- u->dqb_itime = n->rq_ftimeleft + now;
|
|
|
7c06a3 |
+ u->dqb_itime = (int32_t)n->rq_ftimeleft + now;
|
|
|
7c06a3 |
else
|
|
|
7c06a3 |
u->dqb_itime = 0;
|
|
|
7c06a3 |
}
|
|
|
7c06a3 |
@@ -127,11 +128,11 @@ static inline void servutil2netdqblk(struct rquota *n, struct util_dqblk *u)
|
|
|
7c06a3 |
|
|
|
7c06a3 |
time(&now;;
|
|
|
7c06a3 |
if (u->dqb_btime)
|
|
|
7c06a3 |
- n->rq_btimeleft = u->dqb_btime - now;
|
|
|
7c06a3 |
+ n->rq_btimeleft = difftime2net(u->dqb_btime, now);
|
|
|
7c06a3 |
else
|
|
|
7c06a3 |
n->rq_btimeleft = 0;
|
|
|
7c06a3 |
if (u->dqb_itime)
|
|
|
7c06a3 |
- n->rq_ftimeleft = u->dqb_itime - now;
|
|
|
7c06a3 |
+ n->rq_ftimeleft = difftime2net(u->dqb_itime, now);
|
|
|
7c06a3 |
else
|
|
|
7c06a3 |
n->rq_ftimeleft = 0;
|
|
|
7c06a3 |
}
|
|
|
7c06a3 |
--
|
|
|
7c06a3 |
2.5.0
|
|
|
7c06a3 |
|