summaryrefslogtreecommitdiffstats
path: root/usr.sbin/rpc.lockd
diff options
context:
space:
mode:
authormjacob <mjacob@FreeBSD.org>2007-01-04 20:38:50 +0000
committermjacob <mjacob@FreeBSD.org>2007-01-04 20:38:50 +0000
commit3bc2efe5348c9a8b3576b986c86967e9c5f0c03a (patch)
tree16bda884a173caa07bac78086054302375e362a6 /usr.sbin/rpc.lockd
parent2cd5f6bd1c305d31cb77914f9d103bfebf737dbb (diff)
downloadFreeBSD-src-3bc2efe5348c9a8b3576b986c86967e9c5f0c03a.zip
FreeBSD-src-3bc2efe5348c9a8b3576b986c86967e9c5f0c03a.tar.gz
Add a function that checks for duplicate requests (based
on some fairly tight criteria) so we avoid having broken clients spam rpc.lockd to death. PR: 107530 Obtained from: Doug Rudoff MFC after: 1 week
Diffstat (limited to 'usr.sbin/rpc.lockd')
-rw-r--r--usr.sbin/rpc.lockd/lockd_lock.c45
1 files changed, 43 insertions, 2 deletions
diff --git a/usr.sbin/rpc.lockd/lockd_lock.c b/usr.sbin/rpc.lockd/lockd_lock.c
index cc09bcb..770cb5e 100644
--- a/usr.sbin/rpc.lockd/lockd_lock.c
+++ b/usr.sbin/rpc.lockd/lockd_lock.c
@@ -1195,13 +1195,54 @@ test_hwlock(fl, conflicting_fl)
* if at all possible
*/
+int
+duplicate_block(struct file_lock *fl)
+{
+ struct file_lock *ifl,*nfl;
+ int retval = 0;
+
+ debuglog("Entering duplicate_block");
+
+ /*
+ * Is this lock request already on the blocking list?
+ * Condider it a dupe if the file handles, offset, length,
+ * exclusivity and client match.
+ */
+ LIST_FOREACH(ifl, &blockedlocklist_head, nfslocklist) {
+ if (!bcmp(&fl->filehandle, &ifl->filehandle,
+ sizeof(fhandle_t)) &&
+ fl->client.exclusive == ifl->client.exclusive &&
+ fl->client.l_offset == ifl->client.l_offset &&
+ fl->client.l_len == ifl->client.l_len &&
+ same_filelock_identity(fl, ifl)) {
+ retval = 1;
+ break;
+ }
+ }
+
+ debuglog("Exiting duplicate_block: %s\n", retval ? "already blocked"
+ : "not already blocked");
+ return retval;
+}
+
void
add_blockingfilelock(struct file_lock *fl)
{
-
debuglog("Entering add_blockingfilelock\n");
/*
+ * A blocking lock request _should_ never be duplicated as a client
+ * that is already blocked shouldn't be able to request another
+ * lock. Alas, there are some buggy clients that do request the same
+ * lock repeatedly. Make sure only unique locks are on the blocked
+ * lock list.
+ */
+ if (duplicate_block(fl)) {
+ debuglog("Exiting add_blockingfilelock: already blocked\n");
+ return;
+ }
+
+ /*
* Clear the blocking flag so that it can be reused without
* adding it to the blocking queue a second time
*/
@@ -1209,7 +1250,7 @@ add_blockingfilelock(struct file_lock *fl)
fl->blocking = 0;
LIST_INSERT_HEAD(&blockedlocklist_head, fl, nfslocklist);
- debuglog("Exiting add_blockingfilelock\n");
+ debuglog("Exiting add_blockingfilelock: added blocked lock\n");
}
void
OpenPOWER on IntegriCloud