diff options
author | Petr Písař <ppisar@redhat.com> | 2011-01-07 13:53:13 +0100 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2011-10-04 21:57:07 +0200 |
commit | 803a300b63cc9065818354c1d11a8125dbbdb571 (patch) | |
tree | 0f8609b399776f33ecaee40b75e3d9d782984fea | |
parent | 7d2ac8097d65c6698124abd2dda25bffd8590aa7 (diff) | |
download | linuxquota-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.c | 2 | ||||
-rw-r--r-- | quotaio_rpc.c | 18 | ||||
-rw-r--r-- | rquota_client.c | 4 |
3 files changed, 24 insertions, 0 deletions
@@ -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 = "afile_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. */ |