From: Ronnie Sahlberg Date: Wed, 25 Aug 2021 11:16:56 +0000 (+1000) Subject: cifs: Do not leak EDEADLK to dgetents64 for STATUS_USER_SESSION_DELETED X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=3998f0b8bc49ec784990971dc1f16bf367b19078;p=linux.git cifs: Do not leak EDEADLK to dgetents64 for STATUS_USER_SESSION_DELETED RHBZ: 1994393 If we hit a STATUS_USER_SESSION_DELETED for the Create part in the Create/QueryDirectory compound that starts a directory scan we will leak EDEADLK back to userspace and surprise glibc and the application. Pick this up initiate_cifs_search() and retry a small number of tries before we return an error to userspace. Cc: stable@vger.kernel.org Reported-by: Xiaoli Feng Signed-off-by: Ronnie Sahlberg Signed-off-by: Steve French --- diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index bfee176b901d4..54d77c99e21c0 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -369,7 +369,7 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb, */ static int -initiate_cifs_search(const unsigned int xid, struct file *file, +_initiate_cifs_search(const unsigned int xid, struct file *file, const char *full_path) { __u16 search_flags; @@ -451,6 +451,27 @@ error_exit: return rc; } +static int +initiate_cifs_search(const unsigned int xid, struct file *file, + const char *full_path) +{ + int rc, retry_count = 0; + + do { + rc = _initiate_cifs_search(xid, file, full_path); + /* + * If we don't have enough credits to start reading the + * directory just try again after short wait. + */ + if (rc != -EDEADLK) + break; + + usleep_range(512, 2048); + } while (retry_count++ < 5); + + return rc; +} + /* return length of unicode string in bytes */ static int cifs_unicode_bytelen(const char *str) {