diff options
author | 2013-06-05 16:08:19 -0400 | |
---|---|---|
committer | 2013-06-05 16:08:19 -0400 | |
commit | 7613b2514cbb5fd2e7956f2facabe3204b4449bc (patch) | |
tree | 733e7d165dd875be2966355b95e948f77a5ac948 | |
parent | Grsec/PaX: 2.9.1-{2.6.32.60,3.2.45,3.9.4}-201306011536 (diff) | |
download | hardened-patchset-7613b2514cbb5fd2e7956f2facabe3204b4449bc.tar.gz hardened-patchset-7613b2514cbb5fd2e7956f2facabe3204b4449bc.tar.bz2 hardened-patchset-7613b2514cbb5fd2e7956f2facabe3204b4449bc.zip |
Grsec/PaX: 2.9.1-{2.6.32.60,3.2.45,3.9.4}-201306041949
-rw-r--r-- | 2.6.32/0000_README | 2 | ||||
-rw-r--r-- | 2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201306041946.patch (renamed from 2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201306011535.patch) | 137 | ||||
-rw-r--r-- | 3.2.45/0000_README | 2 | ||||
-rw-r--r-- | 3.2.45/4420_grsecurity-2.9.1-3.2.46-201306041947.patch (renamed from 3.2.45/4420_grsecurity-2.9.1-3.2.46-201306011535.patch) | 390 | ||||
-rw-r--r-- | 3.9.4/0000_README | 2 | ||||
-rw-r--r-- | 3.9.4/4420_grsecurity-2.9.1-3.9.4-201306041949.patch (renamed from 3.9.4/4420_grsecurity-2.9.1-3.9.4-201306011536.patch) | 396 |
6 files changed, 857 insertions, 72 deletions
diff --git a/2.6.32/0000_README b/2.6.32/0000_README index 4edfd58..797feaa 100644 --- a/2.6.32/0000_README +++ b/2.6.32/0000_README @@ -34,7 +34,7 @@ Patch: 1059_linux-2.6.32.60.patch From: http://www.kernel.org Desc: Linux 2.6.32.59 -Patch: 4420_grsecurity-2.9.1-2.6.32.60-201306011535.patch +Patch: 4420_grsecurity-2.9.1-2.6.32.60-201306041946.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201306011535.patch b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201306041946.patch index eb29409..8e09bd0 100644 --- a/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201306011535.patch +++ b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201306041946.patch @@ -3605,6 +3605,19 @@ index a27d2e2..18fd845 100644 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL) #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE) #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE) +diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c +index 994bcd9..f25247a 100644 +--- a/arch/parisc/kernel/drivers.c ++++ b/arch/parisc/kernel/drivers.c +@@ -393,7 +393,7 @@ EXPORT_SYMBOL(print_pci_hwpath); + static void setup_bus_id(struct parisc_device *padev) + { + struct hardware_path path; +- char name[20]; ++ char name[28]; + char *output = name; + int i; + diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 2120746..8d70a5e 100644 --- a/arch/parisc/kernel/module.c @@ -3708,6 +3721,20 @@ index 2120746..8d70a5e 100644 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n", me->arch.unwind_section, table, end, gp); +diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c +index cb71f3d..306f0c0 100644 +--- a/arch/parisc/kernel/setup.c ++++ b/arch/parisc/kernel/setup.c +@@ -68,7 +68,8 @@ void __init setup_cmdline(char **cmdline_p) + /* called from hpux boot loader */ + boot_command_line[0] = '\0'; + } else { +- strcpy(boot_command_line, (char *)__va(boot_args[1])); ++ strlcpy(boot_command_line, (char *)__va(boot_args[1]), ++ COMMAND_LINE_SIZE); + + #ifdef CONFIG_BLK_DEV_INITRD + if (boot_args[2] != 0) /* did palo pass us a ramdisk? */ diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index fb59852..32d43e7 100644 --- a/arch/parisc/kernel/signal32.c @@ -47545,6 +47572,28 @@ index 0236f0d..c7327f1 100644 serio->dev.bus = &serio_bus; serio->dev.release = serio_release_port; if (serio->parent) { +diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c +index dc506ab..af04b54 100644 +--- a/drivers/isdn/capi/kcapi.c ++++ b/drivers/isdn/capi/kcapi.c +@@ -95,7 +95,7 @@ capi_ctr_put(struct capi_ctr *card) + + static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr) + { +- if (contr - 1 >= CAPI_MAXCONTR) ++ if (contr < 1 || contr - 1 >= CAPI_MAXCONTR) + return NULL; + + return capi_cards[contr - 1]; +@@ -103,7 +103,7 @@ static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr) + + static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid) + { +- if (applid - 1 >= CAPI_MAXAPPL) ++ if (applid < 1 || applid - 1 >= CAPI_MAXAPPL) + return NULL; + + return capi_applications[applid - 1]; diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 33dcd8d..2783d25 100644 --- a/drivers/isdn/gigaset/common.c @@ -82186,6 +82235,19 @@ index bfaef7b..e9d03ca 100644 } void nfs_fattr_init(struct nfs_fattr *fattr) +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 21c7190..22688d5 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -915,7 +915,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) + struct nfs4_state *state = opendata->state; + struct nfs_inode *nfsi = NFS_I(state->inode); + struct nfs_delegation *delegation; +- int open_mode = opendata->o_arg.open_flags & O_EXCL; ++ int open_mode = opendata->o_arg.open_flags; + fmode_t fmode = opendata->o_arg.fmode; + nfs4_stateid stateid; + int ret = -EAGAIN; diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c index cc2f505..f6a236f 100644 --- a/fs/nfsd/lockd.c @@ -84523,7 +84585,7 @@ index 7723401..30059a6 100644 error = -EFAULT; else diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c -index d42c30c..4fd8718 100644 +index d42c30c..153b170 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c @@ -66,6 +66,8 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, @@ -84535,6 +84597,15 @@ index d42c30c..4fd8718 100644 reiserfs_write_lock(inode->i_sb); reiserfs_check_lock_depth(inode->i_sb, "readdir"); +@@ -187,6 +189,8 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, + next_pos = deh_offset(deh) + 1; + + if (item_moved(&tmp_ih, &path_to_entry)) { ++ set_cpu_key_k_offset(&pos_key, ++ next_pos); + goto research; + } + } /* for */ diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c index 128d3f7c..8840d44 100644 --- a/fs/reiserfs/do_balan.c @@ -84548,6 +84619,29 @@ index 128d3f7c..8840d44 100644 do_balance_starts(tb); /* balance leaf returns 0 except if combining L R and S into +diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c +index d240c15..c38a41a 100644 +--- a/fs/reiserfs/inode.c ++++ b/fs/reiserfs/inode.c +@@ -1786,11 +1786,16 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, + TYPE_STAT_DATA, SD_SIZE, MAX_US_INT); + memcpy(INODE_PKEY(inode), &(ih.ih_key), KEY_SIZE); + args.dirid = le32_to_cpu(ih.ih_key.k_dir_id); +- if (insert_inode_locked4(inode, args.objectid, +- reiserfs_find_actor, &args) < 0) { ++ ++ reiserfs_write_unlock(inode->i_sb); ++ err = insert_inode_locked4(inode, args.objectid, ++ reiserfs_find_actor, &args); ++ reiserfs_write_lock(inode->i_sb); ++ if (err) { + err = -EINVAL; + goto out_bad_inode; + } ++ + if (old_format_only(sb)) + /* not a perfect generation count, as object ids can be reused, but + ** this is as good as reiserfs can do right now. diff --git a/fs/reiserfs/item_ops.c b/fs/reiserfs/item_ops.c index 72cb1cc..d0e3181 100644 --- a/fs/reiserfs/item_ops.c @@ -115872,7 +115966,7 @@ index 2dcf04d..4656638 100644 { .ctl_name = NET_TCP_DMA_COPYBREAK, diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c -index b9644d8..537313b 100644 +index b9644d8..8e66b8e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2084,6 +2084,8 @@ static int do_tcp_setsockopt(struct sock *sk, int level, @@ -115893,6 +115987,19 @@ index b9644d8..537313b 100644 if (get_user(len, optlen)) return -EFAULT; +@@ -2826,7 +2830,11 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp, + + for (i = 0; i < shi->nr_frags; ++i) { + const struct skb_frag_struct *f = &shi->frags[i]; +- sg_set_page(&sg, f->page, f->size, f->page_offset); ++ unsigned int offset = f->page_offset; ++ struct page *page = f->page + (offset >> PAGE_SHIFT); ++ ++ sg_set_page(&sg, page, f->size, ++ offset_in_page(offset)); + if (crypto_hash_update(desc, &sg, f->size)) + return 1; + } diff --git a/net/ipv4/tcp_illinois.c b/net/ipv4/tcp_illinois.c index 1eba160b..c35d91f 100644 --- a/net/ipv4/tcp_illinois.c @@ -116507,6 +116614,19 @@ index 093e9b2..f72cddb 100644 const unsigned short hnum, const struct in6_addr *daddr, const int dif) +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index 9ad5792..fa406b9 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1138,7 +1138,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, + if (WARN_ON(np->cork.opt)) + return -EINVAL; + +- np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation); ++ np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation); + if (unlikely(np->cork.opt == NULL)) + return -ENOBUFS; + diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 4f7aaf6..f7acf45 100644 --- a/net/ipv6/ipv6_sockglue.c @@ -117047,6 +117167,19 @@ index 35a338b..62102d6 100644 /* Aborting, close connection! */ iriap_disconnect_request(self); +diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c +index 7af2e74..143ae58 100644 +--- a/net/irda/irlap_frame.c ++++ b/net/irda/irlap_frame.c +@@ -543,7 +543,7 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self, + /* + * We now have some discovery info to deliver! + */ +- discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC); ++ discovery = kzalloc(sizeof(discovery_t), GFP_ATOMIC); + if (!discovery) { + IRDA_WARNING("%s: unable to malloc!\n", __func__); + return; diff --git a/net/irda/irttp.c b/net/irda/irttp.c index 9cb79f9..d35d057 100644 --- a/net/irda/irttp.c diff --git a/3.2.45/0000_README b/3.2.45/0000_README index 00f8a3a..4a59301 100644 --- a/3.2.45/0000_README +++ b/3.2.45/0000_README @@ -98,7 +98,7 @@ Patch: 1044_linux-3.2.45.patch From: http://www.kernel.org Desc: Linux 3.2.45 -Patch: 4420_grsecurity-2.9.1-3.2.46-201306011535.patch +Patch: 4420_grsecurity-2.9.1-3.2.46-201306041947.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.2.45/4420_grsecurity-2.9.1-3.2.46-201306011535.patch b/3.2.45/4420_grsecurity-2.9.1-3.2.46-201306041947.patch index 6555c18..bf3ae8a 100644 --- a/3.2.45/4420_grsecurity-2.9.1-3.2.46-201306011535.patch +++ b/3.2.45/4420_grsecurity-2.9.1-3.2.46-201306041947.patch @@ -3860,6 +3860,19 @@ index 5241698..91dcb12 100644 } EXPORT_SYMBOL(purge_tlb_entries); +diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c +index 5709c5e..14285ca 100644 +--- a/arch/parisc/kernel/drivers.c ++++ b/arch/parisc/kernel/drivers.c +@@ -394,7 +394,7 @@ EXPORT_SYMBOL(print_pci_hwpath); + static void setup_bus_id(struct parisc_device *padev) + { + struct hardware_path path; +- char name[20]; ++ char name[28]; + char *output = name; + int i; + diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 5e34ccf..672bc9c 100644 --- a/arch/parisc/kernel/module.c @@ -3963,6 +3976,20 @@ index 5e34ccf..672bc9c 100644 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n", me->arch.unwind_section, table, end, gp); +diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c +index a3328c2..3b812eb 100644 +--- a/arch/parisc/kernel/setup.c ++++ b/arch/parisc/kernel/setup.c +@@ -69,7 +69,8 @@ void __init setup_cmdline(char **cmdline_p) + /* called from hpux boot loader */ + boot_command_line[0] = '\0'; + } else { +- strcpy(boot_command_line, (char *)__va(boot_args[1])); ++ strlcpy(boot_command_line, (char *)__va(boot_args[1]), ++ COMMAND_LINE_SIZE); + + #ifdef CONFIG_BLK_DEV_INITRD + if (boot_args[2] != 0) /* did palo pass us a ramdisk? */ diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 7ea75d1..38ca97d 100644 --- a/arch/parisc/kernel/sys_parisc.c @@ -36879,6 +36906,37 @@ index e44933d..9ba484a 100644 capimsg_setu32(skb->data, 8, mp->ncci); /* NCCI */ capimsg_setu32(skb->data, 12, (u32)(long)skb->data);/* Data32 */ capimsg_setu16(skb->data, 16, len); /* Data length */ +diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c +index 2b33b26..a9c638b 100644 +--- a/drivers/isdn/capi/kcapi.c ++++ b/drivers/isdn/capi/kcapi.c +@@ -93,7 +93,7 @@ capi_ctr_put(struct capi_ctr *ctr) + + static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr) + { +- if (contr - 1 >= CAPI_MAXCONTR) ++ if (contr < 1 || contr - 1 >= CAPI_MAXCONTR) + return NULL; + + return capi_controller[contr - 1]; +@@ -103,7 +103,7 @@ static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid) + { + lockdep_assert_held(&capi_controller_lock); + +- if (applid - 1 >= CAPI_MAXAPPL) ++ if (applid < 1 || applid - 1 >= CAPI_MAXAPPL) + return NULL; + + return capi_applications[applid - 1]; +@@ -111,7 +111,7 @@ static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid) + + static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid) + { +- if (applid - 1 >= CAPI_MAXAPPL) ++ if (applid < 1 || applid - 1 >= CAPI_MAXAPPL) + return NULL; + + return rcu_dereference(capi_applications[applid - 1]); diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index db621db..825ea1a 100644 --- a/drivers/isdn/gigaset/common.c @@ -53660,6 +53718,19 @@ index b78b5b6..c64d84f 100644 } void nfs_fattr_init(struct nfs_fattr *fattr) +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 5639efd..4531174 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1037,7 +1037,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) + struct nfs4_state *state = opendata->state; + struct nfs_inode *nfsi = NFS_I(state->inode); + struct nfs_delegation *delegation; +- int open_mode = opendata->o_arg.open_flags & O_EXCL; ++ int open_mode = opendata->o_arg.open_flags; + fmode_t fmode = opendata->o_arg.fmode; + nfs4_stateid stateid; + int ret = -EAGAIN; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 1943898..396c460 100644 --- a/fs/nfs/super.c @@ -55971,6 +56042,19 @@ index 356f715..c918d38 100644 if (__put_user(d_off, &lastdirent->d_off)) error = -EFAULT; else +diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c +index 133e935..77359db 100644 +--- a/fs/reiserfs/dir.c ++++ b/fs/reiserfs/dir.c +@@ -204,6 +204,8 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, + next_pos = deh_offset(deh) + 1; + + if (item_moved(&tmp_ih, &path_to_entry)) { ++ set_cpu_key_k_offset(&pos_key, ++ next_pos); + goto research; + } + } /* for */ diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c index 60c0804..d814f98 100644 --- a/fs/reiserfs/do_balan.c @@ -55984,6 +56068,29 @@ index 60c0804..d814f98 100644 do_balance_starts(tb); /* balance leaf returns 0 except if combining L R and S into +diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c +index fe677c0..2a15fb2 100644 +--- a/fs/reiserfs/inode.c ++++ b/fs/reiserfs/inode.c +@@ -1816,11 +1816,16 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, + TYPE_STAT_DATA, SD_SIZE, MAX_US_INT); + memcpy(INODE_PKEY(inode), &(ih.ih_key), KEY_SIZE); + args.dirid = le32_to_cpu(ih.ih_key.k_dir_id); +- if (insert_inode_locked4(inode, args.objectid, +- reiserfs_find_actor, &args) < 0) { ++ ++ reiserfs_write_unlock(inode->i_sb); ++ err = insert_inode_locked4(inode, args.objectid, ++ reiserfs_find_actor, &args); ++ reiserfs_write_lock(inode->i_sb); ++ if (err) { + err = -EINVAL; + goto out_bad_inode; + } ++ + if (old_format_only(sb)) + /* not a perfect generation count, as object ids can be reused, but + ** this is as good as reiserfs can do right now. diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index 7a99811..a7c96c4 100644 --- a/fs/reiserfs/procfs.c @@ -56009,6 +56116,45 @@ index 569498a..0886e50f 100644 MODULE_DESCRIPTION("ReiserFS journaled filesystem"); MODULE_AUTHOR("Hans Reiser <reiser@namesys.com>"); +diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c +index 04eecc4..33f74d0 100644 +--- a/fs/reiserfs/xattr.c ++++ b/fs/reiserfs/xattr.c +@@ -318,7 +318,19 @@ static int delete_one_xattr(struct dentry *dentry, void *data) + static int chown_one_xattr(struct dentry *dentry, void *data) + { + struct iattr *attrs = data; +- return reiserfs_setattr(dentry, attrs); ++ int ia_valid = attrs->ia_valid; ++ int err; ++ ++ /* ++ * We only want the ownership bits. Otherwise, we'll do ++ * things like change a directory to a regular file if ++ * ATTR_MODE is set. ++ */ ++ attrs->ia_valid &= (ATTR_UID|ATTR_GID); ++ err = reiserfs_setattr(dentry, attrs); ++ attrs->ia_valid = ia_valid; ++ ++ return err; + } + + /* No i_mutex, but the inode is unconnected. */ +diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c +index 6da0396..fc338f3 100644 +--- a/fs/reiserfs/xattr_acl.c ++++ b/fs/reiserfs/xattr_acl.c +@@ -429,6 +429,9 @@ int reiserfs_acl_chmod(struct inode *inode) + int depth; + int error; + ++ if (IS_PRIVATE(inode)) ++ return 0; ++ + if (S_ISLNK(inode->i_mode)) + return -EOPNOTSUPP; + diff --git a/fs/romfs/super.c b/fs/romfs/super.c index 8b4089f..2575128 100644 --- a/fs/romfs/super.c @@ -56723,7 +56869,7 @@ index d99a905..9f88202 100644 goto out_put; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c -index 23ce927..e274cc1 100644 +index 23ce927..86fd3e8d 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -447,7 +447,7 @@ xfs_vn_put_link( @@ -56735,6 +56881,81 @@ index 23ce927..e274cc1 100644 if (!IS_ERR(s)) kfree(s); +@@ -507,6 +507,28 @@ xfs_vn_getattr( + return 0; + } + ++static void ++xfs_setattr_mode( ++ struct xfs_trans *tp, ++ struct xfs_inode *ip, ++ struct iattr *iattr) ++{ ++ struct inode *inode = VFS_I(ip); ++ umode_t mode = iattr->ia_mode; ++ ++ ASSERT(tp); ++ ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ++ ++ if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) ++ mode &= ~S_ISGID; ++ ++ ip->i_d.di_mode &= S_IFMT; ++ ip->i_d.di_mode |= mode & ~S_IFMT; ++ ++ inode->i_mode &= S_IFMT; ++ inode->i_mode |= mode & ~S_IFMT; ++} ++ + int + xfs_setattr_nonsize( + struct xfs_inode *ip, +@@ -658,18 +680,8 @@ xfs_setattr_nonsize( + /* + * Change file access modes. + */ +- if (mask & ATTR_MODE) { +- umode_t mode = iattr->ia_mode; +- +- if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) +- mode &= ~S_ISGID; +- +- ip->i_d.di_mode &= S_IFMT; +- ip->i_d.di_mode |= mode & ~S_IFMT; +- +- inode->i_mode &= S_IFMT; +- inode->i_mode |= mode & ~S_IFMT; +- } ++ if (mask & ATTR_MODE) ++ xfs_setattr_mode(tp, ip, iattr); + + /* + * Change file access or modified times. +@@ -768,9 +780,8 @@ xfs_setattr_size( + return XFS_ERROR(error); + + ASSERT(S_ISREG(ip->i_d.di_mode)); +- ASSERT((mask & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| +- ATTR_MTIME_SET|ATTR_KILL_SUID|ATTR_KILL_SGID| +- ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); ++ ASSERT((mask & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| ++ ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); + + lock_flags = XFS_ILOCK_EXCL; + if (!(flags & XFS_ATTR_NOLOCK)) +@@ -902,6 +913,12 @@ xfs_setattr_size( + xfs_iflags_set(ip, XFS_ITRUNCATED); + } + ++ /* ++ * Change file access modes. ++ */ ++ if (mask & ATTR_MODE) ++ xfs_setattr_mode(tp, ip, iattr); ++ + if (mask & ATTR_CTIME) { + inode->i_ctime = iattr->ia_ctime; + ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 87323f1..dab9d00 100644 --- a/fs/xfs/xfs_rtalloc.c @@ -56762,10 +56983,10 @@ index 8a89949..6776861 100644 xfs_init_zones(void) diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig new file mode 100644 -index 0000000..aef8e91 +index 0000000..15aaf25 --- /dev/null +++ b/grsecurity/Kconfig -@@ -0,0 +1,1031 @@ +@@ -0,0 +1,1053 @@ +# +# grecurity configuration +# @@ -56851,6 +57072,25 @@ index 0000000..aef8e91 + If you're using KERNEXEC, it's recommended that you enable this option + to supplement the hardening of the kernel. + ++config GRKERNSEC_PERF_HARDEN ++ bool "Disable unprivileged PERF_EVENTS usage by default" ++ default y if GRKERNSEC_CONFIG_AUTO ++ depends on PERF_EVENTS ++ help ++ If you say Y here, the range of acceptable values for the ++ /proc/sys/kernel/perf_event_paranoid sysctl will be expanded to allow and ++ default to a new value: 3. When the sysctl is set to this value, no ++ unprivileged use of the PERF_EVENTS syscall interface will be permitted. ++ ++ Though PERF_EVENTS can be used legitimately for performance monitoring ++ and low-level application profiling, it is forced on regardless of ++ configuration, has been at fault for several vulnerabilities, and ++ creates new opportunities for side channels and other information leaks. ++ ++ This feature puts PERF_EVENTS into a secure default state and permits ++ the administrator to change out of it temporarily if unprivileged ++ application profiling is needed. ++ +config GRKERNSEC_RAND_THREADSTACK + bool "Insert random gaps between thread stacks" + default y if GRKERNSEC_CONFIG_AUTO @@ -56961,6 +57201,9 @@ index 0000000..aef8e91 + useful protection against local kernel exploitation of overflows + and arbitrary read/write vulnerabilities. + ++ It is highly recommended that you enable GRKERNSEC_PERF_HARDEN ++ in addition to this feature. ++ +config GRKERNSEC_KERN_LOCKOUT + bool "Active kernel exploit response" + default y if GRKERNSEC_CONFIG_AUTO @@ -70897,7 +71140,7 @@ index 45fc162..01a4068 100644 /** * struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h -index 9b9b2aa..22f09dc 100644 +index 9b9b2aa..df3199e 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -748,8 +748,8 @@ struct perf_event { @@ -70931,8 +71174,15 @@ index 9b9b2aa..22f09dc 100644 extern int sysctl_perf_event_mlock; extern int sysctl_perf_event_sample_rate; -@@ -1111,17 +1111,17 @@ extern int perf_proc_update_handler(struct ctl_table *table, int write, +@@ -1109,19 +1109,24 @@ extern int perf_proc_update_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos); ++static inline bool perf_paranoid_any(void) ++{ ++ return sysctl_perf_event_legitimately_concerned > 2; ++} ++ static inline bool perf_paranoid_tracepoint_raw(void) { - return sysctl_perf_event_paranoid > -1; @@ -70952,7 +71202,7 @@ index 9b9b2aa..22f09dc 100644 } extern void perf_event_init(void); -@@ -1199,7 +1199,7 @@ static inline void perf_restore_debug_store(void) { } +@@ -1199,7 +1204,7 @@ static inline void perf_restore_debug_store(void) { } */ #define perf_cpu_notifier(fn) \ do { \ @@ -74914,15 +75164,19 @@ index 63786e7..0780cac 100644 #ifdef CONFIG_MODULE_UNLOAD { diff --git a/kernel/events/core.c b/kernel/events/core.c -index 9f21915..08e25b4 100644 +index 9f21915..840113c 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c -@@ -146,7 +146,11 @@ static struct srcu_struct pmus_srcu; +@@ -145,8 +145,15 @@ static struct srcu_struct pmus_srcu; + * 0 - disallow raw tracepoint access for unpriv * 1 - disallow cpu events for unpriv * 2 - disallow kernel profiling for unpriv ++ * 3 - disallow all unpriv perf event use */ -int sysctl_perf_event_paranoid __read_mostly = 1; -+#ifdef CONFIG_GRKERNSEC_HIDESYM ++#ifdef CONFIG_GRKERNSEC_PERF_HARDEN ++int sysctl_perf_event_legitimately_concerned __read_mostly = 3; ++#elif CONFIG_GRKERNSEC_HIDESYM +int sysctl_perf_event_legitimately_concerned __read_mostly = 2; +#else +int sysctl_perf_event_legitimately_concerned __read_mostly = 1; @@ -74930,7 +75184,7 @@ index 9f21915..08e25b4 100644 /* Minimum for 512 kiB + 1 user control page */ int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */ -@@ -173,7 +177,7 @@ int perf_proc_update_handler(struct ctl_table *table, int write, +@@ -173,7 +180,7 @@ int perf_proc_update_handler(struct ctl_table *table, int write, return 0; } @@ -74939,7 +75193,7 @@ index 9f21915..08e25b4 100644 static void cpu_ctx_sched_out(struct perf_cpu_context *cpuctx, enum event_type_t event_type); -@@ -2540,7 +2544,7 @@ static void __perf_event_read(void *info) +@@ -2540,7 +2547,7 @@ static void __perf_event_read(void *info) static inline u64 perf_event_count(struct perf_event *event) { @@ -74948,7 +75202,7 @@ index 9f21915..08e25b4 100644 } static u64 perf_event_read(struct perf_event *event) -@@ -3071,9 +3075,9 @@ u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) +@@ -3071,9 +3078,9 @@ u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) mutex_lock(&event->child_mutex); total += perf_event_read(event); *enabled += event->total_time_enabled + @@ -74960,7 +75214,7 @@ index 9f21915..08e25b4 100644 list_for_each_entry(child, &event->child_list, child_list) { total += perf_event_read(child); -@@ -3482,10 +3486,10 @@ void perf_event_update_userpage(struct perf_event *event) +@@ -3482,10 +3489,10 @@ void perf_event_update_userpage(struct perf_event *event) userpg->offset -= local64_read(&event->hw.prev_count); userpg->time_enabled = enabled + @@ -74973,7 +75227,7 @@ index 9f21915..08e25b4 100644 barrier(); ++userpg->lock; -@@ -3914,11 +3918,11 @@ static void perf_output_read_one(struct perf_output_handle *handle, +@@ -3914,11 +3921,11 @@ static void perf_output_read_one(struct perf_output_handle *handle, values[n++] = perf_event_count(event); if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) { values[n++] = enabled + @@ -74987,7 +75241,7 @@ index 9f21915..08e25b4 100644 } if (read_format & PERF_FORMAT_ID) values[n++] = primary_event_id(event); -@@ -4569,12 +4573,12 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) +@@ -4569,12 +4576,12 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) * need to add enough zero bytes after the string to handle * the 64bit alignment we do later. */ @@ -75002,7 +75256,7 @@ index 9f21915..08e25b4 100644 if (IS_ERR(name)) { name = strncpy(tmp, "//toolong", sizeof(tmp)); goto got_name; -@@ -5931,7 +5935,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, +@@ -5931,7 +5938,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, event->parent = parent_event; event->ns = get_pid_ns(current->nsproxy->pid_ns); @@ -75011,7 +75265,19 @@ index 9f21915..08e25b4 100644 event->state = PERF_EVENT_STATE_INACTIVE; -@@ -6451,10 +6455,10 @@ static void sync_child_event(struct perf_event *child_event, +@@ -6164,6 +6171,11 @@ SYSCALL_DEFINE5(perf_event_open, + if (flags & ~PERF_FLAG_ALL) + return -EINVAL; + ++#ifdef CONFIG_GRKERNSEC_PERF_HARDEN ++ if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN)) ++ return -EACCES; ++#endif ++ + err = perf_copy_attr(attr_uptr, &attr); + if (err) + return err; +@@ -6451,10 +6463,10 @@ static void sync_child_event(struct perf_event *child_event, /* * Add back the child's count to the parent's count: */ @@ -78654,7 +78920,7 @@ index be5fa8b..a8c2090 100644 break; } diff --git a/kernel/sysctl.c b/kernel/sysctl.c -index ea7ec7f..b1c7c88 100644 +index ea7ec7f..a823e62 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -86,6 +86,13 @@ @@ -78779,7 +79045,7 @@ index ea7ec7f..b1c7c88 100644 { .procname = "ngroups_max", .data = &ngroups_max, -@@ -957,8 +1002,8 @@ static struct ctl_table kern_table[] = { +@@ -957,10 +1002,17 @@ static struct ctl_table kern_table[] = { */ { .procname = "perf_event_paranoid", @@ -78788,9 +79054,19 @@ index ea7ec7f..b1c7c88 100644 + .data = &sysctl_perf_event_legitimately_concerned, + .maxlen = sizeof(sysctl_perf_event_legitimately_concerned), .mode = 0644, - .proc_handler = proc_dointvec, +- .proc_handler = proc_dointvec, ++ /* go ahead, be a hero */ ++ .proc_handler = proc_dointvec_minmax_sysadmin, ++ .extra1 = &zero, ++#ifdef CONFIG_GRKERNSEC_PERF_HARDEN ++ .extra2 = &three, ++#else ++ .extra2 = &two, ++#endif }, -@@ -1216,6 +1261,13 @@ static struct ctl_table vm_table[] = { + { + .procname = "perf_event_mlock_kb", +@@ -1216,6 +1268,13 @@ static struct ctl_table vm_table[] = { .proc_handler = proc_dointvec_minmax, .extra1 = &zero, }, @@ -78804,7 +79080,7 @@ index ea7ec7f..b1c7c88 100644 #else { .procname = "nr_trim_pages", -@@ -1499,7 +1551,7 @@ static struct ctl_table fs_table[] = { +@@ -1499,7 +1558,7 @@ static struct ctl_table fs_table[] = { .data = &suid_dumpable, .maxlen = sizeof(int), .mode = 0644, @@ -78813,7 +79089,7 @@ index ea7ec7f..b1c7c88 100644 .extra1 = &zero, .extra2 = &two, }, -@@ -1720,6 +1772,17 @@ static int test_perm(int mode, int op) +@@ -1720,6 +1779,17 @@ static int test_perm(int mode, int op) int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op) { int mode; @@ -78831,7 +79107,7 @@ index ea7ec7f..b1c7c88 100644 if (root->permissions) mode = root->permissions(root, current->nsproxy, table); -@@ -1732,7 +1795,9 @@ int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op) +@@ -1732,7 +1802,9 @@ int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op) static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table) { for (; table->procname; table++) { @@ -78842,7 +79118,7 @@ index ea7ec7f..b1c7c88 100644 if (table->child) sysctl_set_parent(table, table->child); } -@@ -1856,7 +1921,8 @@ struct ctl_table_header *__register_sysctl_paths( +@@ -1856,7 +1928,8 @@ struct ctl_table_header *__register_sysctl_paths( const struct ctl_path *path, struct ctl_table *table) { struct ctl_table_header *header; @@ -78852,7 +79128,7 @@ index ea7ec7f..b1c7c88 100644 unsigned int n, npath; struct ctl_table_set *set; -@@ -1877,7 +1943,7 @@ struct ctl_table_header *__register_sysctl_paths( +@@ -1877,7 +1950,7 @@ struct ctl_table_header *__register_sysctl_paths( if (!header) return NULL; @@ -78861,7 +79137,7 @@ index ea7ec7f..b1c7c88 100644 /* Now connect the dots */ prevp = &header->ctl_table; -@@ -2124,6 +2190,16 @@ int proc_dostring(struct ctl_table *table, int write, +@@ -2124,6 +2197,16 @@ int proc_dostring(struct ctl_table *table, int write, buffer, lenp, ppos); } @@ -78878,7 +79154,7 @@ index ea7ec7f..b1c7c88 100644 static size_t proc_skip_spaces(char **buf) { size_t ret; -@@ -2229,6 +2305,8 @@ static int proc_put_long(void __user **buf, size_t *size, unsigned long val, +@@ -2229,6 +2312,8 @@ static int proc_put_long(void __user **buf, size_t *size, unsigned long val, len = strlen(tmp); if (len > *size) len = *size; @@ -78887,7 +79163,7 @@ index ea7ec7f..b1c7c88 100644 if (copy_to_user(*buf, tmp, len)) return -EFAULT; *size -= len; -@@ -2393,7 +2471,7 @@ int proc_dointvec(struct ctl_table *table, int write, +@@ -2393,7 +2478,7 @@ int proc_dointvec(struct ctl_table *table, int write, static int proc_taint(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { @@ -78896,7 +79172,7 @@ index ea7ec7f..b1c7c88 100644 unsigned long tmptaint = get_taint(); int err; -@@ -2421,7 +2499,6 @@ static int proc_taint(struct ctl_table *table, int write, +@@ -2421,7 +2506,6 @@ static int proc_taint(struct ctl_table *table, int write, return err; } @@ -78904,7 +79180,7 @@ index ea7ec7f..b1c7c88 100644 static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { -@@ -2430,7 +2507,6 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, +@@ -2430,7 +2514,6 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, return proc_dointvec_minmax(table, write, buffer, lenp, ppos); } @@ -78912,7 +79188,7 @@ index ea7ec7f..b1c7c88 100644 struct do_proc_dointvec_minmax_conv_param { int *min; -@@ -2488,6 +2564,34 @@ int proc_dointvec_minmax(struct ctl_table *table, int write, +@@ -2488,6 +2571,34 @@ int proc_dointvec_minmax(struct ctl_table *table, int write, do_proc_dointvec_minmax_conv, ¶m); } @@ -78947,7 +79223,7 @@ index ea7ec7f..b1c7c88 100644 static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos, -@@ -2545,8 +2649,11 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int +@@ -2545,8 +2656,11 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int *i = val; } else { val = convdiv * (*i) / convmul; @@ -78960,7 +79236,7 @@ index ea7ec7f..b1c7c88 100644 err = proc_put_long(&buffer, &left, val, false); if (err) break; -@@ -2941,6 +3048,12 @@ int proc_dostring(struct ctl_table *table, int write, +@@ -2941,6 +3055,12 @@ int proc_dostring(struct ctl_table *table, int write, return -ENOSYS; } @@ -78973,7 +79249,7 @@ index ea7ec7f..b1c7c88 100644 int proc_dointvec(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { -@@ -2997,6 +3110,7 @@ EXPORT_SYMBOL(proc_dointvec_minmax); +@@ -2997,6 +3117,7 @@ EXPORT_SYMBOL(proc_dointvec_minmax); EXPORT_SYMBOL(proc_dointvec_userhz_jiffies); EXPORT_SYMBOL(proc_dointvec_ms_jiffies); EXPORT_SYMBOL(proc_dostring); @@ -87943,6 +88219,24 @@ index 5485077..7e37374 100644 hdr = register_sysctl_paths(net_ipv4_ctl_path, ipv4_table); if (hdr == NULL) +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index fe381c2..ec8b4b7e 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -3037,8 +3037,11 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp, + + for (i = 0; i < shi->nr_frags; ++i) { + const struct skb_frag_struct *f = &shi->frags[i]; +- struct page *page = skb_frag_page(f); +- sg_set_page(&sg, page, skb_frag_size(f), f->page_offset); ++ unsigned int offset = f->page_offset; ++ struct page *page = skb_frag_page(f) + (offset >> PAGE_SHIFT); ++ ++ sg_set_page(&sg, page, skb_frag_size(f), ++ offset_in_page(offset)); + if (crypto_hash_update(desc, &sg, skb_frag_size(f))) + return 1; + } diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 872b41d..54a02f1 100644 --- a/net/ipv4/tcp_input.c @@ -88392,6 +88686,19 @@ index 1567fb1..29af910 100644 __sk_dst_reset(sk); dst = NULL; } +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index 3ccd9b2..6aadaa8 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1233,7 +1233,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, + if (WARN_ON(np->cork.opt)) + return -EINVAL; + +- np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation); ++ np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation); + if (unlikely(np->cork.opt == NULL)) + return -ENOBUFS; + diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index b204df8..8f274f4 100644 --- a/net/ipv6/ipv6_sockglue.c @@ -88926,6 +89233,19 @@ index e71e85b..29340a9 100644 /* Aborting, close connection! */ iriap_disconnect_request(self); +diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c +index 8c00416..9ea0c93 100644 +--- a/net/irda/irlap_frame.c ++++ b/net/irda/irlap_frame.c +@@ -544,7 +544,7 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self, + /* + * We now have some discovery info to deliver! + */ +- discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC); ++ discovery = kzalloc(sizeof(discovery_t), GFP_ATOMIC); + if (!discovery) { + IRDA_WARNING("%s: unable to malloc!\n", __func__); + return; diff --git a/net/irda/irttp.c b/net/irda/irttp.c index 32e3bb0..a4e5eb8 100644 --- a/net/irda/irttp.c diff --git a/3.9.4/0000_README b/3.9.4/0000_README index 1cbe9a3..517433d 100644 --- a/3.9.4/0000_README +++ b/3.9.4/0000_README @@ -2,7 +2,7 @@ README ----------------------------------------------------------------------------- Individual Patch Descriptions: ----------------------------------------------------------------------------- -Patch: 4420_grsecurity-2.9.1-3.9.4-201306011536.patch +Patch: 4420_grsecurity-2.9.1-3.9.4-201306041949.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.9.4/4420_grsecurity-2.9.1-3.9.4-201306011536.patch b/3.9.4/4420_grsecurity-2.9.1-3.9.4-201306041949.patch index 9a1a55c..55d122a 100644 --- a/3.9.4/4420_grsecurity-2.9.1-3.9.4-201306011536.patch +++ b/3.9.4/4420_grsecurity-2.9.1-3.9.4-201306041949.patch @@ -5763,6 +5763,19 @@ index e0a8235..ce2f1e1 100644 ret = __copy_from_user(to, from, n); else copy_from_user_overflow(); +diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c +index 5709c5e..14285ca 100644 +--- a/arch/parisc/kernel/drivers.c ++++ b/arch/parisc/kernel/drivers.c +@@ -394,7 +394,7 @@ EXPORT_SYMBOL(print_pci_hwpath); + static void setup_bus_id(struct parisc_device *padev) + { + struct hardware_path path; +- char name[20]; ++ char name[28]; + char *output = name; + int i; + diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index 2a625fb..9908930 100644 --- a/arch/parisc/kernel/module.c @@ -5866,6 +5879,20 @@ index 2a625fb..9908930 100644 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n", me->arch.unwind_section, table, end, gp); +diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c +index a3328c2..3b812eb 100644 +--- a/arch/parisc/kernel/setup.c ++++ b/arch/parisc/kernel/setup.c +@@ -69,7 +69,8 @@ void __init setup_cmdline(char **cmdline_p) + /* called from hpux boot loader */ + boot_command_line[0] = '\0'; + } else { +- strcpy(boot_command_line, (char *)__va(boot_args[1])); ++ strlcpy(boot_command_line, (char *)__va(boot_args[1]), ++ COMMAND_LINE_SIZE); + + #ifdef CONFIG_BLK_DEV_INITRD + if (boot_args[2] != 0) /* did palo pass us a ramdisk? */ diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 5dfd248..64914ac 100644 --- a/arch/parisc/kernel/sys_parisc.c @@ -31951,7 +31978,7 @@ index f9b983a..887b9d8 100644 return 0; } diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c -index 77a7480..05cde58 100644 +index 77a7480d..05cde58 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c @@ -454,7 +454,7 @@ static void tx_complete (amb_dev * dev, tx_out * tx) { @@ -37505,6 +37532,37 @@ index 89562a8..218999b 100644 capimsg_setu32(skb->data, 8, mp->ncci); /* NCCI */ capimsg_setu32(skb->data, 12, (u32)(long)skb->data);/* Data32 */ capimsg_setu16(skb->data, 16, len); /* Data length */ +diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c +index 9b1b274..c123709 100644 +--- a/drivers/isdn/capi/kcapi.c ++++ b/drivers/isdn/capi/kcapi.c +@@ -93,7 +93,7 @@ capi_ctr_put(struct capi_ctr *ctr) + + static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr) + { +- if (contr - 1 >= CAPI_MAXCONTR) ++ if (contr < 1 || contr - 1 >= CAPI_MAXCONTR) + return NULL; + + return capi_controller[contr - 1]; +@@ -103,7 +103,7 @@ static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid) + { + lockdep_assert_held(&capi_controller_lock); + +- if (applid - 1 >= CAPI_MAXAPPL) ++ if (applid < 1 || applid - 1 >= CAPI_MAXAPPL) + return NULL; + + return capi_applications[applid - 1]; +@@ -111,7 +111,7 @@ static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid) + + static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid) + { +- if (applid - 1 >= CAPI_MAXAPPL) ++ if (applid < 1 || applid - 1 >= CAPI_MAXAPPL) + return NULL; + + return rcu_dereference(capi_applications[applid - 1]); diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index e2b5396..c5486dc 100644 --- a/drivers/isdn/gigaset/interface.c @@ -53758,6 +53816,19 @@ index 1f94167..79c4ce4 100644 } void nfs_fattr_init(struct nfs_fattr *fattr) +diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c +index 0086401..261e9b9 100644 +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1022,7 +1022,7 @@ static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata) + struct nfs4_state *state = opendata->state; + struct nfs_inode *nfsi = NFS_I(state->inode); + struct nfs_delegation *delegation; +- int open_mode = opendata->o_arg.open_flags & (O_EXCL|O_TRUNC); ++ int open_mode = opendata->o_arg.open_flags; + fmode_t fmode = opendata->o_arg.fmode; + nfs4_stateid stateid; + int ret = -EAGAIN; diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index d401d01..10b3e62 100644 --- a/fs/nfsd/nfs4proc.c @@ -55856,6 +55927,19 @@ index fee38e0..12fdf47 100644 if (__put_user(d_off, &lastdirent->d_off)) error = -EFAULT; else +diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c +index 66c53b6..6c2d136 100644 +--- a/fs/reiserfs/dir.c ++++ b/fs/reiserfs/dir.c +@@ -204,6 +204,8 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, + next_pos = deh_offset(deh) + 1; + + if (item_moved(&tmp_ih, &path_to_entry)) { ++ set_cpu_key_k_offset(&pos_key, ++ next_pos); + goto research; + } + } /* for */ diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c index 2b7882b..1c5ef48 100644 --- a/fs/reiserfs/do_balan.c @@ -55869,6 +55953,29 @@ index 2b7882b..1c5ef48 100644 do_balance_starts(tb); /* balance leaf returns 0 except if combining L R and S into +diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c +index ea5061f..c3a9de6 100644 +--- a/fs/reiserfs/inode.c ++++ b/fs/reiserfs/inode.c +@@ -1810,11 +1810,16 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, + TYPE_STAT_DATA, SD_SIZE, MAX_US_INT); + memcpy(INODE_PKEY(inode), &(ih.ih_key), KEY_SIZE); + args.dirid = le32_to_cpu(ih.ih_key.k_dir_id); +- if (insert_inode_locked4(inode, args.objectid, +- reiserfs_find_actor, &args) < 0) { ++ ++ reiserfs_write_unlock(inode->i_sb); ++ err = insert_inode_locked4(inode, args.objectid, ++ reiserfs_find_actor, &args); ++ reiserfs_write_lock(inode->i_sb); ++ if (err) { + err = -EINVAL; + goto out_bad_inode; + } ++ + if (old_format_only(sb)) + /* not a perfect generation count, as object ids can be reused, but + ** this is as good as reiserfs can do right now. diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index 9cc0740a..46bf953 100644 --- a/fs/reiserfs/procfs.c @@ -55904,6 +56011,45 @@ index 157e474..65a6114 100644 #define FILESYSTEM_CHANGED_TB(tb) (get_generation((tb)->tb_sb) != (tb)->fs_gen) #define __fs_changed(gen,s) (gen != get_generation (s)) #define fs_changed(gen,s) \ +diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c +index 4cce1d9..821bcf7 100644 +--- a/fs/reiserfs/xattr.c ++++ b/fs/reiserfs/xattr.c +@@ -318,7 +318,19 @@ static int delete_one_xattr(struct dentry *dentry, void *data) + static int chown_one_xattr(struct dentry *dentry, void *data) + { + struct iattr *attrs = data; +- return reiserfs_setattr(dentry, attrs); ++ int ia_valid = attrs->ia_valid; ++ int err; ++ ++ /* ++ * We only want the ownership bits. Otherwise, we'll do ++ * things like change a directory to a regular file if ++ * ATTR_MODE is set. ++ */ ++ attrs->ia_valid &= (ATTR_UID|ATTR_GID); ++ err = reiserfs_setattr(dentry, attrs); ++ attrs->ia_valid = ia_valid; ++ ++ return err; + } + + /* No i_mutex, but the inode is unconnected. */ +diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c +index d7c01ef..6c8767f 100644 +--- a/fs/reiserfs/xattr_acl.c ++++ b/fs/reiserfs/xattr_acl.c +@@ -443,6 +443,9 @@ int reiserfs_acl_chmod(struct inode *inode) + int depth; + int error; + ++ if (IS_PRIVATE(inode)) ++ return 0; ++ + if (S_ISLNK(inode->i_mode)) + return -EOPNOTSUPP; + diff --git a/fs/select.c b/fs/select.c index 8c1c96c..a0f9b6d 100644 --- a/fs/select.c @@ -56526,7 +56672,7 @@ index d681e34..2a3f5ab 100644 goto out_put; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c -index d82efaa..0904a8e 100644 +index d82efaa..60100c7 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -395,7 +395,7 @@ xfs_vn_put_link( @@ -56538,12 +56684,87 @@ index d82efaa..0904a8e 100644 if (!IS_ERR(s)) kfree(s); +@@ -455,6 +455,28 @@ xfs_vn_getattr( + return 0; + } + ++static void ++xfs_setattr_mode( ++ struct xfs_trans *tp, ++ struct xfs_inode *ip, ++ struct iattr *iattr) ++{ ++ struct inode *inode = VFS_I(ip); ++ umode_t mode = iattr->ia_mode; ++ ++ ASSERT(tp); ++ ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); ++ ++ if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) ++ mode &= ~S_ISGID; ++ ++ ip->i_d.di_mode &= S_IFMT; ++ ip->i_d.di_mode |= mode & ~S_IFMT; ++ ++ inode->i_mode &= S_IFMT; ++ inode->i_mode |= mode & ~S_IFMT; ++} ++ + int + xfs_setattr_nonsize( + struct xfs_inode *ip, +@@ -606,18 +628,8 @@ xfs_setattr_nonsize( + /* + * Change file access modes. + */ +- if (mask & ATTR_MODE) { +- umode_t mode = iattr->ia_mode; +- +- if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) +- mode &= ~S_ISGID; +- +- ip->i_d.di_mode &= S_IFMT; +- ip->i_d.di_mode |= mode & ~S_IFMT; +- +- inode->i_mode &= S_IFMT; +- inode->i_mode |= mode & ~S_IFMT; +- } ++ if (mask & ATTR_MODE) ++ xfs_setattr_mode(tp, ip, iattr); + + /* + * Change file access or modified times. +@@ -714,9 +726,8 @@ xfs_setattr_size( + return XFS_ERROR(error); + + ASSERT(S_ISREG(ip->i_d.di_mode)); +- ASSERT((mask & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| +- ATTR_MTIME_SET|ATTR_KILL_SUID|ATTR_KILL_SGID| +- ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); ++ ASSERT((mask & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| ++ ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); + + if (!(flags & XFS_ATTR_NOLOCK)) { + lock_flags |= XFS_IOLOCK_EXCL; +@@ -860,6 +871,12 @@ xfs_setattr_size( + xfs_inode_clear_eofblocks_tag(ip); + } + ++ /* ++ * Change file access modes. ++ */ ++ if (mask & ATTR_MODE) ++ xfs_setattr_mode(tp, ip, iattr); ++ + if (mask & ATTR_CTIME) { + inode->i_ctime = iattr->ia_ctime; + ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig new file mode 100644 -index 0000000..7174794 +index 0000000..ba9c5e3 --- /dev/null +++ b/grsecurity/Kconfig -@@ -0,0 +1,1031 @@ +@@ -0,0 +1,1053 @@ +# +# grecurity configuration +# @@ -56629,6 +56850,25 @@ index 0000000..7174794 + If you're using KERNEXEC, it's recommended that you enable this option + to supplement the hardening of the kernel. + ++config GRKERNSEC_PERF_HARDEN ++ bool "Disable unprivileged PERF_EVENTS usage by default" ++ default y if GRKERNSEC_CONFIG_AUTO ++ depends on PERF_EVENTS ++ help ++ If you say Y here, the range of acceptable values for the ++ /proc/sys/kernel/perf_event_paranoid sysctl will be expanded to allow and ++ default to a new value: 3. When the sysctl is set to this value, no ++ unprivileged use of the PERF_EVENTS syscall interface will be permitted. ++ ++ Though PERF_EVENTS can be used legitimately for performance monitoring ++ and low-level application profiling, it is forced on regardless of ++ configuration, has been at fault for several vulnerabilities, and ++ creates new opportunities for side channels and other information leaks. ++ ++ This feature puts PERF_EVENTS into a secure default state and permits ++ the administrator to change out of it temporarily if unprivileged ++ application profiling is needed. ++ +config GRKERNSEC_RAND_THREADSTACK + bool "Insert random gaps between thread stacks" + default y if GRKERNSEC_CONFIG_AUTO @@ -56739,6 +56979,9 @@ index 0000000..7174794 + useful protection against local kernel exploitation of overflows + and arbitrary read/write vulnerabilities. + ++ It is highly recommended that you enable GRKERNSEC_PERF_HARDEN ++ in addition to this feature. ++ +config GRKERNSEC_KERN_LOCKOUT + bool "Active kernel exploit response" + default y if GRKERNSEC_CONFIG_AUTO @@ -70441,7 +70684,7 @@ index 45fc162..01a4068 100644 /** * struct hotplug_slot_info - used to notify the hotplug pci core of the state of the slot diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h -index 1d795df..727aa7b 100644 +index 1d795df..b0a6449 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -333,8 +333,8 @@ struct perf_event { @@ -70475,8 +70718,15 @@ index 1d795df..727aa7b 100644 extern int sysctl_perf_event_mlock; extern int sysctl_perf_event_sample_rate; -@@ -714,17 +714,17 @@ extern int perf_proc_update_handler(struct ctl_table *table, int write, +@@ -712,19 +712,24 @@ extern int perf_proc_update_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos); ++static inline bool perf_paranoid_any(void) ++{ ++ return sysctl_perf_event_legitimately_concerned > 2; ++} ++ static inline bool perf_paranoid_tracepoint_raw(void) { - return sysctl_perf_event_paranoid > -1; @@ -70496,7 +70746,7 @@ index 1d795df..727aa7b 100644 } extern void perf_event_init(void); -@@ -812,7 +812,7 @@ static inline void perf_restore_debug_store(void) { } +@@ -812,7 +817,7 @@ static inline void perf_restore_debug_store(void) { } */ #define perf_cpu_notifier(fn) \ do { \ @@ -70505,7 +70755,7 @@ index 1d795df..727aa7b 100644 { .notifier_call = fn, .priority = CPU_PRI_PERF }; \ unsigned long cpu = smp_processor_id(); \ unsigned long flags; \ -@@ -831,7 +831,7 @@ do { \ +@@ -831,7 +836,7 @@ do { \ struct perf_pmu_events_attr { struct device_attribute attr; u64 id; @@ -74632,15 +74882,19 @@ index 00eb8f7..d7e3244 100644 #ifdef CONFIG_MODULE_UNLOAD { diff --git a/kernel/events/core.c b/kernel/events/core.c -index 9fcb094..fd68c54 100644 +index 9fcb094..8370228 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c -@@ -155,7 +155,11 @@ static struct srcu_struct pmus_srcu; +@@ -154,8 +154,15 @@ static struct srcu_struct pmus_srcu; + * 0 - disallow raw tracepoint access for unpriv * 1 - disallow cpu events for unpriv * 2 - disallow kernel profiling for unpriv ++ * 3 - disallow all unpriv perf event use */ -int sysctl_perf_event_paranoid __read_mostly = 1; -+#ifdef CONFIG_GRKERNSEC_HIDESYM ++#ifdef CONFIG_GRKERNSEC_PERF_HARDEN ++int sysctl_perf_event_legitimately_concerned __read_mostly = 3; ++#elif CONFIG_GRKERNSEC_HIDESYM +int sysctl_perf_event_legitimately_concerned __read_mostly = 2; +#else +int sysctl_perf_event_legitimately_concerned __read_mostly = 1; @@ -74648,7 +74902,7 @@ index 9fcb094..fd68c54 100644 /* Minimum for 512 kiB + 1 user control page */ int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */ -@@ -182,7 +186,7 @@ int perf_proc_update_handler(struct ctl_table *table, int write, +@@ -182,7 +189,7 @@ int perf_proc_update_handler(struct ctl_table *table, int write, return 0; } @@ -74657,7 +74911,7 @@ index 9fcb094..fd68c54 100644 static void cpu_ctx_sched_out(struct perf_cpu_context *cpuctx, enum event_type_t event_type); -@@ -2677,7 +2681,7 @@ static void __perf_event_read(void *info) +@@ -2677,7 +2684,7 @@ static void __perf_event_read(void *info) static inline u64 perf_event_count(struct perf_event *event) { @@ -74666,7 +74920,7 @@ index 9fcb094..fd68c54 100644 } static u64 perf_event_read(struct perf_event *event) -@@ -3007,9 +3011,9 @@ u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) +@@ -3007,9 +3014,9 @@ u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) mutex_lock(&event->child_mutex); total += perf_event_read(event); *enabled += event->total_time_enabled + @@ -74678,7 +74932,7 @@ index 9fcb094..fd68c54 100644 list_for_each_entry(child, &event->child_list, child_list) { total += perf_event_read(child); -@@ -3412,10 +3416,10 @@ void perf_event_update_userpage(struct perf_event *event) +@@ -3412,10 +3419,10 @@ void perf_event_update_userpage(struct perf_event *event) userpg->offset -= local64_read(&event->hw.prev_count); userpg->time_enabled = enabled + @@ -74691,7 +74945,7 @@ index 9fcb094..fd68c54 100644 arch_perf_update_userpage(userpg, now); -@@ -3886,7 +3890,7 @@ perf_output_sample_ustack(struct perf_output_handle *handle, u64 dump_size, +@@ -3886,7 +3893,7 @@ perf_output_sample_ustack(struct perf_output_handle *handle, u64 dump_size, /* Data. */ sp = perf_user_stack_pointer(regs); @@ -74700,7 +74954,7 @@ index 9fcb094..fd68c54 100644 dyn_size = dump_size - rem; perf_output_skip(handle, rem); -@@ -3974,11 +3978,11 @@ static void perf_output_read_one(struct perf_output_handle *handle, +@@ -3974,11 +3981,11 @@ static void perf_output_read_one(struct perf_output_handle *handle, values[n++] = perf_event_count(event); if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) { values[n++] = enabled + @@ -74714,7 +74968,7 @@ index 9fcb094..fd68c54 100644 } if (read_format & PERF_FORMAT_ID) values[n++] = primary_event_id(event); -@@ -4726,12 +4730,12 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) +@@ -4726,12 +4733,12 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) * need to add enough zero bytes after the string to handle * the 64bit alignment we do later. */ @@ -74729,7 +74983,7 @@ index 9fcb094..fd68c54 100644 if (IS_ERR(name)) { name = strncpy(tmp, "//toolong", sizeof(tmp)); goto got_name; -@@ -6167,7 +6171,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, +@@ -6167,7 +6174,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, event->parent = parent_event; event->ns = get_pid_ns(task_active_pid_ns(current)); @@ -74738,7 +74992,19 @@ index 9fcb094..fd68c54 100644 event->state = PERF_EVENT_STATE_INACTIVE; -@@ -6795,10 +6799,10 @@ static void sync_child_event(struct perf_event *child_event, +@@ -6463,6 +6470,11 @@ SYSCALL_DEFINE5(perf_event_open, + if (flags & ~PERF_FLAG_ALL) + return -EINVAL; + ++#ifdef CONFIG_GRKERNSEC_PERF_HARDEN ++ if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN)) ++ return -EACCES; ++#endif ++ + err = perf_copy_attr(attr_uptr, &attr); + if (err) + return err; +@@ -6795,10 +6807,10 @@ static void sync_child_event(struct perf_event *child_event, /* * Add back the child's count to the parent's count: */ @@ -78585,7 +78851,7 @@ index 0da73cf..5c2af3c 100644 if (!retval) { if (old_rlim) diff --git a/kernel/sysctl.c b/kernel/sysctl.c -index afc1dc6..5e28bbf 100644 +index afc1dc6..fb0671d 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -93,7 +93,6 @@ @@ -78691,7 +78957,7 @@ index afc1dc6..5e28bbf 100644 { .procname = "ngroups_max", .data = &ngroups_max, -@@ -1026,8 +1059,8 @@ static struct ctl_table kern_table[] = { +@@ -1026,10 +1059,17 @@ static struct ctl_table kern_table[] = { */ { .procname = "perf_event_paranoid", @@ -78700,9 +78966,19 @@ index afc1dc6..5e28bbf 100644 + .data = &sysctl_perf_event_legitimately_concerned, + .maxlen = sizeof(sysctl_perf_event_legitimately_concerned), .mode = 0644, - .proc_handler = proc_dointvec, +- .proc_handler = proc_dointvec, ++ /* go ahead, be a hero */ ++ .proc_handler = proc_dointvec_minmax_sysadmin, ++ .extra1 = &zero, ++#ifdef CONFIG_GRKERNSEC_PERF_HARDEN ++ .extra2 = &three, ++#else ++ .extra2 = &two, ++#endif }, -@@ -1283,6 +1316,13 @@ static struct ctl_table vm_table[] = { + { + .procname = "perf_event_mlock_kb", +@@ -1283,6 +1323,13 @@ static struct ctl_table vm_table[] = { .proc_handler = proc_dointvec_minmax, .extra1 = &zero, }, @@ -78716,7 +78992,7 @@ index afc1dc6..5e28bbf 100644 #else { .procname = "nr_trim_pages", -@@ -1733,6 +1773,16 @@ int proc_dostring(struct ctl_table *table, int write, +@@ -1733,6 +1780,16 @@ int proc_dostring(struct ctl_table *table, int write, buffer, lenp, ppos); } @@ -78733,7 +79009,7 @@ index afc1dc6..5e28bbf 100644 static size_t proc_skip_spaces(char **buf) { size_t ret; -@@ -1838,6 +1888,8 @@ static int proc_put_long(void __user **buf, size_t *size, unsigned long val, +@@ -1838,6 +1895,8 @@ static int proc_put_long(void __user **buf, size_t *size, unsigned long val, len = strlen(tmp); if (len > *size) len = *size; @@ -78742,7 +79018,7 @@ index afc1dc6..5e28bbf 100644 if (copy_to_user(*buf, tmp, len)) return -EFAULT; *size -= len; -@@ -2002,7 +2054,7 @@ int proc_dointvec(struct ctl_table *table, int write, +@@ -2002,7 +2061,7 @@ int proc_dointvec(struct ctl_table *table, int write, static int proc_taint(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { @@ -78751,7 +79027,7 @@ index afc1dc6..5e28bbf 100644 unsigned long tmptaint = get_taint(); int err; -@@ -2030,7 +2082,6 @@ static int proc_taint(struct ctl_table *table, int write, +@@ -2030,7 +2089,6 @@ static int proc_taint(struct ctl_table *table, int write, return err; } @@ -78759,7 +79035,7 @@ index afc1dc6..5e28bbf 100644 static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { -@@ -2039,7 +2090,6 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, +@@ -2039,7 +2097,6 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, return proc_dointvec_minmax(table, write, buffer, lenp, ppos); } @@ -78767,7 +79043,7 @@ index afc1dc6..5e28bbf 100644 struct do_proc_dointvec_minmax_conv_param { int *min; -@@ -2186,8 +2236,11 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int +@@ -2186,8 +2243,11 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int *i = val; } else { val = convdiv * (*i) / convmul; @@ -78780,7 +79056,7 @@ index afc1dc6..5e28bbf 100644 err = proc_put_long(&buffer, &left, val, false); if (err) break; -@@ -2579,6 +2632,12 @@ int proc_dostring(struct ctl_table *table, int write, +@@ -2579,6 +2639,12 @@ int proc_dostring(struct ctl_table *table, int write, return -ENOSYS; } @@ -78793,7 +79069,7 @@ index afc1dc6..5e28bbf 100644 int proc_dointvec(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { -@@ -2635,5 +2694,6 @@ EXPORT_SYMBOL(proc_dointvec_minmax); +@@ -2635,5 +2701,6 @@ EXPORT_SYMBOL(proc_dointvec_minmax); EXPORT_SYMBOL(proc_dointvec_userhz_jiffies); EXPORT_SYMBOL(proc_dointvec_ms_jiffies); EXPORT_SYMBOL(proc_dostring); @@ -87120,6 +87396,24 @@ index 960fd29..d55bf64 100644 hdr = register_net_sysctl(&init_net, "net/ipv4", ipv4_table); if (hdr == NULL) +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index e220207..cdeb839 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -3383,8 +3383,11 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp, + + for (i = 0; i < shi->nr_frags; ++i) { + const struct skb_frag_struct *f = &shi->frags[i]; +- struct page *page = skb_frag_page(f); +- sg_set_page(&sg, page, skb_frag_size(f), f->page_offset); ++ unsigned int offset = f->page_offset; ++ struct page *page = skb_frag_page(f) + (offset >> PAGE_SHIFT); ++ ++ sg_set_page(&sg, page, skb_frag_size(f), ++ offset_in_page(offset)); + if (crypto_hash_update(desc, &sg, skb_frag_size(f))) + return 1; + } diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 13b9c08..d33a8d0 100644 --- a/net/ipv4/tcp_input.c @@ -87527,6 +87821,19 @@ index 95d13c7..791fe2f 100644 .kind = "ip6gretap", .maxtype = IFLA_GRE_MAX, .policy = ip6gre_policy, +diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c +index 155eccf..851fdae 100644 +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1147,7 +1147,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, + if (WARN_ON(np->cork.opt)) + return -EINVAL; + +- np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation); ++ np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation); + if (unlikely(np->cork.opt == NULL)) + return -ENOBUFS; + diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index fff83cb..82d49dd 100644 --- a/net/ipv6/ip6_tunnel.c @@ -88061,6 +88368,19 @@ index 362ba47..66196f4 100644 seq_printf(m, "Max data size: %d\n", self->max_data_size); seq_printf(m, "Max header size: %d\n", self->max_header_size); +diff --git a/net/irda/irlap_frame.c b/net/irda/irlap_frame.c +index 8c00416..9ea0c93 100644 +--- a/net/irda/irlap_frame.c ++++ b/net/irda/irlap_frame.c +@@ -544,7 +544,7 @@ static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self, + /* + * We now have some discovery info to deliver! + */ +- discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC); ++ discovery = kzalloc(sizeof(discovery_t), GFP_ATOMIC); + if (!discovery) { + IRDA_WARNING("%s: unable to malloc!\n", __func__); + return; diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 206ce6d..cfb27cd 100644 --- a/net/iucv/af_iucv.c @@ -90413,6 +90733,18 @@ index c8717c1..08539f5 100644 err = handler(dev, info, (union iwreq_data *) iwp, extra); iwp->length += essid_compat; +diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c +index bcfda89..0cf003d 100644 +--- a/net/xfrm/xfrm_output.c ++++ b/net/xfrm/xfrm_output.c +@@ -64,6 +64,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err) + + if (unlikely(x->km.state != XFRM_STATE_VALID)) { + XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTSTATEINVALID); ++ err = -EINVAL; + goto error; + } + diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 167c67d..3f2ae427 100644 --- a/net/xfrm/xfrm_policy.c |