Commit 504a73d4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag '6.2-rc-ksmbd-server-fixes' of git://git.samba.org/ksmbd

Pull ksmbd updates from Steve French:
 "Six ksmbd server fixes"

* tag '6.2-rc-ksmbd-server-fixes' of git://git.samba.org/ksmbd:
  ksmbd: Convert to use sysfs_emit()/sysfs_emit_at() APIs
  ksmbd: Fix resource leak in smb2_lock()
  ksmbd: Fix resource leak in ksmbd_session_rpc_open()
  ksmbd: replace one-element arrays with flexible-array members
  ksmbd: use F_SETLK when unlocking a file
  ksmbd: set SMB2_SESSION_FLAG_ENCRYPT_DATA when enforcing data encryption for this share
parents 041fae9c 72ee45fd
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ struct ksmbd_heartbeat {
#define KSMBD_GLOBAL_FLAG_SMB2_LEASES		BIT(0)
#define KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION	BIT(1)
#define KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL	BIT(2)
#define KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF	BIT(3)

/*
 * IPC request for ksmbd server startup
+5 −3
Original line number Diff line number Diff line
@@ -108,15 +108,17 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name)
	entry->method = method;
	entry->id = ksmbd_ipc_id_alloc();
	if (entry->id < 0)
		goto error;
		goto free_entry;

	resp = ksmbd_rpc_open(sess, entry->id);
	if (!resp)
		goto error;
		goto free_id;

	kvfree(resp);
	return entry->id;
error:
free_id:
	ksmbd_rpc_id_free(entry->id);
free_entry:
	list_del(&entry->list);
	kfree(entry);
	return -EINVAL;
+6 −14
Original line number Diff line number Diff line
@@ -432,11 +432,9 @@ static ssize_t stats_show(struct class *class, struct class_attribute *attr,
		"reset",
		"shutdown"
	};

	ssize_t sz = scnprintf(buf, PAGE_SIZE, "%d %s %d %lu\n", stats_version,
	return sysfs_emit(buf, "%d %s %d %lu\n", stats_version,
			  state[server_conf.state], server_conf.tcp_port,
			  server_conf.ipc_last_active / HZ);
	return sz;
}

static ssize_t kill_server_store(struct class *class,
@@ -468,19 +466,13 @@ static ssize_t debug_show(struct class *class, struct class_attribute *attr,

	for (i = 0; i < ARRAY_SIZE(debug_type_strings); i++) {
		if ((ksmbd_debug_types >> i) & 1) {
			pos = scnprintf(buf + sz,
					PAGE_SIZE - sz,
					"[%s] ",
					debug_type_strings[i]);
			pos = sysfs_emit_at(buf, sz, "[%s] ", debug_type_strings[i]);
		} else {
			pos = scnprintf(buf + sz,
					PAGE_SIZE - sz,
					"%s ",
					debug_type_strings[i]);
			pos = sysfs_emit_at(buf, sz, "%s ", debug_type_strings[i]);
		}
		sz += pos;
	}
	sz += scnprintf(buf + sz, PAGE_SIZE - sz, "\n");
	sz += sysfs_emit_at(buf, sz, "\n");
	return sz;
}

+8 −2
Original line number Diff line number Diff line
@@ -247,8 +247,9 @@ void init_smb3_02_server(struct ksmbd_conn *conn)
	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
		conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING;

	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION &&
	    conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION)
	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION ||
	    (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) &&
	     conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION))
		conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;

	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
@@ -271,6 +272,11 @@ int init_smb3_11_server(struct ksmbd_conn *conn)
	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
		conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING;

	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION ||
	    (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) &&
	     conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION))
		conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;

	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
		conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;

+11 −5
Original line number Diff line number Diff line
@@ -903,7 +903,7 @@ static void decode_encrypt_ctxt(struct ksmbd_conn *conn,
		return;
	}

	if (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION))
	if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF)
		return;

	for (i = 0; i < cph_cnt; i++) {
@@ -1508,6 +1508,7 @@ static int ntlm_authenticate(struct ksmbd_work *work)
			return -EINVAL;
		}
		sess->enc = true;
		if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION)
			rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE;
		/*
		 * signing is disable if encryption is enable
@@ -1599,6 +1600,7 @@ static int krb5_authenticate(struct ksmbd_work *work)
			return -EINVAL;
		}
		sess->enc = true;
		if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION)
			rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE;
		sess->sign = false;
	}
@@ -6751,7 +6753,7 @@ static int smb2_set_flock_flags(struct file_lock *flock, int flags)
	case SMB2_LOCKFLAG_UNLOCK:
		ksmbd_debug(SMB, "received unlock request\n");
		flock->fl_type = F_UNLCK;
		cmd = 0;
		cmd = F_SETLK;
		break;
	}

@@ -6855,6 +6857,7 @@ int smb2_lock(struct ksmbd_work *work)
		if (lock_start > U64_MAX - lock_length) {
			pr_err("Invalid lock range requested\n");
			rsp->hdr.Status = STATUS_INVALID_LOCK_RANGE;
			locks_free_lock(flock);
			goto out;
		}

@@ -6874,6 +6877,7 @@ int smb2_lock(struct ksmbd_work *work)
				    "the end offset(%llx) is smaller than the start offset(%llx)\n",
				    flock->fl_end, flock->fl_start);
			rsp->hdr.Status = STATUS_INVALID_LOCK_RANGE;
			locks_free_lock(flock);
			goto out;
		}

@@ -6885,6 +6889,7 @@ int smb2_lock(struct ksmbd_work *work)
				    flock->fl_type != F_UNLCK) {
					pr_err("conflict two locks in one request\n");
					err = -EINVAL;
					locks_free_lock(flock);
					goto out;
				}
			}
@@ -6893,6 +6898,7 @@ int smb2_lock(struct ksmbd_work *work)
		smb_lock = smb2_lock_init(flock, cmd, flags, &lock_list);
		if (!smb_lock) {
			err = -EINVAL;
			locks_free_lock(flock);
			goto out;
		}
	}
@@ -7129,7 +7135,7 @@ int smb2_lock(struct ksmbd_work *work)
		rlock->fl_start = smb_lock->start;
		rlock->fl_end = smb_lock->end;

		rc = vfs_lock_file(filp, 0, rlock, NULL);
		rc = vfs_lock_file(filp, F_SETLK, rlock, NULL);
		if (rc)
			pr_err("rollback unlock fail : %d\n", rc);