Skip to content

Commit c3cc9c0

Browse files
committed
Merge: CIFS: sync with upstream for RHEL 9.7
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/7143 - sync CIFS with upstream for RHEL 9.7 JIRA: https://issues.redhat.com/browse/RHEL-104401 Signed-off-by: Paulo Alcantara <paalcant@redhat.com> Approved-by: David Howells <dhowells@redhat.com> Approved-by: Jay Shin <jaeshin@redhat.com> Approved-by: Benjamin Coddington <bcodding@redhat.com> Approved-by: Rafael Aquini <raquini@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Augusto Caringi <acaringi@redhat.com>
2 parents 18bc284 + 55ecb94 commit c3cc9c0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1570
-606
lines changed

Documentation/admin-guide/cifs/usage.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,8 @@ configured for Unix Extensions (and the client has not disabled
270270
illegal Windows/NTFS/SMB characters to a remap range (this mount parameter
271271
is the default for SMB3). This remap (``mapposix``) range is also
272272
compatible with Mac (and "Services for Mac" on some older Windows).
273+
When POSIX Extensions for SMB 3.1.1 are negotiated, remapping is automatically
274+
disabled.
273275

274276
CIFS VFS Mount Options
275277
======================

fs/smb/client/cached_dir.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
2929
{
3030
struct cached_fid *cfid;
3131

32-
spin_lock(&cfids->cfid_list_lock);
3332
list_for_each_entry(cfid, &cfids->entries, entry) {
3433
if (!strcmp(cfid->path, path)) {
3534
/*
@@ -38,25 +37,20 @@ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
3837
* being deleted due to a lease break.
3938
*/
4039
if (!cfid->time || !cfid->has_lease) {
41-
spin_unlock(&cfids->cfid_list_lock);
4240
return NULL;
4341
}
4442
kref_get(&cfid->refcount);
45-
spin_unlock(&cfids->cfid_list_lock);
4643
return cfid;
4744
}
4845
}
4946
if (lookup_only) {
50-
spin_unlock(&cfids->cfid_list_lock);
5147
return NULL;
5248
}
5349
if (cfids->num_entries >= max_cached_dirs) {
54-
spin_unlock(&cfids->cfid_list_lock);
5550
return NULL;
5651
}
5752
cfid = init_cached_dir(path);
5853
if (cfid == NULL) {
59-
spin_unlock(&cfids->cfid_list_lock);
6054
return NULL;
6155
}
6256
cfid->cfids = cfids;
@@ -74,7 +68,6 @@ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
7468
*/
7569
cfid->has_lease = true;
7670

77-
spin_unlock(&cfids->cfid_list_lock);
7871
return cfid;
7972
}
8073

@@ -187,8 +180,10 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
187180
if (!utf16_path)
188181
return -ENOMEM;
189182

183+
spin_lock(&cfids->cfid_list_lock);
190184
cfid = find_or_create_cached_dir(cfids, path, lookup_only, tcon->max_cached_dirs);
191185
if (cfid == NULL) {
186+
spin_unlock(&cfids->cfid_list_lock);
192187
kfree(utf16_path);
193188
return -ENOENT;
194189
}
@@ -197,7 +192,6 @@ int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
197192
* Otherwise, it is either a new entry or laundromat worker removed it
198193
* from @cfids->entries. Caller will put last reference if the latter.
199194
*/
200-
spin_lock(&cfids->cfid_list_lock);
201195
if (cfid->has_lease && cfid->time) {
202196
spin_unlock(&cfids->cfid_list_lock);
203197
*ret_cfid = cfid;
@@ -492,8 +486,17 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
492486
spin_lock(&cfids->cfid_list_lock);
493487
list_for_each_entry(cfid, &cfids->entries, entry) {
494488
tmp_list = kmalloc(sizeof(*tmp_list), GFP_ATOMIC);
495-
if (tmp_list == NULL)
496-
break;
489+
if (tmp_list == NULL) {
490+
/*
491+
* If the malloc() fails, we won't drop all
492+
* dentries, and unmounting is likely to trigger
493+
* a 'Dentry still in use' error.
494+
*/
495+
cifs_tcon_dbg(VFS, "Out of memory while dropping dentries\n");
496+
spin_unlock(&cfids->cfid_list_lock);
497+
spin_unlock(&cifs_sb->tlink_tree_lock);
498+
goto done;
499+
}
497500
spin_lock(&cfid->fid_lock);
498501
tmp_list->dentry = cfid->dentry;
499502
cfid->dentry = NULL;
@@ -505,6 +508,7 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
505508
}
506509
spin_unlock(&cifs_sb->tlink_tree_lock);
507510

511+
done:
508512
list_for_each_entry_safe(tmp_list, q, &entry, entry) {
509513
list_del(&tmp_list->entry);
510514
dput(tmp_list->dentry);

fs/smb/client/cached_dir.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ struct cached_dirent {
2121
struct cached_dirents {
2222
bool is_valid:1;
2323
bool is_failed:1;
24-
struct dir_context *ctx; /*
25-
* Only used to make sure we only take entries
26-
* from a single context. Never dereferenced.
27-
*/
24+
struct file *file; /*
25+
* Used to associate the cache with a single
26+
* open file instance.
27+
*/
2828
struct mutex de_mutex;
29-
int pos; /* Expected ctx->pos */
29+
loff_t pos; /* Expected ctx->pos */
3030
struct list_head entries;
3131
};
3232

fs/smb/client/cifs_debug.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1100,7 +1100,7 @@ static ssize_t cifs_security_flags_proc_write(struct file *file,
11001100
if ((count < 1) || (count > 11))
11011101
return -EINVAL;
11021102

1103-
memset(flags_string, 0, 12);
1103+
memset(flags_string, 0, sizeof(flags_string));
11041104

11051105
if (copy_from_user(flags_string, buffer, count))
11061106
return -EFAULT;

fs/smb/client/cifs_fs_sb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949

5050
struct cifs_sb_info {
5151
struct rb_root tlink_tree;
52+
struct list_head tcon_sb_link;
5253
spinlock_t tlink_tree_lock;
5354
struct tcon_link *master_tlink;
5455
struct nls_table *local_nls;

fs/smb/client/cifs_ioctl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ struct smb_query_info {
6161
struct smb3_key_debug_info {
6262
__u64 Suid;
6363
__u16 cipher_type;
64-
__u8 auth_key[16]; /* SMB2_NTLMV2_SESSKEY_SIZE */
64+
__u8 auth_key[SMB2_NTLMV2_SESSKEY_SIZE];
6565
__u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE];
6666
__u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE];
6767
} __packed;

fs/smb/client/cifsacl.c

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -763,7 +763,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
763763
struct cifs_fattr *fattr, bool mode_from_special_sid)
764764
{
765765
int i;
766-
int num_aces = 0;
766+
u16 num_aces = 0;
767767
int acl_size;
768768
char *acl_base;
769769
struct smb_ace **ppace;
@@ -778,14 +778,15 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
778778
}
779779

780780
/* validate that we do not go past end of acl */
781-
if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
781+
if (end_of_acl < (char *)pdacl + sizeof(struct smb_acl) ||
782+
end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
782783
cifs_dbg(VFS, "ACL too small to parse DACL\n");
783784
return;
784785
}
785786

786787
cifs_dbg(NOISY, "DACL revision %d size %d num aces %d\n",
787788
le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
788-
le32_to_cpu(pdacl->num_aces));
789+
le16_to_cpu(pdacl->num_aces));
789790

790791
/* reset rwx permissions for user/group/other.
791792
Also, if num_aces is 0 i.e. DACL has no ACEs,
@@ -795,19 +796,38 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
795796
acl_base = (char *)pdacl;
796797
acl_size = sizeof(struct smb_acl);
797798

798-
num_aces = le32_to_cpu(pdacl->num_aces);
799+
num_aces = le16_to_cpu(pdacl->num_aces);
799800
if (num_aces > 0) {
800801
umode_t denied_mode = 0;
801802

802-
if (num_aces > ULONG_MAX / sizeof(struct smb_ace *))
803+
if (num_aces > (le16_to_cpu(pdacl->size) - sizeof(struct smb_acl)) /
804+
(offsetof(struct smb_ace, sid) +
805+
offsetof(struct smb_sid, sub_auth) + sizeof(__le16)))
803806
return;
807+
804808
ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *),
805809
GFP_KERNEL);
806810
if (!ppace)
807811
return;
808812

809813
for (i = 0; i < num_aces; ++i) {
814+
if (end_of_acl - acl_base < acl_size)
815+
break;
816+
810817
ppace[i] = (struct smb_ace *) (acl_base + acl_size);
818+
acl_base = (char *)ppace[i];
819+
acl_size = offsetof(struct smb_ace, sid) +
820+
offsetof(struct smb_sid, sub_auth);
821+
822+
if (end_of_acl - acl_base < acl_size ||
823+
ppace[i]->sid.num_subauth == 0 ||
824+
ppace[i]->sid.num_subauth > SID_MAX_SUB_AUTHORITIES ||
825+
(end_of_acl - acl_base <
826+
acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth) ||
827+
(le16_to_cpu(ppace[i]->size) <
828+
acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth))
829+
break;
830+
811831
#ifdef CONFIG_CIFS_DEBUG2
812832
dump_ace(ppace[i], end_of_acl);
813833
#endif
@@ -851,7 +871,6 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl,
851871
(void *)ppace[i],
852872
sizeof(struct smb_ace)); */
853873

854-
acl_base = (char *)ppace[i];
855874
acl_size = le16_to_cpu(ppace[i]->size);
856875
}
857876

@@ -937,12 +956,12 @@ unsigned int setup_special_user_owner_ACE(struct smb_ace *pntace)
937956
static void populate_new_aces(char *nacl_base,
938957
struct smb_sid *pownersid,
939958
struct smb_sid *pgrpsid,
940-
__u64 *pnmode, u32 *pnum_aces, u16 *pnsize,
959+
__u64 *pnmode, u16 *pnum_aces, u16 *pnsize,
941960
bool modefromsid,
942961
bool posix)
943962
{
944963
__u64 nmode;
945-
u32 num_aces = 0;
964+
u16 num_aces = 0;
946965
u16 nsize = 0;
947966
__u64 user_mode;
948967
__u64 group_mode;
@@ -1050,15 +1069,15 @@ static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *p
10501069
u16 size = 0;
10511070
struct smb_ace *pntace = NULL;
10521071
char *acl_base = NULL;
1053-
u32 src_num_aces = 0;
1072+
u16 src_num_aces = 0;
10541073
u16 nsize = 0;
10551074
struct smb_ace *pnntace = NULL;
10561075
char *nacl_base = NULL;
10571076
u16 ace_size = 0;
10581077

10591078
acl_base = (char *)pdacl;
10601079
size = sizeof(struct smb_acl);
1061-
src_num_aces = le32_to_cpu(pdacl->num_aces);
1080+
src_num_aces = le16_to_cpu(pdacl->num_aces);
10621081

10631082
nacl_base = (char *)pndacl;
10641083
nsize = sizeof(struct smb_acl);
@@ -1090,11 +1109,11 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
10901109
u16 size = 0;
10911110
struct smb_ace *pntace = NULL;
10921111
char *acl_base = NULL;
1093-
u32 src_num_aces = 0;
1112+
u16 src_num_aces = 0;
10941113
u16 nsize = 0;
10951114
struct smb_ace *pnntace = NULL;
10961115
char *nacl_base = NULL;
1097-
u32 num_aces = 0;
1116+
u16 num_aces = 0;
10981117
bool new_aces_set = false;
10991118

11001119
/* Assuming that pndacl and pnmode are never NULL */
@@ -1112,7 +1131,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
11121131

11131132
acl_base = (char *)pdacl;
11141133
size = sizeof(struct smb_acl);
1115-
src_num_aces = le32_to_cpu(pdacl->num_aces);
1134+
src_num_aces = le16_to_cpu(pdacl->num_aces);
11161135

11171136
/* Retain old ACEs which we can retain */
11181137
for (i = 0; i < src_num_aces; ++i) {
@@ -1158,7 +1177,7 @@ static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
11581177
}
11591178

11601179
finalize_dacl:
1161-
pndacl->num_aces = cpu_to_le32(num_aces);
1180+
pndacl->num_aces = cpu_to_le16(num_aces);
11621181
pndacl->size = cpu_to_le16(nsize);
11631182

11641183
return 0;
@@ -1293,7 +1312,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd,
12931312
dacloffset ? dacl_ptr->revision : cpu_to_le16(ACL_REVISION);
12941313

12951314
ndacl_ptr->size = cpu_to_le16(0);
1296-
ndacl_ptr->num_aces = cpu_to_le32(0);
1315+
ndacl_ptr->num_aces = cpu_to_le16(0);
12971316

12981317
rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
12991318
pnmode, mode_from_sid, posix);
@@ -1546,7 +1565,7 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
15461565
int rc = 0;
15471566
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
15481567
struct smb_version_operations *ops;
1549-
const u32 info = 0;
1568+
const u32 info = OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO;
15501569

15511570
cifs_dbg(NOISY, "converting ACL to mode for %s\n", path);
15521571

@@ -1600,7 +1619,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
16001619
struct tcon_link *tlink;
16011620
struct smb_version_operations *ops;
16021621
bool mode_from_sid, id_from_sid;
1603-
const u32 info = 0;
1622+
const u32 info = OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO;
16041623
bool posix;
16051624

16061625
tlink = cifs_sb_tlink(cifs_sb);
@@ -1653,7 +1672,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode,
16531672
dacl_ptr = (struct smb_acl *)((char *)pntsd + dacloffset);
16541673
if (mode_from_sid)
16551674
nsecdesclen +=
1656-
le32_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace);
1675+
le16_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace);
16571676
else /* cifsacl */
16581677
nsecdesclen += le16_to_cpu(dacl_ptr->size);
16591678
}

fs/smb/client/cifsfs.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ bool require_gcm_256; /* false by default */
6969
bool enable_negotiate_signing; /* false by default */
7070
unsigned int global_secflags = CIFSSEC_DEF;
7171
/* unsigned int ntlmv2_support = 0; */
72-
unsigned int sign_CIFS_PDUs = 1;
7372

7473
/*
7574
* Global transaction id (XID) information
@@ -631,6 +630,10 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
631630
cifs_sb->ctx->dir_mode);
632631
if (cifs_sb->ctx->iocharset)
633632
seq_printf(s, ",iocharset=%s", cifs_sb->ctx->iocharset);
633+
if (tcon->ses->unicode == 0)
634+
seq_puts(s, ",nounicode");
635+
else if (tcon->ses->unicode == 1)
636+
seq_puts(s, ",unicode");
634637
if (tcon->seal)
635638
seq_puts(s, ",seal");
636639
else if (tcon->ses->server->ignore_signature)

fs/smb/client/cifsfs.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ extern ssize_t cifs_file_copychunk_range(unsigned int xid,
137137

138138
extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
139139
extern void cifs_setsize(struct inode *inode, loff_t offset);
140-
extern int cifs_truncate_page(struct address_space *mapping, loff_t from);
141140

142141
struct smb3_fs_context;
143142
extern struct dentry *cifs_smb3_do_mount(struct file_system_type *fs_type,

0 commit comments

Comments
 (0)