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
6 changes: 3 additions & 3 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1555,15 +1555,15 @@ static int amdgpu_cs_wait_all_fences(struct amdgpu_device *adev,
continue;

r = dma_fence_wait_timeout(fence, true, timeout);
if (r > 0 && fence->error)
r = fence->error;

dma_fence_put(fence);
if (r < 0)
return r;

if (r == 0)
break;

if (fence->error)
return fence->error;
}

memset(wait, 0, sizeof(*wait));
Expand Down
7 changes: 4 additions & 3 deletions drivers/tty/n_gsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2061,7 +2061,7 @@ static int gsm_disconnect(struct gsm_mux *gsm)
static void gsm_cleanup_mux(struct gsm_mux *gsm)
{
int i;
struct gsm_dlci *dlci = gsm->dlci[0];
struct gsm_dlci *dlci;
struct gsm_msg *txq, *ntxq;

gsm->dead = 1;
Expand All @@ -2079,12 +2079,13 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm)
return;

del_timer_sync(&gsm->t2_timer);
/* Free up any link layer users */
mutex_lock(&gsm->mutex);
dlci = gsm->dlci[0];
/* Now we are sure T2 has stopped */
if (dlci)
dlci->dead = 1;

/* Free up any link layer users */
mutex_lock(&gsm->mutex);
for (i = 0; i < NUM_DLCI; i++)
if (gsm->dlci[i])
gsm_dlci_release(gsm->dlci[i]);
Expand Down
14 changes: 8 additions & 6 deletions fs/cifs/smb2ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -4884,6 +4884,7 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
struct smb2_sync_hdr *shdr;
unsigned int pdu_length = server->pdu_size;
unsigned int buf_size;
unsigned int next_cmd;
struct mid_q_entry *mid_entry;
int next_is_large;
char *next_buffer = NULL;
Expand Down Expand Up @@ -4912,14 +4913,15 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
next_is_large = server->large_buf;
one_more:
shdr = (struct smb2_sync_hdr *)buf;
if (shdr->NextCommand) {
next_cmd = le32_to_cpu(shdr->NextCommand);
if (next_cmd) {
if (WARN_ON_ONCE(next_cmd > pdu_length))
return -1;
if (next_is_large)
next_buffer = (char *)cifs_buf_get();
else
next_buffer = (char *)cifs_small_buf_get();
memcpy(next_buffer,
buf + le32_to_cpu(shdr->NextCommand),
pdu_length - le32_to_cpu(shdr->NextCommand));
memcpy(next_buffer, buf + next_cmd, pdu_length - next_cmd);
}

mid_entry = smb2_find_mid(server, buf);
Expand All @@ -4943,8 +4945,8 @@ receive_encrypted_standard(struct TCP_Server_Info *server,
else
ret = cifs_handle_standard(server, mid_entry);

if (ret == 0 && shdr->NextCommand) {
pdu_length -= le32_to_cpu(shdr->NextCommand);
if (ret == 0 && next_cmd) {
pdu_length -= next_cmd;
server->large_buf = next_is_large;
if (next_is_large)
server->bigbuf = buf = next_buffer;
Expand Down
3 changes: 2 additions & 1 deletion fs/ext4/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1402,7 +1402,8 @@ static int ext4_write_end(struct file *file,
int inline_data = ext4_has_inline_data(inode);

trace_ext4_write_end(inode, pos, len, copied);
if (inline_data) {
if (inline_data &&
ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) {
ret = ext4_write_inline_data_end(inode, pos, len,
copied, page);
if (ret < 0) {
Expand Down
67 changes: 46 additions & 21 deletions kernel/events/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1850,28 +1850,31 @@ static inline void perf_event__state_init(struct perf_event *event)
PERF_EVENT_STATE_INACTIVE;
}

static void __perf_event_read_size(struct perf_event *event, int nr_siblings)
static int __perf_event_read_size(u64 read_format, int nr_siblings)
{
int entry = sizeof(u64); /* value */
int size = 0;
int nr = 1;

if (event->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
size += sizeof(u64);

if (event->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
size += sizeof(u64);

if (event->attr.read_format & PERF_FORMAT_ID)
if (read_format & PERF_FORMAT_ID)
entry += sizeof(u64);

if (event->attr.read_format & PERF_FORMAT_GROUP) {
if (read_format & PERF_FORMAT_GROUP) {
nr += nr_siblings;
size += sizeof(u64);
}

size += entry * nr;
event->read_size = size;
/*
* Since perf_event_validate_size() limits this to 16k and inhibits
* adding more siblings, this will never overflow.
*/
return size + nr * entry;
}

static void __perf_event_header_size(struct perf_event *event, u64 sample_type)
Expand Down Expand Up @@ -1921,8 +1924,9 @@ static void __perf_event_header_size(struct perf_event *event, u64 sample_type)
*/
static void perf_event__header_size(struct perf_event *event)
{
__perf_event_read_size(event,
event->group_leader->nr_siblings);
event->read_size =
__perf_event_read_size(event->attr.read_format,
event->group_leader->nr_siblings);
__perf_event_header_size(event, event->attr.sample_type);
}

Expand Down Expand Up @@ -1953,23 +1957,44 @@ static void perf_event__id_header_size(struct perf_event *event)
event->id_header_size = size;
}

/*
* Check that adding an event to the group does not result in anybody
* overflowing the 64k event limit imposed by the output buffer.
*
* Specifically, check that the read_size for the event does not exceed 16k,
* read_size being the one term that grows with groups size. Since read_size
* depends on per-event read_format, also (re)check the existing events.
*
* This leaves 48k for the constant size fields and things like callchains,
* branch stacks and register sets.
*/
static bool perf_event_validate_size(struct perf_event *event)
{
/*
* The values computed here will be over-written when we actually
* attach the event.
*/
__perf_event_read_size(event, event->group_leader->nr_siblings + 1);
__perf_event_header_size(event, event->attr.sample_type & ~PERF_SAMPLE_READ);
perf_event__id_header_size(event);
struct perf_event *sibling, *group_leader = event->group_leader;

if (__perf_event_read_size(event->attr.read_format,
group_leader->nr_siblings + 1) > 16*1024)
return false;

if (__perf_event_read_size(group_leader->attr.read_format,
group_leader->nr_siblings + 1) > 16*1024)
return false;

/*
* Sum the lot; should not exceed the 64k limit we have on records.
* Conservative limit to allow for callchains and other variable fields.
* When creating a new group leader, group_leader->ctx is initialized
* after the size has been validated, but we cannot safely use
* for_each_sibling_event() until group_leader->ctx is set. A new group
* leader cannot have any siblings yet, so we can safely skip checking
* the non-existent siblings.
*/
if (event->read_size + event->header_size +
event->id_header_size + sizeof(struct perf_event_header) >= 16*1024)
return false;
if (event == group_leader)
return true;

for_each_sibling_event(sibling, group_leader) {
if (__perf_event_read_size(sibling->attr.read_format,
group_leader->nr_siblings + 1) > 16*1024)
return false;
}

return true;
}
Expand Down
16 changes: 6 additions & 10 deletions net/netfilter/nf_tables_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -8507,16 +8507,10 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
data->verdict.code = ntohl(nla_get_be32(tb[NFTA_VERDICT_CODE]));

switch (data->verdict.code) {
default:
switch (data->verdict.code & NF_VERDICT_MASK) {
case NF_ACCEPT:
case NF_DROP:
case NF_QUEUE:
break;
default:
return -EINVAL;
}
/* fall through */
case NF_ACCEPT:
case NF_DROP:
case NF_QUEUE:
break;
case NFT_CONTINUE:
case NFT_BREAK:
case NFT_RETURN:
Expand All @@ -8535,6 +8529,8 @@ static int nft_verdict_init(const struct nft_ctx *ctx, struct nft_data *data,
chain->use++;
data->verdict.chain = chain;
break;
default:
return -EINVAL;
}

desc->len = sizeof(data->verdict);
Expand Down