summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetr Písař <ppisar@redhat.com>2011-01-07 13:53:13 +0100
committerJan Kara <jack@suse.cz>2011-10-04 21:57:07 +0200
commit803a300b63cc9065818354c1d11a8125dbbdb571 (patch)
tree0f8609b399776f33ecaee40b75e3d9d782984fea
parent7d2ac8097d65c6698124abd2dda25bffd8590aa7 (diff)
downloadlinuxquota-803a300b63cc9065818354c1d11a8125dbbdb571.tar.gz
Check set limits fit into the range supported by RPC transport
E.g. setquota -r root $((2**32)) 1000 10 10 /mnt/nfs/12tb clamped the values into 32 bits and RPC server got 0 soft block limit. This fixes simalar bug spotted in 8a4dc3612c6c170c05e5eef68dd3555baeb341c1 (Check whether set limits fit into the range supported by quota format.) Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--quotaio.c2
-rw-r--r--quotaio_rpc.c18
-rw-r--r--rquota_client.c4
3 files changed, 24 insertions, 0 deletions
diff --git a/quotaio.c b/quotaio.c
index bf0de85..257252d 100644
--- a/quotaio.c
+++ b/quotaio.c
@@ -70,6 +70,8 @@ struct quota_handle *init_io(struct mntent *mnt, int type, int fmt, int flags)
h->qh_fd = -1;
h->qh_fmt = QF_RPC;
h->qh_ops = &quotafile_ops_rpc;
+ memset(&h->qh_info, 0, sizeof(h->qh_info));
+ h->qh_ops->init_io(h);
return h;
#else
errstr(_("RPC quota format not compiled.\n"));
diff --git a/quotaio_rpc.c b/quotaio_rpc.c
index 14fe410..6f25144 100644
--- a/quotaio_rpc.c
+++ b/quotaio_rpc.c
@@ -15,15 +15,33 @@
#include "rquota_client.h"
#include "pot.h"
+static int rpc_init_io(struct quota_handle *h);
static struct dquot *rpc_read_dquot(struct quota_handle *h, qid_t id);
static int rpc_commit_dquot(struct dquot *dquot, int flags);
struct quotafile_ops quotafile_ops_rpc = {
+init_io: rpc_init_io,
read_dquot: rpc_read_dquot,
commit_dquot: rpc_commit_dquot
};
/*
+ * Define maximal values RPC client can transmit to server.
+ */
+static int rpc_init_io(struct quota_handle *h)
+{
+#ifdef RPC
+ h->qh_info.dqi_max_b_limit = ~(uint32_t)0;
+ h->qh_info.dqi_max_i_limit = ~(uint32_t)0;
+ h->qh_info.dqi_max_b_usage = (~(uint32_t)0) << QUOTABLOCK_BITS;
+ h->qh_info.dqi_max_i_usage = ~(uint32_t)0;
+ return 0;
+#else
+ return -1;
+#endif
+}
+
+/*
* Read a dqblk struct from RPC server - just wrapper function.
*/
static struct dquot *rpc_read_dquot(struct quota_handle *h, qid_t id)
diff --git a/rquota_client.c b/rquota_client.c
index d67dd25..54a8921 100644
--- a/rquota_client.c
+++ b/rquota_client.c
@@ -265,6 +265,10 @@ int rpc_rquota_set(int qcmd, struct dquot *dquot)
char *fsname_tmp, *host, *pathname;
struct timeval timeout = { 2, 0 };
+ /* RPC limits values to 32b variables. Prevent value wrapping. */
+ if (check_dquot_range(dquot) < 0)
+ return -ERANGE;
+
/*
* Convert host:pathname to seperate host and pathname.
*/