lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20241227144120.lnxc4acxpkvt7khw@pali>
Date: Fri, 27 Dec 2024 15:41:20 +0100
From: Pali Rohár <pali@...nel.org>
To: Steve French <sfrench@...ba.org>, Paulo Alcantara <pc@...guebit.com>,
	Ronnie Sahlberg <ronniesahlberg@...il.com>
Cc: linux-cifs@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH] cifs: Implement is_network_name_deleted for SMB1

On Sunday 22 December 2024 18:14:31 Pali Rohár wrote:
> This change allows Linux SMB1 client to autoreconnect the share when it is
> modified on server by admin operation which removes and re-adds it.
> 
> Implementation is reused from SMB2+ is_network_name_deleted callback. There
> are just adjusted checks for error codes and access to struct smb_hdr.
> 
> Signed-off-by: Pali Rohár <pali@...nel.org>
> ---
>  fs/smb/client/smb1ops.c | 44 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
> 
> diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c
> index 0533aca770fc..76e7353f2a72 100644
> --- a/fs/smb/client/smb1ops.c
> +++ b/fs/smb/client/smb1ops.c
> @@ -14,6 +14,8 @@
>  #include "cifspdu.h"
>  #include "cifs_unicode.h"
>  #include "fs_context.h"
> +#include "nterr.h"
> +#include "smberr.h"
>  
>  /*
>   * An NT cancel request header looks just like the original request except:
> @@ -1075,6 +1077,47 @@ cifs_make_node(unsigned int xid, struct inode *inode,
>  				  full_path, mode, dev);
>  }
>  
> +static bool
> +cifs_is_network_name_deleted(char *buf, struct TCP_Server_Info *server)
> +{
> +	struct smb_hdr *shdr = (struct smb_hdr *)buf;
> +	struct TCP_Server_Info *pserver;
> +	struct cifs_ses *ses;
> +	struct cifs_tcon *tcon;
> +
> +	if (shdr->Flags2 & SMBFLG2_ERR_STATUS) {
> +		if (shdr->Status.CifsError != cpu_to_le32(NT_STATUS_NETWORK_NAME_DELETED))
> +			return false;
> +	} else {
> +		if (shdr->Status.DosError.ErrorClass != ERRSRV ||
> +		    shdr->Status.DosError.Error != cpu_to_le16(ERRinvtid))
> +			return false;
> +	}
> +
> +	/* If server is a channel, select the primary channel */
> +	pserver = SERVER_IS_CHAN(server) ? server->primary_server : server;
> +
> +	spin_lock(&cifs_tcp_ses_lock);
> +	list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
> +		if (cifs_ses_exiting(ses))
> +			continue;
> +		list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
> +			if (tcon->tid == le32_to_cpu(shdr->Tid)) {

Kernel test robot complained on this line about endianity issues. I have
looked why, and I figured out that for smb1 the tcon->tid value is
stored in the little endian, but for smb2+ it is stored in cpu endian.
Hence this line should be:

-			if (tcon->tid == le32_to_cpu(shdr->Tid)) {
+			if (tcon->tid == shdr->Tid) {

I will include this fixup into v2 when needed (during next rebase).

Note that it is hard to catch such endianity issues as majority of user
machines are little endian, so such issues are hidden.

> +				spin_lock(&tcon->tc_lock);
> +				tcon->need_reconnect = true;
> +				spin_unlock(&tcon->tc_lock);
> +				spin_unlock(&cifs_tcp_ses_lock);
> +				pr_warn_once("Server share %s deleted.\n",
> +					     tcon->tree_name);
> +				return true;
> +			}
> +		}
> +	}
> +	spin_unlock(&cifs_tcp_ses_lock);
> +
> +	return false;
> +}
> +
>  struct smb_version_operations smb1_operations = {
>  	.send_cancel = send_nt_cancel,
>  	.compare_fids = cifs_compare_fids,
> @@ -1159,6 +1202,7 @@ struct smb_version_operations smb1_operations = {
>  	.get_acl_by_fid = get_cifs_acl_by_fid,
>  	.set_acl = set_cifs_acl,
>  	.make_node = cifs_make_node,
> +	.is_network_name_deleted = cifs_is_network_name_deleted,
>  };
>  
>  struct smb_version_values smb1_values = {
> -- 
> 2.20.1
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ