can someone test this? and eyeball the use of a pointer as data to
get mixed into the hash?

Index: ufs_quota.c
===================================================================
RCS file: /cvs/src/sys/ufs/ufs/ufs_quota.c,v
retrieving revision 1.35
diff -u -p -r1.35 ufs_quota.c
--- ufs_quota.c 13 Oct 2014 03:46:33 -0000      1.35
+++ ufs_quota.c 17 Nov 2014 00:59:49 -0000
@@ -53,6 +53,9 @@
 
 #include <sys/queue.h>
 
+#include <dev/rndvar.h>
+#include <crypto/siphash.h>
+
 /*
  * The following structure records disk usage for a user or group on a
  * filesystem. There is one allocated for each quota that exists on any
@@ -805,9 +808,8 @@ qsync(struct mount *mp)
 /*
  * Code pertaining to management of the in-core dquot data structures.
  */
-#define DQHASH(dqvp, id) \
-       (&dqhashtbl[((((long)(dqvp)) >> 8) + id) & dqhash])
 LIST_HEAD(dqhash, dquot) *dqhashtbl;
+SIPHASH_KEY dqhashkey;
 u_long dqhash;
 
 /*
@@ -824,6 +826,7 @@ void
 ufs_quota_init(void)
 {
        dqhashtbl = hashinit(desiredvnodes, M_DQUOT, M_WAITOK, &dqhash);
+       arc4random_buf(&dqhashkey, sizeof(dqhashkey));
        TAILQ_INIT(&dqfreelist);
 }
 
@@ -835,6 +838,7 @@ int
 dqget(struct vnode *vp, u_long id, struct ufsmount *ump, int type,
     struct dquot **dqp)
 {
+       SIPHASH_CTX ctx;
        struct proc *p = curproc;
        struct dquot *dq;
        struct dqhash *dqh;
@@ -851,7 +855,11 @@ dqget(struct vnode *vp, u_long id, struc
        /*
         * Check the cache first.
         */
-       dqh = DQHASH(dqvp, id);
+       SipHash24_Init(&ctx, &dqhashkey);
+       SipHash24_Update(&ctx, &dqvp, sizeof(dqvp));
+       SipHash24_Update(&ctx, &id, sizeof(id));
+       dqh = &dqhashtbl[SipHash24_End(&ctx) & dqhash];
+
        LIST_FOREACH(dq, dqh, dq_hash) {
                if (dq->dq_id != id ||
                    dq->dq_vp != dqvp)

Reply via email to