@@ -756,19 +756,6 @@ static void build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt,
756756 pneg_ctxt -> Ciphers [0 ] = cipher_type ;
757757}
758758
759- static void build_compression_ctxt (struct smb2_compression_capabilities_context * pneg_ctxt ,
760- __le16 comp_algo )
761- {
762- pneg_ctxt -> ContextType = SMB2_COMPRESSION_CAPABILITIES ;
763- pneg_ctxt -> DataLength =
764- cpu_to_le16 (sizeof (struct smb2_compression_capabilities_context )
765- - sizeof (struct smb2_neg_context ));
766- pneg_ctxt -> Reserved = cpu_to_le32 (0 );
767- pneg_ctxt -> CompressionAlgorithmCount = cpu_to_le16 (1 );
768- pneg_ctxt -> Flags = cpu_to_le32 (0 );
769- pneg_ctxt -> CompressionAlgorithms [0 ] = comp_algo ;
770- }
771-
772759static void build_sign_cap_ctxt (struct smb2_signing_capabilities * pneg_ctxt ,
773760 __le16 sign_algo )
774761{
@@ -808,7 +795,7 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn,
808795 struct smb2_negotiate_rsp * rsp ,
809796 void * smb2_buf_len )
810797{
811- char * pneg_ctxt = (char * )rsp +
798+ char * const pneg_ctxt = (char * )rsp +
812799 le32_to_cpu (rsp -> NegotiateContextOffset );
813800 int neg_ctxt_cnt = 1 ;
814801 int ctxt_size ;
@@ -817,61 +804,46 @@ static void assemble_neg_contexts(struct ksmbd_conn *conn,
817804 "assemble SMB2_PREAUTH_INTEGRITY_CAPABILITIES context\n" );
818805 build_preauth_ctxt ((struct smb2_preauth_neg_context * )pneg_ctxt ,
819806 conn -> preauth_info -> Preauth_HashId );
820- rsp -> NegotiateContextCount = cpu_to_le16 (neg_ctxt_cnt );
821807 inc_rfc1001_len (smb2_buf_len , AUTH_GSS_PADDING );
822808 ctxt_size = sizeof (struct smb2_preauth_neg_context );
823- /* Round to 8 byte boundary */
824- pneg_ctxt += round_up (sizeof (struct smb2_preauth_neg_context ), 8 );
825809
826810 if (conn -> cipher_type ) {
811+ /* Round to 8 byte boundary */
827812 ctxt_size = round_up (ctxt_size , 8 );
828813 ksmbd_debug (SMB ,
829814 "assemble SMB2_ENCRYPTION_CAPABILITIES context\n" );
830- build_encrypt_ctxt ((struct smb2_encryption_neg_context * )pneg_ctxt ,
815+ build_encrypt_ctxt ((struct smb2_encryption_neg_context * )
816+ (pneg_ctxt + ctxt_size ),
831817 conn -> cipher_type );
832- rsp -> NegotiateContextCount = cpu_to_le16 ( ++ neg_ctxt_cnt ) ;
818+ neg_ctxt_cnt ++ ;
833819 ctxt_size += sizeof (struct smb2_encryption_neg_context ) + 2 ;
834- /* Round to 8 byte boundary */
835- pneg_ctxt +=
836- round_up (sizeof (struct smb2_encryption_neg_context ) + 2 ,
837- 8 );
838820 }
839821
840- if (conn -> compress_algorithm ) {
841- ctxt_size = round_up (ctxt_size , 8 );
842- ksmbd_debug (SMB ,
843- "assemble SMB2_COMPRESSION_CAPABILITIES context\n" );
844- /* Temporarily set to SMB3_COMPRESS_NONE */
845- build_compression_ctxt ((struct smb2_compression_capabilities_context * )pneg_ctxt ,
846- conn -> compress_algorithm );
847- rsp -> NegotiateContextCount = cpu_to_le16 (++ neg_ctxt_cnt );
848- ctxt_size += sizeof (struct smb2_compression_capabilities_context ) + 2 ;
849- /* Round to 8 byte boundary */
850- pneg_ctxt += round_up (sizeof (struct smb2_compression_capabilities_context ) + 2 ,
851- 8 );
852- }
822+ /* compression context not yet supported */
823+ WARN_ON (conn -> compress_algorithm != SMB3_COMPRESS_NONE );
853824
854825 if (conn -> posix_ext_supported ) {
855826 ctxt_size = round_up (ctxt_size , 8 );
856827 ksmbd_debug (SMB ,
857828 "assemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n" );
858- build_posix_ctxt ((struct smb2_posix_neg_context * )pneg_ctxt );
859- rsp -> NegotiateContextCount = cpu_to_le16 (++ neg_ctxt_cnt );
829+ build_posix_ctxt ((struct smb2_posix_neg_context * )
830+ (pneg_ctxt + ctxt_size ));
831+ neg_ctxt_cnt ++ ;
860832 ctxt_size += sizeof (struct smb2_posix_neg_context );
861- /* Round to 8 byte boundary */
862- pneg_ctxt += round_up (sizeof (struct smb2_posix_neg_context ), 8 );
863833 }
864834
865835 if (conn -> signing_negotiated ) {
866836 ctxt_size = round_up (ctxt_size , 8 );
867837 ksmbd_debug (SMB ,
868838 "assemble SMB2_SIGNING_CAPABILITIES context\n" );
869- build_sign_cap_ctxt ((struct smb2_signing_capabilities * )pneg_ctxt ,
839+ build_sign_cap_ctxt ((struct smb2_signing_capabilities * )
840+ (pneg_ctxt + ctxt_size ),
870841 conn -> signing_algorithm );
871- rsp -> NegotiateContextCount = cpu_to_le16 ( ++ neg_ctxt_cnt ) ;
842+ neg_ctxt_cnt ++ ;
872843 ctxt_size += sizeof (struct smb2_signing_capabilities ) + 2 ;
873844 }
874845
846+ rsp -> NegotiateContextCount = cpu_to_le16 (neg_ctxt_cnt );
875847 inc_rfc1001_len (smb2_buf_len , ctxt_size );
876848}
877849
@@ -2436,7 +2408,7 @@ static int smb2_creat(struct ksmbd_work *work, struct path *path, char *name,
24362408 return rc ;
24372409 }
24382410
2439- rc = ksmbd_vfs_kern_path (work , name , 0 , path , 0 );
2411+ rc = ksmbd_vfs_kern_path_locked (work , name , 0 , path , 0 );
24402412 if (rc ) {
24412413 pr_err ("cannot get linux path (%s), err = %d\n" ,
24422414 name , rc );
@@ -2727,8 +2699,10 @@ int smb2_open(struct ksmbd_work *work)
27272699 goto err_out1 ;
27282700 }
27292701
2730- rc = ksmbd_vfs_kern_path (work , name , LOOKUP_NO_SYMLINKS , & path , 1 );
2702+ rc = ksmbd_vfs_kern_path_locked (work , name , LOOKUP_NO_SYMLINKS , & path , 1 );
27312703 if (!rc ) {
2704+ file_present = true;
2705+
27322706 if (req -> CreateOptions & FILE_DELETE_ON_CLOSE_LE ) {
27332707 /*
27342708 * If file exists with under flags, return access
@@ -2737,34 +2711,30 @@ int smb2_open(struct ksmbd_work *work)
27372711 if (req -> CreateDisposition == FILE_OVERWRITE_IF_LE ||
27382712 req -> CreateDisposition == FILE_OPEN_IF_LE ) {
27392713 rc = - EACCES ;
2740- path_put (& path );
27412714 goto err_out ;
27422715 }
27432716
27442717 if (!test_tree_conn_flag (tcon , KSMBD_TREE_CONN_FLAG_WRITABLE )) {
27452718 ksmbd_debug (SMB ,
27462719 "User does not have write permission\n" );
27472720 rc = - EACCES ;
2748- path_put (& path );
27492721 goto err_out ;
27502722 }
27512723 } else if (d_is_symlink (path .dentry )) {
27522724 rc = - EACCES ;
2753- path_put (& path );
27542725 goto err_out ;
27552726 }
2756- }
27572727
2758- if (rc ) {
2728+ file_present = true;
2729+ idmap = mnt_idmap (path .mnt );
2730+ } else {
27592731 if (rc != - ENOENT )
27602732 goto err_out ;
27612733 ksmbd_debug (SMB , "can not get linux path for %s, rc = %d\n" ,
27622734 name , rc );
27632735 rc = 0 ;
2764- } else {
2765- file_present = true;
2766- idmap = mnt_idmap (path .mnt );
27672736 }
2737+
27682738 if (stream_name ) {
27692739 if (req -> CreateOptions & FILE_DIRECTORY_FILE_LE ) {
27702740 if (s_type == DATA_STREAM ) {
@@ -2892,8 +2862,9 @@ int smb2_open(struct ksmbd_work *work)
28922862
28932863 if ((daccess & FILE_DELETE_LE ) ||
28942864 (req -> CreateOptions & FILE_DELETE_ON_CLOSE_LE )) {
2895- rc = ksmbd_vfs_may_delete (idmap ,
2896- path .dentry );
2865+ rc = inode_permission (idmap ,
2866+ d_inode (path .dentry -> d_parent ),
2867+ MAY_EXEC | MAY_WRITE );
28972868 if (rc )
28982869 goto err_out ;
28992870 }
@@ -3264,10 +3235,13 @@ int smb2_open(struct ksmbd_work *work)
32643235 }
32653236
32663237err_out :
3267- if (file_present || created )
3268- path_put (& path );
3238+ if (file_present || created ) {
3239+ inode_unlock (d_inode (path .dentry -> d_parent ));
3240+ dput (path .dentry );
3241+ }
32693242 ksmbd_revert_fsids (work );
32703243err_out1 :
3244+
32713245 if (rc ) {
32723246 if (rc == - EINVAL )
32733247 rsp -> hdr .Status = STATUS_INVALID_PARAMETER ;
@@ -5418,44 +5392,19 @@ int smb2_echo(struct ksmbd_work *work)
54185392
54195393static int smb2_rename (struct ksmbd_work * work ,
54205394 struct ksmbd_file * fp ,
5421- struct mnt_idmap * idmap ,
54225395 struct smb2_file_rename_info * file_info ,
54235396 struct nls_table * local_nls )
54245397{
54255398 struct ksmbd_share_config * share = fp -> tcon -> share_conf ;
5426- char * new_name = NULL , * abs_oldname = NULL , * old_name = NULL ;
5427- char * pathname = NULL ;
5428- struct path path ;
5429- bool file_present = true;
5430- int rc ;
5399+ char * new_name = NULL ;
5400+ int rc , flags = 0 ;
54315401
54325402 ksmbd_debug (SMB , "setting FILE_RENAME_INFO\n" );
5433- pathname = kmalloc (PATH_MAX , GFP_KERNEL );
5434- if (!pathname )
5435- return - ENOMEM ;
5436-
5437- abs_oldname = file_path (fp -> filp , pathname , PATH_MAX );
5438- if (IS_ERR (abs_oldname )) {
5439- rc = - EINVAL ;
5440- goto out ;
5441- }
5442- old_name = strrchr (abs_oldname , '/' );
5443- if (old_name && old_name [1 ] != '\0' ) {
5444- old_name ++ ;
5445- } else {
5446- ksmbd_debug (SMB , "can't get last component in path %s\n" ,
5447- abs_oldname );
5448- rc = - ENOENT ;
5449- goto out ;
5450- }
5451-
54525403 new_name = smb2_get_name (file_info -> FileName ,
54535404 le32_to_cpu (file_info -> FileNameLength ),
54545405 local_nls );
5455- if (IS_ERR (new_name )) {
5456- rc = PTR_ERR (new_name );
5457- goto out ;
5458- }
5406+ if (IS_ERR (new_name ))
5407+ return PTR_ERR (new_name );
54595408
54605409 if (strchr (new_name , ':' )) {
54615410 int s_type ;
@@ -5481,7 +5430,7 @@ static int smb2_rename(struct ksmbd_work *work,
54815430 if (rc )
54825431 goto out ;
54835432
5484- rc = ksmbd_vfs_setxattr (idmap ,
5433+ rc = ksmbd_vfs_setxattr (file_mnt_idmap ( fp -> filp ) ,
54855434 fp -> filp -> f_path .dentry ,
54865435 xattr_stream_name ,
54875436 NULL , 0 , 0 );
@@ -5496,47 +5445,18 @@ static int smb2_rename(struct ksmbd_work *work,
54965445 }
54975446
54985447 ksmbd_debug (SMB , "new name %s\n" , new_name );
5499- rc = ksmbd_vfs_kern_path (work , new_name , LOOKUP_NO_SYMLINKS , & path , 1 );
5500- if (rc ) {
5501- if (rc != - ENOENT )
5502- goto out ;
5503- file_present = false;
5504- } else {
5505- path_put (& path );
5506- }
5507-
55085448 if (ksmbd_share_veto_filename (share , new_name )) {
55095449 rc = - ENOENT ;
55105450 ksmbd_debug (SMB , "Can't rename vetoed file: %s\n" , new_name );
55115451 goto out ;
55125452 }
55135453
5514- if (file_info -> ReplaceIfExists ) {
5515- if (file_present ) {
5516- rc = ksmbd_vfs_remove_file (work , new_name );
5517- if (rc ) {
5518- if (rc != - ENOTEMPTY )
5519- rc = - EINVAL ;
5520- ksmbd_debug (SMB , "cannot delete %s, rc %d\n" ,
5521- new_name , rc );
5522- goto out ;
5523- }
5524- }
5525- } else {
5526- if (file_present &&
5527- strncmp (old_name , path .dentry -> d_name .name , strlen (old_name ))) {
5528- rc = - EEXIST ;
5529- ksmbd_debug (SMB ,
5530- "cannot rename already existing file\n" );
5531- goto out ;
5532- }
5533- }
5454+ if (!file_info -> ReplaceIfExists )
5455+ flags = RENAME_NOREPLACE ;
55345456
5535- rc = ksmbd_vfs_fp_rename (work , fp , new_name );
5457+ rc = ksmbd_vfs_rename (work , & fp -> filp -> f_path , new_name , flags );
55365458out :
5537- kfree (pathname );
5538- if (!IS_ERR (new_name ))
5539- kfree (new_name );
5459+ kfree (new_name );
55405460 return rc ;
55415461}
55425462
@@ -5576,18 +5496,17 @@ static int smb2_create_link(struct ksmbd_work *work,
55765496 }
55775497
55785498 ksmbd_debug (SMB , "target name is %s\n" , target_name );
5579- rc = ksmbd_vfs_kern_path (work , link_name , LOOKUP_NO_SYMLINKS , & path , 0 );
5499+ rc = ksmbd_vfs_kern_path_locked (work , link_name , LOOKUP_NO_SYMLINKS ,
5500+ & path , 0 );
55805501 if (rc ) {
55815502 if (rc != - ENOENT )
55825503 goto out ;
55835504 file_present = false;
5584- } else {
5585- path_put (& path );
55865505 }
55875506
55885507 if (file_info -> ReplaceIfExists ) {
55895508 if (file_present ) {
5590- rc = ksmbd_vfs_remove_file (work , link_name );
5509+ rc = ksmbd_vfs_remove_file (work , & path );
55915510 if (rc ) {
55925511 rc = - EINVAL ;
55935512 ksmbd_debug (SMB , "cannot delete %s\n" ,
@@ -5607,6 +5526,10 @@ static int smb2_create_link(struct ksmbd_work *work,
56075526 if (rc )
56085527 rc = - EINVAL ;
56095528out :
5529+ if (file_present ) {
5530+ inode_unlock (d_inode (path .dentry -> d_parent ));
5531+ path_put (& path );
5532+ }
56105533 if (!IS_ERR (link_name ))
56115534 kfree (link_name );
56125535 kfree (pathname );
@@ -5784,12 +5707,6 @@ static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp,
57845707 struct smb2_file_rename_info * rename_info ,
57855708 unsigned int buf_len )
57865709{
5787- struct mnt_idmap * idmap ;
5788- struct ksmbd_file * parent_fp ;
5789- struct dentry * parent ;
5790- struct dentry * dentry = fp -> filp -> f_path .dentry ;
5791- int ret ;
5792-
57935710 if (!(fp -> daccess & FILE_DELETE_LE )) {
57945711 pr_err ("no right to delete : 0x%x\n" , fp -> daccess );
57955712 return - EACCES ;
@@ -5799,32 +5716,10 @@ static int set_rename_info(struct ksmbd_work *work, struct ksmbd_file *fp,
57995716 le32_to_cpu (rename_info -> FileNameLength ))
58005717 return - EINVAL ;
58015718
5802- idmap = file_mnt_idmap (fp -> filp );
5803- if (ksmbd_stream_fd (fp ))
5804- goto next ;
5805-
5806- parent = dget_parent (dentry );
5807- ret = ksmbd_vfs_lock_parent (idmap , parent , dentry );
5808- if (ret ) {
5809- dput (parent );
5810- return ret ;
5811- }
5812-
5813- parent_fp = ksmbd_lookup_fd_inode (d_inode (parent ));
5814- inode_unlock (d_inode (parent ));
5815- dput (parent );
5719+ if (!le32_to_cpu (rename_info -> FileNameLength ))
5720+ return - EINVAL ;
58165721
5817- if (parent_fp ) {
5818- if (parent_fp -> daccess & FILE_DELETE_LE ) {
5819- pr_err ("parent dir is opened with delete access\n" );
5820- ksmbd_fd_put (work , parent_fp );
5821- return - ESHARE ;
5822- }
5823- ksmbd_fd_put (work , parent_fp );
5824- }
5825- next :
5826- return smb2_rename (work , fp , idmap , rename_info ,
5827- work -> conn -> local_nls );
5722+ return smb2_rename (work , fp , rename_info , work -> conn -> local_nls );
58285723}
58295724
58305725static int set_file_disposition_info (struct ksmbd_file * fp ,
0 commit comments