Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .container_build_image
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lts-9.4-kernel-builder
11 changes: 11 additions & 0 deletions .github/workflows/kernel-build-and-test-x86_64.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: Automated kernel build and test (x86_64)

on:
push:
branches:
- '*_ciqlts9_4'

jobs:
build:
uses: ctrliq/kernel-src-tree/.github/workflows/kernel-build-and-test-x86_64.yml@main
secrets: inherit
4 changes: 2 additions & 2 deletions drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2386,7 +2386,7 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg)
}

if (vf->adq_enabled) {
if (idx >= ARRAY_SIZE(vf->ch)) {
if (idx >= vf->num_tc) {
aq_ret = -ENODEV;
goto error_param;
}
Expand All @@ -2407,7 +2407,7 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg)
* to its appropriate VSIs based on TC mapping
*/
if (vf->adq_enabled) {
if (idx >= ARRAY_SIZE(vf->ch)) {
if (idx >= vf->num_tc) {
aq_ret = -ENODEV;
goto error_param;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/usb/dwc3/ep0.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,
req->request.actual = 0;
req->request.status = -EINPROGRESS;
req->epnum = dep->number;
req->status = DWC3_REQUEST_STATUS_QUEUED;

list_add_tail(&req->list, &dep->pending_list);

Expand Down
7 changes: 7 additions & 0 deletions drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,13 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
{
struct dwc3 *dwc = dep->dwc;

/*
* The request might have been processed and completed while the
* spinlock was released. Skip processing if already completed.
*/
if (req->status == DWC3_REQUEST_STATUS_COMPLETED)
return;

dwc3_gadget_del_and_unmap_request(dep, req, status);
req->status = DWC3_REQUEST_STATUS_COMPLETED;

Expand Down
20 changes: 15 additions & 5 deletions fs/nfsd/nfs4state.c
Original file line number Diff line number Diff line change
Expand Up @@ -4293,10 +4293,16 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
}
status = nfs_ok;
if (conf) {
old = unconf;
unhash_client_locked(old);
nfsd4_change_callback(conf, &unconf->cl_cb_conn);
} else {
if (get_client_locked(conf) == nfs_ok) {
old = unconf;
unhash_client_locked(old);
nfsd4_change_callback(conf, &unconf->cl_cb_conn);
} else {
conf = NULL;
}
}

if (!conf) {
old = find_confirmed_client_by_name(&unconf->cl_name, nn);
if (old) {
status = nfserr_clid_inuse;
Expand All @@ -4313,10 +4319,14 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
}
trace_nfsd_clid_replaced(&old->cl_clientid);
}
status = get_client_locked(unconf);
if (status != nfs_ok) {
old = NULL;
goto out;
}
move_to_confirmed(unconf);
conf = unconf;
}
get_client_locked(conf);
spin_unlock(&nn->client_lock);
if (conf == unconf)
fsnotify_dentry(conf->cl_nfsd_info_dentry, FS_MODIFY);
Expand Down
18 changes: 18 additions & 0 deletions fs/smb/client/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -2146,6 +2146,7 @@ cifs_rename2(struct user_namespace *mnt_userns, struct inode *source_dir,
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
struct cifs_tcon *tcon;
bool rehash = false;
unsigned int xid;
int rc, tmprc;
int retry_count = 0;
Expand All @@ -2161,6 +2162,17 @@ cifs_rename2(struct user_namespace *mnt_userns, struct inode *source_dir,
if (unlikely(cifs_forced_shutdown(cifs_sb)))
return -EIO;

/*
* Prevent any concurrent opens on the target by unhashing the dentry.
* VFS already unhashes the target when renaming directories.
*/
if (d_is_positive(target_dentry) && !d_is_dir(target_dentry)) {
if (!d_unhashed(target_dentry)) {
d_drop(target_dentry);
rehash = true;
}
}

tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
return PTR_ERR(tlink);
Expand Down Expand Up @@ -2200,6 +2212,8 @@ cifs_rename2(struct user_namespace *mnt_userns, struct inode *source_dir,
}
}

if (!rc)
rehash = false;
/*
* No-replace is the natural behavior for CIFS, so skip unlink hacks.
*/
Expand Down Expand Up @@ -2258,6 +2272,8 @@ cifs_rename2(struct user_namespace *mnt_userns, struct inode *source_dir,
goto cifs_rename_exit;
rc = cifs_do_rename(xid, source_dentry, from_name,
target_dentry, to_name);
if (!rc)
rehash = false;
}

/* force revalidate to go get info when needed */
Expand All @@ -2267,6 +2283,8 @@ cifs_rename2(struct user_namespace *mnt_userns, struct inode *source_dir,
target_dir->i_mtime = current_time(source_dir);

cifs_rename_exit:
if (rehash)
d_rehash(target_dentry);
kfree(info_buf_source);
free_dentry_path(page2);
free_dentry_path(page1);
Expand Down
21 changes: 21 additions & 0 deletions include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1186,6 +1186,27 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
return NULL;
}

static inline struct hci_conn *hci_conn_hash_lookup_role(struct hci_dev *hdev,
__u8 type, __u8 role,
bdaddr_t *ba)
{
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;

rcu_read_lock();

list_for_each_entry_rcu(c, &h->list, list) {
if (c->type == type && c->role == role && !bacmp(&c->dst, ba)) {
rcu_read_unlock();
return c;
}
}

rcu_read_unlock();

return NULL;
}

static inline struct hci_conn *hci_conn_hash_lookup_le(struct hci_dev *hdev,
bdaddr_t *ba,
__u8 ba_type)
Expand Down
3 changes: 2 additions & 1 deletion include/net/sctp/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,7 @@ struct sctp_transport {

/* Reference counting. */
refcount_t refcnt;
__u32 dead:1,
/* RTO-Pending : A flag used to track if one of the DATA
* chunks sent to this address is currently being
* used to compute a RTT. If this flag is 0,
Expand All @@ -787,7 +788,7 @@ struct sctp_transport {
* calculation completes (i.e. the DATA chunk
* is SACK'd) clear this flag.
*/
__u32 rto_pending:1,
rto_pending:1,

/*
* hb_sent : a flag that signals that we have a pending
Expand Down
26 changes: 23 additions & 3 deletions net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -3144,8 +3144,18 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,

hci_dev_lock(hdev);

/* Check for existing connection:
*
* 1. If it doesn't exist then it must be receiver/slave role.
* 2. If it does exist confirm that it is connecting/BT_CONNECT in case
* of initiator/master role since there could be a collision where
* either side is attempting to connect or something like a fuzzing
* testing is trying to play tricks to destroy the hcon object before
* it even attempts to connect (e.g. hcon->state == BT_OPEN).
*/
conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
if (!conn) {
if (!conn ||
(conn->role == HCI_ROLE_MASTER && conn->state != BT_CONNECT)) {
/* In case of error status and there is no connection pending
* just unlock as there is nothing to cleanup.
*/
Expand Down Expand Up @@ -5877,8 +5887,18 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
*/
hci_dev_clear_flag(hdev, HCI_LE_ADV);

conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, bdaddr);
if (!conn) {
/* Check for existing connection:
*
* 1. If it doesn't exist then use the role to create a new object.
* 2. If it does exist confirm that it is connecting/BT_CONNECT in case
* of initiator/master role since there could be a collision where
* either side is attempting to connect or something like a fuzzing
* testing is trying to play tricks to destroy the hcon object before
* it even attempts to connect (e.g. hcon->state == BT_OPEN).
*/
conn = hci_conn_hash_lookup_role(hdev, LE_LINK, role, bdaddr);
if (!conn ||
(conn->role == HCI_ROLE_MASTER && conn->state != BT_CONNECT)) {
/* In case of error status and there is no connection pending
* just unlock as there is nothing to cleanup.
*/
Expand Down
7 changes: 7 additions & 0 deletions net/bluetooth/iso.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,13 @@ static void iso_sock_kill(struct sock *sk)

BT_DBG("sk %p state %d", sk, sk->sk_state);

/* Sock is dead, so set conn->sk to NULL to avoid possible UAF */
if (iso_pi(sk)->conn) {
iso_conn_lock(iso_pi(sk)->conn);
iso_pi(sk)->conn->sk = NULL;
iso_conn_unlock(iso_pi(sk)->conn);
}

/* Kill poor orphan */
bt_sock_unlink(&iso_sk_list, sk);
sock_set_flag(sk, SOCK_DEAD);
Expand Down
53 changes: 32 additions & 21 deletions net/ceph/ceph_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -785,42 +785,53 @@ void ceph_reset_client_addr(struct ceph_client *client)
}
EXPORT_SYMBOL(ceph_reset_client_addr);

/*
* true if we have the mon map (and have thus joined the cluster)
*/
static bool have_mon_and_osd_map(struct ceph_client *client)
{
return client->monc.monmap && client->monc.monmap->epoch &&
client->osdc.osdmap && client->osdc.osdmap->epoch;
}

/*
* mount: join the ceph cluster, and open root directory.
*/
int __ceph_open_session(struct ceph_client *client, unsigned long started)
{
unsigned long timeout = client->options->mount_timeout;
long err;
DEFINE_WAIT_FUNC(wait, woken_wake_function);
long timeout = ceph_timeout_jiffies(client->options->mount_timeout);
bool have_monmap, have_osdmap;
int err;

/* open session, and wait for mon and osd maps */
err = ceph_monc_open_session(&client->monc);
if (err < 0)
return err;

while (!have_mon_and_osd_map(client)) {
if (timeout && time_after_eq(jiffies, started + timeout))
return -ETIMEDOUT;
add_wait_queue(&client->auth_wq, &wait);
for (;;) {
mutex_lock(&client->monc.mutex);
err = client->auth_err;
have_monmap = client->monc.monmap && client->monc.monmap->epoch;
mutex_unlock(&client->monc.mutex);

down_read(&client->osdc.lock);
have_osdmap = client->osdc.osdmap && client->osdc.osdmap->epoch;
up_read(&client->osdc.lock);

if (err || (have_monmap && have_osdmap))
break;

if (signal_pending(current)) {
err = -ERESTARTSYS;
break;
}

if (!timeout) {
err = -ETIMEDOUT;
break;
}

/* wait */
dout("mount waiting for mon_map\n");
err = wait_event_interruptible_timeout(client->auth_wq,
have_mon_and_osd_map(client) || (client->auth_err < 0),
ceph_timeout_jiffies(timeout));
if (err < 0)
return err;
if (client->auth_err < 0)
return client->auth_err;
timeout = wait_woken(&wait, TASK_INTERRUPTIBLE, timeout);
}
remove_wait_queue(&client->auth_wq, &wait);

if (err)
return err;

pr_info("client%llu fsid %pU\n", ceph_client_gid(client),
&client->fsid);
Expand Down
14 changes: 10 additions & 4 deletions net/ceph/debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ static int monmap_show(struct seq_file *s, void *p)
int i;
struct ceph_client *client = s->private;

mutex_lock(&client->monc.mutex);
if (client->monc.monmap == NULL)
return 0;
goto out_unlock;

seq_printf(s, "epoch %d\n", client->monc.monmap->epoch);
for (i = 0; i < client->monc.monmap->num_mon; i++) {
Expand All @@ -48,6 +49,9 @@ static int monmap_show(struct seq_file *s, void *p)
ENTITY_NAME(inst->name),
ceph_pr_addr(&inst->addr));
}

out_unlock:
mutex_unlock(&client->monc.mutex);
return 0;
}

Expand All @@ -56,13 +60,14 @@ static int osdmap_show(struct seq_file *s, void *p)
int i;
struct ceph_client *client = s->private;
struct ceph_osd_client *osdc = &client->osdc;
struct ceph_osdmap *map = osdc->osdmap;
struct ceph_osdmap *map;
struct rb_node *n;

down_read(&osdc->lock);
map = osdc->osdmap;
if (map == NULL)
return 0;
goto out_unlock;

down_read(&osdc->lock);
seq_printf(s, "epoch %u barrier %u flags 0x%x\n", map->epoch,
osdc->epoch_barrier, map->flags);

Expand Down Expand Up @@ -131,6 +136,7 @@ static int osdmap_show(struct seq_file *s, void *p)
seq_printf(s, "]\n");
}

out_unlock:
up_read(&osdc->lock);
return 0;
}
Expand Down
Loading
Loading