xref: /linux/fs/smb/client/smb2file.c (revision b0662be9131d87d8858d34d6134500e109dff958)
1 // SPDX-License-Identifier: LGPL-2.1
2 /*
3  *
4  *   Copyright (C) International Business Machines  Corp., 2002, 2011
5  *   Author(s): Steve French (sfrench@us.ibm.com),
6  *              Pavel Shilovsky ((pshilovsky@samba.org) 2012
7  *
8  */
9 #include <linux/fs.h>
10 #include <linux/filelock.h>
11 #include <linux/stat.h>
12 #include <linux/slab.h>
13 #include <linux/pagemap.h>
14 #include <asm/div64.h>
15 #include "cifsfs.h"
16 #include "cifsglob.h"
17 #include "cifsproto.h"
18 #include "cifs_debug.h"
19 #include "cifs_fs_sb.h"
20 #include "cifs_unicode.h"
21 #include "fscache.h"
22 #include "smb2proto.h"
23 #include "../common/smb2status.h"
24 #include "../common/smbfsctl.h"
25 
symlink_data(const struct kvec * iov)26 static struct smb2_symlink_err_rsp *symlink_data(const struct kvec *iov)
27 {
28 	struct smb2_err_rsp *err = iov->iov_base;
29 	struct smb2_symlink_err_rsp *sym = ERR_PTR(-EINVAL);
30 	u8 *end = (u8 *)err + iov->iov_len;
31 	u32 len;
32 
33 	if (err->ErrorContextCount) {
34 		struct smb2_error_context_rsp *p;
35 
36 		len = (u32)err->ErrorContextCount * (offsetof(struct smb2_error_context_rsp,
37 							      ErrorContextData) +
38 						     sizeof(struct smb2_symlink_err_rsp));
39 		if (le32_to_cpu(err->ByteCount) < len || iov->iov_len < len + sizeof(*err) + 1)
40 			return ERR_PTR(-EINVAL);
41 
42 		p = (struct smb2_error_context_rsp *)err->ErrorData;
43 		while ((u8 *)p + sizeof(*p) <= end) {
44 			if (le32_to_cpu(p->ErrorId) == SMB2_ERROR_ID_DEFAULT) {
45 				sym = (struct smb2_symlink_err_rsp *)p->ErrorContextData;
46 				break;
47 			}
48 			cifs_dbg(FYI, "%s: skipping unhandled error context: 0x%x\n",
49 				 __func__, le32_to_cpu(p->ErrorId));
50 
51 			len = ALIGN(le32_to_cpu(p->ErrorDataLength), 8);
52 			if (len > end - ((u8 *)p + sizeof(*p)))
53 				return ERR_PTR(-EINVAL);
54 
55 			p = (struct smb2_error_context_rsp *)(p->ErrorContextData + len);
56 		}
57 	} else if (le32_to_cpu(err->ByteCount) >= sizeof(*sym) &&
58 		   iov->iov_len >= SMB2_SYMLINK_STRUCT_SIZE) {
59 		sym = (struct smb2_symlink_err_rsp *)err->ErrorData;
60 	}
61 
62 	if (!IS_ERR(sym) &&
63 	    ((u8 *)sym + sizeof(*sym) > end ||
64 	     le32_to_cpu(sym->SymLinkErrorTag) != SYMLINK_ERROR_TAG ||
65 	     le32_to_cpu(sym->ReparseTag) != IO_REPARSE_TAG_SYMLINK))
66 		sym = ERR_PTR(-EINVAL);
67 
68 	return sym;
69 }
70 
smb2_fix_symlink_target_type(char ** target,bool directory,struct cifs_sb_info * cifs_sb)71 int smb2_fix_symlink_target_type(char **target, bool directory, struct cifs_sb_info *cifs_sb)
72 {
73 	char *buf;
74 	int len;
75 
76 	/*
77 	 * POSIX server does not distinguish between symlinks to file and
78 	 * symlink directory. So nothing is needed to fix on the client side.
79 	 */
80 	if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_POSIX_PATHS)
81 		return 0;
82 
83 	if (!*target)
84 		return smb_EIO(smb_eio_trace_null_pointers);
85 
86 	len = strlen(*target);
87 	if (!len)
88 		return smb_EIO1(smb_eio_trace_sym_target_len, len);
89 
90 	/*
91 	 * If this is directory symlink and it does not have trailing slash then
92 	 * append it. Trailing slash simulates Windows/SMB behavior which do not
93 	 * allow resolving directory symlink to file.
94 	 */
95 	if (directory && (*target)[len-1] != '/') {
96 		buf = krealloc(*target, len+2, GFP_KERNEL);
97 		if (!buf)
98 			return -ENOMEM;
99 		buf[len] = '/';
100 		buf[len+1] = '\0';
101 		*target = buf;
102 		len++;
103 	}
104 
105 	/*
106 	 * If this is a file (non-directory) symlink and it points to path name
107 	 * with trailing slash then this is an invalid symlink because file name
108 	 * cannot contain slash character. File name with slash is invalid on
109 	 * both Windows and Linux systems. So return an error for such symlink.
110 	 */
111 	if (!directory && (*target)[len-1] == '/')
112 		return smb_EIO(smb_eio_trace_sym_slash);
113 
114 	return 0;
115 }
116 
smb2_parse_symlink_response(struct cifs_sb_info * cifs_sb,const struct kvec * iov,const char * full_path,char ** path)117 int smb2_parse_symlink_response(struct cifs_sb_info *cifs_sb, const struct kvec *iov,
118 				const char *full_path, char **path)
119 {
120 	struct smb2_symlink_err_rsp *sym;
121 	unsigned int sub_offs, sub_len;
122 	unsigned int print_offs, print_len;
123 
124 	if (!cifs_sb || !iov || !iov->iov_base || !iov->iov_len || !path)
125 		return -EINVAL;
126 
127 	sym = symlink_data(iov);
128 	if (IS_ERR(sym))
129 		return PTR_ERR(sym);
130 
131 	sub_len = le16_to_cpu(sym->SubstituteNameLength);
132 	sub_offs = le16_to_cpu(sym->SubstituteNameOffset);
133 	print_len = le16_to_cpu(sym->PrintNameLength);
134 	print_offs = le16_to_cpu(sym->PrintNameOffset);
135 
136 	if ((char *)sym->PathBuffer + sub_offs + sub_len >
137 		(char *)iov->iov_base + iov->iov_len ||
138 	    (char *)sym->PathBuffer + print_offs + print_len >
139 		(char *)iov->iov_base + iov->iov_len)
140 		return -EINVAL;
141 
142 	return smb2_parse_native_symlink(path,
143 					 (char *)sym->PathBuffer + sub_offs,
144 					 sub_len,
145 					 le32_to_cpu(sym->Flags) & SYMLINK_FLAG_RELATIVE,
146 					 full_path,
147 					 cifs_sb);
148 }
149 
smb2_open_file(const unsigned int xid,struct cifs_open_parms * oparms,__u32 * oplock,void * buf)150 int smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
151 		   __u32 *oplock, void *buf)
152 {
153 	int rc;
154 	__le16 *smb2_path;
155 	__u8 smb2_oplock;
156 	struct cifs_open_info_data *data = buf;
157 	struct smb2_file_all_info file_info = {};
158 	struct smb2_file_all_info *smb2_data = data ? &file_info : NULL;
159 	struct kvec err_iov = {};
160 	int err_buftype = CIFS_NO_BUFFER;
161 	struct cifs_fid *fid = oparms->fid;
162 	struct network_resiliency_req nr_ioctl_req;
163 	bool retry_without_read_attributes = false;
164 
165 	smb2_path = cifs_convert_path_to_utf16(oparms->path, oparms->cifs_sb);
166 	if (smb2_path == NULL)
167 		return -ENOMEM;
168 
169 	/*
170 	 * GENERIC_READ, GENERIC_EXECUTE, GENERIC_ALL and MAXIMUM_ALLOWED
171 	 * contains also FILE_READ_ATTRIBUTES access right. So do not append
172 	 * FILE_READ_ATTRIBUTES when not needed and prevent calling code path
173 	 * for retry_without_read_attributes.
174 	 */
175 	if (!(oparms->desired_access & FILE_READ_ATTRIBUTES) &&
176 	    !(oparms->desired_access & GENERIC_READ) &&
177 	    !(oparms->desired_access & GENERIC_EXECUTE) &&
178 	    !(oparms->desired_access & GENERIC_ALL) &&
179 	    !(oparms->desired_access & MAXIMUM_ALLOWED)) {
180 		oparms->desired_access |= FILE_READ_ATTRIBUTES;
181 		retry_without_read_attributes = true;
182 	}
183 	smb2_oplock = SMB2_OPLOCK_LEVEL_BATCH;
184 
185 	rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov,
186 		       &err_buftype);
187 	if (rc == -EACCES && retry_without_read_attributes) {
188 		free_rsp_buf(err_buftype, err_iov.iov_base);
189 		memset(&err_iov, 0, sizeof(err_iov));
190 		err_buftype = CIFS_NO_BUFFER;
191 		oparms->desired_access &= ~FILE_READ_ATTRIBUTES;
192 		rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data, NULL, &err_iov,
193 			       &err_buftype);
194 	}
195 	if (rc && data) {
196 		struct smb2_hdr *hdr = err_iov.iov_base;
197 
198 		if (unlikely(!err_iov.iov_base || err_buftype == CIFS_NO_BUFFER))
199 			goto out;
200 		if (hdr->Status == STATUS_STOPPED_ON_SYMLINK) {
201 			rc = smb2_parse_symlink_response(oparms->cifs_sb, &err_iov,
202 							 oparms->path,
203 							 &data->symlink_target);
204 			if (!rc) {
205 				memset(smb2_data, 0, sizeof(*smb2_data));
206 				oparms->create_options |= OPEN_REPARSE_POINT;
207 				rc = SMB2_open(xid, oparms, smb2_path, &smb2_oplock, smb2_data,
208 					       NULL, NULL, NULL);
209 				oparms->create_options &= ~OPEN_REPARSE_POINT;
210 			}
211 			if (!rc) {
212 				bool directory = le32_to_cpu(data->fi.Attributes) & ATTR_DIRECTORY;
213 				rc = smb2_fix_symlink_target_type(&data->symlink_target,
214 								  directory, oparms->cifs_sb);
215 			}
216 		}
217 	}
218 
219 	if (rc)
220 		goto out;
221 
222 	if (oparms->tcon->use_resilient) {
223 		/* default timeout is 0, servers pick default (120 seconds) */
224 		nr_ioctl_req.Timeout =
225 			cpu_to_le32(oparms->tcon->handle_timeout);
226 		nr_ioctl_req.Reserved = 0;
227 		rc = SMB2_ioctl(xid, oparms->tcon, fid->persistent_fid,
228 			fid->volatile_fid, FSCTL_LMR_REQUEST_RESILIENCY,
229 			(char *)&nr_ioctl_req, sizeof(nr_ioctl_req),
230 			CIFSMaxBufSize, NULL, NULL /* no return info */);
231 		if (rc == -EOPNOTSUPP) {
232 			cifs_dbg(VFS,
233 			     "resiliency not supported by server, disabling\n");
234 			oparms->tcon->use_resilient = false;
235 		} else if (rc)
236 			cifs_dbg(FYI, "error %d setting resiliency\n", rc);
237 
238 		rc = 0;
239 	}
240 
241 	if (smb2_data) {
242 		/* if open response does not have IndexNumber field - get it */
243 		if (smb2_data->IndexNumber == 0) {
244 			rc = SMB2_get_srv_num(xid, oparms->tcon,
245 				      fid->persistent_fid,
246 				      fid->volatile_fid,
247 				      &smb2_data->IndexNumber);
248 			if (rc) {
249 				/*
250 				 * let get_inode_info disable server inode
251 				 * numbers
252 				 */
253 				smb2_data->IndexNumber = 0;
254 				rc = 0;
255 			}
256 		}
257 		memcpy(&data->fi, smb2_data, sizeof(data->fi));
258 	}
259 
260 	*oplock = smb2_oplock;
261 out:
262 	free_rsp_buf(err_buftype, err_iov.iov_base);
263 	kfree(smb2_path);
264 	return rc;
265 }
266 
267 int
smb2_unlock_range(struct cifsFileInfo * cfile,struct file_lock * flock,const unsigned int xid)268 smb2_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock,
269 		  const unsigned int xid)
270 {
271 	int rc = 0, stored_rc;
272 	unsigned int max_num, num = 0, max_buf;
273 	struct smb2_lock_element *buf, *cur;
274 	struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
275 	struct cifsInodeInfo *cinode = CIFS_I(d_inode(cfile->dentry));
276 	struct cifsLockInfo *li, *tmp;
277 	__u64 length = 1 + flock->fl_end - flock->fl_start;
278 	LIST_HEAD(tmp_llist);
279 
280 	/*
281 	 * Accessing maxBuf is racy with cifs_reconnect - need to store value
282 	 * and check it before using.
283 	 */
284 	max_buf = tcon->ses->server->maxBuf;
285 	if (max_buf < sizeof(struct smb2_lock_element))
286 		return -EINVAL;
287 
288 	BUILD_BUG_ON(sizeof(struct smb2_lock_element) > PAGE_SIZE);
289 	max_buf = min_t(unsigned int, max_buf, PAGE_SIZE);
290 	max_num = max_buf / sizeof(struct smb2_lock_element);
291 	buf = kzalloc_objs(struct smb2_lock_element, max_num);
292 	if (!buf)
293 		return -ENOMEM;
294 
295 	cur = buf;
296 
297 	cifs_down_write(&cinode->lock_sem);
298 	list_for_each_entry_safe(li, tmp, &cfile->llist->locks, llist) {
299 		if (flock->fl_start > li->offset ||
300 		    (flock->fl_start + length) <
301 		    (li->offset + li->length))
302 			continue;
303 		if (current->tgid != li->pid)
304 			/*
305 			 * flock and OFD lock are associated with an open
306 			 * file description, not the process.
307 			 */
308 			if (!(flock->c.flc_flags & (FL_FLOCK | FL_OFDLCK)))
309 				continue;
310 		if (cinode->can_cache_brlcks) {
311 			/*
312 			 * We can cache brlock requests - simply remove a lock
313 			 * from the file's list.
314 			 */
315 			list_del(&li->llist);
316 			cifs_del_lock_waiters(li);
317 			kfree(li);
318 			continue;
319 		}
320 		cur->Length = cpu_to_le64(li->length);
321 		cur->Offset = cpu_to_le64(li->offset);
322 		cur->Flags = cpu_to_le32(SMB2_LOCKFLAG_UNLOCK);
323 		/*
324 		 * We need to save a lock here to let us add it again to the
325 		 * file's list if the unlock range request fails on the server.
326 		 */
327 		list_move(&li->llist, &tmp_llist);
328 		if (++num == max_num) {
329 			stored_rc = smb2_lockv(xid, tcon,
330 					       cfile->fid.persistent_fid,
331 					       cfile->fid.volatile_fid,
332 					       current->tgid, num, buf);
333 			if (stored_rc) {
334 				/*
335 				 * We failed on the unlock range request - add
336 				 * all locks from the tmp list to the head of
337 				 * the file's list.
338 				 */
339 				cifs_move_llist(&tmp_llist,
340 						&cfile->llist->locks);
341 				rc = stored_rc;
342 			} else
343 				/*
344 				 * The unlock range request succeed - free the
345 				 * tmp list.
346 				 */
347 				cifs_free_llist(&tmp_llist);
348 			cur = buf;
349 			num = 0;
350 		} else
351 			cur++;
352 	}
353 	if (num) {
354 		stored_rc = smb2_lockv(xid, tcon, cfile->fid.persistent_fid,
355 				       cfile->fid.volatile_fid, current->tgid,
356 				       num, buf);
357 		if (stored_rc) {
358 			cifs_move_llist(&tmp_llist, &cfile->llist->locks);
359 			rc = stored_rc;
360 		} else
361 			cifs_free_llist(&tmp_llist);
362 	}
363 	up_write(&cinode->lock_sem);
364 
365 	kfree(buf);
366 	return rc;
367 }
368 
369 static int
smb2_push_mand_fdlocks(struct cifs_fid_locks * fdlocks,const unsigned int xid,struct smb2_lock_element * buf,unsigned int max_num)370 smb2_push_mand_fdlocks(struct cifs_fid_locks *fdlocks, const unsigned int xid,
371 		       struct smb2_lock_element *buf, unsigned int max_num)
372 {
373 	int rc = 0, stored_rc;
374 	struct cifsFileInfo *cfile = fdlocks->cfile;
375 	struct cifsLockInfo *li;
376 	unsigned int num = 0;
377 	struct smb2_lock_element *cur = buf;
378 	struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
379 
380 	list_for_each_entry(li, &fdlocks->locks, llist) {
381 		cur->Length = cpu_to_le64(li->length);
382 		cur->Offset = cpu_to_le64(li->offset);
383 		cur->Flags = cpu_to_le32(li->type |
384 						SMB2_LOCKFLAG_FAIL_IMMEDIATELY);
385 		if (++num == max_num) {
386 			stored_rc = smb2_lockv(xid, tcon,
387 					       cfile->fid.persistent_fid,
388 					       cfile->fid.volatile_fid,
389 					       current->tgid, num, buf);
390 			if (stored_rc)
391 				rc = stored_rc;
392 			cur = buf;
393 			num = 0;
394 		} else
395 			cur++;
396 	}
397 	if (num) {
398 		stored_rc = smb2_lockv(xid, tcon,
399 				       cfile->fid.persistent_fid,
400 				       cfile->fid.volatile_fid,
401 				       current->tgid, num, buf);
402 		if (stored_rc)
403 			rc = stored_rc;
404 	}
405 
406 	return rc;
407 }
408 
409 int
smb2_push_mandatory_locks(struct cifsFileInfo * cfile)410 smb2_push_mandatory_locks(struct cifsFileInfo *cfile)
411 {
412 	int rc = 0, stored_rc;
413 	unsigned int xid;
414 	unsigned int max_num, max_buf;
415 	struct smb2_lock_element *buf;
416 	struct cifsInodeInfo *cinode = CIFS_I(d_inode(cfile->dentry));
417 	struct cifs_fid_locks *fdlocks;
418 
419 	xid = get_xid();
420 
421 	/*
422 	 * Accessing maxBuf is racy with cifs_reconnect - need to store value
423 	 * and check it for zero before using.
424 	 */
425 	max_buf = tlink_tcon(cfile->tlink)->ses->server->maxBuf;
426 	if (max_buf < sizeof(struct smb2_lock_element)) {
427 		free_xid(xid);
428 		return -EINVAL;
429 	}
430 
431 	BUILD_BUG_ON(sizeof(struct smb2_lock_element) > PAGE_SIZE);
432 	max_buf = min_t(unsigned int, max_buf, PAGE_SIZE);
433 	max_num = max_buf / sizeof(struct smb2_lock_element);
434 	buf = kzalloc_objs(struct smb2_lock_element, max_num);
435 	if (!buf) {
436 		free_xid(xid);
437 		return -ENOMEM;
438 	}
439 
440 	list_for_each_entry(fdlocks, &cinode->llist, llist) {
441 		stored_rc = smb2_push_mand_fdlocks(fdlocks, xid, buf, max_num);
442 		if (stored_rc)
443 			rc = stored_rc;
444 	}
445 
446 	kfree(buf);
447 	free_xid(xid);
448 	return rc;
449 }
450