diff --git a/.config b/.config index 64764e63..7dbd43e2 100644 --- a/.config +++ b/.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.9-prep -# Sun Jan 23 12:43:24 2011 +# Sun Jan 23 12:41:46 2011 # CONFIG_X86_64=y CONFIG_64BIT=y diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c index f696ef57..689ff6ad 100644 --- a/arch/x86_64/kernel/signal.c +++ b/arch/x86_64/kernel/signal.c @@ -29,6 +29,7 @@ #include #include #include +#include /* #define DEBUG_SIG 1 */ @@ -99,8 +100,12 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, unsigned #define COPY(x) err |= __get_user(regs->x, &sc->x) - COPY(rdi); COPY(rsi); COPY(rbp); COPY(rsp); COPY(rbx); - COPY(rdx); COPY(rcx); COPY(rip); + COPY(rdi); COPY(rsi); COPY(rbp); COPY(rsp); + if (unlikely(regs->rsp >= TASK_SIZE)) + regs->rsp = 0UL; + COPY(rbx); COPY(rdx); COPY(rcx); COPY(rip); + if (unlikely(regs->rip >= TASK_SIZE && regs->rip < VSYSCALL_START)) + regs->rip = 0UL; COPY(r8); COPY(r9); COPY(r10); @@ -325,9 +330,11 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, next argument after the signal number on the stack. */ regs->rsi = (unsigned long)&frame->info; regs->rdx = (unsigned long)&frame->uc; - regs->rip = (unsigned long) ka->sa.sa_handler; - regs->rsp = (unsigned long)frame; + if (unlikely((unsigned long)ka->sa.sa_handler >= TASK_SIZE)) + regs->rip = 0UL; + else + regs->rip = (unsigned long)ka->sa.sa_handler; set_fs(USER_DS); if (regs->eflags & TF_MASK) { diff --git a/configs/kernel-2.6.9-x86_64-largesmp.config b/configs/kernel-2.6.9-x86_64-largesmp.config index 4b90ccdc..0dee49e1 100644 --- a/configs/kernel-2.6.9-x86_64-largesmp.config +++ b/configs/kernel-2.6.9-x86_64-largesmp.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.9-prep -# Sun Jan 23 12:43:24 2011 +# Sun Jan 23 12:41:46 2011 # CONFIG_X86_64=y CONFIG_64BIT=y diff --git a/configs/kernel-2.6.9-x86_64-smp.config b/configs/kernel-2.6.9-x86_64-smp.config index 25e3bf9c..fcc91ba0 100644 --- a/configs/kernel-2.6.9-x86_64-smp.config +++ b/configs/kernel-2.6.9-x86_64-smp.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.9-prep -# Sun Jan 23 12:43:24 2011 +# Sun Jan 23 12:41:46 2011 # CONFIG_X86_64=y CONFIG_64BIT=y diff --git a/configs/kernel-2.6.9-x86_64.config b/configs/kernel-2.6.9-x86_64.config index 64764e63..7dbd43e2 100644 --- a/configs/kernel-2.6.9-x86_64.config +++ b/configs/kernel-2.6.9-x86_64.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Linux kernel version: 2.6.9-prep -# Sun Jan 23 12:43:24 2011 +# Sun Jan 23 12:41:46 2011 # CONFIG_X86_64=y CONFIG_64BIT=y diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 4362ba3b..8849ce43 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1734,7 +1734,7 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, up_read(¤t->mm->mmap_sem); /* Errors and no page mapped should return here */ - if (res < nr_pages) + if ((res < 0) || (res < nr_pages)) goto out_unmap; for (i=0; i < nr_pages; i++) { diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 25212205..7319a2b9 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -4312,7 +4312,7 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa up_read(¤t->mm->mmap_sem); /* Errors and no page mapped should return here */ - if (res < nr_pages) + if ((res < 0) || (res < nr_pages)) goto out_unmap; for (i=0; i < nr_pages; i++) { diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index daca5e0b..08f2f514 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -81,7 +81,7 @@ static struct linux_binfmt elf_format = { .min_coredump = ELF_EXEC_PAGESIZE }; -#define BAD_ADDR(x) ((unsigned long)(x) > TASK_SIZE) +#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE) static int set_brk(unsigned long start, unsigned long end) { @@ -409,7 +409,7 @@ static unsigned long load_elf_interp(struct elfhdr * interp_elf_ex, * <= p_memsize so it is only necessary to check p_memsz. */ k = load_addr + eppnt->p_vaddr; - if (k > TASK_SIZE || eppnt->p_filesz > eppnt->p_memsz || + if (BAD_ADDR(k) || eppnt->p_filesz > eppnt->p_memsz || eppnt->p_memsz > TASK_SIZE || TASK_SIZE - eppnt->p_memsz < k) { error = -ENOMEM; goto out_close; @@ -885,7 +885,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) * allowed task size. Note that p_filesz must always be * <= p_memsz so it is only necessary to check p_memsz. */ - if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz || + if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz || elf_ppnt->p_memsz > TASK_SIZE || TASK_SIZE - elf_ppnt->p_memsz < k) { /* set_brk can never work. Avoid overflows. */ @@ -936,9 +936,9 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) &interp_load_addr, load_bias); if (BAD_ADDR(elf_entry)) { - printk(KERN_ERR "Unable to load interpreter\n"); - send_sig(SIGSEGV, current, 0); - retval = -ENOEXEC; /* Nobody gets to see this, but.. */ + force_sig(SIGSEGV, current); + retval = IS_ERR((void *)elf_entry) ? + (int)elf_entry : -EINVAL; goto out_free_dentry; } reloc_func_desc = interp_load_addr; @@ -948,6 +948,11 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) kfree(elf_interpreter); } else { elf_entry = loc->elf_ex.e_entry; + if (BAD_ADDR(elf_entry)) { + force_sig(SIGSEGV, current); + retval = -EINVAL; + goto out_free_dentry; + } } kfree(elf_phdata); diff --git a/fs/compat.c b/fs/compat.c index e90b4dfd..849576f8 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -1213,6 +1213,10 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, if (ret) goto out; + ret = security_file_permission(file, type == READ ? MAY_READ:MAY_WRITE); + if (ret) + goto out; + fnv = NULL; if (type == READ) { fn = file->f_op->read; diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index f0d4964f..09a3796b 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -57,6 +57,7 @@ #define NFSDBG_FACILITY NFSDBG_VFS +static void nfs_free_user_pages(struct page **pages, int npages, int do_dirty); static kmem_cache_t *nfs_direct_cachep; /* @@ -121,6 +122,15 @@ static inline int nfs_get_user_pages(int rw, unsigned long user_addr, size_t siz page_count, (rw == READ), 0, *pages, NULL); up_read(¤t->mm->mmap_sem); + /* + * If we got fewer pages than expected from get_user_pages(), + * the user buffer runs off the end of a mapping; return EFAULT. + */ + if (result >= 0 && result < page_count) { + nfs_free_user_pages(*pages, result, 0); + *pages = NULL; + result = -EFAULT; + } } return result; } diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 0310ae6c..bf06cf4d 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -55,9 +55,6 @@ int task_statm(struct mm_struct *mm, int *shared, int *text, static int show_map(struct seq_file *m, void *v) { -#ifdef __i386__ - struct task_struct *task = m->private; -#endif struct vm_area_struct *map = v; struct file *file = map->vm_file; int flags = map->vm_flags; @@ -78,8 +75,8 @@ static int show_map(struct seq_file *m, void *v) flags & VM_WRITE ? 'w' : '-', (flags & VM_EXEC #ifdef __i386__ - || (!nx_enabled && - (map->vm_start < task->mm->context.exec_limit)) + || (!nx_enabled && map->vm_mm && + (map->vm_start < map->vm_mm->context.exec_limit)) #endif ) ? 'x' : '-', diff --git a/fs/read_write.c b/fs/read_write.c index ca32594f..dac004d5 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -455,6 +455,10 @@ static ssize_t do_readv_writev(int type, struct file *file, if (ret) goto out; + ret = security_file_permission(file, type == READ ? MAY_READ:MAY_WRITE); + if (ret) + goto out; + fnv = NULL; if (type == READ) { fn = file->f_op->read; diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c index c6c33e15..6bf7f6f2 100644 --- a/fs/smbfs/dir.c +++ b/fs/smbfs/dir.c @@ -431,6 +431,11 @@ smb_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) if (dentry->d_name.len > SMB_MAXNAMELEN) goto out; + /* Do not allow lookup of names with backslashes in them */ + error = -EINVAL; + if (memchr(dentry->d_name.name, '\\', dentry->d_name.len)) + goto out; + lock_kernel(); error = smb_proc_getattr(dentry, &finfo); #ifdef SMBFS_PARANOIA diff --git a/include/linux/autoconf.h b/include/linux/autoconf.h index 20b9e6f0..521defd2 100644 --- a/include/linux/autoconf.h +++ b/include/linux/autoconf.h @@ -1,7 +1,7 @@ /* * Automatically generated C config: don't edit * Linux kernel version: 2.6.9-prep - * Sun Jan 23 12:43:24 2011 + * Sun Jan 23 12:41:46 2011 */ #define AUTOCONF_INCLUDED #define CONFIG_X86_64 1 diff --git a/kernel/exit.c b/kernel/exit.c index 98ec4c67..72537d73 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -522,8 +522,6 @@ static inline void choose_new_parent(task_t *p, task_t *reaper, task_t *child_re */ BUG_ON(p == reaper || reaper->state >= EXIT_ZOMBIE || reaper->exit_state >= EXIT_ZOMBIE); p->real_parent = reaper; - if (p->parent == p->real_parent) - BUG(); } static inline void reparent_thread(task_t *p, task_t *father, int traced) diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 943d5ddc..0c4a8aa0 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -54,6 +54,9 @@ int br_handle_frame_finish(struct sk_buff *skb) struct net_bridge_fdb_entry *dst; int passedup = 0; + /* insert into forwarding database after filtering to avoid spoofing */ + br_fdb_insert(p->br, p, eth_hdr(skb)->h_source, 0); + if (br->dev->flags & IFF_PROMISC) { struct sk_buff *skb2; @@ -108,8 +111,7 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb) if (eth_hdr(skb)->h_source[0] & 1) goto err; - if (p->state == BR_STATE_LEARNING || - p->state == BR_STATE_FORWARDING) + if (p->state == BR_STATE_LEARNING) br_fdb_insert(p->br, p, eth_hdr(skb)->h_source, 0); if (p->br->stp_enabled && diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c index b91a875a..f62e08d6 100644 --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c @@ -140,6 +140,9 @@ int br_stp_handle_bpdu(struct sk_buff *skb) struct net_bridge *br = p->br; unsigned char *buf; + /* insert into forwarding database after filtering to avoid spoofing */ + br_fdb_insert(p->br, p, eth_hdr(skb)->h_source, 0); + /* need at least the 802 and STP headers */ if (!pskb_may_pull(skb, sizeof(header)+1) || memcmp(skb->data, header, sizeof(header))) diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c index 0cefc6f7..e36e3726 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c @@ -235,12 +235,15 @@ static int do_basic_checks(struct ip_conntrack *conntrack, flag = 1; } - /* Cookie Ack/Echo chunks not the first OR - Init / Init Ack / Shutdown compl chunks not the only chunks */ - if ((sch->type == SCTP_CID_COOKIE_ACK + /* + * Cookie Ack/Echo chunks not the first OR + * Init / Init Ack / Shutdown compl chunks not the only chunks + * OR zero-length. + */ + if (((sch->type == SCTP_CID_COOKIE_ACK || sch->type == SCTP_CID_COOKIE_ECHO || flag) - && count !=0 ) { + && count !=0) || !sch->length) { DEBUGP("Basic checks failed\n"); return 1; } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 41b32003..dd0a1008 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2351,7 +2351,10 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) /* Reserve room for dummy headers, this skb can pass through good chunk of routing engine. */ - skb->mac.raw = skb->data; + skb->mac.raw = skb->nh.raw = skb->data; + + /* Bugfix: need to give ip_route_input enough of an IP header to not gag. */ + skb->nh.iph->protocol = IPPROTO_ICMP; skb_reserve(skb, MAX_HEADER + sizeof(struct iphdr)); if (rta[RTA_SRC - 1]) diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index ff00dc49..739f54bb 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -98,7 +98,7 @@ static int udp_v6_get_port(struct sock *sk, unsigned short snum) next:; } result = best; - for(;; result += UDP_HTABLE_SIZE) { + for(i = 0; i < (1 << 16) / UDP_HTABLE_SIZE; i++, result += UDP_HTABLE_SIZE) { if (result > sysctl_local_port_range[1]) result = sysctl_local_port_range[0] + ((result - sysctl_local_port_range[0]) & @@ -106,6 +106,8 @@ static int udp_v6_get_port(struct sock *sk, unsigned short snum) if (!udp_lport_inuse(result)) break; } + if (i >= (1 << 16) / UDP_HTABLE_SIZE) + goto fail; gotit: udp_port_rover = snum = result; } else { diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 8a6eace1..57fa3164 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -547,8 +547,9 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep, */ chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data; - skb_pull(chunk->skb, - ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t)); + if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - + sizeof(sctp_chunkhdr_t))) + goto nomem; /* 5.1 D) Upon reception of the COOKIE ECHO chunk, Endpoint * "Z" will reply with a COOKIE ACK chunk after building a TCB @@ -836,7 +837,8 @@ sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep, */ chunk->subh.hb_hdr = (sctp_heartbeathdr_t *) chunk->skb->data; paylen = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_chunkhdr_t); - skb_pull(chunk->skb, paylen); + if (!pskb_pull(chunk->skb, paylen)) + goto nomem; reply = sctp_make_heartbeat_ack(asoc, chunk, chunk->subh.hb_hdr, paylen); @@ -1663,8 +1665,9 @@ sctp_disposition_t sctp_sf_do_5_2_4_dupcook(const struct sctp_endpoint *ep, * are in good shape. */ chunk->subh.cookie_hdr = (struct sctp_signed_cookie *)chunk->skb->data; - skb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - - sizeof(sctp_chunkhdr_t)); + if (!pskb_pull(chunk->skb, ntohs(chunk->chunk_hdr->length) - + sizeof(sctp_chunkhdr_t))) + goto nomem; /* In RFC 2960 5.2.4 3, if both Verification Tags in the State Cookie * of a duplicate COOKIE ECHO match the Verification Tags of the diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c index 516dc791..885fcc4a 100644 --- a/net/sctp/sm_statetable.c +++ b/net/sctp/sm_statetable.c @@ -355,9 +355,9 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, /* SCTP_STATE_EMPTY */ \ {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ /* SCTP_STATE_COOKIE_WAIT */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ /* SCTP_STATE_COOKIE_ECHOED */ \ {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ /* SCTP_STATE_ESTABLISHED */ \ @@ -369,7 +369,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ } /* TYPE_SCTP_ECN_ECNE */ #define TYPE_SCTP_ECN_CWR { \ @@ -390,7 +390,7 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ + {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ } /* TYPE_SCTP_ECN_CWR */ #define TYPE_SCTP_SHUTDOWN_COMPLETE { \ @@ -636,7 +636,7 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { /* SCTP_STATE_EMPTY */ \ {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ /* SCTP_STATE_CLOSED */ \ - {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ + {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \ /* SCTP_STATE_COOKIE_WAIT */ \ {.fn = sctp_sf_do_prm_requestheartbeat, \ .name = "sctp_sf_do_prm_requestheartbeat"}, \ diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index 350a97ec..4c7c85bf 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c @@ -289,9 +289,10 @@ static inline void sctp_ulpq_store_reasm(struct sctp_ulpq *ulpq, * payload was fragmented on the way and ip had to reassemble them. * We add the rest of skb's to the first skb's fraglist. */ -static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff *f_frag, struct sk_buff *l_frag) +static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff_head *queue, struct sk_buff *f_frag, struct sk_buff *l_frag) { struct sk_buff *pos; + struct sk_buff *new = NULL; struct sctp_ulpevent *event; struct sk_buff *pnext, *last; struct sk_buff *list = skb_shinfo(f_frag)->frag_list; @@ -310,11 +311,35 @@ static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff *f_frag, */ if (last) last->next = pos; - else - skb_shinfo(f_frag)->frag_list = pos; + else { + if (skb_cloned(f_frag)) { + /* This is a cloned skb, we can't just modify + * the frag_list. We need a new skb to do that. + * Instead of calling skb_unshare(), we'll do it + * ourselves since we need to delay the free. + */ + new = skb_copy(f_frag, GFP_ATOMIC); + if (!new) + return NULL; /* try again later */ + + new->sk = f_frag->sk; + + skb_shinfo(new)->frag_list = pos; + } else + skb_shinfo(f_frag)->frag_list = pos; + } + /* Remove the first fragment from the reassembly queue. */ - __skb_unlink(f_frag, f_frag->list); + __skb_unlink(f_frag, queue); + + /* if we did unshare, then free the old skb and re-assign */ + if (new) { + kfree_skb(f_frag); + f_frag = new; + } + + while (pos) { pnext = pos->next; @@ -324,7 +349,7 @@ static struct sctp_ulpevent *sctp_make_reassembled_event(struct sk_buff *f_frag, f_frag->data_len += pos->len; /* Remove the fragment from the reassembly queue. */ - __skb_unlink(pos, pos->list); + __skb_unlink(pos, queue); /* Break if we have reached the last fragment. */ if (pos == l_frag) @@ -395,7 +420,7 @@ static inline struct sctp_ulpevent *sctp_ulpq_retrieve_reassembled(struct sctp_u done: return retval; found: - retval = sctp_make_reassembled_event(first_frag, pos); + retval = sctp_make_reassembled_event(&ulpq->reasm, first_frag, pos); if (retval) retval->msg_flags |= MSG_EOR; goto done; @@ -455,7 +480,7 @@ static inline struct sctp_ulpevent *sctp_ulpq_retrieve_partial(struct sctp_ulpq * further. */ done: - retval = sctp_make_reassembled_event(first_frag, last_frag); + retval = sctp_make_reassembled_event(&ulpq->reasm, first_frag, last_frag); if (retval && is_last) retval->msg_flags |= MSG_EOR; @@ -547,7 +572,7 @@ static inline struct sctp_ulpevent *sctp_ulpq_retrieve_first(struct sctp_ulpq *u * further. */ done: - retval = sctp_make_reassembled_event(first_frag, last_frag); + retval = sctp_make_reassembled_event(&ulpq->reasm, first_frag, last_frag); return retval; } diff --git a/net/socket.c b/net/socket.c index afb3de88..b9110547 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1161,8 +1161,10 @@ static int __sock_create(int family, int type, int protocol, struct socket **res if (!try_module_get(net_families[family]->owner)) goto out_release; - if ((i = net_families[family]->create(sock, protocol)) < 0) + if ((i = net_families[family]->create(sock, protocol)) < 0) { + sock->ops = NULL; goto out_module_put; + } /* * Now to bump the refcnt of the [loadable] module that owns this * socket at sock_release time we decrement its refcnt. diff --git a/security/keys/key.c b/security/keys/key.c index 886ae0f8..dc09f5dd 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -782,6 +782,10 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, key_check(keyring); + key_ref = ERR_PTR(-ENOTDIR); + if (keyring->type != &key_type_keyring) + goto error_2; + down_write(&keyring->sem); /* if we're going to allocate a new key, we're going to have diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 5e68ea2a..be6dadb6 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -437,6 +437,7 @@ EXPORT_SYMBOL(keyring_search); /* * search the given keyring only (no recursion) * - keyring must be locked by caller + * - caller must guarantee that the keyring is a keyring */ key_ref_t __keyring_search_one(key_ref_t keyring_ref, const struct key_type *ktype,