* [gentoo-commits] proj/hardened-patchset:master commit in: 4.3.3/
@ 2015-12-17 8:10 Anthony G. Basile
0 siblings, 0 replies; 7+ messages in thread
From: Anthony G. Basile @ 2015-12-17 8:10 UTC (permalink / raw
To: gentoo-commits
commit: 6485ed4c6c7b75478f316358112481024754b2fb
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Thu Dec 17 08:16:43 2015 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Thu Dec 17 08:16:43 2015 +0000
URL: https://gitweb.gentoo.org/proj/hardened-patchset.git/commit/?id=6485ed4c
grsecurity-3.1-4.3.3-201512162141
4.3.3/0000_README | 2 +-
...> 4420_grsecurity-3.1-4.3.3-201512162141.patch} | 172 +++++++++++++++++----
2 files changed, 142 insertions(+), 32 deletions(-)
diff --git a/4.3.3/0000_README b/4.3.3/0000_README
index 651d7dc..3e1d5a0 100644
--- a/4.3.3/0000_README
+++ b/4.3.3/0000_README
@@ -6,7 +6,7 @@ Patch: 1002_linux-4.3.3.patch
From: http://www.kernel.org
Desc: Linux 4.3.3
-Patch: 4420_grsecurity-3.1-4.3.3-201512151908.patch
+Patch: 4420_grsecurity-3.1-4.3.3-201512162141.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/4.3.3/4420_grsecurity-3.1-4.3.3-201512151908.patch b/4.3.3/4420_grsecurity-3.1-4.3.3-201512162141.patch
similarity index 99%
rename from 4.3.3/4420_grsecurity-3.1-4.3.3-201512151908.patch
rename to 4.3.3/4420_grsecurity-3.1-4.3.3-201512162141.patch
index 38b71b4..4b7bff5 100644
--- a/4.3.3/4420_grsecurity-3.1-4.3.3-201512151908.patch
+++ b/4.3.3/4420_grsecurity-3.1-4.3.3-201512162141.patch
@@ -2622,7 +2622,7 @@ index 3e1c26e..9ea61e6 100644
#endif
mov r5, r0
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
-index 30a7228..fc55cca 100644
+index 30a7228..d071196 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -11,18 +11,46 @@
@@ -2675,7 +2675,29 @@ index 30a7228..fc55cca 100644
.align 5
#if !(IS_ENABLED(CONFIG_TRACE_IRQFLAGS) || IS_ENABLED(CONFIG_CONTEXT_TRACKING))
/*
-@@ -199,6 +227,12 @@ ENTRY(vector_swi)
+@@ -36,7 +64,9 @@ ret_fast_syscall:
+ UNWIND(.cantunwind )
+ disable_irq_notrace @ disable interrupts
+ ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing
+- tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK
++ tst r1, #_TIF_SYSCALL_WORK
++ bne fast_work_pending
++ tst r1, #_TIF_WORK_MASK
+ bne fast_work_pending
+
+ /* perform architecture specific actions before user return */
+@@ -62,7 +92,9 @@ ret_fast_syscall:
+ str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
+ disable_irq_notrace @ disable interrupts
+ ldr r1, [tsk, #TI_FLAGS] @ re-check for syscall tracing
+- tst r1, #_TIF_SYSCALL_WORK | _TIF_WORK_MASK
++ tst r1, #_TIF_SYSCALL_WORK
++ bne __sys_trace_return_nosave
++ tst r1, #_TIF_WORK_MASK
+ beq no_work_pending
+ UNWIND(.fnend )
+ ENDPROC(ret_fast_syscall)
+@@ -199,6 +231,12 @@ ENTRY(vector_swi)
uaccess_disable tbl
@@ -56491,9 +56513,76 @@ index c3fe026..9cfe421 100644
dlci->modem_rx = 0;
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
-index a0285da..bddb306 100644
+index a0285da..e84f8de 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
+@@ -1514,7 +1514,7 @@ n_tty_receive_char_lnext(struct tty_struct *tty, unsigned char c, char flag)
+
+ static void
+ n_tty_receive_buf_real_raw(struct tty_struct *tty, const unsigned char *cp,
+- char *fp, int count)
++ char *fp, size_t count)
+ {
+ struct n_tty_data *ldata = tty->disc_data;
+ size_t n, head;
+@@ -1534,7 +1534,7 @@ n_tty_receive_buf_real_raw(struct tty_struct *tty, const unsigned char *cp,
+
+ static void
+ n_tty_receive_buf_raw(struct tty_struct *tty, const unsigned char *cp,
+- char *fp, int count)
++ char *fp, size_t count)
+ {
+ struct n_tty_data *ldata = tty->disc_data;
+ char flag = TTY_NORMAL;
+@@ -1551,7 +1551,7 @@ n_tty_receive_buf_raw(struct tty_struct *tty, const unsigned char *cp,
+
+ static void
+ n_tty_receive_buf_closing(struct tty_struct *tty, const unsigned char *cp,
+- char *fp, int count)
++ char *fp, size_t count)
+ {
+ char flag = TTY_NORMAL;
+
+@@ -1567,7 +1567,7 @@ n_tty_receive_buf_closing(struct tty_struct *tty, const unsigned char *cp,
+
+ static void
+ n_tty_receive_buf_standard(struct tty_struct *tty, const unsigned char *cp,
+- char *fp, int count)
++ char *fp, size_t count)
+ {
+ struct n_tty_data *ldata = tty->disc_data;
+ char flag = TTY_NORMAL;
+@@ -1601,7 +1601,7 @@ n_tty_receive_buf_standard(struct tty_struct *tty, const unsigned char *cp,
+
+ static void
+ n_tty_receive_buf_fast(struct tty_struct *tty, const unsigned char *cp,
+- char *fp, int count)
++ char *fp, size_t count)
+ {
+ struct n_tty_data *ldata = tty->disc_data;
+ char flag = TTY_NORMAL;
+@@ -1626,7 +1626,7 @@ n_tty_receive_buf_fast(struct tty_struct *tty, const unsigned char *cp,
+ }
+
+ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,
+- char *fp, int count)
++ char *fp, size_t count)
+ {
+ struct n_tty_data *ldata = tty->disc_data;
+ bool preops = I_ISTRIP(tty) || (I_IUCLC(tty) && L_IEXTEN(tty));
+@@ -1704,10 +1704,10 @@ static void __receive_buf(struct tty_struct *tty, const unsigned char *cp,
+ */
+ static int
+ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp,
+- char *fp, int count, int flow)
++ char *fp, size_t count, int flow)
+ {
+ struct n_tty_data *ldata = tty->disc_data;
+- int room, n, rcvd = 0, overflow;
++ size_t room, n, rcvd = 0, overflow;
+
+ down_read(&tty->termios_rwsem);
+
@@ -2583,6 +2583,7 @@ void n_tty_inherit_ops(struct tty_ldisc_ops *ops)
{
*ops = tty_ldisc_N_TTY;
@@ -121765,7 +121854,7 @@ index c10a9ee..c621a01 100644
return -ENOMEM;
}
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
-index 3939dd2..d99c89d 100644
+index 3939dd2..ea4fbed 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -178,7 +178,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
@@ -121786,7 +121875,20 @@ index 3939dd2..d99c89d 100644
.autoconf = 1,
.force_mld_version = 0,
.mldv1_unsolicited_report_interval = 10 * HZ,
-@@ -636,7 +636,7 @@ static int inet6_netconf_dump_devconf(struct sk_buff *skb,
+@@ -349,6 +349,12 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
+ setup_timer(&ndev->rs_timer, addrconf_rs_timer,
+ (unsigned long)ndev);
+ memcpy(&ndev->cnf, dev_net(dev)->ipv6.devconf_dflt, sizeof(ndev->cnf));
++
++ if (ndev->cnf.stable_secret.initialized)
++ ndev->addr_gen_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
++ else
++ ndev->addr_gen_mode = IN6_ADDR_GEN_MODE_EUI64;
++
+ ndev->cnf.mtu6 = dev->mtu;
+ ndev->cnf.sysctl = NULL;
+ ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
+@@ -636,7 +642,7 @@ static int inet6_netconf_dump_devconf(struct sk_buff *skb,
idx = 0;
head = &net->dev_index_head[h];
rcu_read_lock();
@@ -121795,7 +121897,7 @@ index 3939dd2..d99c89d 100644
net->dev_base_seq;
hlist_for_each_entry_rcu(dev, head, index_hlist) {
if (idx < s_idx)
-@@ -2576,7 +2576,7 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg)
+@@ -2576,7 +2582,7 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg)
p.iph.ihl = 5;
p.iph.protocol = IPPROTO_IPV6;
p.iph.ttl = 64;
@@ -121804,7 +121906,7 @@ index 3939dd2..d99c89d 100644
if (ops->ndo_do_ioctl) {
mm_segment_t oldfs = get_fs();
-@@ -3844,16 +3844,23 @@ static const struct file_operations if6_fops = {
+@@ -3844,16 +3850,23 @@ static const struct file_operations if6_fops = {
.release = seq_release_net,
};
@@ -121829,7 +121931,7 @@ index 3939dd2..d99c89d 100644
}
static struct pernet_operations if6_proc_net_ops = {
-@@ -4472,7 +4479,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
+@@ -4472,7 +4485,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
s_ip_idx = ip_idx = cb->args[2];
rcu_read_lock();
@@ -121838,7 +121940,7 @@ index 3939dd2..d99c89d 100644
for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
idx = 0;
head = &net->dev_index_head[h];
-@@ -5140,7 +5147,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
+@@ -5140,7 +5153,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
rt_genid_bump_ipv6(net);
break;
}
@@ -121847,7 +121949,7 @@ index 3939dd2..d99c89d 100644
}
static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
-@@ -5160,7 +5167,7 @@ int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
+@@ -5160,7 +5173,7 @@ int addrconf_sysctl_forward(struct ctl_table *ctl, int write,
int *valp = ctl->data;
int val = *valp;
loff_t pos = *ppos;
@@ -121856,7 +121958,7 @@ index 3939dd2..d99c89d 100644
int ret;
/*
-@@ -5185,7 +5192,7 @@ int addrconf_sysctl_mtu(struct ctl_table *ctl, int write,
+@@ -5185,7 +5198,7 @@ int addrconf_sysctl_mtu(struct ctl_table *ctl, int write,
{
struct inet6_dev *idev = ctl->extra1;
int min_mtu = IPV6_MIN_MTU;
@@ -121865,7 +121967,7 @@ index 3939dd2..d99c89d 100644
lctl = *ctl;
lctl.extra1 = &min_mtu;
-@@ -5260,7 +5267,7 @@ int addrconf_sysctl_disable(struct ctl_table *ctl, int write,
+@@ -5260,7 +5273,7 @@ int addrconf_sysctl_disable(struct ctl_table *ctl, int write,
int *valp = ctl->data;
int val = *valp;
loff_t pos = *ppos;
@@ -121874,7 +121976,7 @@ index 3939dd2..d99c89d 100644
int ret;
/*
-@@ -5325,7 +5332,7 @@ static int addrconf_sysctl_stable_secret(struct ctl_table *ctl, int write,
+@@ -5325,7 +5338,7 @@ static int addrconf_sysctl_stable_secret(struct ctl_table *ctl, int write,
int err;
struct in6_addr addr;
char str[IPV6_MAX_STRLEN];
@@ -121883,7 +121985,7 @@ index 3939dd2..d99c89d 100644
struct net *net = ctl->extra2;
struct ipv6_stable_secret *secret = ctl->data;
-@@ -5397,7 +5404,7 @@ int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl,
+@@ -5397,7 +5410,7 @@ int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl,
int *valp = ctl->data;
int val = *valp;
loff_t pos = *ppos;
@@ -124486,7 +124588,7 @@ index 26d50c5..dfae665 100644
table = kmemdup(sctp_net_table, sizeof(sctp_net_table), GFP_KERNEL);
diff --git a/net/socket.c b/net/socket.c
-index 9963a0b..aca2d16 100644
+index 9963a0b..b88ff74 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -89,6 +89,7 @@
@@ -124687,7 +124789,15 @@ index 9963a0b..aca2d16 100644
int err, err2;
int fput_needed;
-@@ -1927,7 +1992,7 @@ static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
+@@ -1702,6 +1767,7 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
+ msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
+ /* We assume all kernel code knows the size of sockaddr_storage */
+ msg.msg_namelen = 0;
++ msg.msg_iocb = NULL;
+ if (sock->file->f_flags & O_NONBLOCK)
+ flags |= MSG_DONTWAIT;
+ err = sock_recvmsg(sock, &msg, iov_iter_count(&msg.msg_iter), flags);
+@@ -1927,7 +1993,7 @@ static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,
* checking falls down on this.
*/
if (copy_from_user(ctl_buf,
@@ -124696,7 +124806,7 @@ index 9963a0b..aca2d16 100644
ctl_len))
goto out_freectl;
msg_sys->msg_control = ctl_buf;
-@@ -2077,7 +2142,7 @@ static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
+@@ -2077,7 +2143,7 @@ static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg,
ssize_t err;
/* kernel mode address */
@@ -124705,7 +124815,7 @@ index 9963a0b..aca2d16 100644
/* user mode address pointers */
struct sockaddr __user *uaddr;
-@@ -2722,7 +2787,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
+@@ -2722,7 +2788,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32)
ifr = compat_alloc_user_space(buf_size);
rxnfc = (void __user *)ifr + ALIGN(sizeof(struct ifreq), 8);
@@ -124714,7 +124824,7 @@ index 9963a0b..aca2d16 100644
return -EFAULT;
if (put_user(convert_in ? rxnfc : compat_ptr(data),
-@@ -2833,7 +2898,7 @@ static int bond_ioctl(struct net *net, unsigned int cmd,
+@@ -2833,7 +2899,7 @@ static int bond_ioctl(struct net *net, unsigned int cmd,
old_fs = get_fs();
set_fs(KERNEL_DS);
err = dev_ioctl(net, cmd,
@@ -124723,7 +124833,7 @@ index 9963a0b..aca2d16 100644
set_fs(old_fs);
return err;
-@@ -2926,7 +2991,7 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
+@@ -2926,7 +2992,7 @@ static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
old_fs = get_fs();
set_fs(KERNEL_DS);
@@ -124732,7 +124842,7 @@ index 9963a0b..aca2d16 100644
set_fs(old_fs);
if (cmd == SIOCGIFMAP && !err) {
-@@ -3010,7 +3075,7 @@ static int routing_ioctl(struct net *net, struct socket *sock,
+@@ -3010,7 +3076,7 @@ static int routing_ioctl(struct net *net, struct socket *sock,
ret |= get_user(rtdev, &(ur4->rt_dev));
if (rtdev) {
ret |= copy_from_user(devname, compat_ptr(rtdev), 15);
@@ -124741,7 +124851,7 @@ index 9963a0b..aca2d16 100644
devname[15] = 0;
} else
r4.rt_dev = NULL;
-@@ -3237,8 +3302,8 @@ int kernel_getsockopt(struct socket *sock, int level, int optname,
+@@ -3237,8 +3303,8 @@ int kernel_getsockopt(struct socket *sock, int level, int optname,
int __user *uoptlen;
int err;
@@ -124752,7 +124862,7 @@ index 9963a0b..aca2d16 100644
set_fs(KERNEL_DS);
if (level == SOL_SOCKET)
-@@ -3258,7 +3323,7 @@ int kernel_setsockopt(struct socket *sock, int level, int optname,
+@@ -3258,7 +3324,7 @@ int kernel_setsockopt(struct socket *sock, int level, int optname,
char __user *uoptval;
int err;
@@ -133880,10 +133990,10 @@ index 0000000..f74d85a
+targets += size_overflow_hash.h size_overflow_hash_aux.h disable_size_overflow_hash.h
diff --git a/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data b/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data
new file mode 100644
-index 0000000..eeb57be
+index 0000000..b7a7596
--- /dev/null
+++ b/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data
-@@ -0,0 +1,12429 @@
+@@ -0,0 +1,12431 @@
+disable_so_interrupt_pnode_gru_message_queue_desc_4 interrupt_pnode gru_message_queue_desc 0 4 NULL
+disable_so_bch_btree_insert_fndecl_12 bch_btree_insert fndecl 0 12 NULL
+disable_so_macvlan_sync_address_fndecl_22 macvlan_sync_address fndecl 0 22 NULL nohasharray
@@ -146313,6 +146423,8 @@ index 0000000..eeb57be
+enable_so_rate_n_flags_iwlagn_tx_resp_63401 rate_n_flags iwlagn_tx_resp 0 63401 NULL
+enable_so_iwlagn_hwrate_to_mac80211_idx_fndecl_57485 iwlagn_hwrate_to_mac80211_idx fndecl 0-1 57485 NULL
+enable_so_rate_n_flags_iwl_rx_phy_info_45542 rate_n_flags iwl_rx_phy_info 0 45542 NULL
++enable_so_deh_location_reiserfs_de_head_7682 deh_location reiserfs_de_head 0 7682 NULL
++enable_so_deh_offset_reiserfs_de_head_42314 deh_offset reiserfs_de_head 0 42314 NULL
diff --git a/tools/gcc/size_overflow_plugin/generate_size_overflow_hash.sh b/tools/gcc/size_overflow_plugin/generate_size_overflow_hash.sh
new file mode 100644
index 0000000..be9724d
@@ -148556,10 +148668,10 @@ index 0000000..fc58e16
+}
diff --git a/tools/gcc/size_overflow_plugin/size_overflow_hash.data b/tools/gcc/size_overflow_plugin/size_overflow_hash.data
new file mode 100644
-index 0000000..311b440
+index 0000000..7a7776b
--- /dev/null
+++ b/tools/gcc/size_overflow_plugin/size_overflow_hash.data
-@@ -0,0 +1,21748 @@
+@@ -0,0 +1,21746 @@
+enable_so_recv_ctrl_pipe_us_data_0 recv_ctrl_pipe us_data 0 0 NULL
+enable_so___earlyonly_bootmem_alloc_fndecl_3 __earlyonly_bootmem_alloc fndecl 2-3-4 3 NULL
+enable_so_size_ttm_mem_reg_8 size ttm_mem_reg 0 8 NULL
@@ -151082,8 +151194,7 @@ index 0000000..311b440
+enable_so_rds_sendmsg_fndecl_7675 rds_sendmsg fndecl 3 7675 NULL
+enable_so_nfsd_max_blksize_vardecl_7678 nfsd_max_blksize vardecl 0 7678 NULL
+enable_so_shmem_read_mapping_page_gfp_fndecl_7681 shmem_read_mapping_page_gfp fndecl 2 7681 NULL
-+enable_so_deh_location_reiserfs_de_head_7682 deh_location reiserfs_de_head 0 7682 NULL nohasharray
-+enable_so_UniStrnlen_fndecl_7682 UniStrnlen fndecl 0 7682 &enable_so_deh_location_reiserfs_de_head_7682
++enable_so_UniStrnlen_fndecl_7682 UniStrnlen fndecl 0 7682 NULL
+enable_so_pm860x_page_bulk_read_fndecl_7685 pm860x_page_bulk_read fndecl 3 7685 NULL nohasharray
+enable_so_l1oip_socket_send_fndecl_7685 l1oip_socket_send fndecl 7 7685 &enable_so_pm860x_page_bulk_read_fndecl_7685
+enable_so_ipoib_dev_init_fndecl_7687 ipoib_dev_init fndecl 3 7687 NULL nohasharray
@@ -162643,8 +162754,7 @@ index 0000000..311b440
+enable_so_ubi_more_leb_change_data_fndecl_42301 ubi_more_leb_change_data fndecl 4 42301 &enable_so_generic_cont_expand_simple_fndecl_42301
+enable_so_dcache_dir_lseek_fndecl_42308 dcache_dir_lseek fndecl 2 42308 NULL nohasharray
+enable_so_iwch_reg_user_mr_fndecl_42308 iwch_reg_user_mr fndecl 2-3 42308 &enable_so_dcache_dir_lseek_fndecl_42308
-+enable_so_deh_offset_reiserfs_de_head_42314 deh_offset reiserfs_de_head 0 42314 NULL nohasharray
-+enable_so_rproc_alloc_fndecl_42314 rproc_alloc fndecl 5 42314 &enable_so_deh_offset_reiserfs_de_head_42314
++enable_so_rproc_alloc_fndecl_42314 rproc_alloc fndecl 5 42314 NULL
+enable_so_log_pg_sz_remote_qpn_mlx5_qp_context_42315 log_pg_sz_remote_qpn mlx5_qp_context 0 42315 NULL
+enable_so_num_rcv_contexts_hfi1_devdata_42317 num_rcv_contexts hfi1_devdata 0 42317 NULL
+enable_so_kvm_write_guest_page_fndecl_42320 kvm_write_guest_page fndecl 2-5 42320 NULL nohasharray
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [gentoo-commits] proj/hardened-patchset:master commit in: 4.3.3/
@ 2015-12-23 7:52 Anthony G. Basile
0 siblings, 0 replies; 7+ messages in thread
From: Anthony G. Basile @ 2015-12-23 7:52 UTC (permalink / raw
To: gentoo-commits
commit: 3cf9059c012c71a2844696f25f29fcbd3dacbfc0
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 23 07:58:43 2015 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Wed Dec 23 07:58:43 2015 +0000
URL: https://gitweb.gentoo.org/proj/hardened-patchset.git/commit/?id=3cf9059c
grsecurity-3.1-4.3.3-201512222129
4.3.3/0000_README | 6 +-
4.3.3/1002_linux-4.3.3.patch | 4424 --------------------
...> 4420_grsecurity-3.1-4.3.3-201512222129.patch} | 295 +-
3 files changed, 241 insertions(+), 4484 deletions(-)
diff --git a/4.3.3/0000_README b/4.3.3/0000_README
index 3e1d5a0..2c1a853 100644
--- a/4.3.3/0000_README
+++ b/4.3.3/0000_README
@@ -2,11 +2,7 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 1002_linux-4.3.3.patch
-From: http://www.kernel.org
-Desc: Linux 4.3.3
-
-Patch: 4420_grsecurity-3.1-4.3.3-201512162141.patch
+Patch: 4420_grsecurity-3.1-4.3.3-201512222129.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/4.3.3/1002_linux-4.3.3.patch b/4.3.3/1002_linux-4.3.3.patch
deleted file mode 100644
index d8cd741..0000000
--- a/4.3.3/1002_linux-4.3.3.patch
+++ /dev/null
@@ -1,4424 +0,0 @@
-diff --git a/Makefile b/Makefile
-index 1a4953b..2070d16 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1,6 +1,6 @@
- VERSION = 4
- PATCHLEVEL = 3
--SUBLEVEL = 2
-+SUBLEVEL = 3
- EXTRAVERSION =
- NAME = Blurry Fish Butt
-
-diff --git a/block/blk-merge.c b/block/blk-merge.c
-index c4e9c37..0e5f4fc 100644
---- a/block/blk-merge.c
-+++ b/block/blk-merge.c
-@@ -91,7 +91,7 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
-
- seg_size += bv.bv_len;
- bvprv = bv;
-- bvprvp = &bv;
-+ bvprvp = &bvprv;
- sectors += bv.bv_len >> 9;
- continue;
- }
-@@ -101,7 +101,7 @@ new_segment:
-
- nsegs++;
- bvprv = bv;
-- bvprvp = &bv;
-+ bvprvp = &bvprv;
- seg_size = bv.bv_len;
- sectors += bv.bv_len >> 9;
- }
-diff --git a/certs/.gitignore b/certs/.gitignore
-new file mode 100644
-index 0000000..f51aea4
---- /dev/null
-+++ b/certs/.gitignore
-@@ -0,0 +1,4 @@
-+#
-+# Generated files
-+#
-+x509_certificate_list
-diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
-index 128e7df..8630a77 100644
---- a/drivers/block/rbd.c
-+++ b/drivers/block/rbd.c
-@@ -3444,6 +3444,7 @@ static void rbd_queue_workfn(struct work_struct *work)
- goto err_rq;
- }
- img_request->rq = rq;
-+ snapc = NULL; /* img_request consumes a ref */
-
- if (op_type == OBJ_OP_DISCARD)
- result = rbd_img_request_fill(img_request, OBJ_REQUEST_NODATA,
-diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
-index f51d376..c2f5117 100644
---- a/drivers/firewire/ohci.c
-+++ b/drivers/firewire/ohci.c
-@@ -3675,6 +3675,11 @@ static int pci_probe(struct pci_dev *dev,
-
- reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0);
- ohci->it_context_support = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet);
-+ /* JMicron JMB38x often shows 0 at first read, just ignore it */
-+ if (!ohci->it_context_support) {
-+ ohci_notice(ohci, "overriding IsoXmitIntMask\n");
-+ ohci->it_context_support = 0xf;
-+ }
- reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0);
- ohci->it_context_mask = ohci->it_context_support;
- ohci->n_it = hweight32(ohci->it_context_mask);
-diff --git a/drivers/media/pci/cobalt/Kconfig b/drivers/media/pci/cobalt/Kconfig
-index 1f88ccc..a01f0cc 100644
---- a/drivers/media/pci/cobalt/Kconfig
-+++ b/drivers/media/pci/cobalt/Kconfig
-@@ -1,6 +1,6 @@
- config VIDEO_COBALT
- tristate "Cisco Cobalt support"
-- depends on VIDEO_V4L2 && I2C && MEDIA_CONTROLLER
-+ depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API
- depends on PCI_MSI && MTD_COMPLEX_MAPPINGS
- depends on GPIOLIB || COMPILE_TEST
- depends on SND
-diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
-index a937772..7f709cb 100644
---- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
-+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
-@@ -1583,8 +1583,14 @@ err_disable_device:
- static void nicvf_remove(struct pci_dev *pdev)
- {
- struct net_device *netdev = pci_get_drvdata(pdev);
-- struct nicvf *nic = netdev_priv(netdev);
-- struct net_device *pnetdev = nic->pnicvf->netdev;
-+ struct nicvf *nic;
-+ struct net_device *pnetdev;
-+
-+ if (!netdev)
-+ return;
-+
-+ nic = netdev_priv(netdev);
-+ pnetdev = nic->pnicvf->netdev;
-
- /* Check if this Qset is assigned to different VF.
- * If yes, clean primary and all secondary Qsets.
-diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
-index 731423c..8bead97 100644
---- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
-+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
-@@ -4934,26 +4934,41 @@ static void rem_slave_counters(struct mlx4_dev *dev, int slave)
- struct res_counter *counter;
- struct res_counter *tmp;
- int err;
-- int index;
-+ int *counters_arr = NULL;
-+ int i, j;
-
- err = move_all_busy(dev, slave, RES_COUNTER);
- if (err)
- mlx4_warn(dev, "rem_slave_counters: Could not move all counters - too busy for slave %d\n",
- slave);
-
-- spin_lock_irq(mlx4_tlock(dev));
-- list_for_each_entry_safe(counter, tmp, counter_list, com.list) {
-- if (counter->com.owner == slave) {
-- index = counter->com.res_id;
-- rb_erase(&counter->com.node,
-- &tracker->res_tree[RES_COUNTER]);
-- list_del(&counter->com.list);
-- kfree(counter);
-- __mlx4_counter_free(dev, index);
-+ counters_arr = kmalloc_array(dev->caps.max_counters,
-+ sizeof(*counters_arr), GFP_KERNEL);
-+ if (!counters_arr)
-+ return;
-+
-+ do {
-+ i = 0;
-+ j = 0;
-+ spin_lock_irq(mlx4_tlock(dev));
-+ list_for_each_entry_safe(counter, tmp, counter_list, com.list) {
-+ if (counter->com.owner == slave) {
-+ counters_arr[i++] = counter->com.res_id;
-+ rb_erase(&counter->com.node,
-+ &tracker->res_tree[RES_COUNTER]);
-+ list_del(&counter->com.list);
-+ kfree(counter);
-+ }
-+ }
-+ spin_unlock_irq(mlx4_tlock(dev));
-+
-+ while (j < i) {
-+ __mlx4_counter_free(dev, counters_arr[j++]);
- mlx4_release_resource(dev, slave, RES_COUNTER, 1, 0);
- }
-- }
-- spin_unlock_irq(mlx4_tlock(dev));
-+ } while (i);
-+
-+ kfree(counters_arr);
- }
-
- static void rem_slave_xrcdns(struct mlx4_dev *dev, int slave)
-diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
-index 59874d6..443632d 100644
---- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
-+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
-@@ -1332,6 +1332,42 @@ static int mlx5e_modify_tir_lro(struct mlx5e_priv *priv, int tt)
- return err;
- }
-
-+static int mlx5e_refresh_tir_self_loopback_enable(struct mlx5_core_dev *mdev,
-+ u32 tirn)
-+{
-+ void *in;
-+ int inlen;
-+ int err;
-+
-+ inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
-+ in = mlx5_vzalloc(inlen);
-+ if (!in)
-+ return -ENOMEM;
-+
-+ MLX5_SET(modify_tir_in, in, bitmask.self_lb_en, 1);
-+
-+ err = mlx5_core_modify_tir(mdev, tirn, in, inlen);
-+
-+ kvfree(in);
-+
-+ return err;
-+}
-+
-+static int mlx5e_refresh_tirs_self_loopback_enable(struct mlx5e_priv *priv)
-+{
-+ int err;
-+ int i;
-+
-+ for (i = 0; i < MLX5E_NUM_TT; i++) {
-+ err = mlx5e_refresh_tir_self_loopback_enable(priv->mdev,
-+ priv->tirn[i]);
-+ if (err)
-+ return err;
-+ }
-+
-+ return 0;
-+}
-+
- static int mlx5e_set_dev_port_mtu(struct net_device *netdev)
- {
- struct mlx5e_priv *priv = netdev_priv(netdev);
-@@ -1367,13 +1403,20 @@ int mlx5e_open_locked(struct net_device *netdev)
-
- err = mlx5e_set_dev_port_mtu(netdev);
- if (err)
-- return err;
-+ goto err_clear_state_opened_flag;
-
- err = mlx5e_open_channels(priv);
- if (err) {
- netdev_err(netdev, "%s: mlx5e_open_channels failed, %d\n",
- __func__, err);
-- return err;
-+ goto err_clear_state_opened_flag;
-+ }
-+
-+ err = mlx5e_refresh_tirs_self_loopback_enable(priv);
-+ if (err) {
-+ netdev_err(netdev, "%s: mlx5e_refresh_tirs_self_loopback_enable failed, %d\n",
-+ __func__, err);
-+ goto err_close_channels;
- }
-
- mlx5e_update_carrier(priv);
-@@ -1382,6 +1425,12 @@ int mlx5e_open_locked(struct net_device *netdev)
- schedule_delayed_work(&priv->update_stats_work, 0);
-
- return 0;
-+
-+err_close_channels:
-+ mlx5e_close_channels(priv);
-+err_clear_state_opened_flag:
-+ clear_bit(MLX5E_STATE_OPENED, &priv->state);
-+ return err;
- }
-
- static int mlx5e_open(struct net_device *netdev)
-@@ -1899,6 +1948,9 @@ static int mlx5e_check_required_hca_cap(struct mlx5_core_dev *mdev)
- "Not creating net device, some required device capabilities are missing\n");
- return -ENOTSUPP;
- }
-+ if (!MLX5_CAP_ETH(mdev, self_lb_en_modifiable))
-+ mlx5_core_warn(mdev, "Self loop back prevention is not supported\n");
-+
- return 0;
- }
-
-diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c
-index b4f2123..79ef799 100644
---- a/drivers/net/ethernet/realtek/r8169.c
-+++ b/drivers/net/ethernet/realtek/r8169.c
-@@ -7429,15 +7429,15 @@ process_pkt:
-
- rtl8169_rx_vlan_tag(desc, skb);
-
-+ if (skb->pkt_type == PACKET_MULTICAST)
-+ dev->stats.multicast++;
-+
- napi_gro_receive(&tp->napi, skb);
-
- u64_stats_update_begin(&tp->rx_stats.syncp);
- tp->rx_stats.packets++;
- tp->rx_stats.bytes += pkt_size;
- u64_stats_update_end(&tp->rx_stats.syncp);
--
-- if (skb->pkt_type == PACKET_MULTICAST)
-- dev->stats.multicast++;
- }
- release_descriptor:
- desc->opts2 = 0;
-diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
-index 9c71295..85e64044 100644
---- a/drivers/net/phy/broadcom.c
-+++ b/drivers/net/phy/broadcom.c
-@@ -675,7 +675,7 @@ static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
- { PHY_ID_BCM5461, 0xfffffff0 },
- { PHY_ID_BCM54616S, 0xfffffff0 },
- { PHY_ID_BCM5464, 0xfffffff0 },
-- { PHY_ID_BCM5482, 0xfffffff0 },
-+ { PHY_ID_BCM5481, 0xfffffff0 },
- { PHY_ID_BCM5482, 0xfffffff0 },
- { PHY_ID_BCM50610, 0xfffffff0 },
- { PHY_ID_BCM50610M, 0xfffffff0 },
-diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
-index 2a7c1be..66e0853 100644
---- a/drivers/net/usb/qmi_wwan.c
-+++ b/drivers/net/usb/qmi_wwan.c
-@@ -775,6 +775,7 @@ static const struct usb_device_id products[] = {
- {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */
- {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */
- {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */
-+ {QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)}, /* XS Stick W100-2 from 4G Systems */
- {QMI_FIXED_INTF(0x0b3c, 0xc000, 4)}, /* Olivetti Olicard 100 */
- {QMI_FIXED_INTF(0x0b3c, 0xc001, 4)}, /* Olivetti Olicard 120 */
- {QMI_FIXED_INTF(0x0b3c, 0xc002, 4)}, /* Olivetti Olicard 140 */
-diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
-index 488c6f5..c9e309c 100644
---- a/drivers/net/vrf.c
-+++ b/drivers/net/vrf.c
-@@ -581,7 +581,6 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev,
- {
- struct net_vrf *vrf = netdev_priv(dev);
- struct net_vrf_dev *vrf_ptr;
-- int err;
-
- if (!data || !data[IFLA_VRF_TABLE])
- return -EINVAL;
-@@ -590,26 +589,16 @@ static int vrf_newlink(struct net *src_net, struct net_device *dev,
-
- dev->priv_flags |= IFF_VRF_MASTER;
-
-- err = -ENOMEM;
- vrf_ptr = kmalloc(sizeof(*dev->vrf_ptr), GFP_KERNEL);
- if (!vrf_ptr)
-- goto out_fail;
-+ return -ENOMEM;
-
- vrf_ptr->ifindex = dev->ifindex;
- vrf_ptr->tb_id = vrf->tb_id;
-
-- err = register_netdevice(dev);
-- if (err < 0)
-- goto out_fail;
--
- rcu_assign_pointer(dev->vrf_ptr, vrf_ptr);
-
-- return 0;
--
--out_fail:
-- kfree(vrf_ptr);
-- free_netdev(dev);
-- return err;
-+ return register_netdev(dev);
- }
-
- static size_t vrf_nl_getsize(const struct net_device *dev)
-diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
-index 938efe3..94eea1f 100644
---- a/fs/btrfs/ctree.h
-+++ b/fs/btrfs/ctree.h
-@@ -3398,7 +3398,7 @@ int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
- int btrfs_free_extent(struct btrfs_trans_handle *trans,
- struct btrfs_root *root,
- u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
-- u64 owner, u64 offset, int no_quota);
-+ u64 owner, u64 offset);
-
- int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len,
- int delalloc);
-@@ -3411,7 +3411,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
- int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
- struct btrfs_root *root,
- u64 bytenr, u64 num_bytes, u64 parent,
-- u64 root_objectid, u64 owner, u64 offset, int no_quota);
-+ u64 root_objectid, u64 owner, u64 offset);
-
- int btrfs_start_dirty_block_groups(struct btrfs_trans_handle *trans,
- struct btrfs_root *root);
-diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
-index ac3e81d..7832031 100644
---- a/fs/btrfs/delayed-ref.c
-+++ b/fs/btrfs/delayed-ref.c
-@@ -197,6 +197,119 @@ static inline void drop_delayed_ref(struct btrfs_trans_handle *trans,
- trans->delayed_ref_updates--;
- }
-
-+static bool merge_ref(struct btrfs_trans_handle *trans,
-+ struct btrfs_delayed_ref_root *delayed_refs,
-+ struct btrfs_delayed_ref_head *head,
-+ struct btrfs_delayed_ref_node *ref,
-+ u64 seq)
-+{
-+ struct btrfs_delayed_ref_node *next;
-+ bool done = false;
-+
-+ next = list_first_entry(&head->ref_list, struct btrfs_delayed_ref_node,
-+ list);
-+ while (!done && &next->list != &head->ref_list) {
-+ int mod;
-+ struct btrfs_delayed_ref_node *next2;
-+
-+ next2 = list_next_entry(next, list);
-+
-+ if (next == ref)
-+ goto next;
-+
-+ if (seq && next->seq >= seq)
-+ goto next;
-+
-+ if (next->type != ref->type)
-+ goto next;
-+
-+ if ((ref->type == BTRFS_TREE_BLOCK_REF_KEY ||
-+ ref->type == BTRFS_SHARED_BLOCK_REF_KEY) &&
-+ comp_tree_refs(btrfs_delayed_node_to_tree_ref(ref),
-+ btrfs_delayed_node_to_tree_ref(next),
-+ ref->type))
-+ goto next;
-+ if ((ref->type == BTRFS_EXTENT_DATA_REF_KEY ||
-+ ref->type == BTRFS_SHARED_DATA_REF_KEY) &&
-+ comp_data_refs(btrfs_delayed_node_to_data_ref(ref),
-+ btrfs_delayed_node_to_data_ref(next)))
-+ goto next;
-+
-+ if (ref->action == next->action) {
-+ mod = next->ref_mod;
-+ } else {
-+ if (ref->ref_mod < next->ref_mod) {
-+ swap(ref, next);
-+ done = true;
-+ }
-+ mod = -next->ref_mod;
-+ }
-+
-+ drop_delayed_ref(trans, delayed_refs, head, next);
-+ ref->ref_mod += mod;
-+ if (ref->ref_mod == 0) {
-+ drop_delayed_ref(trans, delayed_refs, head, ref);
-+ done = true;
-+ } else {
-+ /*
-+ * Can't have multiples of the same ref on a tree block.
-+ */
-+ WARN_ON(ref->type == BTRFS_TREE_BLOCK_REF_KEY ||
-+ ref->type == BTRFS_SHARED_BLOCK_REF_KEY);
-+ }
-+next:
-+ next = next2;
-+ }
-+
-+ return done;
-+}
-+
-+void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans,
-+ struct btrfs_fs_info *fs_info,
-+ struct btrfs_delayed_ref_root *delayed_refs,
-+ struct btrfs_delayed_ref_head *head)
-+{
-+ struct btrfs_delayed_ref_node *ref;
-+ u64 seq = 0;
-+
-+ assert_spin_locked(&head->lock);
-+
-+ if (list_empty(&head->ref_list))
-+ return;
-+
-+ /* We don't have too many refs to merge for data. */
-+ if (head->is_data)
-+ return;
-+
-+ spin_lock(&fs_info->tree_mod_seq_lock);
-+ if (!list_empty(&fs_info->tree_mod_seq_list)) {
-+ struct seq_list *elem;
-+
-+ elem = list_first_entry(&fs_info->tree_mod_seq_list,
-+ struct seq_list, list);
-+ seq = elem->seq;
-+ }
-+ spin_unlock(&fs_info->tree_mod_seq_lock);
-+
-+ ref = list_first_entry(&head->ref_list, struct btrfs_delayed_ref_node,
-+ list);
-+ while (&ref->list != &head->ref_list) {
-+ if (seq && ref->seq >= seq)
-+ goto next;
-+
-+ if (merge_ref(trans, delayed_refs, head, ref, seq)) {
-+ if (list_empty(&head->ref_list))
-+ break;
-+ ref = list_first_entry(&head->ref_list,
-+ struct btrfs_delayed_ref_node,
-+ list);
-+ continue;
-+ }
-+next:
-+ ref = list_next_entry(ref, list);
-+ }
-+}
-+
- int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info,
- struct btrfs_delayed_ref_root *delayed_refs,
- u64 seq)
-@@ -292,8 +405,7 @@ add_delayed_ref_tail_merge(struct btrfs_trans_handle *trans,
- exist = list_entry(href->ref_list.prev, struct btrfs_delayed_ref_node,
- list);
- /* No need to compare bytenr nor is_head */
-- if (exist->type != ref->type || exist->no_quota != ref->no_quota ||
-- exist->seq != ref->seq)
-+ if (exist->type != ref->type || exist->seq != ref->seq)
- goto add_tail;
-
- if ((exist->type == BTRFS_TREE_BLOCK_REF_KEY ||
-@@ -524,7 +636,7 @@ add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
- struct btrfs_delayed_ref_head *head_ref,
- struct btrfs_delayed_ref_node *ref, u64 bytenr,
- u64 num_bytes, u64 parent, u64 ref_root, int level,
-- int action, int no_quota)
-+ int action)
- {
- struct btrfs_delayed_tree_ref *full_ref;
- struct btrfs_delayed_ref_root *delayed_refs;
-@@ -546,7 +658,6 @@ add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
- ref->action = action;
- ref->is_head = 0;
- ref->in_tree = 1;
-- ref->no_quota = no_quota;
- ref->seq = seq;
-
- full_ref = btrfs_delayed_node_to_tree_ref(ref);
-@@ -579,7 +690,7 @@ add_delayed_data_ref(struct btrfs_fs_info *fs_info,
- struct btrfs_delayed_ref_head *head_ref,
- struct btrfs_delayed_ref_node *ref, u64 bytenr,
- u64 num_bytes, u64 parent, u64 ref_root, u64 owner,
-- u64 offset, int action, int no_quota)
-+ u64 offset, int action)
- {
- struct btrfs_delayed_data_ref *full_ref;
- struct btrfs_delayed_ref_root *delayed_refs;
-@@ -602,7 +713,6 @@ add_delayed_data_ref(struct btrfs_fs_info *fs_info,
- ref->action = action;
- ref->is_head = 0;
- ref->in_tree = 1;
-- ref->no_quota = no_quota;
- ref->seq = seq;
-
- full_ref = btrfs_delayed_node_to_data_ref(ref);
-@@ -633,17 +743,13 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
- struct btrfs_trans_handle *trans,
- u64 bytenr, u64 num_bytes, u64 parent,
- u64 ref_root, int level, int action,
-- struct btrfs_delayed_extent_op *extent_op,
-- int no_quota)
-+ struct btrfs_delayed_extent_op *extent_op)
- {
- struct btrfs_delayed_tree_ref *ref;
- struct btrfs_delayed_ref_head *head_ref;
- struct btrfs_delayed_ref_root *delayed_refs;
- struct btrfs_qgroup_extent_record *record = NULL;
-
-- if (!is_fstree(ref_root) || !fs_info->quota_enabled)
-- no_quota = 0;
--
- BUG_ON(extent_op && extent_op->is_data);
- ref = kmem_cache_alloc(btrfs_delayed_tree_ref_cachep, GFP_NOFS);
- if (!ref)
-@@ -672,8 +778,7 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
- bytenr, num_bytes, action, 0);
-
- add_delayed_tree_ref(fs_info, trans, head_ref, &ref->node, bytenr,
-- num_bytes, parent, ref_root, level, action,
-- no_quota);
-+ num_bytes, parent, ref_root, level, action);
- spin_unlock(&delayed_refs->lock);
-
- return 0;
-@@ -694,17 +799,13 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
- u64 bytenr, u64 num_bytes,
- u64 parent, u64 ref_root,
- u64 owner, u64 offset, int action,
-- struct btrfs_delayed_extent_op *extent_op,
-- int no_quota)
-+ struct btrfs_delayed_extent_op *extent_op)
- {
- struct btrfs_delayed_data_ref *ref;
- struct btrfs_delayed_ref_head *head_ref;
- struct btrfs_delayed_ref_root *delayed_refs;
- struct btrfs_qgroup_extent_record *record = NULL;
-
-- if (!is_fstree(ref_root) || !fs_info->quota_enabled)
-- no_quota = 0;
--
- BUG_ON(extent_op && !extent_op->is_data);
- ref = kmem_cache_alloc(btrfs_delayed_data_ref_cachep, GFP_NOFS);
- if (!ref)
-@@ -740,7 +841,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
-
- add_delayed_data_ref(fs_info, trans, head_ref, &ref->node, bytenr,
- num_bytes, parent, ref_root, owner, offset,
-- action, no_quota);
-+ action);
- spin_unlock(&delayed_refs->lock);
-
- return 0;
-diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h
-index 13fb5e6..930887a 100644
---- a/fs/btrfs/delayed-ref.h
-+++ b/fs/btrfs/delayed-ref.h
-@@ -68,7 +68,6 @@ struct btrfs_delayed_ref_node {
-
- unsigned int action:8;
- unsigned int type:8;
-- unsigned int no_quota:1;
- /* is this node still in the rbtree? */
- unsigned int is_head:1;
- unsigned int in_tree:1;
-@@ -233,15 +232,13 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
- struct btrfs_trans_handle *trans,
- u64 bytenr, u64 num_bytes, u64 parent,
- u64 ref_root, int level, int action,
-- struct btrfs_delayed_extent_op *extent_op,
-- int no_quota);
-+ struct btrfs_delayed_extent_op *extent_op);
- int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
- struct btrfs_trans_handle *trans,
- u64 bytenr, u64 num_bytes,
- u64 parent, u64 ref_root,
- u64 owner, u64 offset, int action,
-- struct btrfs_delayed_extent_op *extent_op,
-- int no_quota);
-+ struct btrfs_delayed_extent_op *extent_op);
- int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
- struct btrfs_trans_handle *trans,
- u64 bytenr, u64 num_bytes,
-diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
-index 601d7d4..cadacf6 100644
---- a/fs/btrfs/extent-tree.c
-+++ b/fs/btrfs/extent-tree.c
-@@ -95,8 +95,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
- struct btrfs_root *root,
- u64 parent, u64 root_objectid,
- u64 flags, struct btrfs_disk_key *key,
-- int level, struct btrfs_key *ins,
-- int no_quota);
-+ int level, struct btrfs_key *ins);
- static int do_chunk_alloc(struct btrfs_trans_handle *trans,
- struct btrfs_root *extent_root, u64 flags,
- int force);
-@@ -2009,8 +2008,7 @@ int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
- int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
- struct btrfs_root *root,
- u64 bytenr, u64 num_bytes, u64 parent,
-- u64 root_objectid, u64 owner, u64 offset,
-- int no_quota)
-+ u64 root_objectid, u64 owner, u64 offset)
- {
- int ret;
- struct btrfs_fs_info *fs_info = root->fs_info;
-@@ -2022,12 +2020,12 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
- ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr,
- num_bytes,
- parent, root_objectid, (int)owner,
-- BTRFS_ADD_DELAYED_REF, NULL, no_quota);
-+ BTRFS_ADD_DELAYED_REF, NULL);
- } else {
- ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
- num_bytes,
- parent, root_objectid, owner, offset,
-- BTRFS_ADD_DELAYED_REF, NULL, no_quota);
-+ BTRFS_ADD_DELAYED_REF, NULL);
- }
- return ret;
- }
-@@ -2048,15 +2046,11 @@ static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
- u64 num_bytes = node->num_bytes;
- u64 refs;
- int ret;
-- int no_quota = node->no_quota;
-
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
-- if (!is_fstree(root_objectid) || !root->fs_info->quota_enabled)
-- no_quota = 1;
--
- path->reada = 1;
- path->leave_spinning = 1;
- /* this will setup the path even if it fails to insert the back ref */
-@@ -2291,8 +2285,7 @@ static int run_delayed_tree_ref(struct btrfs_trans_handle *trans,
- parent, ref_root,
- extent_op->flags_to_set,
- &extent_op->key,
-- ref->level, &ins,
-- node->no_quota);
-+ ref->level, &ins);
- } else if (node->action == BTRFS_ADD_DELAYED_REF) {
- ret = __btrfs_inc_extent_ref(trans, root, node,
- parent, ref_root,
-@@ -2433,7 +2426,21 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
- }
- }
-
-+ /*
-+ * We need to try and merge add/drops of the same ref since we
-+ * can run into issues with relocate dropping the implicit ref
-+ * and then it being added back again before the drop can
-+ * finish. If we merged anything we need to re-loop so we can
-+ * get a good ref.
-+ * Or we can get node references of the same type that weren't
-+ * merged when created due to bumps in the tree mod seq, and
-+ * we need to merge them to prevent adding an inline extent
-+ * backref before dropping it (triggering a BUG_ON at
-+ * insert_inline_extent_backref()).
-+ */
- spin_lock(&locked_ref->lock);
-+ btrfs_merge_delayed_refs(trans, fs_info, delayed_refs,
-+ locked_ref);
-
- /*
- * locked_ref is the head node, so we have to go one
-@@ -3109,7 +3116,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
- int level;
- int ret = 0;
- int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *,
-- u64, u64, u64, u64, u64, u64, int);
-+ u64, u64, u64, u64, u64, u64);
-
-
- if (btrfs_test_is_dummy_root(root))
-@@ -3150,15 +3157,14 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans,
- key.offset -= btrfs_file_extent_offset(buf, fi);
- ret = process_func(trans, root, bytenr, num_bytes,
- parent, ref_root, key.objectid,
-- key.offset, 1);
-+ key.offset);
- if (ret)
- goto fail;
- } else {
- bytenr = btrfs_node_blockptr(buf, i);
- num_bytes = root->nodesize;
- ret = process_func(trans, root, bytenr, num_bytes,
-- parent, ref_root, level - 1, 0,
-- 1);
-+ parent, ref_root, level - 1, 0);
- if (ret)
- goto fail;
- }
-@@ -6233,7 +6239,6 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
- int extent_slot = 0;
- int found_extent = 0;
- int num_to_del = 1;
-- int no_quota = node->no_quota;
- u32 item_size;
- u64 refs;
- u64 bytenr = node->bytenr;
-@@ -6242,9 +6247,6 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
- bool skinny_metadata = btrfs_fs_incompat(root->fs_info,
- SKINNY_METADATA);
-
-- if (!info->quota_enabled || !is_fstree(root_objectid))
-- no_quota = 1;
--
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-@@ -6570,7 +6572,7 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
- buf->start, buf->len,
- parent, root->root_key.objectid,
- btrfs_header_level(buf),
-- BTRFS_DROP_DELAYED_REF, NULL, 0);
-+ BTRFS_DROP_DELAYED_REF, NULL);
- BUG_ON(ret); /* -ENOMEM */
- }
-
-@@ -6618,7 +6620,7 @@ out:
- /* Can return -ENOMEM */
- int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root,
- u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
-- u64 owner, u64 offset, int no_quota)
-+ u64 owner, u64 offset)
- {
- int ret;
- struct btrfs_fs_info *fs_info = root->fs_info;
-@@ -6641,13 +6643,13 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root,
- ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr,
- num_bytes,
- parent, root_objectid, (int)owner,
-- BTRFS_DROP_DELAYED_REF, NULL, no_quota);
-+ BTRFS_DROP_DELAYED_REF, NULL);
- } else {
- ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
- num_bytes,
- parent, root_objectid, owner,
- offset, BTRFS_DROP_DELAYED_REF,
-- NULL, no_quota);
-+ NULL);
- }
- return ret;
- }
-@@ -7429,8 +7431,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
- struct btrfs_root *root,
- u64 parent, u64 root_objectid,
- u64 flags, struct btrfs_disk_key *key,
-- int level, struct btrfs_key *ins,
-- int no_quota)
-+ int level, struct btrfs_key *ins)
- {
- int ret;
- struct btrfs_fs_info *fs_info = root->fs_info;
-@@ -7520,7 +7521,7 @@ int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
- ret = btrfs_add_delayed_data_ref(root->fs_info, trans, ins->objectid,
- ins->offset, 0,
- root_objectid, owner, offset,
-- BTRFS_ADD_DELAYED_EXTENT, NULL, 0);
-+ BTRFS_ADD_DELAYED_EXTENT, NULL);
- return ret;
- }
-
-@@ -7734,7 +7735,7 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
- ins.objectid, ins.offset,
- parent, root_objectid, level,
- BTRFS_ADD_DELAYED_EXTENT,
-- extent_op, 0);
-+ extent_op);
- if (ret)
- goto out_free_delayed;
- }
-@@ -8282,7 +8283,7 @@ skip:
- }
- }
- ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent,
-- root->root_key.objectid, level - 1, 0, 0);
-+ root->root_key.objectid, level - 1, 0);
- BUG_ON(ret); /* -ENOMEM */
- }
- btrfs_tree_unlock(next);
-diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
-index 8c6f247..e27ea7a 100644
---- a/fs/btrfs/file.c
-+++ b/fs/btrfs/file.c
-@@ -756,8 +756,16 @@ next_slot:
- }
-
- btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
-- if (key.objectid > ino ||
-- key.type > BTRFS_EXTENT_DATA_KEY || key.offset >= end)
-+
-+ if (key.objectid > ino)
-+ break;
-+ if (WARN_ON_ONCE(key.objectid < ino) ||
-+ key.type < BTRFS_EXTENT_DATA_KEY) {
-+ ASSERT(del_nr == 0);
-+ path->slots[0]++;
-+ goto next_slot;
-+ }
-+ if (key.type > BTRFS_EXTENT_DATA_KEY || key.offset >= end)
- break;
-
- fi = btrfs_item_ptr(leaf, path->slots[0],
-@@ -776,8 +784,8 @@ next_slot:
- btrfs_file_extent_inline_len(leaf,
- path->slots[0], fi);
- } else {
-- WARN_ON(1);
-- extent_end = search_start;
-+ /* can't happen */
-+ BUG();
- }
-
- /*
-@@ -847,7 +855,7 @@ next_slot:
- disk_bytenr, num_bytes, 0,
- root->root_key.objectid,
- new_key.objectid,
-- start - extent_offset, 1);
-+ start - extent_offset);
- BUG_ON(ret); /* -ENOMEM */
- }
- key.offset = start;
-@@ -925,7 +933,7 @@ delete_extent_item:
- disk_bytenr, num_bytes, 0,
- root->root_key.objectid,
- key.objectid, key.offset -
-- extent_offset, 0);
-+ extent_offset);
- BUG_ON(ret); /* -ENOMEM */
- inode_sub_bytes(inode,
- extent_end - key.offset);
-@@ -1204,7 +1212,7 @@ again:
-
- ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0,
- root->root_key.objectid,
-- ino, orig_offset, 1);
-+ ino, orig_offset);
- BUG_ON(ret); /* -ENOMEM */
-
- if (split == start) {
-@@ -1231,7 +1239,7 @@ again:
- del_nr++;
- ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
- 0, root->root_key.objectid,
-- ino, orig_offset, 0);
-+ ino, orig_offset);
- BUG_ON(ret); /* -ENOMEM */
- }
- other_start = 0;
-@@ -1248,7 +1256,7 @@ again:
- del_nr++;
- ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
- 0, root->root_key.objectid,
-- ino, orig_offset, 0);
-+ ino, orig_offset);
- BUG_ON(ret); /* -ENOMEM */
- }
- if (del_nr == 0) {
-@@ -1868,8 +1876,13 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
- struct btrfs_log_ctx ctx;
- int ret = 0;
- bool full_sync = 0;
-- const u64 len = end - start + 1;
-+ u64 len;
-
-+ /*
-+ * The range length can be represented by u64, we have to do the typecasts
-+ * to avoid signed overflow if it's [0, LLONG_MAX] eg. from fsync()
-+ */
-+ len = (u64)end - (u64)start + 1;
- trace_btrfs_sync_file(file, datasync);
-
- /*
-@@ -2057,8 +2070,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
- }
- }
- if (!full_sync) {
-- ret = btrfs_wait_ordered_range(inode, start,
-- end - start + 1);
-+ ret = btrfs_wait_ordered_range(inode, start, len);
- if (ret) {
- btrfs_end_transaction(trans, root);
- goto out;
-diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
-index 611b66d..396e3d5 100644
---- a/fs/btrfs/inode.c
-+++ b/fs/btrfs/inode.c
-@@ -1294,8 +1294,14 @@ next_slot:
- num_bytes = 0;
- btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
-
-- if (found_key.objectid > ino ||
-- found_key.type > BTRFS_EXTENT_DATA_KEY ||
-+ if (found_key.objectid > ino)
-+ break;
-+ if (WARN_ON_ONCE(found_key.objectid < ino) ||
-+ found_key.type < BTRFS_EXTENT_DATA_KEY) {
-+ path->slots[0]++;
-+ goto next_slot;
-+ }
-+ if (found_key.type > BTRFS_EXTENT_DATA_KEY ||
- found_key.offset > end)
- break;
-
-@@ -2573,7 +2579,7 @@ again:
- ret = btrfs_inc_extent_ref(trans, root, new->bytenr,
- new->disk_len, 0,
- backref->root_id, backref->inum,
-- new->file_pos, 0); /* start - extent_offset */
-+ new->file_pos); /* start - extent_offset */
- if (ret) {
- btrfs_abort_transaction(trans, root, ret);
- goto out_free_path;
-@@ -4217,6 +4223,47 @@ static int truncate_space_check(struct btrfs_trans_handle *trans,
-
- }
-
-+static int truncate_inline_extent(struct inode *inode,
-+ struct btrfs_path *path,
-+ struct btrfs_key *found_key,
-+ const u64 item_end,
-+ const u64 new_size)
-+{
-+ struct extent_buffer *leaf = path->nodes[0];
-+ int slot = path->slots[0];
-+ struct btrfs_file_extent_item *fi;
-+ u32 size = (u32)(new_size - found_key->offset);
-+ struct btrfs_root *root = BTRFS_I(inode)->root;
-+
-+ fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
-+
-+ if (btrfs_file_extent_compression(leaf, fi) != BTRFS_COMPRESS_NONE) {
-+ loff_t offset = new_size;
-+ loff_t page_end = ALIGN(offset, PAGE_CACHE_SIZE);
-+
-+ /*
-+ * Zero out the remaining of the last page of our inline extent,
-+ * instead of directly truncating our inline extent here - that
-+ * would be much more complex (decompressing all the data, then
-+ * compressing the truncated data, which might be bigger than
-+ * the size of the inline extent, resize the extent, etc).
-+ * We release the path because to get the page we might need to
-+ * read the extent item from disk (data not in the page cache).
-+ */
-+ btrfs_release_path(path);
-+ return btrfs_truncate_page(inode, offset, page_end - offset, 0);
-+ }
-+
-+ btrfs_set_file_extent_ram_bytes(leaf, fi, size);
-+ size = btrfs_file_extent_calc_inline_size(size);
-+ btrfs_truncate_item(root, path, size, 1);
-+
-+ if (test_bit(BTRFS_ROOT_REF_COWS, &root->state))
-+ inode_sub_bytes(inode, item_end + 1 - new_size);
-+
-+ return 0;
-+}
-+
- /*
- * this can truncate away extent items, csum items and directory items.
- * It starts at a high offset and removes keys until it can't find
-@@ -4411,27 +4458,40 @@ search_again:
- * special encodings
- */
- if (!del_item &&
-- btrfs_file_extent_compression(leaf, fi) == 0 &&
- btrfs_file_extent_encryption(leaf, fi) == 0 &&
- btrfs_file_extent_other_encoding(leaf, fi) == 0) {
-- u32 size = new_size - found_key.offset;
--
-- if (test_bit(BTRFS_ROOT_REF_COWS, &root->state))
-- inode_sub_bytes(inode, item_end + 1 -
-- new_size);
-
- /*
-- * update the ram bytes to properly reflect
-- * the new size of our item
-+ * Need to release path in order to truncate a
-+ * compressed extent. So delete any accumulated
-+ * extent items so far.
- */
-- btrfs_set_file_extent_ram_bytes(leaf, fi, size);
-- size =
-- btrfs_file_extent_calc_inline_size(size);
-- btrfs_truncate_item(root, path, size, 1);
-+ if (btrfs_file_extent_compression(leaf, fi) !=
-+ BTRFS_COMPRESS_NONE && pending_del_nr) {
-+ err = btrfs_del_items(trans, root, path,
-+ pending_del_slot,
-+ pending_del_nr);
-+ if (err) {
-+ btrfs_abort_transaction(trans,
-+ root,
-+ err);
-+ goto error;
-+ }
-+ pending_del_nr = 0;
-+ }
-+
-+ err = truncate_inline_extent(inode, path,
-+ &found_key,
-+ item_end,
-+ new_size);
-+ if (err) {
-+ btrfs_abort_transaction(trans,
-+ root, err);
-+ goto error;
-+ }
- } else if (test_bit(BTRFS_ROOT_REF_COWS,
- &root->state)) {
-- inode_sub_bytes(inode, item_end + 1 -
-- found_key.offset);
-+ inode_sub_bytes(inode, item_end + 1 - new_size);
- }
- }
- delete:
-@@ -4461,7 +4521,7 @@ delete:
- ret = btrfs_free_extent(trans, root, extent_start,
- extent_num_bytes, 0,
- btrfs_header_owner(leaf),
-- ino, extent_offset, 0);
-+ ino, extent_offset);
- BUG_ON(ret);
- if (btrfs_should_throttle_delayed_refs(trans, root))
- btrfs_async_run_delayed_refs(root,
-diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
-index 8d20f3b..6548a36 100644
---- a/fs/btrfs/ioctl.c
-+++ b/fs/btrfs/ioctl.c
-@@ -3203,41 +3203,6 @@ out:
- return ret;
- }
-
--/* Helper to check and see if this root currently has a ref on the given disk
-- * bytenr. If it does then we need to update the quota for this root. This
-- * doesn't do anything if quotas aren't enabled.
-- */
--static int check_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
-- u64 disko)
--{
-- struct seq_list tree_mod_seq_elem = SEQ_LIST_INIT(tree_mod_seq_elem);
-- struct ulist *roots;
-- struct ulist_iterator uiter;
-- struct ulist_node *root_node = NULL;
-- int ret;
--
-- if (!root->fs_info->quota_enabled)
-- return 1;
--
-- btrfs_get_tree_mod_seq(root->fs_info, &tree_mod_seq_elem);
-- ret = btrfs_find_all_roots(trans, root->fs_info, disko,
-- tree_mod_seq_elem.seq, &roots);
-- if (ret < 0)
-- goto out;
-- ret = 0;
-- ULIST_ITER_INIT(&uiter);
-- while ((root_node = ulist_next(roots, &uiter))) {
-- if (root_node->val == root->objectid) {
-- ret = 1;
-- break;
-- }
-- }
-- ulist_free(roots);
--out:
-- btrfs_put_tree_mod_seq(root->fs_info, &tree_mod_seq_elem);
-- return ret;
--}
--
- static int clone_finish_inode_update(struct btrfs_trans_handle *trans,
- struct inode *inode,
- u64 endoff,
-@@ -3328,6 +3293,150 @@ static void clone_update_extent_map(struct inode *inode,
- &BTRFS_I(inode)->runtime_flags);
- }
-
-+/*
-+ * Make sure we do not end up inserting an inline extent into a file that has
-+ * already other (non-inline) extents. If a file has an inline extent it can
-+ * not have any other extents and the (single) inline extent must start at the
-+ * file offset 0. Failing to respect these rules will lead to file corruption,
-+ * resulting in EIO errors on read/write operations, hitting BUG_ON's in mm, etc
-+ *
-+ * We can have extents that have been already written to disk or we can have
-+ * dirty ranges still in delalloc, in which case the extent maps and items are
-+ * created only when we run delalloc, and the delalloc ranges might fall outside
-+ * the range we are currently locking in the inode's io tree. So we check the
-+ * inode's i_size because of that (i_size updates are done while holding the
-+ * i_mutex, which we are holding here).
-+ * We also check to see if the inode has a size not greater than "datal" but has
-+ * extents beyond it, due to an fallocate with FALLOC_FL_KEEP_SIZE (and we are
-+ * protected against such concurrent fallocate calls by the i_mutex).
-+ *
-+ * If the file has no extents but a size greater than datal, do not allow the
-+ * copy because we would need turn the inline extent into a non-inline one (even
-+ * with NO_HOLES enabled). If we find our destination inode only has one inline
-+ * extent, just overwrite it with the source inline extent if its size is less
-+ * than the source extent's size, or we could copy the source inline extent's
-+ * data into the destination inode's inline extent if the later is greater then
-+ * the former.
-+ */
-+static int clone_copy_inline_extent(struct inode *src,
-+ struct inode *dst,
-+ struct btrfs_trans_handle *trans,
-+ struct btrfs_path *path,
-+ struct btrfs_key *new_key,
-+ const u64 drop_start,
-+ const u64 datal,
-+ const u64 skip,
-+ const u64 size,
-+ char *inline_data)
-+{
-+ struct btrfs_root *root = BTRFS_I(dst)->root;
-+ const u64 aligned_end = ALIGN(new_key->offset + datal,
-+ root->sectorsize);
-+ int ret;
-+ struct btrfs_key key;
-+
-+ if (new_key->offset > 0)
-+ return -EOPNOTSUPP;
-+
-+ key.objectid = btrfs_ino(dst);
-+ key.type = BTRFS_EXTENT_DATA_KEY;
-+ key.offset = 0;
-+ ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
-+ if (ret < 0) {
-+ return ret;
-+ } else if (ret > 0) {
-+ if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
-+ ret = btrfs_next_leaf(root, path);
-+ if (ret < 0)
-+ return ret;
-+ else if (ret > 0)
-+ goto copy_inline_extent;
-+ }
-+ btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
-+ if (key.objectid == btrfs_ino(dst) &&
-+ key.type == BTRFS_EXTENT_DATA_KEY) {
-+ ASSERT(key.offset > 0);
-+ return -EOPNOTSUPP;
-+ }
-+ } else if (i_size_read(dst) <= datal) {
-+ struct btrfs_file_extent_item *ei;
-+ u64 ext_len;
-+
-+ /*
-+ * If the file size is <= datal, make sure there are no other
-+ * extents following (can happen do to an fallocate call with
-+ * the flag FALLOC_FL_KEEP_SIZE).
-+ */
-+ ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
-+ struct btrfs_file_extent_item);
-+ /*
-+ * If it's an inline extent, it can not have other extents
-+ * following it.
-+ */
-+ if (btrfs_file_extent_type(path->nodes[0], ei) ==
-+ BTRFS_FILE_EXTENT_INLINE)
-+ goto copy_inline_extent;
-+
-+ ext_len = btrfs_file_extent_num_bytes(path->nodes[0], ei);
-+ if (ext_len > aligned_end)
-+ return -EOPNOTSUPP;
-+
-+ ret = btrfs_next_item(root, path);
-+ if (ret < 0) {
-+ return ret;
-+ } else if (ret == 0) {
-+ btrfs_item_key_to_cpu(path->nodes[0], &key,
-+ path->slots[0]);
-+ if (key.objectid == btrfs_ino(dst) &&
-+ key.type == BTRFS_EXTENT_DATA_KEY)
-+ return -EOPNOTSUPP;
-+ }
-+ }
-+
-+copy_inline_extent:
-+ /*
-+ * We have no extent items, or we have an extent at offset 0 which may
-+ * or may not be inlined. All these cases are dealt the same way.
-+ */
-+ if (i_size_read(dst) > datal) {
-+ /*
-+ * If the destination inode has an inline extent...
-+ * This would require copying the data from the source inline
-+ * extent into the beginning of the destination's inline extent.
-+ * But this is really complex, both extents can be compressed
-+ * or just one of them, which would require decompressing and
-+ * re-compressing data (which could increase the new compressed
-+ * size, not allowing the compressed data to fit anymore in an
-+ * inline extent).
-+ * So just don't support this case for now (it should be rare,
-+ * we are not really saving space when cloning inline extents).
-+ */
-+ return -EOPNOTSUPP;
-+ }
-+
-+ btrfs_release_path(path);
-+ ret = btrfs_drop_extents(trans, root, dst, drop_start, aligned_end, 1);
-+ if (ret)
-+ return ret;
-+ ret = btrfs_insert_empty_item(trans, root, path, new_key, size);
-+ if (ret)
-+ return ret;
-+
-+ if (skip) {
-+ const u32 start = btrfs_file_extent_calc_inline_size(0);
-+
-+ memmove(inline_data + start, inline_data + start + skip, datal);
-+ }
-+
-+ write_extent_buffer(path->nodes[0], inline_data,
-+ btrfs_item_ptr_offset(path->nodes[0],
-+ path->slots[0]),
-+ size);
-+ inode_add_bytes(dst, datal);
-+
-+ return 0;
-+}
-+
- /**
- * btrfs_clone() - clone a range from inode file to another
- *
-@@ -3352,9 +3461,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
- u32 nritems;
- int slot;
- int ret;
-- int no_quota;
- const u64 len = olen_aligned;
-- u64 last_disko = 0;
- u64 last_dest_end = destoff;
-
- ret = -ENOMEM;
-@@ -3400,7 +3507,6 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
-
- nritems = btrfs_header_nritems(path->nodes[0]);
- process_slot:
-- no_quota = 1;
- if (path->slots[0] >= nritems) {
- ret = btrfs_next_leaf(BTRFS_I(src)->root, path);
- if (ret < 0)
-@@ -3552,35 +3658,13 @@ process_slot:
- btrfs_set_file_extent_num_bytes(leaf, extent,
- datal);
-
-- /*
-- * We need to look up the roots that point at
-- * this bytenr and see if the new root does. If
-- * it does not we need to make sure we update
-- * quotas appropriately.
-- */
-- if (disko && root != BTRFS_I(src)->root &&
-- disko != last_disko) {
-- no_quota = check_ref(trans, root,
-- disko);
-- if (no_quota < 0) {
-- btrfs_abort_transaction(trans,
-- root,
-- ret);
-- btrfs_end_transaction(trans,
-- root);
-- ret = no_quota;
-- goto out;
-- }
-- }
--
- if (disko) {
- inode_add_bytes(inode, datal);
- ret = btrfs_inc_extent_ref(trans, root,
- disko, diskl, 0,
- root->root_key.objectid,
- btrfs_ino(inode),
-- new_key.offset - datao,
-- no_quota);
-+ new_key.offset - datao);
- if (ret) {
- btrfs_abort_transaction(trans,
- root,
-@@ -3594,21 +3678,6 @@ process_slot:
- } else if (type == BTRFS_FILE_EXTENT_INLINE) {
- u64 skip = 0;
- u64 trim = 0;
-- u64 aligned_end = 0;
--
-- /*
-- * Don't copy an inline extent into an offset
-- * greater than zero. Having an inline extent
-- * at such an offset results in chaos as btrfs
-- * isn't prepared for such cases. Just skip
-- * this case for the same reasons as commented
-- * at btrfs_ioctl_clone().
-- */
-- if (last_dest_end > 0) {
-- ret = -EOPNOTSUPP;
-- btrfs_end_transaction(trans, root);
-- goto out;
-- }
-
- if (off > key.offset) {
- skip = off - key.offset;
-@@ -3626,42 +3695,22 @@ process_slot:
- size -= skip + trim;
- datal -= skip + trim;
-
-- aligned_end = ALIGN(new_key.offset + datal,
-- root->sectorsize);
-- ret = btrfs_drop_extents(trans, root, inode,
-- drop_start,
-- aligned_end,
-- 1);
-+ ret = clone_copy_inline_extent(src, inode,
-+ trans, path,
-+ &new_key,
-+ drop_start,
-+ datal,
-+ skip, size, buf);
- if (ret) {
- if (ret != -EOPNOTSUPP)
- btrfs_abort_transaction(trans,
-- root, ret);
-- btrfs_end_transaction(trans, root);
-- goto out;
-- }
--
-- ret = btrfs_insert_empty_item(trans, root, path,
-- &new_key, size);
-- if (ret) {
-- btrfs_abort_transaction(trans, root,
-- ret);
-+ root,
-+ ret);
- btrfs_end_transaction(trans, root);
- goto out;
- }
--
-- if (skip) {
-- u32 start =
-- btrfs_file_extent_calc_inline_size(0);
-- memmove(buf+start, buf+start+skip,
-- datal);
-- }
--
- leaf = path->nodes[0];
- slot = path->slots[0];
-- write_extent_buffer(leaf, buf,
-- btrfs_item_ptr_offset(leaf, slot),
-- size);
-- inode_add_bytes(inode, datal);
- }
-
- /* If we have an implicit hole (NO_HOLES feature). */
-diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
-index 303babe..ab507e3 100644
---- a/fs/btrfs/relocation.c
-+++ b/fs/btrfs/relocation.c
-@@ -1716,7 +1716,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
- ret = btrfs_inc_extent_ref(trans, root, new_bytenr,
- num_bytes, parent,
- btrfs_header_owner(leaf),
-- key.objectid, key.offset, 1);
-+ key.objectid, key.offset);
- if (ret) {
- btrfs_abort_transaction(trans, root, ret);
- break;
-@@ -1724,7 +1724,7 @@ int replace_file_extents(struct btrfs_trans_handle *trans,
-
- ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
- parent, btrfs_header_owner(leaf),
-- key.objectid, key.offset, 1);
-+ key.objectid, key.offset);
- if (ret) {
- btrfs_abort_transaction(trans, root, ret);
- break;
-@@ -1900,23 +1900,21 @@ again:
-
- ret = btrfs_inc_extent_ref(trans, src, old_bytenr, blocksize,
- path->nodes[level]->start,
-- src->root_key.objectid, level - 1, 0,
-- 1);
-+ src->root_key.objectid, level - 1, 0);
- BUG_ON(ret);
- ret = btrfs_inc_extent_ref(trans, dest, new_bytenr, blocksize,
- 0, dest->root_key.objectid, level - 1,
-- 0, 1);
-+ 0);
- BUG_ON(ret);
-
- ret = btrfs_free_extent(trans, src, new_bytenr, blocksize,
- path->nodes[level]->start,
-- src->root_key.objectid, level - 1, 0,
-- 1);
-+ src->root_key.objectid, level - 1, 0);
- BUG_ON(ret);
-
- ret = btrfs_free_extent(trans, dest, old_bytenr, blocksize,
- 0, dest->root_key.objectid, level - 1,
-- 0, 1);
-+ 0);
- BUG_ON(ret);
-
- btrfs_unlock_up_safe(path, 0);
-@@ -2745,7 +2743,7 @@ static int do_relocation(struct btrfs_trans_handle *trans,
- node->eb->start, blocksize,
- upper->eb->start,
- btrfs_header_owner(upper->eb),
-- node->level, 0, 1);
-+ node->level, 0);
- BUG_ON(ret);
-
- ret = btrfs_drop_subtree(trans, root, eb, upper->eb);
-diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
-index a739b82..23bb2e4 100644
---- a/fs/btrfs/send.c
-+++ b/fs/btrfs/send.c
-@@ -2353,8 +2353,14 @@ static int send_subvol_begin(struct send_ctx *sctx)
- }
-
- TLV_PUT_STRING(sctx, BTRFS_SEND_A_PATH, name, namelen);
-- TLV_PUT_UUID(sctx, BTRFS_SEND_A_UUID,
-- sctx->send_root->root_item.uuid);
-+
-+ if (!btrfs_is_empty_uuid(sctx->send_root->root_item.received_uuid))
-+ TLV_PUT_UUID(sctx, BTRFS_SEND_A_UUID,
-+ sctx->send_root->root_item.received_uuid);
-+ else
-+ TLV_PUT_UUID(sctx, BTRFS_SEND_A_UUID,
-+ sctx->send_root->root_item.uuid);
-+
- TLV_PUT_U64(sctx, BTRFS_SEND_A_CTRANSID,
- le64_to_cpu(sctx->send_root->root_item.ctransid));
- if (parent_root) {
-diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
-index 1bbaace..6f8af2d 100644
---- a/fs/btrfs/tree-log.c
-+++ b/fs/btrfs/tree-log.c
-@@ -691,7 +691,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
- ret = btrfs_inc_extent_ref(trans, root,
- ins.objectid, ins.offset,
- 0, root->root_key.objectid,
-- key->objectid, offset, 0);
-+ key->objectid, offset);
- if (ret)
- goto out;
- } else {
-diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
-index 6f518c9..1fcd7b6 100644
---- a/fs/btrfs/xattr.c
-+++ b/fs/btrfs/xattr.c
-@@ -313,8 +313,10 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
- /* check to make sure this item is what we want */
- if (found_key.objectid != key.objectid)
- break;
-- if (found_key.type != BTRFS_XATTR_ITEM_KEY)
-+ if (found_key.type > BTRFS_XATTR_ITEM_KEY)
- break;
-+ if (found_key.type < BTRFS_XATTR_ITEM_KEY)
-+ goto next;
-
- di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
- if (verify_dir_item(root, leaf, di))
-diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
-index 51cb02d..fe2c982 100644
---- a/fs/ceph/mds_client.c
-+++ b/fs/ceph/mds_client.c
-@@ -1935,7 +1935,7 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
-
- len = sizeof(*head) +
- pathlen1 + pathlen2 + 2*(1 + sizeof(u32) + sizeof(u64)) +
-- sizeof(struct timespec);
-+ sizeof(struct ceph_timespec);
-
- /* calculate (max) length for cap releases */
- len += sizeof(struct ceph_mds_request_release) *
-diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
-index c711be8..9c8d233 100644
---- a/fs/debugfs/inode.c
-+++ b/fs/debugfs/inode.c
-@@ -271,8 +271,12 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
- dput(dentry);
- dentry = ERR_PTR(-EEXIST);
- }
-- if (IS_ERR(dentry))
-+
-+ if (IS_ERR(dentry)) {
- mutex_unlock(&d_inode(parent)->i_mutex);
-+ simple_release_fs(&debugfs_mount, &debugfs_mount_count);
-+ }
-+
- return dentry;
- }
-
-diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c
-index 4573155..2fab243 100644
---- a/fs/ext4/crypto.c
-+++ b/fs/ext4/crypto.c
-@@ -411,7 +411,13 @@ int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex)
- ext4_lblk_t lblk = ex->ee_block;
- ext4_fsblk_t pblk = ext4_ext_pblock(ex);
- unsigned int len = ext4_ext_get_actual_len(ex);
-- int err = 0;
-+ int ret, err = 0;
-+
-+#if 0
-+ ext4_msg(inode->i_sb, KERN_CRIT,
-+ "ext4_encrypted_zeroout ino %lu lblk %u len %u",
-+ (unsigned long) inode->i_ino, lblk, len);
-+#endif
-
- BUG_ON(inode->i_sb->s_blocksize != PAGE_CACHE_SIZE);
-
-@@ -437,17 +443,26 @@ int ext4_encrypted_zeroout(struct inode *inode, struct ext4_extent *ex)
- goto errout;
- }
- bio->bi_bdev = inode->i_sb->s_bdev;
-- bio->bi_iter.bi_sector = pblk;
-- err = bio_add_page(bio, ciphertext_page,
-+ bio->bi_iter.bi_sector =
-+ pblk << (inode->i_sb->s_blocksize_bits - 9);
-+ ret = bio_add_page(bio, ciphertext_page,
- inode->i_sb->s_blocksize, 0);
-- if (err) {
-+ if (ret != inode->i_sb->s_blocksize) {
-+ /* should never happen! */
-+ ext4_msg(inode->i_sb, KERN_ERR,
-+ "bio_add_page failed: %d", ret);
-+ WARN_ON(1);
- bio_put(bio);
-+ err = -EIO;
- goto errout;
- }
- err = submit_bio_wait(WRITE, bio);
-+ if ((err == 0) && bio->bi_error)
-+ err = -EIO;
- bio_put(bio);
- if (err)
- goto errout;
-+ lblk++; pblk++;
- }
- err = 0;
- errout:
-diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
-index d418431..e770c1ee 100644
---- a/fs/ext4/ext4_jbd2.c
-+++ b/fs/ext4/ext4_jbd2.c
-@@ -88,13 +88,13 @@ int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle)
- return 0;
- }
-
-+ err = handle->h_err;
- if (!handle->h_transaction) {
-- err = jbd2_journal_stop(handle);
-- return handle->h_err ? handle->h_err : err;
-+ rc = jbd2_journal_stop(handle);
-+ return err ? err : rc;
- }
-
- sb = handle->h_transaction->t_journal->j_private;
-- err = handle->h_err;
- rc = jbd2_journal_stop(handle);
-
- if (!err)
-diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
-index 2553aa8..7f486e3 100644
---- a/fs/ext4/extents.c
-+++ b/fs/ext4/extents.c
-@@ -3558,6 +3558,9 @@ static int ext4_ext_convert_to_initialized(handle_t *handle,
- max_zeroout = sbi->s_extent_max_zeroout_kb >>
- (inode->i_sb->s_blocksize_bits - 10);
-
-+ if (ext4_encrypted_inode(inode))
-+ max_zeroout = 0;
-+
- /* If extent is less than s_max_zeroout_kb, zeroout directly */
- if (max_zeroout && (ee_len <= max_zeroout)) {
- err = ext4_ext_zeroout(inode, ex);
-diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
-index 84ba4d2..17fbe38 100644
---- a/fs/ext4/page-io.c
-+++ b/fs/ext4/page-io.c
-@@ -425,6 +425,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
- struct buffer_head *bh, *head;
- int ret = 0;
- int nr_submitted = 0;
-+ int nr_to_submit = 0;
-
- blocksize = 1 << inode->i_blkbits;
-
-@@ -477,11 +478,13 @@ int ext4_bio_write_page(struct ext4_io_submit *io,
- unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);
- }
- set_buffer_async_write(bh);
-+ nr_to_submit++;
- } while ((bh = bh->b_this_page) != head);
-
- bh = head = page_buffers(page);
-
-- if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode)) {
-+ if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode) &&
-+ nr_to_submit) {
- data_page = ext4_encrypt(inode, page);
- if (IS_ERR(data_page)) {
- ret = PTR_ERR(data_page);
-diff --git a/fs/ext4/super.c b/fs/ext4/super.c
-index a63c7b0..df84bd2 100644
---- a/fs/ext4/super.c
-+++ b/fs/ext4/super.c
-@@ -394,9 +394,13 @@ static void ext4_handle_error(struct super_block *sb)
- smp_wmb();
- sb->s_flags |= MS_RDONLY;
- }
-- if (test_opt(sb, ERRORS_PANIC))
-+ if (test_opt(sb, ERRORS_PANIC)) {
-+ if (EXT4_SB(sb)->s_journal &&
-+ !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
-+ return;
- panic("EXT4-fs (device %s): panic forced after error\n",
- sb->s_id);
-+ }
- }
-
- #define ext4_error_ratelimit(sb) \
-@@ -585,8 +589,12 @@ void __ext4_abort(struct super_block *sb, const char *function,
- jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO);
- save_error_info(sb, function, line);
- }
-- if (test_opt(sb, ERRORS_PANIC))
-+ if (test_opt(sb, ERRORS_PANIC)) {
-+ if (EXT4_SB(sb)->s_journal &&
-+ !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
-+ return;
- panic("EXT4-fs panic from previous error\n");
-+ }
- }
-
- void __ext4_msg(struct super_block *sb,
-diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
-index 8270fe9..37023d0 100644
---- a/fs/jbd2/journal.c
-+++ b/fs/jbd2/journal.c
-@@ -2071,8 +2071,12 @@ static void __journal_abort_soft (journal_t *journal, int errno)
-
- __jbd2_journal_abort_hard(journal);
-
-- if (errno)
-+ if (errno) {
- jbd2_journal_update_sb_errno(journal);
-+ write_lock(&journal->j_state_lock);
-+ journal->j_flags |= JBD2_REC_ERR;
-+ write_unlock(&journal->j_state_lock);
-+ }
- }
-
- /**
-diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
-index 326d9e1..ffdf9b9 100644
---- a/fs/nfs/inode.c
-+++ b/fs/nfs/inode.c
-@@ -1824,7 +1824,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
- if ((long)fattr->gencount - (long)nfsi->attr_gencount > 0)
- nfsi->attr_gencount = fattr->gencount;
- }
-- invalid &= ~NFS_INO_INVALID_ATTR;
-+
-+ /* Don't declare attrcache up to date if there were no attrs! */
-+ if (fattr->valid != 0)
-+ invalid &= ~NFS_INO_INVALID_ATTR;
-+
- /* Don't invalidate the data if we were to blame */
- if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
- || S_ISLNK(inode->i_mode)))
-diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
-index 223bedd..10410e8 100644
---- a/fs/nfs/nfs4client.c
-+++ b/fs/nfs/nfs4client.c
-@@ -33,7 +33,7 @@ static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion)
- return ret;
- idr_preload(GFP_KERNEL);
- spin_lock(&nn->nfs_client_lock);
-- ret = idr_alloc(&nn->cb_ident_idr, clp, 0, 0, GFP_NOWAIT);
-+ ret = idr_alloc(&nn->cb_ident_idr, clp, 1, 0, GFP_NOWAIT);
- if (ret >= 0)
- clp->cl_cb_ident = ret;
- spin_unlock(&nn->nfs_client_lock);
-diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
-index 8abe271..abf5cae 100644
---- a/fs/nfs/pnfs.c
-+++ b/fs/nfs/pnfs.c
-@@ -872,33 +872,38 @@ send_layoutget(struct pnfs_layout_hdr *lo,
-
- dprintk("--> %s\n", __func__);
-
-- lgp = kzalloc(sizeof(*lgp), gfp_flags);
-- if (lgp == NULL)
-- return NULL;
-+ /*
-+ * Synchronously retrieve layout information from server and
-+ * store in lseg. If we race with a concurrent seqid morphing
-+ * op, then re-send the LAYOUTGET.
-+ */
-+ do {
-+ lgp = kzalloc(sizeof(*lgp), gfp_flags);
-+ if (lgp == NULL)
-+ return NULL;
-+
-+ i_size = i_size_read(ino);
-+
-+ lgp->args.minlength = PAGE_CACHE_SIZE;
-+ if (lgp->args.minlength > range->length)
-+ lgp->args.minlength = range->length;
-+ if (range->iomode == IOMODE_READ) {
-+ if (range->offset >= i_size)
-+ lgp->args.minlength = 0;
-+ else if (i_size - range->offset < lgp->args.minlength)
-+ lgp->args.minlength = i_size - range->offset;
-+ }
-+ lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE;
-+ lgp->args.range = *range;
-+ lgp->args.type = server->pnfs_curr_ld->id;
-+ lgp->args.inode = ino;
-+ lgp->args.ctx = get_nfs_open_context(ctx);
-+ lgp->gfp_flags = gfp_flags;
-+ lgp->cred = lo->plh_lc_cred;
-
-- i_size = i_size_read(ino);
-+ lseg = nfs4_proc_layoutget(lgp, gfp_flags);
-+ } while (lseg == ERR_PTR(-EAGAIN));
-
-- lgp->args.minlength = PAGE_CACHE_SIZE;
-- if (lgp->args.minlength > range->length)
-- lgp->args.minlength = range->length;
-- if (range->iomode == IOMODE_READ) {
-- if (range->offset >= i_size)
-- lgp->args.minlength = 0;
-- else if (i_size - range->offset < lgp->args.minlength)
-- lgp->args.minlength = i_size - range->offset;
-- }
-- lgp->args.maxcount = PNFS_LAYOUT_MAXSIZE;
-- lgp->args.range = *range;
-- lgp->args.type = server->pnfs_curr_ld->id;
-- lgp->args.inode = ino;
-- lgp->args.ctx = get_nfs_open_context(ctx);
-- lgp->gfp_flags = gfp_flags;
-- lgp->cred = lo->plh_lc_cred;
--
-- /* Synchronously retrieve layout information from server and
-- * store in lseg.
-- */
-- lseg = nfs4_proc_layoutget(lgp, gfp_flags);
- if (IS_ERR(lseg)) {
- switch (PTR_ERR(lseg)) {
- case -ENOMEM:
-@@ -1687,6 +1692,7 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
- /* existing state ID, make sure the sequence number matches. */
- if (pnfs_layout_stateid_blocked(lo, &res->stateid)) {
- dprintk("%s forget reply due to sequence\n", __func__);
-+ status = -EAGAIN;
- goto out_forget_reply;
- }
- pnfs_set_layout_stateid(lo, &res->stateid, false);
-diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
-index 0f1d569..0dea0c2 100644
---- a/fs/nfsd/nfs4state.c
-+++ b/fs/nfsd/nfs4state.c
-@@ -765,16 +765,68 @@ void nfs4_unhash_stid(struct nfs4_stid *s)
- s->sc_type = 0;
- }
-
--static void
-+/**
-+ * nfs4_get_existing_delegation - Discover if this delegation already exists
-+ * @clp: a pointer to the nfs4_client we're granting a delegation to
-+ * @fp: a pointer to the nfs4_file we're granting a delegation on
-+ *
-+ * Return:
-+ * On success: NULL if an existing delegation was not found.
-+ *
-+ * On error: -EAGAIN if one was previously granted to this nfs4_client
-+ * for this nfs4_file.
-+ *
-+ */
-+
-+static int
-+nfs4_get_existing_delegation(struct nfs4_client *clp, struct nfs4_file *fp)
-+{
-+ struct nfs4_delegation *searchdp = NULL;
-+ struct nfs4_client *searchclp = NULL;
-+
-+ lockdep_assert_held(&state_lock);
-+ lockdep_assert_held(&fp->fi_lock);
-+
-+ list_for_each_entry(searchdp, &fp->fi_delegations, dl_perfile) {
-+ searchclp = searchdp->dl_stid.sc_client;
-+ if (clp == searchclp) {
-+ return -EAGAIN;
-+ }
-+ }
-+ return 0;
-+}
-+
-+/**
-+ * hash_delegation_locked - Add a delegation to the appropriate lists
-+ * @dp: a pointer to the nfs4_delegation we are adding.
-+ * @fp: a pointer to the nfs4_file we're granting a delegation on
-+ *
-+ * Return:
-+ * On success: NULL if the delegation was successfully hashed.
-+ *
-+ * On error: -EAGAIN if one was previously granted to this
-+ * nfs4_client for this nfs4_file. Delegation is not hashed.
-+ *
-+ */
-+
-+static int
- hash_delegation_locked(struct nfs4_delegation *dp, struct nfs4_file *fp)
- {
-+ int status;
-+ struct nfs4_client *clp = dp->dl_stid.sc_client;
-+
- lockdep_assert_held(&state_lock);
- lockdep_assert_held(&fp->fi_lock);
-
-+ status = nfs4_get_existing_delegation(clp, fp);
-+ if (status)
-+ return status;
-+ ++fp->fi_delegees;
- atomic_inc(&dp->dl_stid.sc_count);
- dp->dl_stid.sc_type = NFS4_DELEG_STID;
- list_add(&dp->dl_perfile, &fp->fi_delegations);
-- list_add(&dp->dl_perclnt, &dp->dl_stid.sc_client->cl_delegations);
-+ list_add(&dp->dl_perclnt, &clp->cl_delegations);
-+ return 0;
- }
-
- static bool
-@@ -3360,6 +3412,7 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
- stp->st_access_bmap = 0;
- stp->st_deny_bmap = 0;
- stp->st_openstp = NULL;
-+ init_rwsem(&stp->st_rwsem);
- spin_lock(&oo->oo_owner.so_client->cl_lock);
- list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids);
- spin_lock(&fp->fi_lock);
-@@ -3945,6 +3998,18 @@ static struct file_lock *nfs4_alloc_init_lease(struct nfs4_file *fp, int flag)
- return fl;
- }
-
-+/**
-+ * nfs4_setlease - Obtain a delegation by requesting lease from vfs layer
-+ * @dp: a pointer to the nfs4_delegation we're adding.
-+ *
-+ * Return:
-+ * On success: Return code will be 0 on success.
-+ *
-+ * On error: -EAGAIN if there was an existing delegation.
-+ * nonzero if there is an error in other cases.
-+ *
-+ */
-+
- static int nfs4_setlease(struct nfs4_delegation *dp)
- {
- struct nfs4_file *fp = dp->dl_stid.sc_file;
-@@ -3976,16 +4041,19 @@ static int nfs4_setlease(struct nfs4_delegation *dp)
- goto out_unlock;
- /* Race breaker */
- if (fp->fi_deleg_file) {
-- status = 0;
-- ++fp->fi_delegees;
-- hash_delegation_locked(dp, fp);
-+ status = hash_delegation_locked(dp, fp);
- goto out_unlock;
- }
- fp->fi_deleg_file = filp;
-- fp->fi_delegees = 1;
-- hash_delegation_locked(dp, fp);
-+ fp->fi_delegees = 0;
-+ status = hash_delegation_locked(dp, fp);
- spin_unlock(&fp->fi_lock);
- spin_unlock(&state_lock);
-+ if (status) {
-+ /* Should never happen, this is a new fi_deleg_file */
-+ WARN_ON_ONCE(1);
-+ goto out_fput;
-+ }
- return 0;
- out_unlock:
- spin_unlock(&fp->fi_lock);
-@@ -4005,6 +4073,15 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
- if (fp->fi_had_conflict)
- return ERR_PTR(-EAGAIN);
-
-+ spin_lock(&state_lock);
-+ spin_lock(&fp->fi_lock);
-+ status = nfs4_get_existing_delegation(clp, fp);
-+ spin_unlock(&fp->fi_lock);
-+ spin_unlock(&state_lock);
-+
-+ if (status)
-+ return ERR_PTR(status);
-+
- dp = alloc_init_deleg(clp, fh, odstate);
- if (!dp)
- return ERR_PTR(-ENOMEM);
-@@ -4023,9 +4100,7 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh,
- status = -EAGAIN;
- goto out_unlock;
- }
-- ++fp->fi_delegees;
-- hash_delegation_locked(dp, fp);
-- status = 0;
-+ status = hash_delegation_locked(dp, fp);
- out_unlock:
- spin_unlock(&fp->fi_lock);
- spin_unlock(&state_lock);
-@@ -4187,15 +4262,20 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
- */
- if (stp) {
- /* Stateid was found, this is an OPEN upgrade */
-+ down_read(&stp->st_rwsem);
- status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
-- if (status)
-+ if (status) {
-+ up_read(&stp->st_rwsem);
- goto out;
-+ }
- } else {
- stp = open->op_stp;
- open->op_stp = NULL;
- init_open_stateid(stp, fp, open);
-+ down_read(&stp->st_rwsem);
- status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open);
- if (status) {
-+ up_read(&stp->st_rwsem);
- release_open_stateid(stp);
- goto out;
- }
-@@ -4207,6 +4287,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
- }
- update_stateid(&stp->st_stid.sc_stateid);
- memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
-+ up_read(&stp->st_rwsem);
-
- if (nfsd4_has_session(&resp->cstate)) {
- if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) {
-@@ -4819,10 +4900,13 @@ static __be32 nfs4_seqid_op_checks(struct nfsd4_compound_state *cstate, stateid_
- * revoked delegations are kept only for free_stateid.
- */
- return nfserr_bad_stateid;
-+ down_write(&stp->st_rwsem);
- status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate));
-- if (status)
-- return status;
-- return nfs4_check_fh(current_fh, &stp->st_stid);
-+ if (status == nfs_ok)
-+ status = nfs4_check_fh(current_fh, &stp->st_stid);
-+ if (status != nfs_ok)
-+ up_write(&stp->st_rwsem);
-+ return status;
- }
-
- /*
-@@ -4869,6 +4953,7 @@ static __be32 nfs4_preprocess_confirmed_seqid_op(struct nfsd4_compound_state *cs
- return status;
- oo = openowner(stp->st_stateowner);
- if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {
-+ up_write(&stp->st_rwsem);
- nfs4_put_stid(&stp->st_stid);
- return nfserr_bad_stateid;
- }
-@@ -4899,11 +4984,14 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
- goto out;
- oo = openowner(stp->st_stateowner);
- status = nfserr_bad_stateid;
-- if (oo->oo_flags & NFS4_OO_CONFIRMED)
-+ if (oo->oo_flags & NFS4_OO_CONFIRMED) {
-+ up_write(&stp->st_rwsem);
- goto put_stateid;
-+ }
- oo->oo_flags |= NFS4_OO_CONFIRMED;
- update_stateid(&stp->st_stid.sc_stateid);
- memcpy(&oc->oc_resp_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
-+ up_write(&stp->st_rwsem);
- dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
- __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid));
-
-@@ -4982,6 +5070,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
- memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
- status = nfs_ok;
- put_stateid:
-+ up_write(&stp->st_rwsem);
- nfs4_put_stid(&stp->st_stid);
- out:
- nfsd4_bump_seqid(cstate, status);
-@@ -5035,6 +5124,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
- goto out;
- update_stateid(&stp->st_stid.sc_stateid);
- memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
-+ up_write(&stp->st_rwsem);
-
- nfsd4_close_open_stateid(stp);
-
-@@ -5260,6 +5350,7 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo,
- stp->st_access_bmap = 0;
- stp->st_deny_bmap = open_stp->st_deny_bmap;
- stp->st_openstp = open_stp;
-+ init_rwsem(&stp->st_rwsem);
- list_add(&stp->st_locks, &open_stp->st_locks);
- list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids);
- spin_lock(&fp->fi_lock);
-@@ -5428,6 +5519,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
- &open_stp, nn);
- if (status)
- goto out;
-+ up_write(&open_stp->st_rwsem);
- open_sop = openowner(open_stp->st_stateowner);
- status = nfserr_bad_stateid;
- if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid,
-@@ -5435,6 +5527,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
- goto out;
- status = lookup_or_create_lock_state(cstate, open_stp, lock,
- &lock_stp, &new);
-+ if (status == nfs_ok)
-+ down_write(&lock_stp->st_rwsem);
- } else {
- status = nfs4_preprocess_seqid_op(cstate,
- lock->lk_old_lock_seqid,
-@@ -5540,6 +5634,8 @@ out:
- seqid_mutating_err(ntohl(status)))
- lock_sop->lo_owner.so_seqid++;
-
-+ up_write(&lock_stp->st_rwsem);
-+
- /*
- * If this is a new, never-before-used stateid, and we are
- * returning an error, then just go ahead and release it.
-@@ -5709,6 +5805,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
- fput:
- fput(filp);
- put_stateid:
-+ up_write(&stp->st_rwsem);
- nfs4_put_stid(&stp->st_stid);
- out:
- nfsd4_bump_seqid(cstate, status);
-diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
-index 583ffc1..31bde12 100644
---- a/fs/nfsd/state.h
-+++ b/fs/nfsd/state.h
-@@ -534,15 +534,16 @@ struct nfs4_file {
- * Better suggestions welcome.
- */
- struct nfs4_ol_stateid {
-- struct nfs4_stid st_stid; /* must be first field */
-- struct list_head st_perfile;
-- struct list_head st_perstateowner;
-- struct list_head st_locks;
-- struct nfs4_stateowner * st_stateowner;
-- struct nfs4_clnt_odstate * st_clnt_odstate;
-- unsigned char st_access_bmap;
-- unsigned char st_deny_bmap;
-- struct nfs4_ol_stateid * st_openstp;
-+ struct nfs4_stid st_stid;
-+ struct list_head st_perfile;
-+ struct list_head st_perstateowner;
-+ struct list_head st_locks;
-+ struct nfs4_stateowner *st_stateowner;
-+ struct nfs4_clnt_odstate *st_clnt_odstate;
-+ unsigned char st_access_bmap;
-+ unsigned char st_deny_bmap;
-+ struct nfs4_ol_stateid *st_openstp;
-+ struct rw_semaphore st_rwsem;
- };
-
- static inline struct nfs4_ol_stateid *openlockstateid(struct nfs4_stid *s)
-diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
-index b7dfac2..12bfa9c 100644
---- a/fs/ocfs2/namei.c
-+++ b/fs/ocfs2/namei.c
-@@ -374,6 +374,8 @@ static int ocfs2_mknod(struct inode *dir,
- mlog_errno(status);
- goto leave;
- }
-+ /* update inode->i_mode after mask with "umask". */
-+ inode->i_mode = mode;
-
- handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb,
- S_ISDIR(mode),
-diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
-index f1f32af..3e4ff3f 100644
---- a/include/linux/ipv6.h
-+++ b/include/linux/ipv6.h
-@@ -227,7 +227,7 @@ struct ipv6_pinfo {
- struct ipv6_ac_socklist *ipv6_ac_list;
- struct ipv6_fl_socklist __rcu *ipv6_fl_list;
-
-- struct ipv6_txoptions *opt;
-+ struct ipv6_txoptions __rcu *opt;
- struct sk_buff *pktoptions;
- struct sk_buff *rxpmtu;
- struct inet6_cork cork;
-diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
-index df07e78..1abeb82 100644
---- a/include/linux/jbd2.h
-+++ b/include/linux/jbd2.h
-@@ -1046,6 +1046,7 @@ struct journal_s
- #define JBD2_ABORT_ON_SYNCDATA_ERR 0x040 /* Abort the journal on file
- * data write error in ordered
- * mode */
-+#define JBD2_REC_ERR 0x080 /* The errno in the sb has been recorded */
-
- /*
- * Function declarations for the journaling transaction and buffer
-diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
-index dd20974..1565324 100644
---- a/include/linux/mlx5/mlx5_ifc.h
-+++ b/include/linux/mlx5/mlx5_ifc.h
-@@ -453,26 +453,28 @@ struct mlx5_ifc_per_protocol_networking_offload_caps_bits {
- u8 lro_cap[0x1];
- u8 lro_psh_flag[0x1];
- u8 lro_time_stamp[0x1];
-- u8 reserved_0[0x6];
-+ u8 reserved_0[0x3];
-+ u8 self_lb_en_modifiable[0x1];
-+ u8 reserved_1[0x2];
- u8 max_lso_cap[0x5];
-- u8 reserved_1[0x4];
-+ u8 reserved_2[0x4];
- u8 rss_ind_tbl_cap[0x4];
-- u8 reserved_2[0x3];
-+ u8 reserved_3[0x3];
- u8 tunnel_lso_const_out_ip_id[0x1];
-- u8 reserved_3[0x2];
-+ u8 reserved_4[0x2];
- u8 tunnel_statless_gre[0x1];
- u8 tunnel_stateless_vxlan[0x1];
-
-- u8 reserved_4[0x20];
-+ u8 reserved_5[0x20];
-
-- u8 reserved_5[0x10];
-+ u8 reserved_6[0x10];
- u8 lro_min_mss_size[0x10];
-
-- u8 reserved_6[0x120];
-+ u8 reserved_7[0x120];
-
- u8 lro_timer_supported_periods[4][0x20];
-
-- u8 reserved_7[0x600];
-+ u8 reserved_8[0x600];
- };
-
- struct mlx5_ifc_roce_cap_bits {
-@@ -4051,9 +4053,11 @@ struct mlx5_ifc_modify_tis_in_bits {
- };
-
- struct mlx5_ifc_modify_tir_bitmask_bits {
-- u8 reserved[0x20];
-+ u8 reserved_0[0x20];
-
-- u8 reserved1[0x1f];
-+ u8 reserved_1[0x1b];
-+ u8 self_lb_en[0x1];
-+ u8 reserved_2[0x3];
- u8 lro[0x1];
- };
-
-diff --git a/include/net/af_unix.h b/include/net/af_unix.h
-index b36d837..2a91a05 100644
---- a/include/net/af_unix.h
-+++ b/include/net/af_unix.h
-@@ -62,6 +62,7 @@ struct unix_sock {
- #define UNIX_GC_CANDIDATE 0
- #define UNIX_GC_MAYBE_CYCLE 1
- struct socket_wq peer_wq;
-+ wait_queue_t peer_wake;
- };
-
- static inline struct unix_sock *unix_sk(const struct sock *sk)
-diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
-index aaf9700..fb961a5 100644
---- a/include/net/ip6_fib.h
-+++ b/include/net/ip6_fib.h
-@@ -167,7 +167,8 @@ static inline void rt6_update_expires(struct rt6_info *rt0, int timeout)
-
- static inline u32 rt6_get_cookie(const struct rt6_info *rt)
- {
-- if (rt->rt6i_flags & RTF_PCPU || unlikely(rt->dst.flags & DST_NOCACHE))
-+ if (rt->rt6i_flags & RTF_PCPU ||
-+ (unlikely(rt->dst.flags & DST_NOCACHE) && rt->dst.from))
- rt = (struct rt6_info *)(rt->dst.from);
-
- return rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
-diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h
-index fa915fa..d49a8f8 100644
---- a/include/net/ip6_tunnel.h
-+++ b/include/net/ip6_tunnel.h
-@@ -90,11 +90,12 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb,
- err = ip6_local_out_sk(sk, skb);
-
- if (net_xmit_eval(err) == 0) {
-- struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats);
-+ struct pcpu_sw_netstats *tstats = get_cpu_ptr(dev->tstats);
- u64_stats_update_begin(&tstats->syncp);
- tstats->tx_bytes += pkt_len;
- tstats->tx_packets++;
- u64_stats_update_end(&tstats->syncp);
-+ put_cpu_ptr(tstats);
- } else {
- stats->tx_errors++;
- stats->tx_aborted_errors++;
-diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
-index f6dafec..62a750a 100644
---- a/include/net/ip_tunnels.h
-+++ b/include/net/ip_tunnels.h
-@@ -287,12 +287,13 @@ static inline void iptunnel_xmit_stats(int err,
- struct pcpu_sw_netstats __percpu *stats)
- {
- if (err > 0) {
-- struct pcpu_sw_netstats *tstats = this_cpu_ptr(stats);
-+ struct pcpu_sw_netstats *tstats = get_cpu_ptr(stats);
-
- u64_stats_update_begin(&tstats->syncp);
- tstats->tx_bytes += err;
- tstats->tx_packets++;
- u64_stats_update_end(&tstats->syncp);
-+ put_cpu_ptr(tstats);
- } else if (err < 0) {
- err_stats->tx_errors++;
- err_stats->tx_aborted_errors++;
-diff --git a/include/net/ipv6.h b/include/net/ipv6.h
-index 711cca4..b14e158 100644
---- a/include/net/ipv6.h
-+++ b/include/net/ipv6.h
-@@ -205,6 +205,7 @@ extern rwlock_t ip6_ra_lock;
- */
-
- struct ipv6_txoptions {
-+ atomic_t refcnt;
- /* Length of this structure */
- int tot_len;
-
-@@ -217,7 +218,7 @@ struct ipv6_txoptions {
- struct ipv6_opt_hdr *dst0opt;
- struct ipv6_rt_hdr *srcrt; /* Routing Header */
- struct ipv6_opt_hdr *dst1opt;
--
-+ struct rcu_head rcu;
- /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
- };
-
-@@ -252,6 +253,24 @@ struct ipv6_fl_socklist {
- struct rcu_head rcu;
- };
-
-+static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np)
-+{
-+ struct ipv6_txoptions *opt;
-+
-+ rcu_read_lock();
-+ opt = rcu_dereference(np->opt);
-+ if (opt && !atomic_inc_not_zero(&opt->refcnt))
-+ opt = NULL;
-+ rcu_read_unlock();
-+ return opt;
-+}
-+
-+static inline void txopt_put(struct ipv6_txoptions *opt)
-+{
-+ if (opt && atomic_dec_and_test(&opt->refcnt))
-+ kfree_rcu(opt, rcu);
-+}
-+
- struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk, __be32 label);
- struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions *opt_space,
- struct ip6_flowlabel *fl,
-@@ -490,6 +509,7 @@ struct ip6_create_arg {
- u32 user;
- const struct in6_addr *src;
- const struct in6_addr *dst;
-+ int iif;
- u8 ecn;
- };
-
-diff --git a/include/net/ndisc.h b/include/net/ndisc.h
-index aba5695..b3a7751 100644
---- a/include/net/ndisc.h
-+++ b/include/net/ndisc.h
-@@ -182,8 +182,7 @@ int ndisc_rcv(struct sk_buff *skb);
-
- void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
- const struct in6_addr *solicit,
-- const struct in6_addr *daddr, const struct in6_addr *saddr,
-- struct sk_buff *oskb);
-+ const struct in6_addr *daddr, const struct in6_addr *saddr);
-
- void ndisc_send_rs(struct net_device *dev,
- const struct in6_addr *saddr, const struct in6_addr *daddr);
-diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
-index 444faa8..f1ad8f8 100644
---- a/include/net/sch_generic.h
-+++ b/include/net/sch_generic.h
-@@ -61,6 +61,9 @@ struct Qdisc {
- */
- #define TCQ_F_WARN_NONWC (1 << 16)
- #define TCQ_F_CPUSTATS 0x20 /* run using percpu statistics */
-+#define TCQ_F_NOPARENT 0x40 /* root of its hierarchy :
-+ * qdisc_tree_decrease_qlen() should stop.
-+ */
- u32 limit;
- const struct Qdisc_ops *ops;
- struct qdisc_size_table __rcu *stab;
-diff --git a/include/net/switchdev.h b/include/net/switchdev.h
-index 319baab..731c40e 100644
---- a/include/net/switchdev.h
-+++ b/include/net/switchdev.h
-@@ -272,7 +272,7 @@ static inline int switchdev_port_fdb_dump(struct sk_buff *skb,
- struct net_device *filter_dev,
- int idx)
- {
-- return -EOPNOTSUPP;
-+ return idx;
- }
-
- static inline void switchdev_port_fwd_mark_set(struct net_device *dev,
-diff --git a/kernel/.gitignore b/kernel/.gitignore
-index 790d83c..b3097bd 100644
---- a/kernel/.gitignore
-+++ b/kernel/.gitignore
-@@ -5,4 +5,3 @@ config_data.h
- config_data.gz
- timeconst.h
- hz.bc
--x509_certificate_list
-diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
-index 29ace10..7a0decf 100644
---- a/kernel/bpf/arraymap.c
-+++ b/kernel/bpf/arraymap.c
-@@ -104,7 +104,7 @@ static int array_map_update_elem(struct bpf_map *map, void *key, void *value,
- /* all elements already exist */
- return -EEXIST;
-
-- memcpy(array->value + array->elem_size * index, value, array->elem_size);
-+ memcpy(array->value + array->elem_size * index, value, map->value_size);
- return 0;
- }
-
-diff --git a/net/core/neighbour.c b/net/core/neighbour.c
-index 2b515ba..c169bba 100644
---- a/net/core/neighbour.c
-+++ b/net/core/neighbour.c
-@@ -2215,7 +2215,7 @@ static int pneigh_fill_info(struct sk_buff *skb, struct pneigh_entry *pn,
- ndm->ndm_pad2 = 0;
- ndm->ndm_flags = pn->flags | NTF_PROXY;
- ndm->ndm_type = RTN_UNICAST;
-- ndm->ndm_ifindex = pn->dev->ifindex;
-+ ndm->ndm_ifindex = pn->dev ? pn->dev->ifindex : 0;
- ndm->ndm_state = NUD_NONE;
-
- if (nla_put(skb, NDA_DST, tbl->key_len, pn->key))
-@@ -2290,7 +2290,7 @@ static int pneigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
- if (h > s_h)
- s_idx = 0;
- for (n = tbl->phash_buckets[h], idx = 0; n; n = n->next) {
-- if (dev_net(n->dev) != net)
-+ if (pneigh_net(n) != net)
- continue;
- if (idx < s_idx)
- goto next;
-diff --git a/net/core/scm.c b/net/core/scm.c
-index 3b6899b..8a1741b 100644
---- a/net/core/scm.c
-+++ b/net/core/scm.c
-@@ -305,6 +305,8 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
- err = put_user(cmlen, &cm->cmsg_len);
- if (!err) {
- cmlen = CMSG_SPACE(i*sizeof(int));
-+ if (msg->msg_controllen < cmlen)
-+ cmlen = msg->msg_controllen;
- msg->msg_control += cmlen;
- msg->msg_controllen -= cmlen;
- }
-diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
-index 5165571..a049050 100644
---- a/net/dccp/ipv6.c
-+++ b/net/dccp/ipv6.c
-@@ -202,7 +202,9 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req)
- security_req_classify_flow(req, flowi6_to_flowi(&fl6));
-
-
-- final_p = fl6_update_dst(&fl6, np->opt, &final);
-+ rcu_read_lock();
-+ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
-+ rcu_read_unlock();
-
- dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
- if (IS_ERR(dst)) {
-@@ -219,7 +221,10 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req)
- &ireq->ir_v6_loc_addr,
- &ireq->ir_v6_rmt_addr);
- fl6.daddr = ireq->ir_v6_rmt_addr;
-- err = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);
-+ rcu_read_lock();
-+ err = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt),
-+ np->tclass);
-+ rcu_read_unlock();
- err = net_xmit_eval(err);
- }
-
-@@ -415,6 +420,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
- {
- struct inet_request_sock *ireq = inet_rsk(req);
- struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
-+ struct ipv6_txoptions *opt;
- struct inet_sock *newinet;
- struct dccp6_sock *newdp6;
- struct sock *newsk;
-@@ -534,13 +540,15 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
- * Yes, keeping reference count would be much more clever, but we make
- * one more one thing there: reattach optmem to newsk.
- */
-- if (np->opt != NULL)
-- newnp->opt = ipv6_dup_options(newsk, np->opt);
--
-+ opt = rcu_dereference(np->opt);
-+ if (opt) {
-+ opt = ipv6_dup_options(newsk, opt);
-+ RCU_INIT_POINTER(newnp->opt, opt);
-+ }
- inet_csk(newsk)->icsk_ext_hdr_len = 0;
-- if (newnp->opt != NULL)
-- inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
-- newnp->opt->opt_flen);
-+ if (opt)
-+ inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen +
-+ opt->opt_flen;
-
- dccp_sync_mss(newsk, dst_mtu(dst));
-
-@@ -793,6 +801,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
- struct ipv6_pinfo *np = inet6_sk(sk);
- struct dccp_sock *dp = dccp_sk(sk);
- struct in6_addr *saddr = NULL, *final_p, final;
-+ struct ipv6_txoptions *opt;
- struct flowi6 fl6;
- struct dst_entry *dst;
- int addr_type;
-@@ -892,7 +901,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
- fl6.fl6_sport = inet->inet_sport;
- security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
-
-- final_p = fl6_update_dst(&fl6, np->opt, &final);
-+ opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
-+ final_p = fl6_update_dst(&fl6, opt, &final);
-
- dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
- if (IS_ERR(dst)) {
-@@ -912,9 +922,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
- __ip6_dst_store(sk, dst, NULL, NULL);
-
- icsk->icsk_ext_hdr_len = 0;
-- if (np->opt != NULL)
-- icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
-- np->opt->opt_nflen);
-+ if (opt)
-+ icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen;
-
- inet->inet_dport = usin->sin6_port;
-
-diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
-index 8e8203d..ef7e2c4 100644
---- a/net/ipv4/ipmr.c
-+++ b/net/ipv4/ipmr.c
-@@ -134,7 +134,7 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
- struct mfc_cache *c, struct rtmsg *rtm);
- static void mroute_netlink_event(struct mr_table *mrt, struct mfc_cache *mfc,
- int cmd);
--static void mroute_clean_tables(struct mr_table *mrt);
-+static void mroute_clean_tables(struct mr_table *mrt, bool all);
- static void ipmr_expire_process(unsigned long arg);
-
- #ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES
-@@ -350,7 +350,7 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id)
- static void ipmr_free_table(struct mr_table *mrt)
- {
- del_timer_sync(&mrt->ipmr_expire_timer);
-- mroute_clean_tables(mrt);
-+ mroute_clean_tables(mrt, true);
- kfree(mrt);
- }
-
-@@ -1208,7 +1208,7 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
- * Close the multicast socket, and clear the vif tables etc
- */
-
--static void mroute_clean_tables(struct mr_table *mrt)
-+static void mroute_clean_tables(struct mr_table *mrt, bool all)
- {
- int i;
- LIST_HEAD(list);
-@@ -1217,8 +1217,9 @@ static void mroute_clean_tables(struct mr_table *mrt)
- /* Shut down all active vif entries */
-
- for (i = 0; i < mrt->maxvif; i++) {
-- if (!(mrt->vif_table[i].flags & VIFF_STATIC))
-- vif_delete(mrt, i, 0, &list);
-+ if (!all && (mrt->vif_table[i].flags & VIFF_STATIC))
-+ continue;
-+ vif_delete(mrt, i, 0, &list);
- }
- unregister_netdevice_many(&list);
-
-@@ -1226,7 +1227,7 @@ static void mroute_clean_tables(struct mr_table *mrt)
-
- for (i = 0; i < MFC_LINES; i++) {
- list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[i], list) {
-- if (c->mfc_flags & MFC_STATIC)
-+ if (!all && (c->mfc_flags & MFC_STATIC))
- continue;
- list_del_rcu(&c->list);
- mroute_netlink_event(mrt, c, RTM_DELROUTE);
-@@ -1261,7 +1262,7 @@ static void mrtsock_destruct(struct sock *sk)
- NETCONFA_IFINDEX_ALL,
- net->ipv4.devconf_all);
- RCU_INIT_POINTER(mrt->mroute_sk, NULL);
-- mroute_clean_tables(mrt);
-+ mroute_clean_tables(mrt, false);
- }
- }
- rtnl_unlock();
-diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
-index a8f515b..0a2b61d 100644
---- a/net/ipv4/tcp_input.c
-+++ b/net/ipv4/tcp_input.c
-@@ -4457,19 +4457,34 @@ static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int
- int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size)
- {
- struct sk_buff *skb;
-+ int err = -ENOMEM;
-+ int data_len = 0;
- bool fragstolen;
-
- if (size == 0)
- return 0;
-
-- skb = alloc_skb(size, sk->sk_allocation);
-+ if (size > PAGE_SIZE) {
-+ int npages = min_t(size_t, size >> PAGE_SHIFT, MAX_SKB_FRAGS);
-+
-+ data_len = npages << PAGE_SHIFT;
-+ size = data_len + (size & ~PAGE_MASK);
-+ }
-+ skb = alloc_skb_with_frags(size - data_len, data_len,
-+ PAGE_ALLOC_COSTLY_ORDER,
-+ &err, sk->sk_allocation);
- if (!skb)
- goto err;
-
-+ skb_put(skb, size - data_len);
-+ skb->data_len = data_len;
-+ skb->len = size;
-+
- if (tcp_try_rmem_schedule(sk, skb, skb->truesize))
- goto err_free;
-
-- if (memcpy_from_msg(skb_put(skb, size), msg, size))
-+ err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size);
-+ if (err)
- goto err_free;
-
- TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt;
-@@ -4485,7 +4500,8 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size)
- err_free:
- kfree_skb(skb);
- err:
-- return -ENOMEM;
-+ return err;
-+
- }
-
- static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
-@@ -5643,6 +5659,7 @@ discard:
- }
-
- tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1;
-+ tp->copied_seq = tp->rcv_nxt;
- tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1;
-
- /* RFC1323: The window in SYN & SYN/ACK segments is
-diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
-index 93898e0..a7739c8 100644
---- a/net/ipv4/tcp_ipv4.c
-+++ b/net/ipv4/tcp_ipv4.c
-@@ -922,7 +922,8 @@ int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr,
- }
-
- md5sig = rcu_dereference_protected(tp->md5sig_info,
-- sock_owned_by_user(sk));
-+ sock_owned_by_user(sk) ||
-+ lockdep_is_held(&sk->sk_lock.slock));
- if (!md5sig) {
- md5sig = kmalloc(sizeof(*md5sig), gfp);
- if (!md5sig)
-diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
-index 7149ebc..04f0a05 100644
---- a/net/ipv4/tcp_timer.c
-+++ b/net/ipv4/tcp_timer.c
-@@ -176,6 +176,18 @@ static int tcp_write_timeout(struct sock *sk)
- syn_set = true;
- } else {
- if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0, 0)) {
-+ /* Some middle-boxes may black-hole Fast Open _after_
-+ * the handshake. Therefore we conservatively disable
-+ * Fast Open on this path on recurring timeouts with
-+ * few or zero bytes acked after Fast Open.
-+ */
-+ if (tp->syn_data_acked &&
-+ tp->bytes_acked <= tp->rx_opt.mss_clamp) {
-+ tcp_fastopen_cache_set(sk, 0, NULL, true, 0);
-+ if (icsk->icsk_retransmits == sysctl_tcp_retries1)
-+ NET_INC_STATS_BH(sock_net(sk),
-+ LINUX_MIB_TCPFASTOPENACTIVEFAIL);
-+ }
- /* Black hole detection */
- tcp_mtu_probing(icsk, sk);
-
-diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
-index dd00828..3939dd2 100644
---- a/net/ipv6/addrconf.c
-+++ b/net/ipv6/addrconf.c
-@@ -3628,7 +3628,7 @@ static void addrconf_dad_work(struct work_struct *w)
-
- /* send a neighbour solicitation for our addr */
- addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
-- ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any, NULL);
-+ ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any);
- out:
- in6_ifa_put(ifp);
- rtnl_unlock();
-diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
-index 44bb66b..38d66dd 100644
---- a/net/ipv6/af_inet6.c
-+++ b/net/ipv6/af_inet6.c
-@@ -428,9 +428,11 @@ void inet6_destroy_sock(struct sock *sk)
-
- /* Free tx options */
-
-- opt = xchg(&np->opt, NULL);
-- if (opt)
-- sock_kfree_s(sk, opt, opt->tot_len);
-+ opt = xchg((__force struct ipv6_txoptions **)&np->opt, NULL);
-+ if (opt) {
-+ atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
-+ txopt_put(opt);
-+ }
- }
- EXPORT_SYMBOL_GPL(inet6_destroy_sock);
-
-@@ -659,7 +661,10 @@ int inet6_sk_rebuild_header(struct sock *sk)
- fl6.fl6_sport = inet->inet_sport;
- security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
-
-- final_p = fl6_update_dst(&fl6, np->opt, &final);
-+ rcu_read_lock();
-+ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt),
-+ &final);
-+ rcu_read_unlock();
-
- dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
- if (IS_ERR(dst)) {
-diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
-index 9aadd57..a42a673 100644
---- a/net/ipv6/datagram.c
-+++ b/net/ipv6/datagram.c
-@@ -167,8 +167,10 @@ ipv4_connected:
-
- security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
-
-- opt = flowlabel ? flowlabel->opt : np->opt;
-+ rcu_read_lock();
-+ opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt);
- final_p = fl6_update_dst(&fl6, opt, &final);
-+ rcu_read_unlock();
-
- dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
- err = 0;
-diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
-index ce203b0..ea7c4d6 100644
---- a/net/ipv6/exthdrs.c
-+++ b/net/ipv6/exthdrs.c
-@@ -727,6 +727,7 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
- *((char **)&opt2->dst1opt) += dif;
- if (opt2->srcrt)
- *((char **)&opt2->srcrt) += dif;
-+ atomic_set(&opt2->refcnt, 1);
- }
- return opt2;
- }
-@@ -790,7 +791,7 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
- return ERR_PTR(-ENOBUFS);
-
- memset(opt2, 0, tot_len);
--
-+ atomic_set(&opt2->refcnt, 1);
- opt2->tot_len = tot_len;
- p = (char *)(opt2 + 1);
-
-diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
-index 6927f3f..9beed30 100644
---- a/net/ipv6/inet6_connection_sock.c
-+++ b/net/ipv6/inet6_connection_sock.c
-@@ -77,7 +77,9 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk,
- memset(fl6, 0, sizeof(*fl6));
- fl6->flowi6_proto = IPPROTO_TCP;
- fl6->daddr = ireq->ir_v6_rmt_addr;
-- final_p = fl6_update_dst(fl6, np->opt, &final);
-+ rcu_read_lock();
-+ final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
-+ rcu_read_unlock();
- fl6->saddr = ireq->ir_v6_loc_addr;
- fl6->flowi6_oif = ireq->ir_iif;
- fl6->flowi6_mark = ireq->ir_mark;
-@@ -207,7 +209,9 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
- fl6->fl6_dport = inet->inet_dport;
- security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
-
-- final_p = fl6_update_dst(fl6, np->opt, &final);
-+ rcu_read_lock();
-+ final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
-+ rcu_read_unlock();
-
- dst = __inet6_csk_dst_check(sk, np->dst_cookie);
- if (!dst) {
-@@ -240,7 +244,8 @@ int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl_unused
- /* Restore final destination back after routing done */
- fl6.daddr = sk->sk_v6_daddr;
-
-- res = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);
-+ res = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt),
-+ np->tclass);
- rcu_read_unlock();
- return res;
- }
-diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
-index eabffbb..137fca4 100644
---- a/net/ipv6/ip6_tunnel.c
-+++ b/net/ipv6/ip6_tunnel.c
-@@ -177,7 +177,7 @@ void ip6_tnl_dst_reset(struct ip6_tnl *t)
- int i;
-
- for_each_possible_cpu(i)
-- ip6_tnl_per_cpu_dst_set(raw_cpu_ptr(t->dst_cache), NULL);
-+ ip6_tnl_per_cpu_dst_set(per_cpu_ptr(t->dst_cache, i), NULL);
- }
- EXPORT_SYMBOL_GPL(ip6_tnl_dst_reset);
-
-diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
-index 0e004cc..35eee72 100644
---- a/net/ipv6/ip6mr.c
-+++ b/net/ipv6/ip6mr.c
-@@ -118,7 +118,7 @@ static void mr6_netlink_event(struct mr6_table *mrt, struct mfc6_cache *mfc,
- int cmd);
- static int ip6mr_rtm_dumproute(struct sk_buff *skb,
- struct netlink_callback *cb);
--static void mroute_clean_tables(struct mr6_table *mrt);
-+static void mroute_clean_tables(struct mr6_table *mrt, bool all);
- static void ipmr_expire_process(unsigned long arg);
-
- #ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
-@@ -334,7 +334,7 @@ static struct mr6_table *ip6mr_new_table(struct net *net, u32 id)
- static void ip6mr_free_table(struct mr6_table *mrt)
- {
- del_timer_sync(&mrt->ipmr_expire_timer);
-- mroute_clean_tables(mrt);
-+ mroute_clean_tables(mrt, true);
- kfree(mrt);
- }
-
-@@ -1542,7 +1542,7 @@ static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt,
- * Close the multicast socket, and clear the vif tables etc
- */
-
--static void mroute_clean_tables(struct mr6_table *mrt)
-+static void mroute_clean_tables(struct mr6_table *mrt, bool all)
- {
- int i;
- LIST_HEAD(list);
-@@ -1552,8 +1552,9 @@ static void mroute_clean_tables(struct mr6_table *mrt)
- * Shut down all active vif entries
- */
- for (i = 0; i < mrt->maxvif; i++) {
-- if (!(mrt->vif6_table[i].flags & VIFF_STATIC))
-- mif6_delete(mrt, i, &list);
-+ if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC))
-+ continue;
-+ mif6_delete(mrt, i, &list);
- }
- unregister_netdevice_many(&list);
-
-@@ -1562,7 +1563,7 @@ static void mroute_clean_tables(struct mr6_table *mrt)
- */
- for (i = 0; i < MFC6_LINES; i++) {
- list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[i], list) {
-- if (c->mfc_flags & MFC_STATIC)
-+ if (!all && (c->mfc_flags & MFC_STATIC))
- continue;
- write_lock_bh(&mrt_lock);
- list_del(&c->list);
-@@ -1625,7 +1626,7 @@ int ip6mr_sk_done(struct sock *sk)
- net->ipv6.devconf_all);
- write_unlock_bh(&mrt_lock);
-
-- mroute_clean_tables(mrt);
-+ mroute_clean_tables(mrt, false);
- err = 0;
- break;
- }
-diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
-index 63e6956..4449ad1 100644
---- a/net/ipv6/ipv6_sockglue.c
-+++ b/net/ipv6/ipv6_sockglue.c
-@@ -111,7 +111,8 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
- icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
- }
- }
-- opt = xchg(&inet6_sk(sk)->opt, opt);
-+ opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt,
-+ opt);
- sk_dst_reset(sk);
-
- return opt;
-@@ -231,9 +232,12 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
- sk->sk_socket->ops = &inet_dgram_ops;
- sk->sk_family = PF_INET;
- }
-- opt = xchg(&np->opt, NULL);
-- if (opt)
-- sock_kfree_s(sk, opt, opt->tot_len);
-+ opt = xchg((__force struct ipv6_txoptions **)&np->opt,
-+ NULL);
-+ if (opt) {
-+ atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
-+ txopt_put(opt);
-+ }
- pktopt = xchg(&np->pktoptions, NULL);
- kfree_skb(pktopt);
-
-@@ -403,7 +407,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
- if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW))
- break;
-
-- opt = ipv6_renew_options(sk, np->opt, optname,
-+ opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
-+ opt = ipv6_renew_options(sk, opt, optname,
- (struct ipv6_opt_hdr __user *)optval,
- optlen);
- if (IS_ERR(opt)) {
-@@ -432,8 +437,10 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
- retv = 0;
- opt = ipv6_update_options(sk, opt);
- sticky_done:
-- if (opt)
-- sock_kfree_s(sk, opt, opt->tot_len);
-+ if (opt) {
-+ atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
-+ txopt_put(opt);
-+ }
- break;
- }
-
-@@ -486,6 +493,7 @@ sticky_done:
- break;
-
- memset(opt, 0, sizeof(*opt));
-+ atomic_set(&opt->refcnt, 1);
- opt->tot_len = sizeof(*opt) + optlen;
- retv = -EFAULT;
- if (copy_from_user(opt+1, optval, optlen))
-@@ -502,8 +510,10 @@ update:
- retv = 0;
- opt = ipv6_update_options(sk, opt);
- done:
-- if (opt)
-- sock_kfree_s(sk, opt, opt->tot_len);
-+ if (opt) {
-+ atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
-+ txopt_put(opt);
-+ }
- break;
- }
- case IPV6_UNICAST_HOPS:
-@@ -1110,10 +1120,11 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
- case IPV6_RTHDR:
- case IPV6_DSTOPTS:
- {
-+ struct ipv6_txoptions *opt;
-
- lock_sock(sk);
-- len = ipv6_getsockopt_sticky(sk, np->opt,
-- optname, optval, len);
-+ opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
-+ len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len);
- release_sock(sk);
- /* check if ipv6_getsockopt_sticky() returns err code */
- if (len < 0)
-diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
-index 083b292..41e3b5e 100644
---- a/net/ipv6/mcast.c
-+++ b/net/ipv6/mcast.c
-@@ -1651,7 +1651,6 @@ out:
- if (!err) {
- ICMP6MSGOUT_INC_STATS(net, idev, ICMPV6_MLD2_REPORT);
- ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
-- IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, payload_len);
- } else {
- IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
- }
-@@ -2014,7 +2013,6 @@ out:
- if (!err) {
- ICMP6MSGOUT_INC_STATS(net, idev, type);
- ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
-- IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, full_len);
- } else
- IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
-
-diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
-index 64a7135..9ad46cd 100644
---- a/net/ipv6/ndisc.c
-+++ b/net/ipv6/ndisc.c
-@@ -553,8 +553,7 @@ static void ndisc_send_unsol_na(struct net_device *dev)
-
- void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
- const struct in6_addr *solicit,
-- const struct in6_addr *daddr, const struct in6_addr *saddr,
-- struct sk_buff *oskb)
-+ const struct in6_addr *daddr, const struct in6_addr *saddr)
- {
- struct sk_buff *skb;
- struct in6_addr addr_buf;
-@@ -590,9 +589,6 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
- ndisc_fill_addr_option(skb, ND_OPT_SOURCE_LL_ADDR,
- dev->dev_addr);
-
-- if (!(dev->priv_flags & IFF_XMIT_DST_RELEASE) && oskb)
-- skb_dst_copy(skb, oskb);
--
- ndisc_send_skb(skb, daddr, saddr);
- }
-
-@@ -679,12 +675,12 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
- "%s: trying to ucast probe in NUD_INVALID: %pI6\n",
- __func__, target);
- }
-- ndisc_send_ns(dev, neigh, target, target, saddr, skb);
-+ ndisc_send_ns(dev, neigh, target, target, saddr);
- } else if ((probes -= NEIGH_VAR(neigh->parms, APP_PROBES)) < 0) {
- neigh_app_ns(neigh);
- } else {
- addrconf_addr_solict_mult(target, &mcaddr);
-- ndisc_send_ns(dev, NULL, target, &mcaddr, saddr, skb);
-+ ndisc_send_ns(dev, NULL, target, &mcaddr, saddr);
- }
- }
-
-diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
-index c7196ad..dc50143 100644
---- a/net/ipv6/netfilter/nf_conntrack_reasm.c
-+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
-@@ -190,7 +190,7 @@ static void nf_ct_frag6_expire(unsigned long data)
- /* Creation primitives. */
- static inline struct frag_queue *fq_find(struct net *net, __be32 id,
- u32 user, struct in6_addr *src,
-- struct in6_addr *dst, u8 ecn)
-+ struct in6_addr *dst, int iif, u8 ecn)
- {
- struct inet_frag_queue *q;
- struct ip6_create_arg arg;
-@@ -200,6 +200,7 @@ static inline struct frag_queue *fq_find(struct net *net, __be32 id,
- arg.user = user;
- arg.src = src;
- arg.dst = dst;
-+ arg.iif = iif;
- arg.ecn = ecn;
-
- local_bh_disable();
-@@ -603,7 +604,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
- fhdr = (struct frag_hdr *)skb_transport_header(clone);
-
- fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr,
-- ip6_frag_ecn(hdr));
-+ skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr));
- if (fq == NULL) {
- pr_debug("Can't find and can't create new queue\n");
- goto ret_orig;
-diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
-index fdbada156..fe97729 100644
---- a/net/ipv6/raw.c
-+++ b/net/ipv6/raw.c
-@@ -732,6 +732,7 @@ static int raw6_getfrag(void *from, char *to, int offset, int len, int odd,
-
- static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
- {
-+ struct ipv6_txoptions *opt_to_free = NULL;
- struct ipv6_txoptions opt_space;
- DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
- struct in6_addr *daddr, *final_p, final;
-@@ -838,8 +839,10 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
- if (!(opt->opt_nflen|opt->opt_flen))
- opt = NULL;
- }
-- if (!opt)
-- opt = np->opt;
-+ if (!opt) {
-+ opt = txopt_get(np);
-+ opt_to_free = opt;
-+ }
- if (flowlabel)
- opt = fl6_merge_options(&opt_space, flowlabel, opt);
- opt = ipv6_fixup_options(&opt_space, opt);
-@@ -905,6 +908,7 @@ done:
- dst_release(dst);
- out:
- fl6_sock_release(flowlabel);
-+ txopt_put(opt_to_free);
- return err < 0 ? err : len;
- do_confirm:
- dst_confirm(dst);
-diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
-index f1159bb..04013a9 100644
---- a/net/ipv6/reassembly.c
-+++ b/net/ipv6/reassembly.c
-@@ -108,7 +108,10 @@ bool ip6_frag_match(const struct inet_frag_queue *q, const void *a)
- return fq->id == arg->id &&
- fq->user == arg->user &&
- ipv6_addr_equal(&fq->saddr, arg->src) &&
-- ipv6_addr_equal(&fq->daddr, arg->dst);
-+ ipv6_addr_equal(&fq->daddr, arg->dst) &&
-+ (arg->iif == fq->iif ||
-+ !(ipv6_addr_type(arg->dst) & (IPV6_ADDR_MULTICAST |
-+ IPV6_ADDR_LINKLOCAL)));
- }
- EXPORT_SYMBOL(ip6_frag_match);
-
-@@ -180,7 +183,7 @@ static void ip6_frag_expire(unsigned long data)
-
- static struct frag_queue *
- fq_find(struct net *net, __be32 id, const struct in6_addr *src,
-- const struct in6_addr *dst, u8 ecn)
-+ const struct in6_addr *dst, int iif, u8 ecn)
- {
- struct inet_frag_queue *q;
- struct ip6_create_arg arg;
-@@ -190,6 +193,7 @@ fq_find(struct net *net, __be32 id, const struct in6_addr *src,
- arg.user = IP6_DEFRAG_LOCAL_DELIVER;
- arg.src = src;
- arg.dst = dst;
-+ arg.iif = iif;
- arg.ecn = ecn;
-
- hash = inet6_hash_frag(id, src, dst);
-@@ -551,7 +555,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
- }
-
- fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr,
-- ip6_frag_ecn(hdr));
-+ skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr));
- if (fq) {
- int ret;
-
-diff --git a/net/ipv6/route.c b/net/ipv6/route.c
-index 946880a..fd0e674 100644
---- a/net/ipv6/route.c
-+++ b/net/ipv6/route.c
-@@ -403,6 +403,14 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
- }
- }
-
-+static bool __rt6_check_expired(const struct rt6_info *rt)
-+{
-+ if (rt->rt6i_flags & RTF_EXPIRES)
-+ return time_after(jiffies, rt->dst.expires);
-+ else
-+ return false;
-+}
-+
- static bool rt6_check_expired(const struct rt6_info *rt)
- {
- if (rt->rt6i_flags & RTF_EXPIRES) {
-@@ -538,7 +546,7 @@ static void rt6_probe_deferred(struct work_struct *w)
- container_of(w, struct __rt6_probe_work, work);
-
- addrconf_addr_solict_mult(&work->target, &mcaddr);
-- ndisc_send_ns(work->dev, NULL, &work->target, &mcaddr, NULL, NULL);
-+ ndisc_send_ns(work->dev, NULL, &work->target, &mcaddr, NULL);
- dev_put(work->dev);
- kfree(work);
- }
-@@ -1270,7 +1278,8 @@ static struct dst_entry *rt6_check(struct rt6_info *rt, u32 cookie)
-
- static struct dst_entry *rt6_dst_from_check(struct rt6_info *rt, u32 cookie)
- {
-- if (rt->dst.obsolete == DST_OBSOLETE_FORCE_CHK &&
-+ if (!__rt6_check_expired(rt) &&
-+ rt->dst.obsolete == DST_OBSOLETE_FORCE_CHK &&
- rt6_check((struct rt6_info *)(rt->dst.from), cookie))
- return &rt->dst;
- else
-@@ -1290,7 +1299,8 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
-
- rt6_dst_from_metrics_check(rt);
-
-- if ((rt->rt6i_flags & RTF_PCPU) || unlikely(dst->flags & DST_NOCACHE))
-+ if (rt->rt6i_flags & RTF_PCPU ||
-+ (unlikely(dst->flags & DST_NOCACHE) && rt->dst.from))
- return rt6_dst_from_check(rt, cookie);
- else
- return rt6_check(rt, cookie);
-@@ -1340,6 +1350,12 @@ static void rt6_do_update_pmtu(struct rt6_info *rt, u32 mtu)
- rt6_update_expires(rt, net->ipv6.sysctl.ip6_rt_mtu_expires);
- }
-
-+static bool rt6_cache_allowed_for_pmtu(const struct rt6_info *rt)
-+{
-+ return !(rt->rt6i_flags & RTF_CACHE) &&
-+ (rt->rt6i_flags & RTF_PCPU || rt->rt6i_node);
-+}
-+
- static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk,
- const struct ipv6hdr *iph, u32 mtu)
- {
-@@ -1353,7 +1369,7 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk,
- if (mtu >= dst_mtu(dst))
- return;
-
-- if (rt6->rt6i_flags & RTF_CACHE) {
-+ if (!rt6_cache_allowed_for_pmtu(rt6)) {
- rt6_do_update_pmtu(rt6, mtu);
- } else {
- const struct in6_addr *daddr, *saddr;
-diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
-index 0909f4e..f30bfdc 100644
---- a/net/ipv6/syncookies.c
-+++ b/net/ipv6/syncookies.c
-@@ -225,7 +225,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
- memset(&fl6, 0, sizeof(fl6));
- fl6.flowi6_proto = IPPROTO_TCP;
- fl6.daddr = ireq->ir_v6_rmt_addr;
-- final_p = fl6_update_dst(&fl6, np->opt, &final);
-+ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
- fl6.saddr = ireq->ir_v6_loc_addr;
- fl6.flowi6_oif = sk->sk_bound_dev_if;
- fl6.flowi6_mark = ireq->ir_mark;
-diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
-index 97d9314..9e9b77b 100644
---- a/net/ipv6/tcp_ipv6.c
-+++ b/net/ipv6/tcp_ipv6.c
-@@ -120,6 +120,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
- struct ipv6_pinfo *np = inet6_sk(sk);
- struct tcp_sock *tp = tcp_sk(sk);
- struct in6_addr *saddr = NULL, *final_p, final;
-+ struct ipv6_txoptions *opt;
- struct flowi6 fl6;
- struct dst_entry *dst;
- int addr_type;
-@@ -235,7 +236,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
- fl6.fl6_dport = usin->sin6_port;
- fl6.fl6_sport = inet->inet_sport;
-
-- final_p = fl6_update_dst(&fl6, np->opt, &final);
-+ opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
-+ final_p = fl6_update_dst(&fl6, opt, &final);
-
- security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
-
-@@ -263,9 +265,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
- tcp_fetch_timewait_stamp(sk, dst);
-
- icsk->icsk_ext_hdr_len = 0;
-- if (np->opt)
-- icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
-- np->opt->opt_nflen);
-+ if (opt)
-+ icsk->icsk_ext_hdr_len = opt->opt_flen +
-+ opt->opt_nflen;
-
- tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
-
-@@ -461,7 +463,8 @@ static int tcp_v6_send_synack(struct sock *sk, struct dst_entry *dst,
- fl6->flowlabel = ip6_flowlabel(ipv6_hdr(ireq->pktopts));
-
- skb_set_queue_mapping(skb, queue_mapping);
-- err = ip6_xmit(sk, skb, fl6, np->opt, np->tclass);
-+ err = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt),
-+ np->tclass);
- err = net_xmit_eval(err);
- }
-
-@@ -991,6 +994,7 @@ static struct sock *tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
- struct inet_request_sock *ireq;
- struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
- struct tcp6_sock *newtcp6sk;
-+ struct ipv6_txoptions *opt;
- struct inet_sock *newinet;
- struct tcp_sock *newtp;
- struct sock *newsk;
-@@ -1126,13 +1130,15 @@ static struct sock *tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
- but we make one more one thing there: reattach optmem
- to newsk.
- */
-- if (np->opt)
-- newnp->opt = ipv6_dup_options(newsk, np->opt);
--
-+ opt = rcu_dereference(np->opt);
-+ if (opt) {
-+ opt = ipv6_dup_options(newsk, opt);
-+ RCU_INIT_POINTER(newnp->opt, opt);
-+ }
- inet_csk(newsk)->icsk_ext_hdr_len = 0;
-- if (newnp->opt)
-- inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
-- newnp->opt->opt_flen);
-+ if (opt)
-+ inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen +
-+ opt->opt_flen;
-
- tcp_ca_openreq_child(newsk, dst);
-
-diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
-index 0aba654..8379fc2 100644
---- a/net/ipv6/udp.c
-+++ b/net/ipv6/udp.c
-@@ -1107,6 +1107,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
- DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
- struct in6_addr *daddr, *final_p, final;
- struct ipv6_txoptions *opt = NULL;
-+ struct ipv6_txoptions *opt_to_free = NULL;
- struct ip6_flowlabel *flowlabel = NULL;
- struct flowi6 fl6;
- struct dst_entry *dst;
-@@ -1260,8 +1261,10 @@ do_udp_sendmsg:
- opt = NULL;
- connected = 0;
- }
-- if (!opt)
-- opt = np->opt;
-+ if (!opt) {
-+ opt = txopt_get(np);
-+ opt_to_free = opt;
-+ }
- if (flowlabel)
- opt = fl6_merge_options(&opt_space, flowlabel, opt);
- opt = ipv6_fixup_options(&opt_space, opt);
-@@ -1370,6 +1373,7 @@ release_dst:
- out:
- dst_release(dst);
- fl6_sock_release(flowlabel);
-+ txopt_put(opt_to_free);
- if (!err)
- return len;
- /*
-diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
-index d1ded37..0ce9da9 100644
---- a/net/l2tp/l2tp_ip6.c
-+++ b/net/l2tp/l2tp_ip6.c
-@@ -486,6 +486,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
- DECLARE_SOCKADDR(struct sockaddr_l2tpip6 *, lsa, msg->msg_name);
- struct in6_addr *daddr, *final_p, final;
- struct ipv6_pinfo *np = inet6_sk(sk);
-+ struct ipv6_txoptions *opt_to_free = NULL;
- struct ipv6_txoptions *opt = NULL;
- struct ip6_flowlabel *flowlabel = NULL;
- struct dst_entry *dst = NULL;
-@@ -575,8 +576,10 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
- opt = NULL;
- }
-
-- if (opt == NULL)
-- opt = np->opt;
-+ if (!opt) {
-+ opt = txopt_get(np);
-+ opt_to_free = opt;
-+ }
- if (flowlabel)
- opt = fl6_merge_options(&opt_space, flowlabel, opt);
- opt = ipv6_fixup_options(&opt_space, opt);
-@@ -631,6 +634,7 @@ done:
- dst_release(dst);
- out:
- fl6_sock_release(flowlabel);
-+ txopt_put(opt_to_free);
-
- return err < 0 ? err : len;
-
-diff --git a/net/openvswitch/dp_notify.c b/net/openvswitch/dp_notify.c
-index a7a80a6..653d073 100644
---- a/net/openvswitch/dp_notify.c
-+++ b/net/openvswitch/dp_notify.c
-@@ -58,7 +58,7 @@ void ovs_dp_notify_wq(struct work_struct *work)
- struct hlist_node *n;
-
- hlist_for_each_entry_safe(vport, n, &dp->ports[i], dp_hash_node) {
-- if (vport->ops->type != OVS_VPORT_TYPE_NETDEV)
-+ if (vport->ops->type == OVS_VPORT_TYPE_INTERNAL)
- continue;
-
- if (!(vport->dev->priv_flags & IFF_OVS_DATAPATH))
-diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c
-index f7e8dcc..ac14c48 100644
---- a/net/openvswitch/vport-netdev.c
-+++ b/net/openvswitch/vport-netdev.c
-@@ -180,9 +180,13 @@ void ovs_netdev_tunnel_destroy(struct vport *vport)
- if (vport->dev->priv_flags & IFF_OVS_DATAPATH)
- ovs_netdev_detach_dev(vport);
-
-- /* Early release so we can unregister the device */
-+ /* We can be invoked by both explicit vport deletion and
-+ * underlying netdev deregistration; delete the link only
-+ * if it's not already shutting down.
-+ */
-+ if (vport->dev->reg_state == NETREG_REGISTERED)
-+ rtnl_delete_link(vport->dev);
- dev_put(vport->dev);
-- rtnl_delete_link(vport->dev);
- vport->dev = NULL;
- rtnl_unlock();
-
-diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
-index 27b2898..4695a36 100644
---- a/net/packet/af_packet.c
-+++ b/net/packet/af_packet.c
-@@ -1741,6 +1741,20 @@ static void fanout_release(struct sock *sk)
- kfree_rcu(po->rollover, rcu);
- }
-
-+static bool packet_extra_vlan_len_allowed(const struct net_device *dev,
-+ struct sk_buff *skb)
-+{
-+ /* Earlier code assumed this would be a VLAN pkt, double-check
-+ * this now that we have the actual packet in hand. We can only
-+ * do this check on Ethernet devices.
-+ */
-+ if (unlikely(dev->type != ARPHRD_ETHER))
-+ return false;
-+
-+ skb_reset_mac_header(skb);
-+ return likely(eth_hdr(skb)->h_proto == htons(ETH_P_8021Q));
-+}
-+
- static const struct proto_ops packet_ops;
-
- static const struct proto_ops packet_ops_spkt;
-@@ -1902,18 +1916,10 @@ retry:
- goto retry;
- }
-
-- if (len > (dev->mtu + dev->hard_header_len + extra_len)) {
-- /* Earlier code assumed this would be a VLAN pkt,
-- * double-check this now that we have the actual
-- * packet in hand.
-- */
-- struct ethhdr *ehdr;
-- skb_reset_mac_header(skb);
-- ehdr = eth_hdr(skb);
-- if (ehdr->h_proto != htons(ETH_P_8021Q)) {
-- err = -EMSGSIZE;
-- goto out_unlock;
-- }
-+ if (len > (dev->mtu + dev->hard_header_len + extra_len) &&
-+ !packet_extra_vlan_len_allowed(dev, skb)) {
-+ err = -EMSGSIZE;
-+ goto out_unlock;
- }
-
- skb->protocol = proto;
-@@ -2332,6 +2338,15 @@ static bool ll_header_truncated(const struct net_device *dev, int len)
- return false;
- }
-
-+static void tpacket_set_protocol(const struct net_device *dev,
-+ struct sk_buff *skb)
-+{
-+ if (dev->type == ARPHRD_ETHER) {
-+ skb_reset_mac_header(skb);
-+ skb->protocol = eth_hdr(skb)->h_proto;
-+ }
-+}
-+
- static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
- void *frame, struct net_device *dev, int size_max,
- __be16 proto, unsigned char *addr, int hlen)
-@@ -2368,8 +2383,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
- skb_reserve(skb, hlen);
- skb_reset_network_header(skb);
-
-- if (!packet_use_direct_xmit(po))
-- skb_probe_transport_header(skb, 0);
- if (unlikely(po->tp_tx_has_off)) {
- int off_min, off_max, off;
- off_min = po->tp_hdrlen - sizeof(struct sockaddr_ll);
-@@ -2415,6 +2428,8 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
- dev->hard_header_len);
- if (unlikely(err))
- return err;
-+ if (!skb->protocol)
-+ tpacket_set_protocol(dev, skb);
-
- data += dev->hard_header_len;
- to_write -= dev->hard_header_len;
-@@ -2449,6 +2464,8 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
- len = ((to_write > len_max) ? len_max : to_write);
- }
-
-+ skb_probe_transport_header(skb, 0);
-+
- return tp_len;
- }
-
-@@ -2493,12 +2510,13 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
- if (unlikely(!(dev->flags & IFF_UP)))
- goto out_put;
-
-- reserve = dev->hard_header_len + VLAN_HLEN;
-+ if (po->sk.sk_socket->type == SOCK_RAW)
-+ reserve = dev->hard_header_len;
- size_max = po->tx_ring.frame_size
- - (po->tp_hdrlen - sizeof(struct sockaddr_ll));
-
-- if (size_max > dev->mtu + reserve)
-- size_max = dev->mtu + reserve;
-+ if (size_max > dev->mtu + reserve + VLAN_HLEN)
-+ size_max = dev->mtu + reserve + VLAN_HLEN;
-
- do {
- ph = packet_current_frame(po, &po->tx_ring,
-@@ -2525,18 +2543,10 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
- tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto,
- addr, hlen);
- if (likely(tp_len >= 0) &&
-- tp_len > dev->mtu + dev->hard_header_len) {
-- struct ethhdr *ehdr;
-- /* Earlier code assumed this would be a VLAN pkt,
-- * double-check this now that we have the actual
-- * packet in hand.
-- */
-+ tp_len > dev->mtu + reserve &&
-+ !packet_extra_vlan_len_allowed(dev, skb))
-+ tp_len = -EMSGSIZE;
-
-- skb_reset_mac_header(skb);
-- ehdr = eth_hdr(skb);
-- if (ehdr->h_proto != htons(ETH_P_8021Q))
-- tp_len = -EMSGSIZE;
-- }
- if (unlikely(tp_len < 0)) {
- if (po->tp_loss) {
- __packet_set_status(po, ph,
-@@ -2757,18 +2767,10 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
-
- sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags);
-
-- if (!gso_type && (len > dev->mtu + reserve + extra_len)) {
-- /* Earlier code assumed this would be a VLAN pkt,
-- * double-check this now that we have the actual
-- * packet in hand.
-- */
-- struct ethhdr *ehdr;
-- skb_reset_mac_header(skb);
-- ehdr = eth_hdr(skb);
-- if (ehdr->h_proto != htons(ETH_P_8021Q)) {
-- err = -EMSGSIZE;
-- goto out_free;
-- }
-+ if (!gso_type && (len > dev->mtu + reserve + extra_len) &&
-+ !packet_extra_vlan_len_allowed(dev, skb)) {
-+ err = -EMSGSIZE;
-+ goto out_free;
- }
-
- skb->protocol = proto;
-@@ -2799,8 +2801,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
- len += vnet_hdr_len;
- }
-
-- if (!packet_use_direct_xmit(po))
-- skb_probe_transport_header(skb, reserve);
-+ skb_probe_transport_header(skb, reserve);
-+
- if (unlikely(extra_len == 4))
- skb->no_fcs = 1;
-
-diff --git a/net/rds/connection.c b/net/rds/connection.c
-index 49adeef..9b2de5e 100644
---- a/net/rds/connection.c
-+++ b/net/rds/connection.c
-@@ -190,12 +190,6 @@ new_conn:
- }
- }
-
-- if (trans == NULL) {
-- kmem_cache_free(rds_conn_slab, conn);
-- conn = ERR_PTR(-ENODEV);
-- goto out;
-- }
--
- conn->c_trans = trans;
-
- ret = trans->conn_alloc(conn, gfp);
-diff --git a/net/rds/send.c b/net/rds/send.c
-index 4df61a5..859de6f 100644
---- a/net/rds/send.c
-+++ b/net/rds/send.c
-@@ -1009,11 +1009,13 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len)
- release_sock(sk);
- }
-
-- /* racing with another thread binding seems ok here */
-+ lock_sock(sk);
- if (daddr == 0 || rs->rs_bound_addr == 0) {
-+ release_sock(sk);
- ret = -ENOTCONN; /* XXX not a great errno */
- goto out;
- }
-+ release_sock(sk);
-
- if (payload_len > rds_sk_sndbuf(rs)) {
- ret = -EMSGSIZE;
-diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
-index f43c8f3..7ec667d 100644
---- a/net/sched/sch_api.c
-+++ b/net/sched/sch_api.c
-@@ -253,7 +253,8 @@ int qdisc_set_default(const char *name)
- }
-
- /* We know handle. Find qdisc among all qdisc's attached to device
-- (root qdisc, all its children, children of children etc.)
-+ * (root qdisc, all its children, children of children etc.)
-+ * Note: caller either uses rtnl or rcu_read_lock()
- */
-
- static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
-@@ -264,7 +265,7 @@ static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
- root->handle == handle)
- return root;
-
-- list_for_each_entry(q, &root->list, list) {
-+ list_for_each_entry_rcu(q, &root->list, list) {
- if (q->handle == handle)
- return q;
- }
-@@ -277,15 +278,18 @@ void qdisc_list_add(struct Qdisc *q)
- struct Qdisc *root = qdisc_dev(q)->qdisc;
-
- WARN_ON_ONCE(root == &noop_qdisc);
-- list_add_tail(&q->list, &root->list);
-+ ASSERT_RTNL();
-+ list_add_tail_rcu(&q->list, &root->list);
- }
- }
- EXPORT_SYMBOL(qdisc_list_add);
-
- void qdisc_list_del(struct Qdisc *q)
- {
-- if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS))
-- list_del(&q->list);
-+ if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
-+ ASSERT_RTNL();
-+ list_del_rcu(&q->list);
-+ }
- }
- EXPORT_SYMBOL(qdisc_list_del);
-
-@@ -750,14 +754,18 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
- if (n == 0)
- return;
- drops = max_t(int, n, 0);
-+ rcu_read_lock();
- while ((parentid = sch->parent)) {
- if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS))
-- return;
-+ break;
-
-+ if (sch->flags & TCQ_F_NOPARENT)
-+ break;
-+ /* TODO: perform the search on a per txq basis */
- sch = qdisc_lookup(qdisc_dev(sch), TC_H_MAJ(parentid));
- if (sch == NULL) {
-- WARN_ON(parentid != TC_H_ROOT);
-- return;
-+ WARN_ON_ONCE(parentid != TC_H_ROOT);
-+ break;
- }
- cops = sch->ops->cl_ops;
- if (cops->qlen_notify) {
-@@ -768,6 +776,7 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
- sch->q.qlen -= n;
- __qdisc_qstats_drop(sch, drops);
- }
-+ rcu_read_unlock();
- }
- EXPORT_SYMBOL(qdisc_tree_decrease_qlen);
-
-@@ -941,7 +950,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
- }
- lockdep_set_class(qdisc_lock(sch), &qdisc_tx_lock);
- if (!netif_is_multiqueue(dev))
-- sch->flags |= TCQ_F_ONETXQUEUE;
-+ sch->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
- }
-
- sch->handle = handle;
-diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
-index cb5d4ad..e82a1ad 100644
---- a/net/sched/sch_generic.c
-+++ b/net/sched/sch_generic.c
-@@ -737,7 +737,7 @@ static void attach_one_default_qdisc(struct net_device *dev,
- return;
- }
- if (!netif_is_multiqueue(dev))
-- qdisc->flags |= TCQ_F_ONETXQUEUE;
-+ qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
- dev_queue->qdisc_sleeping = qdisc;
- }
-
-diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
-index f3cbaec..3e82f04 100644
---- a/net/sched/sch_mq.c
-+++ b/net/sched/sch_mq.c
-@@ -63,7 +63,7 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt)
- if (qdisc == NULL)
- goto err;
- priv->qdiscs[ntx] = qdisc;
-- qdisc->flags |= TCQ_F_ONETXQUEUE;
-+ qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
- }
-
- sch->flags |= TCQ_F_MQROOT;
-@@ -156,7 +156,7 @@ static int mq_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new,
-
- *old = dev_graft_qdisc(dev_queue, new);
- if (new)
-- new->flags |= TCQ_F_ONETXQUEUE;
-+ new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
- if (dev->flags & IFF_UP)
- dev_activate(dev);
- return 0;
-diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
-index 3811a74..ad70ecf 100644
---- a/net/sched/sch_mqprio.c
-+++ b/net/sched/sch_mqprio.c
-@@ -132,7 +132,7 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt)
- goto err;
- }
- priv->qdiscs[i] = qdisc;
-- qdisc->flags |= TCQ_F_ONETXQUEUE;
-+ qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
- }
-
- /* If the mqprio options indicate that hardware should own
-@@ -209,7 +209,7 @@ static int mqprio_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new,
- *old = dev_graft_qdisc(dev_queue, new);
-
- if (new)
-- new->flags |= TCQ_F_ONETXQUEUE;
-+ new->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
-
- if (dev->flags & IFF_UP)
- dev_activate(dev);
-diff --git a/net/sctp/auth.c b/net/sctp/auth.c
-index 4f15b7d..1543e39 100644
---- a/net/sctp/auth.c
-+++ b/net/sctp/auth.c
-@@ -809,8 +809,8 @@ int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep,
- if (!has_sha1)
- return -EINVAL;
-
-- memcpy(ep->auth_hmacs_list->hmac_ids, &hmacs->shmac_idents[0],
-- hmacs->shmac_num_idents * sizeof(__u16));
-+ for (i = 0; i < hmacs->shmac_num_idents; i++)
-+ ep->auth_hmacs_list->hmac_ids[i] = htons(hmacs->shmac_idents[i]);
- ep->auth_hmacs_list->param_hdr.length = htons(sizeof(sctp_paramhdr_t) +
- hmacs->shmac_num_idents * sizeof(__u16));
- return 0;
-diff --git a/net/sctp/socket.c b/net/sctp/socket.c
-index 17bef01..3ec88be 100644
---- a/net/sctp/socket.c
-+++ b/net/sctp/socket.c
-@@ -7375,6 +7375,13 @@ struct proto sctp_prot = {
-
- #if IS_ENABLED(CONFIG_IPV6)
-
-+#include <net/transp_v6.h>
-+static void sctp_v6_destroy_sock(struct sock *sk)
-+{
-+ sctp_destroy_sock(sk);
-+ inet6_destroy_sock(sk);
-+}
-+
- struct proto sctpv6_prot = {
- .name = "SCTPv6",
- .owner = THIS_MODULE,
-@@ -7384,7 +7391,7 @@ struct proto sctpv6_prot = {
- .accept = sctp_accept,
- .ioctl = sctp_ioctl,
- .init = sctp_init_sock,
-- .destroy = sctp_destroy_sock,
-+ .destroy = sctp_v6_destroy_sock,
- .shutdown = sctp_shutdown,
- .setsockopt = sctp_setsockopt,
- .getsockopt = sctp_getsockopt,
-diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
-index cd7c5f1..86f2e7c 100644
---- a/net/tipc/udp_media.c
-+++ b/net/tipc/udp_media.c
-@@ -159,8 +159,11 @@ static int tipc_udp_send_msg(struct net *net, struct sk_buff *skb,
- struct sk_buff *clone;
- struct rtable *rt;
-
-- if (skb_headroom(skb) < UDP_MIN_HEADROOM)
-- pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC);
-+ if (skb_headroom(skb) < UDP_MIN_HEADROOM) {
-+ err = pskb_expand_head(skb, UDP_MIN_HEADROOM, 0, GFP_ATOMIC);
-+ if (err)
-+ goto tx_error;
-+ }
-
- clone = skb_clone(skb, GFP_ATOMIC);
- skb_set_inner_protocol(clone, htons(ETH_P_TIPC));
-diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
-index 94f6582..128b098 100644
---- a/net/unix/af_unix.c
-+++ b/net/unix/af_unix.c
-@@ -326,6 +326,118 @@ found:
- return s;
- }
-
-+/* Support code for asymmetrically connected dgram sockets
-+ *
-+ * If a datagram socket is connected to a socket not itself connected
-+ * to the first socket (eg, /dev/log), clients may only enqueue more
-+ * messages if the present receive queue of the server socket is not
-+ * "too large". This means there's a second writeability condition
-+ * poll and sendmsg need to test. The dgram recv code will do a wake
-+ * up on the peer_wait wait queue of a socket upon reception of a
-+ * datagram which needs to be propagated to sleeping would-be writers
-+ * since these might not have sent anything so far. This can't be
-+ * accomplished via poll_wait because the lifetime of the server
-+ * socket might be less than that of its clients if these break their
-+ * association with it or if the server socket is closed while clients
-+ * are still connected to it and there's no way to inform "a polling
-+ * implementation" that it should let go of a certain wait queue
-+ *
-+ * In order to propagate a wake up, a wait_queue_t of the client
-+ * socket is enqueued on the peer_wait queue of the server socket
-+ * whose wake function does a wake_up on the ordinary client socket
-+ * wait queue. This connection is established whenever a write (or
-+ * poll for write) hit the flow control condition and broken when the
-+ * association to the server socket is dissolved or after a wake up
-+ * was relayed.
-+ */
-+
-+static int unix_dgram_peer_wake_relay(wait_queue_t *q, unsigned mode, int flags,
-+ void *key)
-+{
-+ struct unix_sock *u;
-+ wait_queue_head_t *u_sleep;
-+
-+ u = container_of(q, struct unix_sock, peer_wake);
-+
-+ __remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait,
-+ q);
-+ u->peer_wake.private = NULL;
-+
-+ /* relaying can only happen while the wq still exists */
-+ u_sleep = sk_sleep(&u->sk);
-+ if (u_sleep)
-+ wake_up_interruptible_poll(u_sleep, key);
-+
-+ return 0;
-+}
-+
-+static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other)
-+{
-+ struct unix_sock *u, *u_other;
-+ int rc;
-+
-+ u = unix_sk(sk);
-+ u_other = unix_sk(other);
-+ rc = 0;
-+ spin_lock(&u_other->peer_wait.lock);
-+
-+ if (!u->peer_wake.private) {
-+ u->peer_wake.private = other;
-+ __add_wait_queue(&u_other->peer_wait, &u->peer_wake);
-+
-+ rc = 1;
-+ }
-+
-+ spin_unlock(&u_other->peer_wait.lock);
-+ return rc;
-+}
-+
-+static void unix_dgram_peer_wake_disconnect(struct sock *sk,
-+ struct sock *other)
-+{
-+ struct unix_sock *u, *u_other;
-+
-+ u = unix_sk(sk);
-+ u_other = unix_sk(other);
-+ spin_lock(&u_other->peer_wait.lock);
-+
-+ if (u->peer_wake.private == other) {
-+ __remove_wait_queue(&u_other->peer_wait, &u->peer_wake);
-+ u->peer_wake.private = NULL;
-+ }
-+
-+ spin_unlock(&u_other->peer_wait.lock);
-+}
-+
-+static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk,
-+ struct sock *other)
-+{
-+ unix_dgram_peer_wake_disconnect(sk, other);
-+ wake_up_interruptible_poll(sk_sleep(sk),
-+ POLLOUT |
-+ POLLWRNORM |
-+ POLLWRBAND);
-+}
-+
-+/* preconditions:
-+ * - unix_peer(sk) == other
-+ * - association is stable
-+ */
-+static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
-+{
-+ int connected;
-+
-+ connected = unix_dgram_peer_wake_connect(sk, other);
-+
-+ if (unix_recvq_full(other))
-+ return 1;
-+
-+ if (connected)
-+ unix_dgram_peer_wake_disconnect(sk, other);
-+
-+ return 0;
-+}
-+
- static inline int unix_writable(struct sock *sk)
- {
- return (atomic_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
-@@ -430,6 +542,8 @@ static void unix_release_sock(struct sock *sk, int embrion)
- skpair->sk_state_change(skpair);
- sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
- }
-+
-+ unix_dgram_peer_wake_disconnect(sk, skpair);
- sock_put(skpair); /* It may now die */
- unix_peer(sk) = NULL;
- }
-@@ -440,6 +554,7 @@ static void unix_release_sock(struct sock *sk, int embrion)
- if (state == TCP_LISTEN)
- unix_release_sock(skb->sk, 1);
- /* passed fds are erased in the kfree_skb hook */
-+ UNIXCB(skb).consumed = skb->len;
- kfree_skb(skb);
- }
-
-@@ -664,6 +779,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern)
- INIT_LIST_HEAD(&u->link);
- mutex_init(&u->readlock); /* single task reading lock */
- init_waitqueue_head(&u->peer_wait);
-+ init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay);
- unix_insert_socket(unix_sockets_unbound(sk), sk);
- out:
- if (sk == NULL)
-@@ -1031,6 +1147,8 @@ restart:
- if (unix_peer(sk)) {
- struct sock *old_peer = unix_peer(sk);
- unix_peer(sk) = other;
-+ unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer);
-+
- unix_state_double_unlock(sk, other);
-
- if (other != old_peer)
-@@ -1432,6 +1550,14 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
- return err;
- }
-
-+static bool unix_passcred_enabled(const struct socket *sock,
-+ const struct sock *other)
-+{
-+ return test_bit(SOCK_PASSCRED, &sock->flags) ||
-+ !other->sk_socket ||
-+ test_bit(SOCK_PASSCRED, &other->sk_socket->flags);
-+}
-+
- /*
- * Some apps rely on write() giving SCM_CREDENTIALS
- * We include credentials if source or destination socket
-@@ -1442,14 +1568,41 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
- {
- if (UNIXCB(skb).pid)
- return;
-- if (test_bit(SOCK_PASSCRED, &sock->flags) ||
-- !other->sk_socket ||
-- test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) {
-+ if (unix_passcred_enabled(sock, other)) {
- UNIXCB(skb).pid = get_pid(task_tgid(current));
- current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
- }
- }
-
-+static int maybe_init_creds(struct scm_cookie *scm,
-+ struct socket *socket,
-+ const struct sock *other)
-+{
-+ int err;
-+ struct msghdr msg = { .msg_controllen = 0 };
-+
-+ err = scm_send(socket, &msg, scm, false);
-+ if (err)
-+ return err;
-+
-+ if (unix_passcred_enabled(socket, other)) {
-+ scm->pid = get_pid(task_tgid(current));
-+ current_uid_gid(&scm->creds.uid, &scm->creds.gid);
-+ }
-+ return err;
-+}
-+
-+static bool unix_skb_scm_eq(struct sk_buff *skb,
-+ struct scm_cookie *scm)
-+{
-+ const struct unix_skb_parms *u = &UNIXCB(skb);
-+
-+ return u->pid == scm->pid &&
-+ uid_eq(u->uid, scm->creds.uid) &&
-+ gid_eq(u->gid, scm->creds.gid) &&
-+ unix_secdata_eq(scm, skb);
-+}
-+
- /*
- * Send AF_UNIX data.
- */
-@@ -1470,6 +1623,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
- struct scm_cookie scm;
- int max_level;
- int data_len = 0;
-+ int sk_locked;
-
- wait_for_unix_gc();
- err = scm_send(sock, msg, &scm, false);
-@@ -1548,12 +1702,14 @@ restart:
- goto out_free;
- }
-
-+ sk_locked = 0;
- unix_state_lock(other);
-+restart_locked:
- err = -EPERM;
- if (!unix_may_send(sk, other))
- goto out_unlock;
-
-- if (sock_flag(other, SOCK_DEAD)) {
-+ if (unlikely(sock_flag(other, SOCK_DEAD))) {
- /*
- * Check with 1003.1g - what should
- * datagram error
-@@ -1561,10 +1717,14 @@ restart:
- unix_state_unlock(other);
- sock_put(other);
-
-+ if (!sk_locked)
-+ unix_state_lock(sk);
-+
- err = 0;
-- unix_state_lock(sk);
- if (unix_peer(sk) == other) {
- unix_peer(sk) = NULL;
-+ unix_dgram_peer_wake_disconnect_wakeup(sk, other);
-+
- unix_state_unlock(sk);
-
- unix_dgram_disconnected(sk, other);
-@@ -1590,21 +1750,38 @@ restart:
- goto out_unlock;
- }
-
-- if (unix_peer(other) != sk && unix_recvq_full(other)) {
-- if (!timeo) {
-- err = -EAGAIN;
-- goto out_unlock;
-+ if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
-+ if (timeo) {
-+ timeo = unix_wait_for_peer(other, timeo);
-+
-+ err = sock_intr_errno(timeo);
-+ if (signal_pending(current))
-+ goto out_free;
-+
-+ goto restart;
- }
-
-- timeo = unix_wait_for_peer(other, timeo);
-+ if (!sk_locked) {
-+ unix_state_unlock(other);
-+ unix_state_double_lock(sk, other);
-+ }
-
-- err = sock_intr_errno(timeo);
-- if (signal_pending(current))
-- goto out_free;
-+ if (unix_peer(sk) != other ||
-+ unix_dgram_peer_wake_me(sk, other)) {
-+ err = -EAGAIN;
-+ sk_locked = 1;
-+ goto out_unlock;
-+ }
-
-- goto restart;
-+ if (!sk_locked) {
-+ sk_locked = 1;
-+ goto restart_locked;
-+ }
- }
-
-+ if (unlikely(sk_locked))
-+ unix_state_unlock(sk);
-+
- if (sock_flag(other, SOCK_RCVTSTAMP))
- __net_timestamp(skb);
- maybe_add_creds(skb, sock, other);
-@@ -1618,6 +1795,8 @@ restart:
- return len;
-
- out_unlock:
-+ if (sk_locked)
-+ unix_state_unlock(sk);
- unix_state_unlock(other);
- out_free:
- kfree_skb(skb);
-@@ -1739,8 +1918,10 @@ out_err:
- static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page,
- int offset, size_t size, int flags)
- {
-- int err = 0;
-- bool send_sigpipe = true;
-+ int err;
-+ bool send_sigpipe = false;
-+ bool init_scm = true;
-+ struct scm_cookie scm;
- struct sock *other, *sk = socket->sk;
- struct sk_buff *skb, *newskb = NULL, *tail = NULL;
-
-@@ -1758,7 +1939,7 @@ alloc_skb:
- newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT,
- &err, 0);
- if (!newskb)
-- return err;
-+ goto err;
- }
-
- /* we must acquire readlock as we modify already present
-@@ -1767,12 +1948,12 @@ alloc_skb:
- err = mutex_lock_interruptible(&unix_sk(other)->readlock);
- if (err) {
- err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS;
-- send_sigpipe = false;
- goto err;
- }
-
- if (sk->sk_shutdown & SEND_SHUTDOWN) {
- err = -EPIPE;
-+ send_sigpipe = true;
- goto err_unlock;
- }
-
-@@ -1781,23 +1962,34 @@ alloc_skb:
- if (sock_flag(other, SOCK_DEAD) ||
- other->sk_shutdown & RCV_SHUTDOWN) {
- err = -EPIPE;
-+ send_sigpipe = true;
- goto err_state_unlock;
- }
-
-+ if (init_scm) {
-+ err = maybe_init_creds(&scm, socket, other);
-+ if (err)
-+ goto err_state_unlock;
-+ init_scm = false;
-+ }
-+
- skb = skb_peek_tail(&other->sk_receive_queue);
- if (tail && tail == skb) {
- skb = newskb;
-- } else if (!skb) {
-- if (newskb)
-+ } else if (!skb || !unix_skb_scm_eq(skb, &scm)) {
-+ if (newskb) {
- skb = newskb;
-- else
-+ } else {
-+ tail = skb;
- goto alloc_skb;
-+ }
- } else if (newskb) {
- /* this is fast path, we don't necessarily need to
- * call to kfree_skb even though with newskb == NULL
- * this - does no harm
- */
- consume_skb(newskb);
-+ newskb = NULL;
- }
-
- if (skb_append_pagefrags(skb, page, offset, size)) {
-@@ -1810,14 +2002,20 @@ alloc_skb:
- skb->truesize += size;
- atomic_add(size, &sk->sk_wmem_alloc);
-
-- if (newskb)
-+ if (newskb) {
-+ err = unix_scm_to_skb(&scm, skb, false);
-+ if (err)
-+ goto err_state_unlock;
-+ spin_lock(&other->sk_receive_queue.lock);
- __skb_queue_tail(&other->sk_receive_queue, newskb);
-+ spin_unlock(&other->sk_receive_queue.lock);
-+ }
-
- unix_state_unlock(other);
- mutex_unlock(&unix_sk(other)->readlock);
-
- other->sk_data_ready(other);
--
-+ scm_destroy(&scm);
- return size;
-
- err_state_unlock:
-@@ -1828,6 +2026,8 @@ err:
- kfree_skb(newskb);
- if (send_sigpipe && !(flags & MSG_NOSIGNAL))
- send_sig(SIGPIPE, current, 0);
-+ if (!init_scm)
-+ scm_destroy(&scm);
- return err;
- }
-
-@@ -2071,6 +2271,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state)
-
- do {
- int chunk;
-+ bool drop_skb;
- struct sk_buff *skb, *last;
-
- unix_state_lock(sk);
-@@ -2130,10 +2331,7 @@ unlock:
-
- if (check_creds) {
- /* Never glue messages from different writers */
-- if ((UNIXCB(skb).pid != scm.pid) ||
-- !uid_eq(UNIXCB(skb).uid, scm.creds.uid) ||
-- !gid_eq(UNIXCB(skb).gid, scm.creds.gid) ||
-- !unix_secdata_eq(&scm, skb))
-+ if (!unix_skb_scm_eq(skb, &scm))
- break;
- } else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
- /* Copy credentials */
-@@ -2151,7 +2349,11 @@ unlock:
- }
-
- chunk = min_t(unsigned int, unix_skb_len(skb) - skip, size);
-+ skb_get(skb);
- chunk = state->recv_actor(skb, skip, chunk, state);
-+ drop_skb = !unix_skb_len(skb);
-+ /* skb is only safe to use if !drop_skb */
-+ consume_skb(skb);
- if (chunk < 0) {
- if (copied == 0)
- copied = -EFAULT;
-@@ -2160,6 +2362,18 @@ unlock:
- copied += chunk;
- size -= chunk;
-
-+ if (drop_skb) {
-+ /* the skb was touched by a concurrent reader;
-+ * we should not expect anything from this skb
-+ * anymore and assume it invalid - we can be
-+ * sure it was dropped from the socket queue
-+ *
-+ * let's report a short read
-+ */
-+ err = 0;
-+ break;
-+ }
-+
- /* Mark read part of skb as used */
- if (!(flags & MSG_PEEK)) {
- UNIXCB(skb).consumed += chunk;
-@@ -2453,14 +2667,16 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
- return mask;
-
- writable = unix_writable(sk);
-- other = unix_peer_get(sk);
-- if (other) {
-- if (unix_peer(other) != sk) {
-- sock_poll_wait(file, &unix_sk(other)->peer_wait, wait);
-- if (unix_recvq_full(other))
-- writable = 0;
-- }
-- sock_put(other);
-+ if (writable) {
-+ unix_state_lock(sk);
-+
-+ other = unix_peer(sk);
-+ if (other && unix_peer(other) != sk &&
-+ unix_recvq_full(other) &&
-+ unix_dgram_peer_wake_me(sk, other))
-+ writable = 0;
-+
-+ unix_state_unlock(sk);
- }
-
- if (writable)
-diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
-index edfc1b8..656ce39 100644
---- a/sound/pci/Kconfig
-+++ b/sound/pci/Kconfig
-@@ -25,7 +25,7 @@ config SND_ALS300
- select SND_PCM
- select SND_AC97_CODEC
- select SND_OPL3_LIB
-- select ZONE_DMA
-+ depends on ZONE_DMA
- help
- Say 'Y' or 'M' to include support for Avance Logic ALS300/ALS300+
-
-@@ -50,7 +50,7 @@ config SND_ALI5451
- tristate "ALi M5451 PCI Audio Controller"
- select SND_MPU401_UART
- select SND_AC97_CODEC
-- select ZONE_DMA
-+ depends on ZONE_DMA
- help
- Say Y here to include support for the integrated AC97 sound
- device on motherboards using the ALi M5451 Audio Controller
-@@ -155,7 +155,7 @@ config SND_AZT3328
- select SND_PCM
- select SND_RAWMIDI
- select SND_AC97_CODEC
-- select ZONE_DMA
-+ depends on ZONE_DMA
- help
- Say Y here to include support for Aztech AZF3328 (PCI168)
- soundcards.
-@@ -463,7 +463,7 @@ config SND_EMU10K1
- select SND_HWDEP
- select SND_RAWMIDI
- select SND_AC97_CODEC
-- select ZONE_DMA
-+ depends on ZONE_DMA
- help
- Say Y to include support for Sound Blaster PCI 512, Live!,
- Audigy and E-mu APS (partially supported) soundcards.
-@@ -479,7 +479,7 @@ config SND_EMU10K1X
- tristate "Emu10k1X (Dell OEM Version)"
- select SND_AC97_CODEC
- select SND_RAWMIDI
-- select ZONE_DMA
-+ depends on ZONE_DMA
- help
- Say Y here to include support for the Dell OEM version of the
- Sound Blaster Live!.
-@@ -513,7 +513,7 @@ config SND_ES1938
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_AC97_CODEC
-- select ZONE_DMA
-+ depends on ZONE_DMA
- help
- Say Y here to include support for soundcards based on ESS Solo-1
- (ES1938, ES1946, ES1969) chips.
-@@ -525,7 +525,7 @@ config SND_ES1968
- tristate "ESS ES1968/1978 (Maestro-1/2/2E)"
- select SND_MPU401_UART
- select SND_AC97_CODEC
-- select ZONE_DMA
-+ depends on ZONE_DMA
- help
- Say Y here to include support for soundcards based on ESS Maestro
- 1/2/2E chips.
-@@ -612,7 +612,7 @@ config SND_ICE1712
- select SND_MPU401_UART
- select SND_AC97_CODEC
- select BITREVERSE
-- select ZONE_DMA
-+ depends on ZONE_DMA
- help
- Say Y here to include support for soundcards based on the
- ICE1712 (Envy24) chip.
-@@ -700,7 +700,7 @@ config SND_LX6464ES
- config SND_MAESTRO3
- tristate "ESS Allegro/Maestro3"
- select SND_AC97_CODEC
-- select ZONE_DMA
-+ depends on ZONE_DMA
- help
- Say Y here to include support for soundcards based on ESS Maestro 3
- (Allegro) chips.
-@@ -806,7 +806,7 @@ config SND_SIS7019
- tristate "SiS 7019 Audio Accelerator"
- depends on X86_32
- select SND_AC97_CODEC
-- select ZONE_DMA
-+ depends on ZONE_DMA
- help
- Say Y here to include support for the SiS 7019 Audio Accelerator.
-
-@@ -818,7 +818,7 @@ config SND_SONICVIBES
- select SND_OPL3_LIB
- select SND_MPU401_UART
- select SND_AC97_CODEC
-- select ZONE_DMA
-+ depends on ZONE_DMA
- help
- Say Y here to include support for soundcards based on the S3
- SonicVibes chip.
-@@ -830,7 +830,7 @@ config SND_TRIDENT
- tristate "Trident 4D-Wave DX/NX; SiS 7018"
- select SND_MPU401_UART
- select SND_AC97_CODEC
-- select ZONE_DMA
-+ depends on ZONE_DMA
- help
- Say Y here to include support for soundcards based on Trident
- 4D-Wave DX/NX or SiS 7018 chips.
-diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
-index acbfbe08..f22f5c4 100644
---- a/sound/pci/hda/patch_hdmi.c
-+++ b/sound/pci/hda/patch_hdmi.c
-@@ -50,8 +50,9 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
- #define is_haswell(codec) ((codec)->core.vendor_id == 0x80862807)
- #define is_broadwell(codec) ((codec)->core.vendor_id == 0x80862808)
- #define is_skylake(codec) ((codec)->core.vendor_id == 0x80862809)
-+#define is_broxton(codec) ((codec)->core.vendor_id == 0x8086280a)
- #define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec) \
-- || is_skylake(codec))
-+ || is_skylake(codec) || is_broxton(codec))
-
- #define is_valleyview(codec) ((codec)->core.vendor_id == 0x80862882)
- #define is_cherryview(codec) ((codec)->core.vendor_id == 0x80862883)
-diff --git a/tools/net/Makefile b/tools/net/Makefile
-index ee577ea..ddf8880 100644
---- a/tools/net/Makefile
-+++ b/tools/net/Makefile
-@@ -4,6 +4,9 @@ CC = gcc
- LEX = flex
- YACC = bison
-
-+CFLAGS += -Wall -O2
-+CFLAGS += -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include
-+
- %.yacc.c: %.y
- $(YACC) -o $@ -d $<
-
-@@ -12,15 +15,13 @@ YACC = bison
-
- all : bpf_jit_disasm bpf_dbg bpf_asm
-
--bpf_jit_disasm : CFLAGS = -Wall -O2 -DPACKAGE='bpf_jit_disasm'
-+bpf_jit_disasm : CFLAGS += -DPACKAGE='bpf_jit_disasm'
- bpf_jit_disasm : LDLIBS = -lopcodes -lbfd -ldl
- bpf_jit_disasm : bpf_jit_disasm.o
-
--bpf_dbg : CFLAGS = -Wall -O2
- bpf_dbg : LDLIBS = -lreadline
- bpf_dbg : bpf_dbg.o
-
--bpf_asm : CFLAGS = -Wall -O2 -I.
- bpf_asm : LDLIBS =
- bpf_asm : bpf_asm.o bpf_exp.yacc.o bpf_exp.lex.o
- bpf_exp.lex.o : bpf_exp.yacc.c
diff --git a/4.3.3/4420_grsecurity-3.1-4.3.3-201512162141.patch b/4.3.3/4420_grsecurity-3.1-4.3.3-201512222129.patch
similarity index 99%
rename from 4.3.3/4420_grsecurity-3.1-4.3.3-201512162141.patch
rename to 4.3.3/4420_grsecurity-3.1-4.3.3-201512222129.patch
index 4b7bff5..2c1d2ad 100644
--- a/4.3.3/4420_grsecurity-3.1-4.3.3-201512162141.patch
+++ b/4.3.3/4420_grsecurity-3.1-4.3.3-201512222129.patch
@@ -313,7 +313,7 @@ index 13f888a..250729b 100644
A typical pattern in a Kbuild file looks like this:
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
-index 22a4b68..8c70743 100644
+index 22a4b68..0ec4c2a 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1246,6 +1246,13 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
@@ -341,7 +341,7 @@ index 22a4b68..8c70743 100644
nosmap [X86]
Disable SMAP (Supervisor Mode Access Prevention)
even if it is supported by processor.
-@@ -2677,6 +2688,30 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
+@@ -2677,6 +2688,35 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
the specified number of seconds. This is to be used if
your oopses keep scrolling off the screen.
@@ -366,6 +366,11 @@ index 22a4b68..8c70743 100644
+ from the first 4GB of memory as the bootmem allocator
+ passes the memory pages to the buddy allocator.
+
++ pax_size_overflow_report_only
++ Enables rate-limited logging of size_overflow plugin
++ violations while disabling killing of the violating
++ task.
++
+ pax_weakuderef [X86-64] enables the weaker but faster form of UDEREF
+ when the processor supports PCID.
+
@@ -3811,7 +3816,7 @@ index 845769e..4278fd7 100644
atomic64_set(&mm->context.id, asid);
}
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
-index 0d629b8..01867c8 100644
+index 0d629b8..f13ad33 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -25,6 +25,7 @@
@@ -3859,7 +3864,7 @@ index 0d629b8..01867c8 100644
#endif
+#ifdef CONFIG_PAX_PAGEEXEC
-+ if (fsr & FSR_LNX_PF) {
++ if ((tsk->mm->pax_flags & MF_PAX_PAGEEXEC) && (fsr & FSR_LNX_PF)) {
+ pax_report_fault(regs, (void *)regs->ARM_pc, (void *)regs->ARM_sp);
+ do_group_exit(SIGKILL);
+ }
@@ -32731,7 +32736,7 @@ index 903ec1e..41b4708 100644
}
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
-index eef44d9..b0fb164 100644
+index eef44d9..79b0e58 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -14,6 +14,8 @@
@@ -33203,7 +33208,7 @@ index eef44d9..b0fb164 100644
+
+#ifdef CONFIG_PAX_SEGMEXEC
+ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
-+ if (!(error_code & (PF_PROT | PF_WRITE)) && (ip + SEGMEXEC_TASK_SIZE == address))
++ if (!(error_code & (PF_PROT | PF_WRITE)) && (ip + SEGMEXEC_TASK_SIZE == address))
+ return true;
+ return false;
+ }
@@ -36996,6 +37001,28 @@ index ad3f276..bef6d50 100644
return ERR_PTR(-EINVAL);
nr_pages += end - start;
+diff --git a/block/blk-core.c b/block/blk-core.c
+index 18e92a6..1834d7c 100644
+--- a/block/blk-core.c
++++ b/block/blk-core.c
+@@ -1616,8 +1616,6 @@ static void blk_queue_bio(struct request_queue *q, struct bio *bio)
+ struct request *req;
+ unsigned int request_count = 0;
+
+- blk_queue_split(q, &bio, q->bio_split);
+-
+ /*
+ * low level driver can indicate that it wants pages above a
+ * certain limit bounced to low memory (ie for highmem, or even
+@@ -1625,6 +1623,8 @@ static void blk_queue_bio(struct request_queue *q, struct bio *bio)
+ */
+ blk_queue_bounce(q, &bio);
+
++ blk_queue_split(q, &bio, q->bio_split);
++
+ if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
+ bio->bi_error = -EIO;
+ bio_endio(bio);
diff --git a/block/blk-iopoll.c b/block/blk-iopoll.c
index 0736729..2ec3b48 100644
--- a/block/blk-iopoll.c
@@ -75725,6 +75752,32 @@ index f70119f..b7d2bb4 100644
/* for init */
int __init btrfs_delayed_inode_init(void);
+diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
+index 6a98bdd..fed3da6 100644
+--- a/fs/btrfs/extent_map.c
++++ b/fs/btrfs/extent_map.c
+@@ -235,7 +235,9 @@ static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em)
+ em->start = merge->start;
+ em->orig_start = merge->orig_start;
+ em->len += merge->len;
+- em->block_len += merge->block_len;
++ if (em->block_start != EXTENT_MAP_HOLE &&
++ em->block_start != EXTENT_MAP_INLINE)
++ em->block_len += merge->block_len;
+ em->block_start = merge->block_start;
+ em->mod_len = (em->mod_len + em->mod_start) - merge->mod_start;
+ em->mod_start = merge->mod_start;
+@@ -252,7 +254,9 @@ static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em)
+ merge = rb_entry(rb, struct extent_map, rb_node);
+ if (rb && mergable_maps(em, merge)) {
+ em->len += merge->len;
+- em->block_len += merge->block_len;
++ if (em->block_start != EXTENT_MAP_HOLE &&
++ em->block_start != EXTENT_MAP_INLINE)
++ em->block_len += merge->block_len;
+ rb_erase(&merge->rb_node, &tree->map);
+ RB_CLEAR_NODE(&merge->rb_node);
+ em->mod_len = (merge->mod_start + merge->mod_len) - em->mod_start;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 396e3d5..e752d29 100644
--- a/fs/btrfs/inode.c
@@ -77174,7 +77227,7 @@ index e4141f2..d8263e8 100644
i += packet_length_size;
if (copy_to_user(&buf[i], msg_ctx->msg, msg_ctx->msg_size))
diff --git a/fs/exec.c b/fs/exec.c
-index b06623a..895c666 100644
+index b06623a..1c50b96 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -56,8 +56,20 @@
@@ -77670,7 +77723,7 @@ index b06623a..895c666 100644
out:
if (bprm->mm) {
acct_arg_size(bprm, 0);
-@@ -1749,3 +1924,313 @@ COMPAT_SYSCALL_DEFINE5(execveat, int, fd,
+@@ -1749,3 +1924,319 @@ COMPAT_SYSCALL_DEFINE5(execveat, int, fd,
argv, envp, flags);
}
#endif
@@ -77976,11 +78029,17 @@ index b06623a..895c666 100644
+
+#ifdef CONFIG_PAX_SIZE_OVERFLOW
+
++static DEFINE_RATELIMIT_STATE(size_overflow_ratelimit, 15 * HZ, 3);
++extern bool pax_size_overflow_report_only;
++
+void __nocapture(1, 3, 4) __used report_size_overflow(const char *file, unsigned int line, const char *func, const char *ssa_name)
+{
-+ printk(KERN_EMERG "PAX: size overflow detected in function %s %s:%u %s", func, file, line, ssa_name);
-+ dump_stack();
-+ do_group_exit(SIGKILL);
++ if (!pax_size_overflow_report_only || __ratelimit(&size_overflow_ratelimit)) {
++ printk(KERN_EMERG "PAX: size overflow detected in function %s %s:%u %s", func, file, line, ssa_name);
++ dump_stack();
++ }
++ if (!pax_size_overflow_report_only)
++ do_group_exit(SIGKILL);
+}
+EXPORT_SYMBOL(report_size_overflow);
+#endif
@@ -82413,7 +82472,7 @@ index eed2050..fb443f2 100644
static struct pid *
get_children_pid(struct inode *inode, struct pid *pid_prev, loff_t pos)
diff --git a/fs/proc/base.c b/fs/proc/base.c
-index 29595af..6ab6000 100644
+index 29595af..aeaaf2e 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -113,6 +113,14 @@ struct pid_entry {
@@ -82794,7 +82853,15 @@ index 29595af..6ab6000 100644
if (!dir_emit_dots(file, ctx))
goto out;
-@@ -2519,7 +2645,7 @@ static int do_io_accounting(struct task_struct *task, struct seq_file *m, int wh
+@@ -2484,6 +2610,7 @@ static ssize_t proc_coredump_filter_write(struct file *file,
+ mm = get_task_mm(task);
+ if (!mm)
+ goto out_no_mm;
++ ret = 0;
+
+ for (i = 0, mask = 1; i < MMF_DUMP_FILTER_BITS; i++, mask <<= 1) {
+ if (val & mask)
+@@ -2519,7 +2646,7 @@ static int do_io_accounting(struct task_struct *task, struct seq_file *m, int wh
if (result)
return result;
@@ -82803,7 +82870,7 @@ index 29595af..6ab6000 100644
result = -EACCES;
goto out_unlock;
}
-@@ -2738,7 +2864,7 @@ static const struct pid_entry tgid_base_stuff[] = {
+@@ -2738,7 +2865,7 @@ static const struct pid_entry tgid_base_stuff[] = {
REG("autogroup", S_IRUGO|S_IWUSR, proc_pid_sched_autogroup_operations),
#endif
REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
@@ -82812,7 +82879,7 @@ index 29595af..6ab6000 100644
ONE("syscall", S_IRUSR, proc_pid_syscall),
#endif
REG("cmdline", S_IRUGO, proc_pid_cmdline_ops),
-@@ -2763,10 +2889,10 @@ static const struct pid_entry tgid_base_stuff[] = {
+@@ -2763,10 +2890,10 @@ static const struct pid_entry tgid_base_stuff[] = {
#ifdef CONFIG_SECURITY
DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
#endif
@@ -82825,7 +82892,7 @@ index 29595af..6ab6000 100644
ONE("stack", S_IRUSR, proc_pid_stack),
#endif
#ifdef CONFIG_SCHED_INFO
-@@ -2800,6 +2926,9 @@ static const struct pid_entry tgid_base_stuff[] = {
+@@ -2800,6 +2927,9 @@ static const struct pid_entry tgid_base_stuff[] = {
#ifdef CONFIG_HARDWALL
ONE("hardwall", S_IRUGO, proc_pid_hardwall),
#endif
@@ -82835,7 +82902,7 @@ index 29595af..6ab6000 100644
#ifdef CONFIG_USER_NS
REG("uid_map", S_IRUGO|S_IWUSR, proc_uid_map_operations),
REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations),
-@@ -2932,7 +3061,14 @@ static int proc_pid_instantiate(struct inode *dir,
+@@ -2932,7 +3062,14 @@ static int proc_pid_instantiate(struct inode *dir,
if (!inode)
goto out;
@@ -82850,7 +82917,7 @@ index 29595af..6ab6000 100644
inode->i_op = &proc_tgid_base_inode_operations;
inode->i_fop = &proc_tgid_base_operations;
inode->i_flags|=S_IMMUTABLE;
-@@ -2970,7 +3106,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsign
+@@ -2970,7 +3107,11 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, unsign
if (!task)
goto out;
@@ -82862,7 +82929,7 @@ index 29595af..6ab6000 100644
put_task_struct(task);
out:
return ERR_PTR(result);
-@@ -3084,7 +3224,7 @@ static const struct pid_entry tid_base_stuff[] = {
+@@ -3084,7 +3225,7 @@ static const struct pid_entry tid_base_stuff[] = {
REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
#endif
REG("comm", S_IRUGO|S_IWUSR, proc_pid_set_comm_operations),
@@ -82871,7 +82938,7 @@ index 29595af..6ab6000 100644
ONE("syscall", S_IRUSR, proc_pid_syscall),
#endif
REG("cmdline", S_IRUGO, proc_pid_cmdline_ops),
-@@ -3111,10 +3251,10 @@ static const struct pid_entry tid_base_stuff[] = {
+@@ -3111,10 +3252,10 @@ static const struct pid_entry tid_base_stuff[] = {
#ifdef CONFIG_SECURITY
DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
#endif
@@ -84997,6 +85064,28 @@ index 8e2010d..95549ab 100644
#endif /* DEBUG */
/*
+diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
+index be43248..6bb4442 100644
+--- a/fs/xfs/libxfs/xfs_da_btree.c
++++ b/fs/xfs/libxfs/xfs_da_btree.c
+@@ -2007,6 +2007,7 @@ xfs_da_grow_inode_int(
+ struct xfs_inode *dp = args->dp;
+ int w = args->whichfork;
+ xfs_rfsblock_t nblks = dp->i_d.di_nblocks;
++ xfs_rfsblock_t nblocks;
+ struct xfs_bmbt_irec map, *mapp;
+ int nmap, error, got, i, mapi;
+
+@@ -2075,7 +2076,8 @@ xfs_da_grow_inode_int(
+ }
+
+ /* account for newly allocated blocks in reserved blocks total */
+- args->total -= dp->i_d.di_nblocks - nblks;
++ nblocks = dp->i_d.di_nblocks - nblks;
++ args->total -= nblocks;
+
+ out_free_map:
+ if (mapp != &map)
diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c
index a989a9c..db30c9a 100644
--- a/fs/xfs/xfs_dir2_readdir.c
@@ -105589,7 +105678,7 @@ index b32ad7d..05f6420 100644
next_state = Reset;
return 0;
diff --git a/init/main.c b/init/main.c
-index 9e64d70..141e0b4 100644
+index 9e64d70..2f40cd9 100644
--- a/init/main.c
+++ b/init/main.c
@@ -97,6 +97,8 @@ extern void radix_tree_init(void);
@@ -105601,7 +105690,7 @@ index 9e64d70..141e0b4 100644
/*
* Debug helper: via this flag we know that we are in 'early bootup code'
* where only the boot processor is running with IRQ disabled. This means
-@@ -158,6 +160,37 @@ static int __init set_reset_devices(char *str)
+@@ -158,6 +160,48 @@ static int __init set_reset_devices(char *str)
__setup("reset_devices", set_reset_devices);
@@ -105636,10 +105725,21 @@ index 9e64d70..141e0b4 100644
+__setup("pax_softmode=", setup_pax_softmode);
+#endif
+
++#ifdef CONFIG_PAX_SIZE_OVERFLOW
++bool pax_size_overflow_report_only __read_only;
++
++static int __init setup_pax_size_overflow_report_only(char *str)
++{
++ pax_size_overflow_report_only = true;
++ return 0;
++}
++early_param("pax_size_overflow_report_only", setup_pax_size_overflow_report_only);
++#endif
++
static const char *argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
const char *envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
static const char *panic_later, *panic_param;
-@@ -731,7 +764,7 @@ static bool __init_or_module initcall_blacklisted(initcall_t fn)
+@@ -731,7 +775,7 @@ static bool __init_or_module initcall_blacklisted(initcall_t fn)
struct blacklist_entry *entry;
char *fn_name;
@@ -105648,7 +105748,7 @@ index 9e64d70..141e0b4 100644
if (!fn_name)
return false;
-@@ -783,7 +816,7 @@ int __init_or_module do_one_initcall(initcall_t fn)
+@@ -783,7 +827,7 @@ int __init_or_module do_one_initcall(initcall_t fn)
{
int count = preempt_count();
int ret;
@@ -105657,7 +105757,7 @@ index 9e64d70..141e0b4 100644
if (initcall_blacklisted(fn))
return -EPERM;
-@@ -793,18 +826,17 @@ int __init_or_module do_one_initcall(initcall_t fn)
+@@ -793,18 +837,17 @@ int __init_or_module do_one_initcall(initcall_t fn)
else
ret = fn();
@@ -105680,7 +105780,7 @@ index 9e64d70..141e0b4 100644
return ret;
}
-@@ -909,8 +941,8 @@ static int run_init_process(const char *init_filename)
+@@ -909,8 +952,8 @@ static int run_init_process(const char *init_filename)
{
argv_init[0] = init_filename;
return do_execve(getname_kernel(init_filename),
@@ -105691,7 +105791,7 @@ index 9e64d70..141e0b4 100644
}
static int try_to_run_init_process(const char *init_filename)
-@@ -927,6 +959,10 @@ static int try_to_run_init_process(const char *init_filename)
+@@ -927,6 +970,10 @@ static int try_to_run_init_process(const char *init_filename)
return ret;
}
@@ -105702,7 +105802,7 @@ index 9e64d70..141e0b4 100644
static noinline void __init kernel_init_freeable(void);
static int __ref kernel_init(void *unused)
-@@ -951,6 +987,11 @@ static int __ref kernel_init(void *unused)
+@@ -951,6 +998,11 @@ static int __ref kernel_init(void *unused)
ramdisk_execute_command, ret);
}
@@ -105714,7 +105814,7 @@ index 9e64d70..141e0b4 100644
/*
* We try each of these until one succeeds.
*
-@@ -1008,7 +1049,7 @@ static noinline void __init kernel_init_freeable(void)
+@@ -1008,7 +1060,7 @@ static noinline void __init kernel_init_freeable(void)
do_basic_setup();
/* Open the /dev/console on the rootfs, this should never fail */
@@ -105723,7 +105823,7 @@ index 9e64d70..141e0b4 100644
pr_err("Warning: unable to open an initial console.\n");
(void) sys_dup(0);
-@@ -1021,11 +1062,13 @@ static noinline void __init kernel_init_freeable(void)
+@@ -1021,11 +1073,13 @@ static noinline void __init kernel_init_freeable(void)
if (!ramdisk_execute_command)
ramdisk_execute_command = "/init";
@@ -109683,10 +109783,45 @@ index 99513e1..0caa643 100644
}
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
-index 787320d..9e9535d 100644
+index 787320d..9873654 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
-@@ -219,6 +219,13 @@ static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode)
+@@ -207,18 +207,45 @@ static int ptrace_check_attach(struct task_struct *child, bool ignore_state)
+ return ret;
+ }
+
+-static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode)
++static bool ptrace_has_cap(const struct cred *tcred, unsigned int mode)
+ {
++ struct user_namespace *tns = tcred->user_ns;
++ struct user_namespace *curns = current_cred()->user_ns;
++
++ /* When a root-owned process enters a user namespace created by a
++ * malicious user, the user shouldn't be able to execute code under
++ * uid 0 by attaching to the root-owned process via ptrace.
++ * Therefore, similar to the capable_wrt_inode_uidgid() check,
++ * verify that all the uids and gids of the target process are
++ * mapped into the current namespace.
++ * No fsuid/fsgid check because __ptrace_may_access doesn't do it
++ * either.
++ */
++ if (!kuid_has_mapping(curns, tcred->euid) ||
++ !kuid_has_mapping(curns, tcred->suid) ||
++ !kuid_has_mapping(curns, tcred->uid) ||
++ !kgid_has_mapping(curns, tcred->egid) ||
++ !kgid_has_mapping(curns, tcred->sgid) ||
++ !kgid_has_mapping(curns, tcred->gid))
++ return false;
++
+ if (mode & PTRACE_MODE_NOAUDIT)
+- return has_ns_capability_noaudit(current, ns, CAP_SYS_PTRACE);
++ return has_ns_capability_noaudit(current, tns, CAP_SYS_PTRACE);
+ else
+- return has_ns_capability(current, ns, CAP_SYS_PTRACE);
++ return has_ns_capability(current, tns, CAP_SYS_PTRACE);
+ }
+
+ /* Returns 0 on success, -errno on denial. */
static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
{
const struct cred *cred = current_cred(), *tcred;
@@ -109700,7 +109835,7 @@ index 787320d..9e9535d 100644
/* May we inspect the given task?
* This check is used both for attaching with ptrace
-@@ -233,13 +240,28 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
+@@ -233,15 +260,30 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
if (same_thread_group(task, current))
return 0;
rcu_read_lock();
@@ -109733,9 +109868,21 @@ index 787320d..9e9535d 100644
+ gid_eq(caller_gid, tcred->sgid) &&
+ gid_eq(caller_gid, tcred->gid))
goto ok;
- if (ptrace_has_cap(tcred->user_ns, mode))
+- if (ptrace_has_cap(tcred->user_ns, mode))
++ if (ptrace_has_cap(tcred, mode))
goto ok;
-@@ -306,7 +328,7 @@ static int ptrace_attach(struct task_struct *task, long request,
+ rcu_read_unlock();
+ return -EPERM;
+@@ -252,7 +294,7 @@ ok:
+ dumpable = get_dumpable(task->mm);
+ rcu_read_lock();
+ if (dumpable != SUID_DUMP_USER &&
+- !ptrace_has_cap(__task_cred(task)->user_ns, mode)) {
++ !ptrace_has_cap(__task_cred(task), mode)) {
+ rcu_read_unlock();
+ return -EPERM;
+ }
+@@ -306,7 +348,7 @@ static int ptrace_attach(struct task_struct *task, long request,
goto out;
task_lock(task);
@@ -109744,7 +109891,7 @@ index 787320d..9e9535d 100644
task_unlock(task);
if (retval)
goto unlock_creds;
-@@ -321,7 +343,7 @@ static int ptrace_attach(struct task_struct *task, long request,
+@@ -321,7 +363,7 @@ static int ptrace_attach(struct task_struct *task, long request,
if (seize)
flags |= PT_SEIZED;
rcu_read_lock();
@@ -109753,7 +109900,7 @@ index 787320d..9e9535d 100644
flags |= PT_PTRACE_CAP;
rcu_read_unlock();
task->ptrace = flags;
-@@ -514,7 +536,7 @@ int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst
+@@ -514,7 +556,7 @@ int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst
break;
return -EIO;
}
@@ -109762,7 +109909,7 @@ index 787320d..9e9535d 100644
return -EFAULT;
copied += retval;
src += retval;
-@@ -815,7 +837,7 @@ int ptrace_request(struct task_struct *child, long request,
+@@ -815,7 +857,7 @@ int ptrace_request(struct task_struct *child, long request,
bool seized = child->ptrace & PT_SEIZED;
int ret = -EIO;
siginfo_t siginfo, *si;
@@ -109771,7 +109918,7 @@ index 787320d..9e9535d 100644
unsigned long __user *datalp = datavp;
unsigned long flags;
-@@ -1061,14 +1083,21 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
+@@ -1061,14 +1103,21 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr,
goto out;
}
@@ -109794,7 +109941,7 @@ index 787320d..9e9535d 100644
goto out_put_task_struct;
}
-@@ -1096,7 +1125,7 @@ int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr,
+@@ -1096,7 +1145,7 @@ int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr,
copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0);
if (copied != sizeof(tmp))
return -EIO;
@@ -109803,7 +109950,7 @@ index 787320d..9e9535d 100644
}
int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr,
-@@ -1189,7 +1218,7 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request,
+@@ -1189,7 +1238,7 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request,
}
COMPAT_SYSCALL_DEFINE4(ptrace, compat_long_t, request, compat_long_t, pid,
@@ -109812,7 +109959,7 @@ index 787320d..9e9535d 100644
{
struct task_struct *child;
long ret;
-@@ -1205,14 +1234,21 @@ COMPAT_SYSCALL_DEFINE4(ptrace, compat_long_t, request, compat_long_t, pid,
+@@ -1205,14 +1254,21 @@ COMPAT_SYSCALL_DEFINE4(ptrace, compat_long_t, request, compat_long_t, pid,
goto out;
}
@@ -120164,7 +120311,7 @@ index 8a1741b..20d20e7 100644
if (!err)
err = put_user(SCM_RIGHTS, &cm->cmsg_type);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
-index fab4599..e553f88 100644
+index fab4599..e488a92 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2103,7 +2103,7 @@ EXPORT_SYMBOL(__skb_checksum);
@@ -120193,8 +120340,18 @@ index fab4599..e553f88 100644
NULL);
}
+@@ -3643,7 +3645,8 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb,
+ serr->ee.ee_info = tstype;
+ if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) {
+ serr->ee.ee_data = skb_shinfo(skb)->tskey;
+- if (sk->sk_protocol == IPPROTO_TCP)
++ if (sk->sk_protocol == IPPROTO_TCP &&
++ sk->sk_type == SOCK_STREAM)
+ serr->ee.ee_data -= sk->sk_tskey;
+ }
+
diff --git a/net/core/sock.c b/net/core/sock.c
-index 3307c02..08b1281 100644
+index 3307c02..3a9bfdc 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -441,7 +441,7 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
@@ -120233,7 +120390,17 @@ index 3307c02..08b1281 100644
goto discard_and_relse;
}
-@@ -908,6 +908,7 @@ set_rcvbuf:
+@@ -862,7 +862,8 @@ set_rcvbuf:
+
+ if (val & SOF_TIMESTAMPING_OPT_ID &&
+ !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)) {
+- if (sk->sk_protocol == IPPROTO_TCP) {
++ if (sk->sk_protocol == IPPROTO_TCP &&
++ sk->sk_type == SOCK_STREAM) {
+ if (sk->sk_state != TCP_ESTABLISHED) {
+ ret = -EINVAL;
+ break;
+@@ -908,6 +909,7 @@ set_rcvbuf:
}
break;
@@ -120241,7 +120408,7 @@ index 3307c02..08b1281 100644
case SO_ATTACH_BPF:
ret = -EINVAL;
if (optlen == sizeof(u32)) {
-@@ -920,7 +921,7 @@ set_rcvbuf:
+@@ -920,7 +922,7 @@ set_rcvbuf:
ret = sk_attach_bpf(ufd, sk);
}
break;
@@ -120250,7 +120417,7 @@ index 3307c02..08b1281 100644
case SO_DETACH_FILTER:
ret = sk_detach_filter(sk);
break;
-@@ -1022,12 +1023,12 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
+@@ -1022,12 +1024,12 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
struct timeval tm;
} v;
@@ -120266,7 +120433,7 @@ index 3307c02..08b1281 100644
return -EINVAL;
memset(&v, 0, sizeof(v));
-@@ -1165,11 +1166,11 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
+@@ -1165,11 +1167,11 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
case SO_PEERNAME:
{
@@ -120280,7 +120447,7 @@ index 3307c02..08b1281 100644
return -EINVAL;
if (copy_to_user(optval, address, len))
return -EFAULT;
-@@ -1257,7 +1258,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
+@@ -1257,7 +1259,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
if (len > lv)
len = lv;
@@ -120289,7 +120456,7 @@ index 3307c02..08b1281 100644
return -EFAULT;
lenout:
if (put_user(len, optlen))
-@@ -1550,7 +1551,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
+@@ -1550,7 +1552,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
newsk->sk_err = 0;
newsk->sk_priority = 0;
newsk->sk_incoming_cpu = raw_smp_processor_id();
@@ -120298,7 +120465,7 @@ index 3307c02..08b1281 100644
/*
* Before updating sk_refcnt, we must commit prior changes to memory
* (Documentation/RCU/rculist_nulls.txt for details)
-@@ -2359,7 +2360,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
+@@ -2359,7 +2361,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
*/
smp_wmb();
atomic_set(&sk->sk_refcnt, 1);
@@ -120307,7 +120474,7 @@ index 3307c02..08b1281 100644
}
EXPORT_SYMBOL(sock_init_data);
-@@ -2487,6 +2488,7 @@ void sock_enable_timestamp(struct sock *sk, int flag)
+@@ -2487,6 +2489,7 @@ void sock_enable_timestamp(struct sock *sk, int flag)
int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len,
int level, int type)
{
@@ -120315,7 +120482,7 @@ index 3307c02..08b1281 100644
struct sock_exterr_skb *serr;
struct sk_buff *skb;
int copied, err;
-@@ -2508,7 +2510,8 @@ int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len,
+@@ -2508,7 +2511,8 @@ int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len,
sock_recv_timestamp(msg, sk, skb);
serr = SKB_EXT_ERR(skb);
@@ -121854,7 +122021,7 @@ index c10a9ee..c621a01 100644
return -ENOMEM;
}
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
-index 3939dd2..ea4fbed 100644
+index 3939dd2..7372e9a 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -178,7 +178,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
@@ -121985,7 +122152,25 @@ index 3939dd2..ea4fbed 100644
struct net *net = ctl->extra2;
struct ipv6_stable_secret *secret = ctl->data;
-@@ -5397,7 +5410,7 @@ int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl,
+@@ -5343,13 +5356,10 @@ static int addrconf_sysctl_stable_secret(struct ctl_table *ctl, int write,
+ goto out;
+ }
+
+- if (!write) {
+- err = snprintf(str, sizeof(str), "%pI6",
+- &secret->secret);
+- if (err >= sizeof(str)) {
+- err = -EIO;
+- goto out;
+- }
++ err = snprintf(str, sizeof(str), "%pI6", &secret->secret);
++ if (err >= sizeof(str)) {
++ err = -EIO;
++ goto out;
+ }
+
+ err = proc_dostring(&lctl, write, buffer, lenp, ppos);
+@@ -5397,7 +5407,7 @@ int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl,
int *valp = ctl->data;
int val = *valp;
loff_t pos = *ppos;
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [gentoo-commits] proj/hardened-patchset:master commit in: 4.3.3/
@ 2015-12-31 12:24 Anthony G. Basile
0 siblings, 0 replies; 7+ messages in thread
From: Anthony G. Basile @ 2015-12-31 12:24 UTC (permalink / raw
To: gentoo-commits
commit: 8653be659f83e207eded0dbd8917a1898acf2727
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Thu Dec 31 12:31:34 2015 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Thu Dec 31 12:31:34 2015 +0000
URL: https://gitweb.gentoo.org/proj/hardened-patchset.git/commit/?id=8653be65
grsecurity-3.1-4.3.3-201512282134
4.3.3/0000_README | 2 +-
...> 4420_grsecurity-3.1-4.3.3-201512282134.patch} | 251 +++++++++++++--------
2 files changed, 160 insertions(+), 93 deletions(-)
diff --git a/4.3.3/0000_README b/4.3.3/0000_README
index 2c1a853..0d44c02 100644
--- a/4.3.3/0000_README
+++ b/4.3.3/0000_README
@@ -2,7 +2,7 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 4420_grsecurity-3.1-4.3.3-201512222129.patch
+Patch: 4420_grsecurity-3.1-4.3.3-201512282134.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/4.3.3/4420_grsecurity-3.1-4.3.3-201512222129.patch b/4.3.3/4420_grsecurity-3.1-4.3.3-201512282134.patch
similarity index 99%
rename from 4.3.3/4420_grsecurity-3.1-4.3.3-201512222129.patch
rename to 4.3.3/4420_grsecurity-3.1-4.3.3-201512282134.patch
index 2c1d2ad..0e5c122 100644
--- a/4.3.3/4420_grsecurity-3.1-4.3.3-201512222129.patch
+++ b/4.3.3/4420_grsecurity-3.1-4.3.3-201512282134.patch
@@ -1040,7 +1040,7 @@ index 0cfd7f947..63ed4c0 100644
Say Y here if you want to show the kernel pagetable layout in a
debugfs file. This information is only useful for kernel developers
diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
-index fe3ef39..9406984 100644
+index fe3ef39..60e6ae2 100644
--- a/arch/arm/include/asm/atomic.h
+++ b/arch/arm/include/asm/atomic.h
@@ -18,17 +18,41 @@
@@ -1158,8 +1158,11 @@ index fe3ef39..9406984 100644
: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) \
: "r" (&v->counter), "Ir" (i) \
: "cc"); \
-@@ -80,6 +130,9 @@ static inline int atomic_##op##_return_relaxed(int i, atomic_t *v) \
+@@ -78,8 +128,12 @@ static inline int atomic_##op##_return_relaxed(int i, atomic_t *v) \
+ }
+
#define atomic_add_return_relaxed atomic_add_return_relaxed
++#define atomic_add_return_unchecked atomic_add_return_unchecked_relaxed
#define atomic_sub_return_relaxed atomic_sub_return_relaxed
+#define ATOMIC_OP_RETURN(op, c_op, asm_op) __ATOMIC_OP_RETURN(op, _unchecked, c_op, asm_op, , )\
@@ -1168,7 +1171,7 @@ index fe3ef39..9406984 100644
static inline int atomic_cmpxchg_relaxed(atomic_t *ptr, int old, int new)
{
int oldval;
-@@ -113,12 +166,24 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+@@ -113,12 +167,24 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
__asm__ __volatile__ ("@ atomic_add_unless\n"
"1: ldrex %0, [%4]\n"
" teq %0, %5\n"
@@ -1196,7 +1199,7 @@ index fe3ef39..9406984 100644
: "=&r" (oldval), "=&r" (newval), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "r" (u), "r" (a)
: "cc");
-@@ -129,14 +194,36 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
+@@ -129,14 +195,36 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
return oldval;
}
@@ -1235,7 +1238,7 @@ index fe3ef39..9406984 100644
{ \
unsigned long flags; \
\
-@@ -145,8 +232,11 @@ static inline void atomic_##op(int i, atomic_t *v) \
+@@ -145,8 +233,11 @@ static inline void atomic_##op(int i, atomic_t *v) \
raw_local_irq_restore(flags); \
} \
@@ -1249,7 +1252,7 @@ index fe3ef39..9406984 100644
{ \
unsigned long flags; \
int val; \
-@@ -159,6 +249,9 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
+@@ -159,6 +250,9 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
return val; \
}
@@ -1259,7 +1262,7 @@ index fe3ef39..9406984 100644
static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
{
int ret;
-@@ -173,6 +266,11 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
+@@ -173,6 +267,11 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
return ret;
}
@@ -1271,7 +1274,7 @@ index fe3ef39..9406984 100644
static inline int __atomic_add_unless(atomic_t *v, int a, int u)
{
int c, old;
-@@ -201,16 +299,38 @@ ATOMIC_OP(xor, ^=, eor)
+@@ -201,16 +300,38 @@ ATOMIC_OP(xor, ^=, eor)
#undef ATOMIC_OPS
#undef ATOMIC_OP_RETURN
@@ -1299,18 +1302,18 @@ index fe3ef39..9406984 100644
#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0)
+static inline int atomic_inc_and_test_unchecked(atomic_unchecked_t *v)
+{
-+ return atomic_add_return_unchecked_relaxed(1, v) == 0;
++ return atomic_add_return_unchecked(1, v) == 0;
+}
#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
#define atomic_inc_return(v) (atomic_add_return(1, v))
+static inline int atomic_inc_return_unchecked(atomic_unchecked_t *v)
+{
-+ return atomic_add_return_unchecked_relaxed(1, v);
++ return atomic_add_return_unchecked(1, v);
+}
#define atomic_dec_return(v) (atomic_sub_return(1, v))
#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
-@@ -221,6 +341,14 @@ typedef struct {
+@@ -221,6 +342,14 @@ typedef struct {
long long counter;
} atomic64_t;
@@ -1325,7 +1328,7 @@ index fe3ef39..9406984 100644
#define ATOMIC64_INIT(i) { (i) }
#ifdef CONFIG_ARM_LPAE
-@@ -237,6 +365,19 @@ static inline long long atomic64_read(const atomic64_t *v)
+@@ -237,6 +366,19 @@ static inline long long atomic64_read(const atomic64_t *v)
return result;
}
@@ -1345,7 +1348,7 @@ index fe3ef39..9406984 100644
static inline void atomic64_set(atomic64_t *v, long long i)
{
__asm__ __volatile__("@ atomic64_set\n"
-@@ -245,6 +386,15 @@ static inline void atomic64_set(atomic64_t *v, long long i)
+@@ -245,6 +387,15 @@ static inline void atomic64_set(atomic64_t *v, long long i)
: "r" (&v->counter), "r" (i)
);
}
@@ -1361,7 +1364,7 @@ index fe3ef39..9406984 100644
#else
static inline long long atomic64_read(const atomic64_t *v)
{
-@@ -259,6 +409,19 @@ static inline long long atomic64_read(const atomic64_t *v)
+@@ -259,6 +410,19 @@ static inline long long atomic64_read(const atomic64_t *v)
return result;
}
@@ -1381,7 +1384,7 @@ index fe3ef39..9406984 100644
static inline void atomic64_set(atomic64_t *v, long long i)
{
long long tmp;
-@@ -273,43 +436,73 @@ static inline void atomic64_set(atomic64_t *v, long long i)
+@@ -273,43 +437,73 @@ static inline void atomic64_set(atomic64_t *v, long long i)
: "r" (&v->counter), "r" (i)
: "cc");
}
@@ -1463,7 +1466,7 @@ index fe3ef39..9406984 100644
: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) \
: "r" (&v->counter), "r" (i) \
: "cc"); \
-@@ -317,6 +510,9 @@ atomic64_##op##_return_relaxed(long long i, atomic64_t *v) \
+@@ -317,6 +511,9 @@ atomic64_##op##_return_relaxed(long long i, atomic64_t *v) \
return result; \
}
@@ -1473,7 +1476,15 @@ index fe3ef39..9406984 100644
#define ATOMIC64_OPS(op, op1, op2) \
ATOMIC64_OP(op, op1, op2) \
ATOMIC64_OP_RETURN(op, op1, op2)
-@@ -336,7 +532,12 @@ ATOMIC64_OP(xor, eor, eor)
+@@ -325,6 +522,7 @@ ATOMIC64_OPS(add, adds, adc)
+ ATOMIC64_OPS(sub, subs, sbc)
+
+ #define atomic64_add_return_relaxed atomic64_add_return_relaxed
++#define atomic64_add_return_unchecked atomic64_add_return_unchecked_relaxed
+ #define atomic64_sub_return_relaxed atomic64_sub_return_relaxed
+
+ #define atomic64_andnot atomic64_andnot
+@@ -336,7 +534,12 @@ ATOMIC64_OP(xor, eor, eor)
#undef ATOMIC64_OPS
#undef ATOMIC64_OP_RETURN
@@ -1486,10 +1497,12 @@ index fe3ef39..9406984 100644
static inline long long
atomic64_cmpxchg_relaxed(atomic64_t *ptr, long long old, long long new)
-@@ -362,6 +563,32 @@ atomic64_cmpxchg_relaxed(atomic64_t *ptr, long long old, long long new)
+@@ -361,6 +564,33 @@ atomic64_cmpxchg_relaxed(atomic64_t *ptr, long long old, long long new)
+ return oldval;
}
#define atomic64_cmpxchg_relaxed atomic64_cmpxchg_relaxed
-
++#define atomic64_cmpxchg_unchecked atomic64_cmpxchg_unchecked_relaxed
++
+static inline long long
+atomic64_cmpxchg_unchecked_relaxed(atomic64_unchecked_t *ptr, long long old,
+ long long new)
@@ -1515,11 +1528,10 @@ index fe3ef39..9406984 100644
+
+ return oldval;
+}
-+
+
static inline long long atomic64_xchg_relaxed(atomic64_t *ptr, long long new)
{
- long long result;
-@@ -385,21 +612,35 @@ static inline long long atomic64_xchg_relaxed(atomic64_t *ptr, long long new)
+@@ -385,21 +615,35 @@ static inline long long atomic64_xchg_relaxed(atomic64_t *ptr, long long new)
static inline long long atomic64_dec_if_positive(atomic64_t *v)
{
long long result;
@@ -1561,7 +1573,7 @@ index fe3ef39..9406984 100644
: "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter)
: "cc");
-@@ -423,13 +664,25 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
+@@ -423,13 +667,25 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
" teq %0, %5\n"
" teqeq %H0, %H5\n"
" moveq %1, #0\n"
@@ -1590,7 +1602,7 @@ index fe3ef39..9406984 100644
: "=&r" (val), "+r" (ret), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "r" (u), "r" (a)
: "cc");
-@@ -442,10 +695,13 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
+@@ -442,10 +698,13 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u)
#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
#define atomic64_inc(v) atomic64_add(1LL, (v))
@@ -1694,23 +1706,22 @@ index 0f84249..8e83c55 100644
struct of_cpuidle_method {
const char *method;
diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
-index fc8ba16..805a183 100644
+index fc8ba16..8b84f53 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
-@@ -42,7 +42,7 @@
+@@ -42,7 +42,6 @@
#define DOMAIN_USER 1
#define DOMAIN_IO 0
#endif
-#define DOMAIN_VECTORS 3
-+//#define DOMAIN_VECTORS 3
/*
* Domain types
-@@ -51,8 +51,26 @@
+@@ -51,9 +50,27 @@
#define DOMAIN_CLIENT 1
#ifdef CONFIG_CPU_USE_DOMAINS
#define DOMAIN_MANAGER 3
-+#define DOMAIN_VECTORS DOMAIN_USER
++#define DOMAIN_VECTORS 3
#else
+
+#ifdef CONFIG_PAX_KERNEXEC
@@ -1728,12 +1739,13 @@ index fc8ba16..805a183 100644
+#define DOMAIN_USERCLIENT 1
+#define DOMAIN_VECTORS DOMAIN_USER
+#endif
-+#define DOMAIN_KERNELCLIENT 1
+
#endif
++#define DOMAIN_KERNELCLIENT 1
#define domain_mask(dom) ((3) << (2 * (dom)))
-@@ -62,7 +80,7 @@
+ #define domain_val(dom,type) ((type) << (2 * (dom)))
+@@ -62,7 +79,7 @@
#define DACR_INIT \
(domain_val(DOMAIN_USER, DOMAIN_NOACCESS) | \
domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
@@ -28770,7 +28782,7 @@ index 10e0272..b4bb9a7 100644
if (!(addr & ~PAGE_MASK))
return addr;
diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c
-index 91a4496..42fc304 100644
+index 91a4496..6414b5c 100644
--- a/arch/x86/kernel/tboot.c
+++ b/arch/x86/kernel/tboot.c
@@ -44,6 +44,7 @@
@@ -28781,27 +28793,42 @@ index 91a4496..42fc304 100644
#include "../realmode/rm/wakeup.h"
-@@ -221,7 +222,7 @@ static int tboot_setup_sleep(void)
+@@ -151,6 +152,10 @@ static int map_tboot_pages(unsigned long vaddr, unsigned long start_pfn,
+ if (!tboot_pg_dir)
+ return -1;
+
++ clone_pgd_range(tboot_pg_dir + KERNEL_PGD_BOUNDARY,
++ swapper_pg_dir + KERNEL_PGD_BOUNDARY,
++ KERNEL_PGD_PTRS);
++
+ for (; nr > 0; nr--, vaddr += PAGE_SIZE, start_pfn++) {
+ if (map_tboot_page(vaddr, start_pfn, PAGE_KERNEL_EXEC))
+ return -1;
+@@ -221,8 +226,6 @@ static int tboot_setup_sleep(void)
void tboot_shutdown(u32 shutdown_type)
{
- void (*shutdown)(void);
-+ void (* __noreturn shutdown)(void);
-
+-
if (!tboot_enabled())
return;
-@@ -242,8 +243,9 @@ void tboot_shutdown(u32 shutdown_type)
+
+@@ -242,9 +245,12 @@ void tboot_shutdown(u32 shutdown_type)
tboot->shutdown_type = shutdown_type;
switch_to_tboot_pt();
-+ cr4_clear_bits(X86_CR4_PCIDE);
++ __write_cr4(__read_cr4() & ~X86_CR4_PCIDE);
- shutdown = (void(*)(void))(unsigned long)tboot->shutdown_entry;
-+ shutdown = (void *)(unsigned long)tboot->shutdown_entry;
- shutdown();
+- shutdown();
++ /*
++ * PaX: can't be a C indirect function call due to KERNEXEC
++ */
++ asm volatile("jmp *%0" : : "r"((unsigned long)tboot->shutdown_entry));
/* should not reach here */
-@@ -310,7 +312,7 @@ static int tboot_extended_sleep(u8 sleep_state, u32 val_a, u32 val_b)
+ while (1)
+@@ -310,7 +316,7 @@ static int tboot_extended_sleep(u8 sleep_state, u32 val_a, u32 val_b)
return -ENODEV;
}
@@ -28810,7 +28837,7 @@ index 91a4496..42fc304 100644
static int tboot_wait_for_aps(int num_aps)
{
-@@ -334,9 +336,9 @@ static int tboot_cpu_callback(struct notifier_block *nfb, unsigned long action,
+@@ -334,9 +340,9 @@ static int tboot_cpu_callback(struct notifier_block *nfb, unsigned long action,
{
switch (action) {
case CPU_DYING:
@@ -28822,7 +28849,7 @@ index 91a4496..42fc304 100644
return NOTIFY_BAD;
break;
}
-@@ -422,7 +424,7 @@ static __init int tboot_late_init(void)
+@@ -422,7 +428,7 @@ static __init int tboot_late_init(void)
tboot_create_trampoline();
@@ -44150,7 +44177,7 @@ index c13fb5b..55a3802 100644
*off += size;
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
-index c4dcab0..89d8045 100644
+index c4dcab0..a505f18 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -382,7 +382,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer,
@@ -44162,6 +44189,17 @@ index c4dcab0..89d8045 100644
ret = create_gpadl_header(kbuffer, size, &msginfo, &msgcount);
if (ret)
+@@ -696,9 +696,7 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
+ * Adjust the size down since vmbus_channel_packet_page_buffer is the
+ * largest size we support
+ */
+- descsize = sizeof(struct vmbus_channel_packet_page_buffer) -
+- ((MAX_PAGE_BUFFER_COUNT - pagecount) *
+- sizeof(struct hv_page_buffer));
++ descsize = offsetof(struct vmbus_channel_packet_page_buffer, range[pagecount]);
+ packetlen = descsize + bufferlen;
+ packetlen_aligned = ALIGN(packetlen, sizeof(u64));
+
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 6341be8..1a2fc8d 100644
--- a/drivers/hv/hv.c
@@ -44570,6 +44608,19 @@ index 65e3240..e6c511d 100644
/* Wrapper access functions for multiplexed SMBus */
static DEFINE_MUTEX(amd756_lock);
+diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c
+index df23e8c..1354d8e 100644
+--- a/drivers/i2c/busses/i2c-designware-pcidrv.c
++++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
+@@ -60,7 +60,7 @@ struct dw_scl_sda_cfg {
+ };
+
+ struct dw_pci_controller {
+- u32 bus_num;
++ int bus_num;
+ u32 bus_cfg;
+ u32 tx_fifo_depth;
+ u32 rx_fifo_depth;
diff --git a/drivers/i2c/busses/i2c-nforce2-s4985.c b/drivers/i2c/busses/i2c-nforce2-s4985.c
index 88eda09..cf40434 100644
--- a/drivers/i2c/busses/i2c-nforce2-s4985.c
@@ -51116,7 +51167,7 @@ index 5fa98f5..322f0f8 100644
spinlock_t request_lock;
struct list_head req_list;
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
-index 5931a79..d536e64 100644
+index 5931a79..134ce31 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -101,7 +101,7 @@ static struct rndis_request *get_rndis_request(struct rndis_device *dev,
@@ -51137,6 +51188,16 @@ index 5931a79..d536e64 100644
/* Ignore return since this msg is optional. */
rndis_filter_send_request(dev, request);
+@@ -1138,8 +1138,7 @@ int rndis_filter_device_add(struct hv_device *dev,
+ if (net_device->num_chn == 1)
+ goto out;
+
+- net_device->sub_cb_buf = vzalloc((net_device->num_chn - 1) *
+- NETVSC_PACKET_SIZE);
++ net_device->sub_cb_buf = vzalloc(net_device->num_sc_offered * NETVSC_PACKET_SIZE);
+ if (!net_device->sub_cb_buf) {
+ net_device->num_chn = 1;
+ dev_info(&dev->device, "No memory for subchannels.\n");
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index cc56fac..c15b884 100644
--- a/drivers/net/ifb.c
@@ -77227,7 +77288,7 @@ index e4141f2..d8263e8 100644
i += packet_length_size;
if (copy_to_user(&buf[i], msg_ctx->msg, msg_ctx->msg_size))
diff --git a/fs/exec.c b/fs/exec.c
-index b06623a..1c50b96 100644
+index b06623a..122301f 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -56,8 +56,20 @@
@@ -77736,7 +77797,7 @@ index b06623a..1c50b96 100644
+ if (*flags & MF_PAX_SEGMEXEC)
+ {
+ *flags &= ~MF_PAX_SEGMEXEC;
-+ retval = -EINVAL;
++ retval = -EINVAL;
+ }
+#endif
+
@@ -77761,7 +77822,7 @@ index b06623a..1c50b96 100644
+ )
+ {
+ *flags &= ~MF_PAX_MPROTECT;
-+ retval = -EINVAL;
++ retval = -EINVAL;
+ }
+
+ if ((*flags & MF_PAX_EMUTRAMP)
@@ -97176,46 +97237,10 @@ index c1da539..1dcec55 100644
struct atmphy_ops {
int (*start)(struct atm_dev *dev);
diff --git a/include/linux/atomic.h b/include/linux/atomic.h
-index 00a5763..5322059 100644
+index 00a5763..93fe7f4 100644
--- a/include/linux/atomic.h
+++ b/include/linux/atomic.h
-@@ -79,6 +79,11 @@
- #define atomic_add_return(...) \
- __atomic_op_fence(atomic_add_return, __VA_ARGS__)
- #endif
-+
-+#ifndef atomic_add_return_unchecked
-+#define atomic_add_return_unchecked(...) \
-+ __atomic_op_fence(atomic_add_return_unchecked, __VA_ARGS__)
-+#endif
- #endif /* atomic_add_return_relaxed */
-
- /* atomic_sub_return_relaxed */
-@@ -183,6 +188,11 @@
- #define atomic64_add_return(...) \
- __atomic_op_fence(atomic64_add_return, __VA_ARGS__)
- #endif
-+
-+#ifndef atomic64_add_return_unchecked
-+#define atomic64_add_return_unchecked(...) \
-+ __atomic_op_fence(atomic64_add_return_unchecked, __VA_ARGS__)
-+#endif
- #endif /* atomic64_add_return_relaxed */
-
- /* atomic64_sub_return_relaxed */
-@@ -255,6 +265,11 @@
- #define atomic64_cmpxchg(...) \
- __atomic_op_fence(atomic64_cmpxchg, __VA_ARGS__)
- #endif
-+
-+#ifndef atomic64_cmpxchg_unchecked
-+#define atomic64_cmpxchg_unchecked(...) \
-+ __atomic_op_fence(atomic64_cmpxchg_unchecked, __VA_ARGS__)
-+#endif
- #endif /* atomic64_cmpxchg_relaxed */
-
- /* cmpxchg_relaxed */
-@@ -335,7 +350,7 @@
+@@ -335,7 +335,7 @@
* Atomically adds @a to @v, so long as @v was not already @u.
* Returns non-zero if @v was not @u, and zero otherwise.
*/
@@ -120311,10 +120336,20 @@ index 8a1741b..20d20e7 100644
if (!err)
err = put_user(SCM_RIGHTS, &cm->cmsg_type);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
-index fab4599..e488a92 100644
+index fab4599..daf360d 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
-@@ -2103,7 +2103,7 @@ EXPORT_SYMBOL(__skb_checksum);
+@@ -969,7 +969,8 @@ static void skb_headers_offset_update(struct sk_buff *skb, int off)
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ skb->csum_start += off;
+ /* {transport,network,mac}_header and tail are relative to skb->head */
+- skb->transport_header += off;
++ if (skb_transport_header_was_set(skb))
++ skb->transport_header += off;
+ skb->network_header += off;
+ if (skb_mac_header_was_set(skb))
+ skb->mac_header += off;
+@@ -2103,7 +2104,7 @@ EXPORT_SYMBOL(__skb_checksum);
__wsum skb_checksum(const struct sk_buff *skb, int offset,
int len, __wsum csum)
{
@@ -120323,7 +120358,7 @@ index fab4599..e488a92 100644
.update = csum_partial_ext,
.combine = csum_block_add_ext,
};
-@@ -3318,12 +3318,14 @@ void __init skb_init(void)
+@@ -3318,12 +3319,14 @@ void __init skb_init(void)
skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
sizeof(struct sk_buff),
0,
@@ -120340,7 +120375,7 @@ index fab4599..e488a92 100644
NULL);
}
-@@ -3643,7 +3645,8 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb,
+@@ -3643,7 +3646,8 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb,
serr->ee.ee_info = tstype;
if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) {
serr->ee.ee_data = skb_shinfo(skb)->tskey;
@@ -128018,6 +128053,36 @@ index aee2ec5..c276071 100644
/* record the root user tracking */
rb_link_node(&root_key_user.node,
+diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
+index 0b9ec78..26f0e0a 100644
+--- a/security/keys/keyctl.c
++++ b/security/keys/keyctl.c
+@@ -757,16 +757,16 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
+
+ /* the key is probably readable - now try to read it */
+ can_read_key:
+- ret = key_validate(key);
+- if (ret == 0) {
+- ret = -EOPNOTSUPP;
+- if (key->type->read) {
+- /* read the data with the semaphore held (since we
+- * might sleep) */
+- down_read(&key->sem);
++ ret = -EOPNOTSUPP;
++ if (key->type->read) {
++ /* Read the data with the semaphore held (since we might sleep)
++ * to protect against the key being updated or revoked.
++ */
++ down_read(&key->sem);
++ ret = key_validate(key);
++ if (ret == 0)
+ ret = key->type->read(key, buffer, buflen);
+- up_read(&key->sem);
+- }
++ up_read(&key->sem);
+ }
+
+ error2:
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index d334370..b03e5a8 100644
--- a/security/keys/keyring.c
@@ -131375,10 +131440,10 @@ index 0000000..7514850
+fi
diff --git a/tools/gcc/initify_plugin.c b/tools/gcc/initify_plugin.c
new file mode 100644
-index 0000000..9da49be
+index 0000000..ed3a502
--- /dev/null
+++ b/tools/gcc/initify_plugin.c
-@@ -0,0 +1,586 @@
+@@ -0,0 +1,588 @@
+/*
+ * Copyright 2011-2015 by Emese Revfy <re.emese@gmail.com>
+ * Licensed under the GPL v2, or (at your option) v3
@@ -131399,7 +131464,7 @@ index 0000000..9da49be
+int plugin_is_GPL_compatible;
+
+static struct plugin_info initify_plugin_info = {
-+ .version = "20151213",
++ .version = "20151228",
+ .help = "initify_plugin\n",
+};
+
@@ -131603,6 +131668,7 @@ index 0000000..9da49be
+ decl = get_inner_reference(op, &bitsize, &bitpos, &offset, &mode, &unsignedp, &reversep, &volatilep, true);
+
+ switch (TREE_CODE_CLASS(TREE_CODE(decl))) {
++ case tcc_comparison:
+ case tcc_constant:
+ case tcc_statement:
+ return false;
@@ -131634,6 +131700,7 @@ index 0000000..9da49be
+ return false;
+
+ if (!DECL_P(decl)) {
++ debug_tree(vardecl);
+ debug_tree(op);
+ debug_tree(decl);
+ gcc_unreachable();
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [gentoo-commits] proj/hardened-patchset:master commit in: 4.3.3/
@ 2016-01-06 13:05 Anthony G. Basile
0 siblings, 0 replies; 7+ messages in thread
From: Anthony G. Basile @ 2016-01-06 13:05 UTC (permalink / raw
To: gentoo-commits
commit: 1fbe3d5d3d94cdbd7caa4cb7439a25c832d264dd
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Wed Jan 6 12:54:26 2016 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Wed Jan 6 12:54:26 2016 +0000
URL: https://gitweb.gentoo.org/proj/hardened-patchset.git/commit/?id=1fbe3d5d
grsecurity-3.1-4.3.3-201601051958
4.3.3/0000_README | 2 +-
...> 4420_grsecurity-3.1-4.3.3-201601051958.patch} | 663 ++++++++++++++++-----
2 files changed, 515 insertions(+), 150 deletions(-)
diff --git a/4.3.3/0000_README b/4.3.3/0000_README
index 0d44c02..ac59d19 100644
--- a/4.3.3/0000_README
+++ b/4.3.3/0000_README
@@ -2,7 +2,7 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 4420_grsecurity-3.1-4.3.3-201512282134.patch
+Patch: 4420_grsecurity-3.1-4.3.3-201601051958.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/4.3.3/4420_grsecurity-3.1-4.3.3-201512282134.patch b/4.3.3/4420_grsecurity-3.1-4.3.3-201601051958.patch
similarity index 99%
rename from 4.3.3/4420_grsecurity-3.1-4.3.3-201512282134.patch
rename to 4.3.3/4420_grsecurity-3.1-4.3.3-201601051958.patch
index 0e5c122..0bcf4a7 100644
--- a/4.3.3/4420_grsecurity-3.1-4.3.3-201512282134.patch
+++ b/4.3.3/4420_grsecurity-3.1-4.3.3-201601051958.patch
@@ -3200,6 +3200,103 @@ index 48185a7..426ae3a 100644
void __init smp_set_ops(struct smp_operations *ops)
{
+diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c
+index b83f3b7..087acb5 100644
+--- a/arch/arm/kernel/sys_oabi-compat.c
++++ b/arch/arm/kernel/sys_oabi-compat.c
+@@ -193,15 +193,44 @@ struct oabi_flock64 {
+ pid_t l_pid;
+ } __attribute__ ((packed,aligned(4)));
+
+-asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
++static long do_locks(unsigned int fd, unsigned int cmd,
+ unsigned long arg)
+ {
+- struct oabi_flock64 user;
+ struct flock64 kernel;
+- mm_segment_t fs = USER_DS; /* initialized to kill a warning */
+- unsigned long local_arg = arg;
+- int ret;
++ struct oabi_flock64 user;
++ mm_segment_t fs;
++ long ret;
+
++ if (copy_from_user(&user, (struct oabi_flock64 __user *)arg,
++ sizeof(user)))
++ return -EFAULT;
++ kernel.l_type = user.l_type;
++ kernel.l_whence = user.l_whence;
++ kernel.l_start = user.l_start;
++ kernel.l_len = user.l_len;
++ kernel.l_pid = user.l_pid;
++
++ fs = get_fs();
++ set_fs(KERNEL_DS);
++ ret = sys_fcntl64(fd, cmd, (unsigned long)&kernel);
++ set_fs(fs);
++
++ if (!ret && (cmd == F_GETLK64 || cmd == F_OFD_GETLK)) {
++ user.l_type = kernel.l_type;
++ user.l_whence = kernel.l_whence;
++ user.l_start = kernel.l_start;
++ user.l_len = kernel.l_len;
++ user.l_pid = kernel.l_pid;
++ if (copy_to_user((struct oabi_flock64 __user *)arg,
++ &user, sizeof(user)))
++ ret = -EFAULT;
++ }
++ return ret;
++}
++
++asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
++ unsigned long arg)
++{
+ switch (cmd) {
+ case F_OFD_GETLK:
+ case F_OFD_SETLK:
+@@ -209,39 +238,11 @@ asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
+ case F_GETLK64:
+ case F_SETLK64:
+ case F_SETLKW64:
+- if (copy_from_user(&user, (struct oabi_flock64 __user *)arg,
+- sizeof(user)))
+- return -EFAULT;
+- kernel.l_type = user.l_type;
+- kernel.l_whence = user.l_whence;
+- kernel.l_start = user.l_start;
+- kernel.l_len = user.l_len;
+- kernel.l_pid = user.l_pid;
+- local_arg = (unsigned long)&kernel;
+- fs = get_fs();
+- set_fs(KERNEL_DS);
+- }
+-
+- ret = sys_fcntl64(fd, cmd, local_arg);
++ return do_locks(fd, cmd, arg);
+
+- switch (cmd) {
+- case F_GETLK64:
+- if (!ret) {
+- user.l_type = kernel.l_type;
+- user.l_whence = kernel.l_whence;
+- user.l_start = kernel.l_start;
+- user.l_len = kernel.l_len;
+- user.l_pid = kernel.l_pid;
+- if (copy_to_user((struct oabi_flock64 __user *)arg,
+- &user, sizeof(user)))
+- ret = -EFAULT;
+- }
+- case F_SETLK64:
+- case F_SETLKW64:
+- set_fs(fs);
++ default:
++ return sys_fcntl64(fd, cmd, arg);
+ }
+-
+- return ret;
+ }
+
+ struct oabi_epoll_event {
diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c
index b10e136..cb5edf9 100644
--- a/arch/arm/kernel/tcm.c
@@ -15375,7 +15472,7 @@ index b2909bf..47ba402 100644
+ENDPROC(async_page_fault)
#endif
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
-index 055a01d..8dddafe 100644
+index 055a01d..348b266 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -36,6 +36,8 @@
@@ -15968,26 +16065,36 @@ index 055a01d..8dddafe 100644
/*
* Interrupt entry/exit.
-@@ -529,6 +950,18 @@ END(irq_entries_start)
- incl PER_CPU_VAR(irq_count)
- cmovzq PER_CPU_VAR(irq_stack_ptr), %rsp
- pushq %rdi
-+
+@@ -513,11 +934,19 @@ END(irq_entries_start)
+ * tracking that we're in kernel mode.
+ */
+ SWAPGS
+#ifdef CONFIG_PAX_MEMORY_UDEREF
-+ testb $3, CS(%rdi)
-+ jnz 1f
-+ pax_enter_kernel
-+ jmp 2f
-+1: pax_enter_kernel_user
-+2:
++ pax_enter_kernel_user
+#else
+ pax_enter_kernel
+#endif
+
+ #ifdef CONFIG_CONTEXT_TRACKING
+ call enter_from_user_mode
+ #endif
+
+-1:
++ jmp 2f
++1: pax_enter_kernel
++2:
+ /*
+ * Save previous stack pointer, optionally switch to interrupt stack.
+ * irq_count is used to check if a CPU is already on an interrupt stack
+@@ -529,6 +958,7 @@ END(irq_entries_start)
+ incl PER_CPU_VAR(irq_count)
+ cmovzq PER_CPU_VAR(irq_stack_ptr), %rsp
+ pushq %rdi
++
/* We entered an interrupt context - irqs are off: */
TRACE_IRQS_OFF
-@@ -561,6 +994,8 @@ ret_from_intr:
+@@ -561,6 +991,8 @@ ret_from_intr:
GLOBAL(retint_user)
mov %rsp,%rdi
call prepare_exit_to_usermode
@@ -15996,7 +16103,7 @@ index 055a01d..8dddafe 100644
TRACE_IRQS_IRETQ
SWAPGS
jmp restore_regs_and_iret
-@@ -578,6 +1013,21 @@ retint_kernel:
+@@ -578,6 +1010,21 @@ retint_kernel:
jmp 0b
1:
#endif
@@ -16018,7 +16125,7 @@ index 055a01d..8dddafe 100644
/*
* The iretq could re-enable interrupts:
*/
-@@ -621,15 +1071,15 @@ native_irq_return_ldt:
+@@ -621,15 +1068,15 @@ native_irq_return_ldt:
SWAPGS
movq PER_CPU_VAR(espfix_waddr), %rdi
movq %rax, (0*8)(%rdi) /* RAX */
@@ -16039,7 +16146,7 @@ index 055a01d..8dddafe 100644
movq %rax, (4*8)(%rdi)
andl $0xffff0000, %eax
popq %rdi
-@@ -639,7 +1089,7 @@ native_irq_return_ldt:
+@@ -639,7 +1086,7 @@ native_irq_return_ldt:
popq %rax
jmp native_irq_return_iret
#endif
@@ -16048,7 +16155,7 @@ index 055a01d..8dddafe 100644
/*
* APIC interrupts.
-@@ -651,7 +1101,7 @@ ENTRY(\sym)
+@@ -651,7 +1098,7 @@ ENTRY(\sym)
.Lcommon_\sym:
interrupt \do_sym
jmp ret_from_intr
@@ -16057,7 +16164,7 @@ index 055a01d..8dddafe 100644
.endm
#ifdef CONFIG_TRACING
-@@ -716,7 +1166,7 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt
+@@ -716,7 +1163,7 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt
/*
* Exception entry points.
*/
@@ -16066,7 +16173,7 @@ index 055a01d..8dddafe 100644
.macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1
ENTRY(\sym)
-@@ -763,6 +1213,12 @@ ENTRY(\sym)
+@@ -763,6 +1210,12 @@ ENTRY(\sym)
.endif
.if \shift_ist != -1
@@ -16079,7 +16186,7 @@ index 055a01d..8dddafe 100644
subq $EXCEPTION_STKSZ, CPU_TSS_IST(\shift_ist)
.endif
-@@ -806,7 +1262,7 @@ ENTRY(\sym)
+@@ -806,7 +1259,7 @@ ENTRY(\sym)
jmp error_exit /* %ebx: no swapgs flag */
.endif
@@ -16088,7 +16195,7 @@ index 055a01d..8dddafe 100644
.endm
#ifdef CONFIG_TRACING
-@@ -848,8 +1304,9 @@ gs_change:
+@@ -848,8 +1301,9 @@ gs_change:
2: mfence /* workaround */
SWAPGS
popfq
@@ -16099,7 +16206,7 @@ index 055a01d..8dddafe 100644
_ASM_EXTABLE(gs_change, bad_gs)
.section .fixup, "ax"
-@@ -871,8 +1328,9 @@ ENTRY(do_softirq_own_stack)
+@@ -871,8 +1325,9 @@ ENTRY(do_softirq_own_stack)
call __do_softirq
leaveq
decl PER_CPU_VAR(irq_count)
@@ -16110,7 +16217,7 @@ index 055a01d..8dddafe 100644
#ifdef CONFIG_XEN
idtentry xen_hypervisor_callback xen_do_hypervisor_callback has_error_code=0
-@@ -908,7 +1366,7 @@ ENTRY(xen_do_hypervisor_callback) /* do_hypervisor_callback(struct *pt_regs) */
+@@ -908,7 +1363,7 @@ ENTRY(xen_do_hypervisor_callback) /* do_hypervisor_callback(struct *pt_regs) */
call xen_maybe_preempt_hcall
#endif
jmp error_exit
@@ -16119,7 +16226,7 @@ index 055a01d..8dddafe 100644
/*
* Hypervisor uses this for application faults while it executes.
-@@ -953,7 +1411,7 @@ ENTRY(xen_failsafe_callback)
+@@ -953,7 +1408,7 @@ ENTRY(xen_failsafe_callback)
SAVE_C_REGS
SAVE_EXTRA_REGS
jmp error_exit
@@ -16128,7 +16235,7 @@ index 055a01d..8dddafe 100644
apicinterrupt3 HYPERVISOR_CALLBACK_VECTOR \
xen_hvm_callback_vector xen_evtchn_do_upcall
-@@ -1002,8 +1460,36 @@ ENTRY(paranoid_entry)
+@@ -1002,8 +1457,34 @@ ENTRY(paranoid_entry)
js 1f /* negative -> in kernel */
SWAPGS
xorl %ebx, %ebx
@@ -16137,14 +16244,12 @@ index 055a01d..8dddafe 100644
+1:
+#ifdef CONFIG_PAX_MEMORY_UDEREF
+ testb $3, CS+8(%rsp)
-+ jnz 1f
-+ pax_enter_kernel
++ jz 1f
++ pax_enter_kernel_user
+ jmp 2f
-+1: pax_enter_kernel_user
-+2:
-+#else
-+ pax_enter_kernel
+#endif
++1: pax_enter_kernel
++2:
+ pax_force_retaddr
+ ret
+ENDPROC(paranoid_entry)
@@ -16167,7 +16272,7 @@ index 055a01d..8dddafe 100644
/*
* "Paranoid" exit path from exception stack. This is invoked
-@@ -1020,19 +1506,26 @@ END(paranoid_entry)
+@@ -1020,19 +1501,26 @@ END(paranoid_entry)
ENTRY(paranoid_exit)
DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF_DEBUG
@@ -16196,27 +16301,68 @@ index 055a01d..8dddafe 100644
/*
* Save all registers in pt_regs, and switch gs if needed.
-@@ -1059,8 +1552,18 @@ ENTRY(error_entry)
- #endif
+@@ -1046,21 +1534,26 @@ ENTRY(error_entry)
+ testb $3, CS+8(%rsp)
+ jz .Lerror_kernelspace
+
+-.Lerror_entry_from_usermode_swapgs:
+ /*
+ * We entered from user mode or we're pretending to have entered
+ * from user mode due to an IRET fault.
+ */
+ SWAPGS
- .Lerror_entry_done:
--
+#ifdef CONFIG_PAX_MEMORY_UDEREF
-+ testb $3, CS+8(%rsp)
-+ jnz 1f
-+ pax_enter_kernel
-+ jmp 2f
-+1: pax_enter_kernel_user
-+2:
++ pax_enter_kernel_user
+#else
+ pax_enter_kernel
+#endif
++
+ .Lerror_entry_from_usermode_after_swapgs:
+ #ifdef CONFIG_CONTEXT_TRACKING
+ call enter_from_user_mode
+ #endif
+
+ .Lerror_entry_done:
+-
TRACE_IRQS_OFF
+ pax_force_retaddr
ret
/*
-@@ -1109,11 +1612,11 @@ ENTRY(error_entry)
+@@ -1078,14 +1571,16 @@ ENTRY(error_entry)
+ cmpq %rax, RIP+8(%rsp)
+ je .Lbstep_iret
+ cmpq $gs_change, RIP+8(%rsp)
+- jne .Lerror_entry_done
++ jne 1f
+
+ /*
+ * hack: gs_change can fail with user gsbase. If this happens, fix up
+ * gsbase and proceed. We'll fix up the exception and land in
+ * gs_change's error handler with kernel gsbase.
+ */
+- jmp .Lerror_entry_from_usermode_swapgs
++ SWAPGS
++1: pax_enter_kernel
++ jmp .Lerror_entry_done
+
+ .Lbstep_iret:
+ /* Fix truncated RIP */
+@@ -1099,6 +1594,12 @@ ENTRY(error_entry)
+ */
+ SWAPGS
+
++#ifdef CONFIG_PAX_MEMORY_UDEREF
++ pax_enter_kernel_user
++#else
++ pax_enter_kernel
++#endif
++
+ /*
+ * Pretend that the exception came from user mode: set up pt_regs
+ * as if we faulted immediately after IRET and clear EBX so that
+@@ -1109,11 +1610,11 @@ ENTRY(error_entry)
mov %rax, %rsp
decl %ebx
jmp .Lerror_entry_from_usermode_after_swapgs
@@ -16230,7 +16376,7 @@ index 055a01d..8dddafe 100644
* 1: already in kernel mode, don't need SWAPGS
* 0: user gsbase is loaded, we need SWAPGS and standard preparation for return to usermode
*/
-@@ -1121,10 +1624,10 @@ ENTRY(error_exit)
+@@ -1121,10 +1622,10 @@ ENTRY(error_exit)
movl %ebx, %eax
DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF
@@ -16243,7 +16389,7 @@ index 055a01d..8dddafe 100644
/* Runs on exception stack */
ENTRY(nmi)
-@@ -1178,6 +1681,8 @@ ENTRY(nmi)
+@@ -1178,6 +1679,8 @@ ENTRY(nmi)
* other IST entries.
*/
@@ -16252,7 +16398,7 @@ index 055a01d..8dddafe 100644
/* Use %rdx as our temp variable throughout */
pushq %rdx
-@@ -1221,6 +1726,12 @@ ENTRY(nmi)
+@@ -1221,6 +1724,12 @@ ENTRY(nmi)
pushq %r14 /* pt_regs->r14 */
pushq %r15 /* pt_regs->r15 */
@@ -16265,7 +16411,7 @@ index 055a01d..8dddafe 100644
/*
* At this point we no longer need to worry about stack damage
* due to nesting -- we're on the normal thread stack and we're
-@@ -1231,12 +1742,19 @@ ENTRY(nmi)
+@@ -1231,12 +1740,19 @@ ENTRY(nmi)
movq $-1, %rsi
call do_nmi
@@ -16285,7 +16431,7 @@ index 055a01d..8dddafe 100644
jmp restore_c_regs_and_iret
.Lnmi_from_kernel:
-@@ -1358,6 +1876,7 @@ nested_nmi_out:
+@@ -1358,6 +1874,7 @@ nested_nmi_out:
popq %rdx
/* We are returning to kernel mode, so this cannot result in a fault. */
@@ -16293,7 +16439,7 @@ index 055a01d..8dddafe 100644
INTERRUPT_RETURN
first_nmi:
-@@ -1431,20 +1950,22 @@ end_repeat_nmi:
+@@ -1431,20 +1948,22 @@ end_repeat_nmi:
ALLOC_PT_GPREGS_ON_STACK
/*
@@ -16319,7 +16465,7 @@ index 055a01d..8dddafe 100644
jnz nmi_restore
nmi_swapgs:
SWAPGS_UNSAFE_STACK
-@@ -1455,6 +1976,8 @@ nmi_restore:
+@@ -1455,6 +1974,8 @@ nmi_restore:
/* Point RSP at the "iret" frame. */
REMOVE_PT_GPREGS_FROM_STACK 6*8
@@ -16328,7 +16474,7 @@ index 055a01d..8dddafe 100644
/*
* Clear "NMI executing". Set DF first so that we can easily
* distinguish the remaining code between here and IRET from
-@@ -1472,9 +1995,9 @@ nmi_restore:
+@@ -1472,9 +1993,9 @@ nmi_restore:
* mode, so this cannot result in a fault.
*/
INTERRUPT_RETURN
@@ -22706,7 +22852,7 @@ index 0c26b1b..a766e85 100644
bogus_magic:
jmp bogus_magic
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
-index 25f9093..21d2827 100644
+index 25f9093..f630040 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -20,6 +20,7 @@
@@ -22813,7 +22959,7 @@ index 25f9093..21d2827 100644
/* 0xe8 is a relative jump; fix the offset. */
if (*insnbuf == 0xe8 && a->replacementlen == 5) {
- *(s32 *)(insnbuf + 1) += replacement - instr;
-+ *(s32 *)(insnbuf + 1) += vreplacement - vinstr;
++ *(s32 *)(insnbuf + 1) += vreplacement - instr;
DPRINTK("Fix CALL offset: 0x%x, CALL 0x%lx",
*(s32 *)(insnbuf + 1),
- (unsigned long)instr + *(s32 *)(insnbuf + 1) + 5);
@@ -29542,9 +29688,27 @@ index 2fbea25..9e0f8c7 100644
out:
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
-index 1505587..e7b669d 100644
+index 1505587..0f0516c 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
+@@ -1881,7 +1881,7 @@ static int em_push_sreg(struct x86_emulate_ctxt *ctxt)
+ static int em_pop_sreg(struct x86_emulate_ctxt *ctxt)
+ {
+ int seg = ctxt->src2.val;
+- unsigned long selector;
++ u16 selector;
+ int rc;
+
+ rc = emulate_pop(ctxt, &selector, 2);
+@@ -1893,7 +1893,7 @@ static int em_pop_sreg(struct x86_emulate_ctxt *ctxt)
+ if (ctxt->op_bytes > 2)
+ rsp_increment(ctxt, ctxt->op_bytes - 2);
+
+- rc = load_segment_descriptor(ctxt, (u16)selector, seg);
++ rc = load_segment_descriptor(ctxt, selector, seg);
+ return rc;
+ }
+
@@ -3870,7 +3870,7 @@ static int check_cr_write(struct x86_emulate_ctxt *ctxt)
int cr = ctxt->modrm_reg;
u64 efer = 0;
@@ -40716,6 +40880,40 @@ index b5bcd77..0f7bd99 100644
return 0;
}
+diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
+index 30f5228..c19e7fc 100644
+--- a/drivers/connector/connector.c
++++ b/drivers/connector/connector.c
+@@ -178,26 +178,21 @@ static int cn_call_callback(struct sk_buff *skb)
+ *
+ * It checks skb, netlink header and msg sizes, and calls callback helper.
+ */
+-static void cn_rx_skb(struct sk_buff *__skb)
++static void cn_rx_skb(struct sk_buff *skb)
+ {
+ struct nlmsghdr *nlh;
+- struct sk_buff *skb;
+ int len, err;
+
+- skb = skb_get(__skb);
+-
+ if (skb->len >= NLMSG_HDRLEN) {
+ nlh = nlmsg_hdr(skb);
+ len = nlmsg_len(nlh);
+
+ if (len < (int)sizeof(struct cn_msg) ||
+ skb->len < nlh->nlmsg_len ||
+- len > CONNECTOR_MAX_MSG_SIZE) {
+- kfree_skb(skb);
++ len > CONNECTOR_MAX_MSG_SIZE)
+ return;
+- }
+
+- err = cn_call_callback(skb);
++ err = cn_call_callback(skb_get(skb));
+ if (err < 0)
+ kfree_skb(skb);
+ }
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index cec1ee2..d8e33a0 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
@@ -112550,6 +112748,18 @@ index 8e481a8..a90b4ad 100644
key = event->type & (EVENT_HASHSIZE - 1);
+diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
+index 36c1455..2dbffe2 100644
+--- a/kernel/trace/trace_printk.c
++++ b/kernel/trace/trace_printk.c
+@@ -267,6 +267,7 @@ static const char **find_next(void *v, loff_t *pos)
+ if (*pos < last_index + start_index)
+ return __start___tracepoint_str + (*pos - last_index);
+
++ start_index += last_index;
+ return find_next_mod_format(start_index, v, fmt, pos);
+ }
+
diff --git a/kernel/trace/trace_seq.c b/kernel/trace/trace_seq.c
index e694c9f..6775a38 100644
--- a/kernel/trace/trace_seq.c
@@ -115064,7 +115274,7 @@ index fdadf91..5f527d1 100644
.priority = IPC_CALLBACK_PRI, /* use lowest priority */
};
diff --git a/mm/mmap.c b/mm/mmap.c
-index 79bcc9f..1117624 100644
+index 79bcc9f..481e0f5c 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -42,6 +42,7 @@
@@ -115153,7 +115363,7 @@ index 79bcc9f..1117624 100644
+ rlim = rlimit(RLIMIT_DATA);
+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
+ /* force a minimum 16MB brk heap on setuid/setgid binaries */
-+ if (rlim < PAGE_SIZE && (get_dumpable(mm) != SUID_DUMP_USER) && gr_is_global_nonroot(current_uid()))
++ if (rlim < (4096 * PAGE_SIZE) && (get_dumpable(mm) != SUID_DUMP_USER) && gr_is_global_nonroot(current_uid()))
+ rlim = 4096 * PAGE_SIZE;
+#endif
+ if (check_data_rlimit(rlim, brk, mm->start_brk,
@@ -119610,6 +119820,22 @@ index ea748c9..79056c3 100644
.kind = "bridge",
.priv_size = sizeof(struct net_bridge),
.setup = br_dev_setup,
+diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
+index 4ca449a..49d8d28 100644
+--- a/net/bridge/br_stp_if.c
++++ b/net/bridge/br_stp_if.c
+@@ -130,7 +130,10 @@ static void br_stp_start(struct net_bridge *br)
+ char *envp[] = { NULL };
+ struct net_bridge_port *p;
+
+- r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
++ if (net_eq(dev_net(br->dev), &init_net))
++ r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
++ else
++ r = -ENOENT;
+
+ spin_lock_bh(&br->lock);
+
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 48b6b01..cf544f3 100644
--- a/net/bridge/netfilter/ebtables.c
@@ -124659,7 +124885,7 @@ index 6098d4c..9d87fbd 100644
sctp_generate_t1_cookie_event,
sctp_generate_t1_init_event,
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
-index 3ec88be..eaadf73 100644
+index 3ec88be..a8d9d222 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -972,7 +972,7 @@ static int sctp_setsockopt_bindx(struct sock *sk,
@@ -124671,7 +124897,29 @@ index 3ec88be..eaadf73 100644
if (unlikely(!kaddrs))
return -ENOMEM;
-@@ -2194,11 +2194,13 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
+@@ -1301,8 +1301,9 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
+ int addrs_size,
+ sctp_assoc_t *assoc_id)
+ {
+- int err = 0;
+ struct sockaddr *kaddrs;
++ gfp_t gfp = GFP_KERNEL;
++ int err = 0;
+
+ pr_debug("%s: sk:%p addrs:%p addrs_size:%d\n",
+ __func__, sk, addrs, addrs_size);
+@@ -1315,7 +1316,9 @@ static int __sctp_setsockopt_connectx(struct sock *sk,
+ return -EFAULT;
+
+ /* Alloc space for the address array in kernel memory. */
+- kaddrs = kmalloc(addrs_size, GFP_KERNEL);
++ if (sk->sk_socket->file)
++ gfp = GFP_USER | __GFP_NOWARN;
++ kaddrs = kmalloc(addrs_size, gfp);
+ if (unlikely(!kaddrs))
+ return -ENOMEM;
+
+@@ -2194,11 +2197,13 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval,
{
struct sctp_association *asoc;
struct sctp_ulpevent *event;
@@ -124686,7 +124934,7 @@ index 3ec88be..eaadf73 100644
/* At the time when a user app subscribes to SCTP_SENDER_DRY_EVENT,
* if there is no data to be sent or retransmit, the stack will
-@@ -4373,13 +4375,16 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len,
+@@ -4373,13 +4378,16 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len,
static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval,
int __user *optlen)
{
@@ -124704,7 +124952,7 @@ index 3ec88be..eaadf73 100644
return -EFAULT;
return 0;
}
-@@ -4397,6 +4402,8 @@ static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval,
+@@ -4397,6 +4405,8 @@ static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval,
*/
static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optval, int __user *optlen)
{
@@ -124713,7 +124961,7 @@ index 3ec88be..eaadf73 100644
/* Applicable to UDP-style socket only */
if (sctp_style(sk, TCP))
return -EOPNOTSUPP;
-@@ -4405,7 +4412,8 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv
+@@ -4405,7 +4415,8 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv
len = sizeof(int);
if (put_user(len, optlen))
return -EFAULT;
@@ -124723,7 +124971,7 @@ index 3ec88be..eaadf73 100644
return -EFAULT;
return 0;
}
-@@ -4779,12 +4787,15 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len,
+@@ -4779,12 +4790,15 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len,
*/
static int sctp_getsockopt_initmsg(struct sock *sk, int len, char __user *optval, int __user *optlen)
{
@@ -124740,7 +124988,7 @@ index 3ec88be..eaadf73 100644
return -EFAULT;
return 0;
}
-@@ -4825,6 +4836,8 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
+@@ -4825,6 +4839,8 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
->addr_to_user(sp, &temp);
if (space_left < addrlen)
return -ENOMEM;
@@ -124749,7 +124997,7 @@ index 3ec88be..eaadf73 100644
if (copy_to_user(to, &temp, addrlen))
return -EFAULT;
to += addrlen;
-@@ -4928,7 +4941,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
+@@ -4928,7 +4944,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
to = optval + offsetof(struct sctp_getaddrs, addrs);
space_left = len - offsetof(struct sctp_getaddrs, addrs);
@@ -124758,6 +125006,15 @@ index 3ec88be..eaadf73 100644
if (!addrs)
return -ENOMEM;
+@@ -5777,7 +5793,7 @@ static int sctp_getsockopt_assoc_ids(struct sock *sk, int len,
+
+ len = sizeof(struct sctp_assoc_ids) + sizeof(sctp_assoc_t) * num;
+
+- ids = kmalloc(len, GFP_KERNEL);
++ ids = kmalloc(len, GFP_USER | __GFP_NOWARN);
+ if (unlikely(!ids))
+ return -ENOMEM;
+
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 26d50c5..dfae665 100644
--- a/net/sctp/sysctl.c
@@ -125492,7 +125749,7 @@ index 350cca3..a108fc5 100644
sub->evt.event = htohl(event, sub->swap);
sub->evt.found_lower = htohl(found_lower, sub->swap);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
-index 128b098..665a160 100644
+index 128b098..38013fc 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -918,6 +918,12 @@ static struct sock *unix_find_other(struct net *net,
@@ -125522,26 +125779,141 @@ index 128b098..665a160 100644
if (dentry)
touch_atime(&unix_sk(u)->path);
} else
-@@ -971,12 +984,18 @@ static int unix_mknod(const char *sun_path, umode_t mode, struct path *res)
- */
- err = security_path_mknod(&path, dentry, mode, 0);
+@@ -952,32 +965,26 @@ fail:
+ return NULL;
+ }
+
+-static int unix_mknod(const char *sun_path, umode_t mode, struct path *res)
++static int unix_mknod(struct dentry *dentry, struct path *path, umode_t mode,
++ struct path *res)
+ {
+- struct dentry *dentry;
+- struct path path;
+- int err = 0;
+- /*
+- * Get the parent directory, calculate the hash for last
+- * component.
+- */
+- dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
+- err = PTR_ERR(dentry);
+- if (IS_ERR(dentry))
+- return err;
++ int err;
+
+- /*
+- * All right, let's create it.
+- */
+- err = security_path_mknod(&path, dentry, mode, 0);
++ err = security_path_mknod(path, dentry, mode, 0);
if (!err) {
-+ if (!gr_acl_handle_mknod(dentry, path.dentry, path.mnt, mode)) {
+- err = vfs_mknod(d_inode(path.dentry), dentry, mode, 0);
++ if (!gr_acl_handle_mknod(dentry, path->dentry, path->mnt, mode)) {
+ err = -EACCES;
+ goto out;
+ }
- err = vfs_mknod(d_inode(path.dentry), dentry, mode, 0);
++ err = vfs_mknod(d_inode(path->dentry), dentry, mode, 0);
if (!err) {
- res->mnt = mntget(path.mnt);
+- res->mnt = mntget(path.mnt);
++ res->mnt = mntget(path->mnt);
res->dentry = dget(dentry);
-+ gr_handle_create(dentry, path.mnt);
++ gr_handle_create(dentry, path->mnt);
}
}
+- done_path_create(&path, dentry);
++
+out:
- done_path_create(&path, dentry);
return err;
}
-@@ -2772,9 +2791,13 @@ static int unix_seq_show(struct seq_file *seq, void *v)
+
+@@ -988,10 +995,12 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
+ struct unix_sock *u = unix_sk(sk);
+ struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
+ char *sun_path = sunaddr->sun_path;
+- int err;
++ int err, name_err;
+ unsigned int hash;
+ struct unix_address *addr;
+ struct hlist_head *list;
++ struct path path;
++ struct dentry *dentry;
+
+ err = -EINVAL;
+ if (sunaddr->sun_family != AF_UNIX)
+@@ -1007,14 +1016,34 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
+ goto out;
+ addr_len = err;
+
++ name_err = 0;
++ dentry = NULL;
++ if (sun_path[0]) {
++ /* Get the parent directory, calculate the hash for last
++ * component.
++ */
++ dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
++
++ if (IS_ERR(dentry)) {
++ /* delay report until after 'already bound' check */
++ name_err = PTR_ERR(dentry);
++ dentry = NULL;
++ }
++ }
++
+ err = mutex_lock_interruptible(&u->readlock);
+ if (err)
+- goto out;
++ goto out_path;
+
+ err = -EINVAL;
+ if (u->addr)
+ goto out_up;
+
++ if (name_err) {
++ err = name_err == -EEXIST ? -EADDRINUSE : name_err;
++ goto out_up;
++ }
++
+ err = -ENOMEM;
+ addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL);
+ if (!addr)
+@@ -1025,11 +1054,11 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
+ addr->hash = hash ^ sk->sk_type;
+ atomic_set(&addr->refcnt, 1);
+
+- if (sun_path[0]) {
+- struct path path;
++ if (dentry) {
++ struct path u_path;
+ umode_t mode = S_IFSOCK |
+ (SOCK_INODE(sock)->i_mode & ~current_umask());
+- err = unix_mknod(sun_path, mode, &path);
++ err = unix_mknod(dentry, &path, mode, &u_path);
+ if (err) {
+ if (err == -EEXIST)
+ err = -EADDRINUSE;
+@@ -1037,9 +1066,9 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
+ goto out_up;
+ }
+ addr->hash = UNIX_HASH_SIZE;
+- hash = d_backing_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE-1);
++ hash = d_backing_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1);
+ spin_lock(&unix_table_lock);
+- u->path = path;
++ u->path = u_path;
+ list = &unix_socket_table[hash];
+ } else {
+ spin_lock(&unix_table_lock);
+@@ -1062,6 +1091,10 @@ out_unlock:
+ spin_unlock(&unix_table_lock);
+ out_up:
+ mutex_unlock(&u->readlock);
++out_path:
++ if (dentry)
++ done_path_create(&path, dentry);
++
+ out:
+ return err;
+ }
+@@ -2772,9 +2805,13 @@ static int unix_seq_show(struct seq_file *seq, void *v)
seq_puts(seq, "Num RefCount Protocol Flags Type St "
"Inode Path\n");
else {
@@ -125556,7 +125928,7 @@ index 128b098..665a160 100644
seq_printf(seq, "%pK: %08X %08X %08X %04X %02X %5lu",
s,
-@@ -2799,10 +2822,29 @@ static int unix_seq_show(struct seq_file *seq, void *v)
+@@ -2799,10 +2836,29 @@ static int unix_seq_show(struct seq_file *seq, void *v)
seq_putc(seq, '@');
i++;
}
@@ -131440,12 +131812,12 @@ index 0000000..7514850
+fi
diff --git a/tools/gcc/initify_plugin.c b/tools/gcc/initify_plugin.c
new file mode 100644
-index 0000000..ed3a502
+index 0000000..a518073
--- /dev/null
+++ b/tools/gcc/initify_plugin.c
-@@ -0,0 +1,588 @@
+@@ -0,0 +1,581 @@
+/*
-+ * Copyright 2011-2015 by Emese Revfy <re.emese@gmail.com>
++ * Copyright 2011-2016 by Emese Revfy <re.emese@gmail.com>
+ * Licensed under the GPL v2, or (at your option) v3
+ *
+ * Homepage:
@@ -131464,7 +131836,7 @@ index 0000000..ed3a502
+int plugin_is_GPL_compatible;
+
+static struct plugin_info initify_plugin_info = {
-+ .version = "20151228",
++ .version = "20160104",
+ .help = "initify_plugin\n",
+};
+
@@ -131648,74 +132020,71 @@ index 0000000..ed3a502
+ return false;
+}
+
-+static bool compare_vardecls(const_tree vardecl, tree op)
++static bool is_same_vardecl(const_tree op, const_tree vardecl)
+{
-+ tree decl, offset;
-+ HOST_WIDE_INT bitsize, bitpos;
-+ enum machine_mode mode;
-+ int unsignedp, reversep __unused, volatilep;
-+ enum tree_code code = TREE_CODE(op);
-+
-+ if (TREE_CODE_CLASS(code) == tcc_exceptional && code != SSA_NAME)
-+ return false;
-+
-+ if (code == ADDR_EXPR)
-+ op = TREE_OPERAND(op, 0);
-+
-+ if (TREE_CODE(op) == COMPONENT_REF)
++ if (op == vardecl)
++ return true;
++ if (!DECL_P(op))
+ return false;
++ return DECL_NAME(op) && !strcmp(DECL_NAME_POINTER(op), DECL_NAME_POINTER(vardecl));
++}
+
-+ decl = get_inner_reference(op, &bitsize, &bitpos, &offset, &mode, &unsignedp, &reversep, &volatilep, true);
++static bool search_same_vardecl(const_tree value, const_tree vardecl)
++{
++ int i;
+
-+ switch (TREE_CODE_CLASS(TREE_CODE(decl))) {
-+ case tcc_comparison:
-+ case tcc_constant:
-+ case tcc_statement:
-+ return false;
-+ default:
-+ break;
-+ }
++ for (i = 0; i < TREE_OPERAND_LENGTH(value); i++) {
++ const_tree op = TREE_OPERAND(value, i);
+
-+ switch (TREE_CODE(decl)) {
-+#if BUILDING_GCC_VERSION >= 4006
-+ case MEM_REF:
-+#endif
-+ case INDIRECT_REF:
-+ case TARGET_MEM_REF:
-+ decl = TREE_OPERAND(decl, 0);
-+ if (decl == NULL_TREE)
-+ return false;
-+ break;
-+ default:
-+ break;
++ if (is_same_vardecl(op, vardecl))
++ return true;
++ return search_same_vardecl(op, vardecl);
+ }
++ return false;
++}
+
-+ gcc_assert(decl != NULL_TREE);
++static bool check_constructor(const_tree constructor, const_tree vardecl)
++{
++ unsigned HOST_WIDE_INT cnt __unused;
++ tree value;
+
-+ if (TREE_CODE(decl) == ADDR_EXPR)
-+ decl = TREE_OPERAND(decl, 0);
-+ if (TREE_CODE(decl) == SSA_NAME)
-+ decl = SSA_NAME_VAR(decl);
-+ if (decl == NULL_TREE)
-+ return false;
++ FOR_EACH_CONSTRUCTOR_VALUE(CONSTRUCTOR_ELTS(constructor), cnt, value) {
++ if (TREE_CODE(value) == CONSTRUCTOR)
++ return check_constructor(value, vardecl);
++ if (is_gimple_constant(value))
++ continue;
+
-+ if (!DECL_P(decl)) {
-+ debug_tree(vardecl);
-+ debug_tree(op);
-+ debug_tree(decl);
-+ gcc_unreachable();
++ gcc_assert(TREE_OPERAND_LENGTH(value) > 0);
++ if (search_same_vardecl(value, vardecl))
++ return true;
+ }
++ return false;
++}
+
-+ if (!VAR_P(decl))
-+ return false;
-+ if (!DECL_NAME(decl))
++static bool compare_ops(const_tree vardecl, tree op)
++{
++ if (TREE_CODE(op) == TREE_LIST)
++ op = TREE_VALUE(op);
++ if (TREE_CODE(op) == SSA_NAME)
++ op = SSA_NAME_VAR(op);
++ if (op == NULL_TREE)
+ return false;
+
-+ if (decl != vardecl && strcmp(DECL_NAME_POINTER(decl), DECL_NAME_POINTER(vardecl)))
++ switch (TREE_CODE_CLASS(TREE_CODE(op))) {
++ case tcc_declaration:
++ return is_same_vardecl(op, vardecl);
++ case tcc_exceptional:
++ return check_constructor(op, vardecl);
++ case tcc_constant:
++ case tcc_statement:
++ case tcc_comparison:
+ return false;
++ default:
++ break;
++ }
+
-+ gcc_assert(TREE_CODE(op) != SSA_NAME);
-+ return true;
++ gcc_assert(TREE_OPERAND_LENGTH(op) > 0);
++ return search_same_vardecl(op, vardecl);
+}
+
+static bool search_capture_use(const_tree vardecl, gimple stmt)
@@ -131732,7 +132101,7 @@ index 0000000..ed3a502
+ if (is_gimple_constant(op))
+ continue;
+
-+ if (!compare_vardecls(vardecl, op))
++ if (!compare_ops(vardecl, op))
+ continue;
+
+ if (!is_gimple_call(stmt))
@@ -131759,23 +132128,19 @@ index 0000000..ed3a502
+ tree var;
+
+ FOR_EACH_LOCAL_DECL(cfun, i, var) {
-+ unsigned HOST_WIDE_INT cnt;
-+ tree index __unused, value;
+ const_tree initial = DECL_INITIAL(var);
+
++ if (DECL_EXTERNAL(var))
++ continue;
+ if (initial == NULL_TREE)
+ continue;
+ if (TREE_CODE(initial) != CONSTRUCTOR)
+ continue;
+
-+ FOR_EACH_CONSTRUCTOR_ELT(CONSTRUCTOR_ELTS(initial), cnt, index, value) {
-+ if (TREE_CODE(value) != ADDR_EXPR)
-+ continue;
-+ if (TREE_OPERAND(value, 0) == vardecl)
-+ return true;
-+ }
++ gcc_assert(TREE_CODE(TREE_TYPE(var)) == RECORD_TYPE || DECL_P(var));
++ if (check_constructor(initial, vardecl))
++ return true;
+ }
-+
+ return false;
+}
+
@@ -134242,10 +134607,10 @@ index 0000000..f74d85a
+targets += size_overflow_hash.h size_overflow_hash_aux.h disable_size_overflow_hash.h
diff --git a/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data b/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data
new file mode 100644
-index 0000000..b7a7596
+index 0000000..5276d6e
--- /dev/null
+++ b/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data
-@@ -0,0 +1,12431 @@
+@@ -0,0 +1,12433 @@
+disable_so_interrupt_pnode_gru_message_queue_desc_4 interrupt_pnode gru_message_queue_desc 0 4 NULL
+disable_so_bch_btree_insert_fndecl_12 bch_btree_insert fndecl 0 12 NULL
+disable_so_macvlan_sync_address_fndecl_22 macvlan_sync_address fndecl 0 22 NULL nohasharray
@@ -136399,7 +136764,8 @@ index 0000000..b7a7596
+disable_so_shash_ahash_mcryptd_digest_fndecl_11335 shash_ahash_mcryptd_digest fndecl 0 11335 NULL
+disable_so_crypto_gcm_encrypt_fndecl_11338 crypto_gcm_encrypt fndecl 0 11338 NULL
+disable_so_btrfs_wq_run_delayed_node_fndecl_11342 btrfs_wq_run_delayed_node fndecl 0 11342 NULL
-+disable_so_pch_udc_ep_bit_clr_fndecl_11345 pch_udc_ep_bit_clr fndecl 3 11345 NULL
++disable_so_pch_udc_ep_bit_clr_fndecl_11345 pch_udc_ep_bit_clr fndecl 3 11345 NULL nohasharray
++enable_so_rcv_tsecr_tcp_options_received_11345 rcv_tsecr tcp_options_received 0 11345 &disable_so_pch_udc_ep_bit_clr_fndecl_11345
+disable_so_bin_uuid_fndecl_11348 bin_uuid fndecl 3-0 11348 NULL
+disable_so_offset_to_bitmap_fndecl_11359 offset_to_bitmap fndecl 0-2 11359 NULL
+disable_so_default_tv_freq_vardecl_pvrusb2_hdw_c_11362 default_tv_freq vardecl_pvrusb2-hdw.c 0 11362 NULL
@@ -146677,6 +147043,7 @@ index 0000000..b7a7596
+enable_so_rate_n_flags_iwl_rx_phy_info_45542 rate_n_flags iwl_rx_phy_info 0 45542 NULL
+enable_so_deh_location_reiserfs_de_head_7682 deh_location reiserfs_de_head 0 7682 NULL
+enable_so_deh_offset_reiserfs_de_head_42314 deh_offset reiserfs_de_head 0 42314 NULL
++enable_so_dsack_tcp_options_received_27706 dsack tcp_options_received 0 27706 NULL
diff --git a/tools/gcc/size_overflow_plugin/generate_size_overflow_hash.sh b/tools/gcc/size_overflow_plugin/generate_size_overflow_hash.sh
new file mode 100644
index 0000000..be9724d
@@ -148920,10 +149287,10 @@ index 0000000..fc58e16
+}
diff --git a/tools/gcc/size_overflow_plugin/size_overflow_hash.data b/tools/gcc/size_overflow_plugin/size_overflow_hash.data
new file mode 100644
-index 0000000..7a7776b
+index 0000000..3fc86c1
--- /dev/null
+++ b/tools/gcc/size_overflow_plugin/size_overflow_hash.data
-@@ -0,0 +1,21746 @@
+@@ -0,0 +1,21744 @@
+enable_so_recv_ctrl_pipe_us_data_0 recv_ctrl_pipe us_data 0 0 NULL
+enable_so___earlyonly_bootmem_alloc_fndecl_3 __earlyonly_bootmem_alloc fndecl 2-3-4 3 NULL
+enable_so_size_ttm_mem_reg_8 size ttm_mem_reg 0 8 NULL
@@ -152673,7 +153040,6 @@ index 0000000..7a7776b
+enable_so_charcount_console_font_11338 charcount console_font 0 11338 NULL
+enable_so_command_p_header100_11343 command p_header100 0 11343 NULL
+enable_so_s_sbbase_ufs_sb_private_info_11344 s_sbbase ufs_sb_private_info 0 11344 NULL
-+enable_so_rcv_tsecr_tcp_options_received_11345 rcv_tsecr tcp_options_received 0 11345 NULL
+enable_so_hci_sock_setsockopt_fndecl_11346 hci_sock_setsockopt fndecl 5 11346 NULL
+enable_so_update_devnum_fndecl_11348 update_devnum fndecl 2 11348 NULL
+enable_so_buffer_length_usbdevfs_urb_11350 buffer_length usbdevfs_urb 0 11350 NULL
@@ -158166,7 +158532,6 @@ index 0000000..7a7776b
+enable_so_rx_buf_sz_de_private_27701 rx_buf_sz de_private 0 27701 NULL
+enable_so_snd_pcm_plugin_alloc_fndecl_27703 snd_pcm_plugin_alloc fndecl 2 27703 NULL
+enable_so_actual_size_mlx4_en_rx_ring_27705 actual_size mlx4_en_rx_ring 0 27705 NULL
-+enable_so_dsack_tcp_options_received_27706 dsack tcp_options_received 0 27706 NULL
+enable_so_sequence_num_usb_ftdi_27707 sequence_num usb_ftdi 0 27707 NULL
+enable_so_niu_rx_skb_append_fndecl_27708 niu_rx_skb_append fndecl 4-3-5 27708 NULL
+enable_so_pcpu_extend_area_map_fndecl_27710 pcpu_extend_area_map fndecl 2 27710 NULL
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [gentoo-commits] proj/hardened-patchset:master commit in: 4.3.3/
@ 2016-01-17 19:13 Anthony G. Basile
0 siblings, 0 replies; 7+ messages in thread
From: Anthony G. Basile @ 2016-01-17 19:13 UTC (permalink / raw
To: gentoo-commits
commit: 12f1edb59638e9b2f260174cfb297927edab395f
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Sun Jan 17 19:20:18 2016 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Sun Jan 17 19:20:18 2016 +0000
URL: https://gitweb.gentoo.org/proj/hardened-patchset.git/commit/?id=12f1edb5
grsecurity-3.1-4.3.3-201601161757
4.3.3/0000_README | 2 +-
...> 4420_grsecurity-3.1-4.3.3-201601161757.patch} | 1567 ++++++++++++++++++--
2 files changed, 1466 insertions(+), 103 deletions(-)
diff --git a/4.3.3/0000_README b/4.3.3/0000_README
index ac59d19..8ff755f 100644
--- a/4.3.3/0000_README
+++ b/4.3.3/0000_README
@@ -2,7 +2,7 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 4420_grsecurity-3.1-4.3.3-201601051958.patch
+Patch: 4420_grsecurity-3.1-4.3.3-201601161757.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/4.3.3/4420_grsecurity-3.1-4.3.3-201601051958.patch b/4.3.3/4420_grsecurity-3.1-4.3.3-201601161757.patch
similarity index 99%
rename from 4.3.3/4420_grsecurity-3.1-4.3.3-201601051958.patch
rename to 4.3.3/4420_grsecurity-3.1-4.3.3-201601161757.patch
index 0bcf4a7..15482a1 100644
--- a/4.3.3/4420_grsecurity-3.1-4.3.3-201601051958.patch
+++ b/4.3.3/4420_grsecurity-3.1-4.3.3-201601161757.patch
@@ -4702,7 +4702,7 @@ index 7cd1514..0307305 100644
}
diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
-index b8efb8c..88fa837 100644
+index b8efb8c..0b8f924 100644
--- a/arch/arm/net/bpf_jit_32.c
+++ b/arch/arm/net/bpf_jit_32.c
@@ -20,6 +20,7 @@
@@ -4778,7 +4778,24 @@ index b8efb8c..88fa837 100644
return (u64)err << 32 | ntohl(ret);
}
-@@ -199,8 +184,10 @@ static void jit_fill_hole(void *area, unsigned int size)
+@@ -182,31 +167,19 @@ static inline int mem_words_used(struct jit_ctx *ctx)
+ return fls(ctx->seen & SEEN_MEM);
+ }
+
+-static inline bool is_load_to_a(u16 inst)
+-{
+- switch (inst) {
+- case BPF_LD | BPF_W | BPF_LEN:
+- case BPF_LD | BPF_W | BPF_ABS:
+- case BPF_LD | BPF_H | BPF_ABS:
+- case BPF_LD | BPF_B | BPF_ABS:
+- return true;
+- default:
+- return false;
+- }
+-}
+-
+ static void jit_fill_hole(void *area, unsigned int size)
{
u32 *ptr;
/* We are guaranteed to have aligned memory. */
@@ -4789,7 +4806,22 @@ index b8efb8c..88fa837 100644
}
static void build_prologue(struct jit_ctx *ctx)
-@@ -556,6 +543,9 @@ static int build_body(struct jit_ctx *ctx)
+ {
+ u16 reg_set = saved_regs(ctx);
+- u16 first_inst = ctx->skf->insns[0].code;
+ u16 off;
+
+ #ifdef CONFIG_FRAME_POINTER
+@@ -236,7 +209,7 @@ static void build_prologue(struct jit_ctx *ctx)
+ emit(ARM_MOV_I(r_X, 0), ctx);
+
+ /* do not leak kernel data to userspace */
+- if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst)))
++ if (bpf_needs_clear_a(&ctx->skf->insns[0]))
+ emit(ARM_MOV_I(r_A, 0), ctx);
+
+ /* stack space for the BPF_MEM words */
+@@ -556,6 +529,9 @@ static int build_body(struct jit_ctx *ctx)
case BPF_LD | BPF_B | BPF_ABS:
load_order = 0;
load:
@@ -4799,7 +4831,7 @@ index b8efb8c..88fa837 100644
emit_mov_i(r_off, k, ctx);
load_common:
ctx->seen |= SEEN_DATA | SEEN_CALL;
-@@ -570,18 +560,6 @@ load_common:
+@@ -570,18 +546,6 @@ load_common:
condt = ARM_COND_HI;
}
@@ -4818,6 +4850,16 @@ index b8efb8c..88fa837 100644
_emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data),
ctx);
+@@ -744,7 +708,8 @@ load_ind:
+ case BPF_ALU | BPF_RSH | BPF_K:
+ if (unlikely(k > 31))
+ return -1;
+- emit(ARM_LSR_I(r_A, r_A, k), ctx);
++ if (k)
++ emit(ARM_LSR_I(r_A, r_A, k), ctx);
+ break;
+ case BPF_ALU | BPF_RSH | BPF_X:
+ update_on_xread(ctx);
diff --git a/arch/arm/plat-iop/setup.c b/arch/arm/plat-iop/setup.c
index 5b217f4..c23f40e 100644
--- a/arch/arm/plat-iop/setup.c
@@ -7046,6 +7088,47 @@ index 5c81fdd..db158d3 100644
int __virt_addr_valid(const volatile void *kaddr)
{
return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
+diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c
+index 0c4a133..26e947d 100644
+--- a/arch/mips/net/bpf_jit.c
++++ b/arch/mips/net/bpf_jit.c
+@@ -521,19 +521,6 @@ static inline u16 align_sp(unsigned int num)
+ return num;
+ }
+
+-static bool is_load_to_a(u16 inst)
+-{
+- switch (inst) {
+- case BPF_LD | BPF_W | BPF_LEN:
+- case BPF_LD | BPF_W | BPF_ABS:
+- case BPF_LD | BPF_H | BPF_ABS:
+- case BPF_LD | BPF_B | BPF_ABS:
+- return true;
+- default:
+- return false;
+- }
+-}
+-
+ static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset)
+ {
+ int i = 0, real_off = 0;
+@@ -614,7 +601,6 @@ static unsigned int get_stack_depth(struct jit_ctx *ctx)
+
+ static void build_prologue(struct jit_ctx *ctx)
+ {
+- u16 first_inst = ctx->skf->insns[0].code;
+ int sp_off;
+
+ /* Calculate the total offset for the stack pointer */
+@@ -641,7 +627,7 @@ static void build_prologue(struct jit_ctx *ctx)
+ emit_jit_reg_move(r_X, r_zero, ctx);
+
+ /* Do not leak kernel data to userspace */
+- if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst)))
++ if (bpf_needs_clear_a(&ctx->skf->insns[0]))
+ emit_jit_reg_move(r_A, r_zero, ctx);
+ }
+
diff --git a/arch/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c
index a2358b4..7cead4f 100644
--- a/arch/mips/sgi-ip27/ip27-nmi.c
@@ -9339,6 +9422,31 @@ index 0f432a7..abfe841 100644
/* If hint, make sure it matches our alignment restrictions */
if (!fixed && addr) {
addr = _ALIGN_UP(addr, 1ul << pshift);
+diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
+index 17cea18..264c473 100644
+--- a/arch/powerpc/net/bpf_jit_comp.c
++++ b/arch/powerpc/net/bpf_jit_comp.c
+@@ -78,18 +78,9 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image,
+ PPC_LI(r_X, 0);
+ }
+
+- switch (filter[0].code) {
+- case BPF_RET | BPF_K:
+- case BPF_LD | BPF_W | BPF_LEN:
+- case BPF_LD | BPF_W | BPF_ABS:
+- case BPF_LD | BPF_H | BPF_ABS:
+- case BPF_LD | BPF_B | BPF_ABS:
+- /* first instruction sets A register (or is RET 'constant') */
+- break;
+- default:
+- /* make sure we dont leak kernel information to user */
++ /* make sure we dont leak kernel information to user */
++ if (bpf_needs_clear_a(&filter[0]))
+ PPC_LI(r_A, 0);
+- }
+ }
+
+ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx)
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 5038fd5..87a2033 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
@@ -12192,6 +12300,35 @@ index 4ac88b7..bac6cb2 100644
#endif /* CONFIG_SMP */
#endif /* CONFIG_DEBUG_DCFLUSH */
}
+diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c
+index f8b9f71..17e71d2 100644
+--- a/arch/sparc/net/bpf_jit_comp.c
++++ b/arch/sparc/net/bpf_jit_comp.c
+@@ -420,22 +420,9 @@ void bpf_jit_compile(struct bpf_prog *fp)
+ }
+ emit_reg_move(O7, r_saved_O7);
+
+- switch (filter[0].code) {
+- case BPF_RET | BPF_K:
+- case BPF_LD | BPF_W | BPF_LEN:
+- case BPF_LD | BPF_W | BPF_ABS:
+- case BPF_LD | BPF_H | BPF_ABS:
+- case BPF_LD | BPF_B | BPF_ABS:
+- /* The first instruction sets the A register (or is
+- * a "RET 'constant'")
+- */
+- break;
+- default:
+- /* Make sure we dont leak kernel information to the
+- * user.
+- */
++ /* Make sure we dont leak kernel information to the user. */
++ if (bpf_needs_clear_a(&filter[0]))
+ emit_clear(r_A); /* A = 0 */
+- }
+
+ for (i = 0; i < flen; i++) {
+ unsigned int K = filter[i].k;
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 106c21b..185bf0f 100644
--- a/arch/tile/Kconfig
@@ -24159,6 +24296,19 @@ index 66dd3fe9..c9bfa35 100644
}
}
+diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
+index 165be83..031e5d22 100644
+--- a/arch/x86/kernel/cpu/perf_event.h
++++ b/arch/x86/kernel/cpu/perf_event.h
+@@ -790,7 +790,7 @@ static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip)
+ regs->cs = kernel_ip(ip) ? __KERNEL_CS : __USER_CS;
+ if (regs->flags & X86_VM_MASK)
+ regs->flags ^= (PERF_EFLAGS_VM | X86_VM_MASK);
+- regs->ip = ip;
++ regs->ip = kernel_ip(ip) ? ktva_ktla(ip) : ip;
+ }
+
+ ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event);
diff --git a/arch/x86/kernel/cpu/perf_event_amd_iommu.c b/arch/x86/kernel/cpu/perf_event_amd_iommu.c
index 97242a9..cf9c30e 100644
--- a/arch/x86/kernel/cpu/perf_event_amd_iommu.c
@@ -24321,6 +24471,67 @@ index 377e8f8..2982f48 100644
ret = intel_cqm_setup_rmid_cache();
if (ret)
+diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
+index 84f236a..6251ea8 100644
+--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
++++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
+@@ -561,7 +561,7 @@ int intel_pmu_drain_bts_buffer(void)
+
+ static inline void intel_pmu_drain_pebs_buffer(void)
+ {
+- struct pt_regs regs;
++ struct pt_regs regs = {};
+
+ x86_pmu.drain_pebs(®s);
+ }
+@@ -832,7 +832,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ unsigned long from = cpuc->lbr_entries[0].from;
+ unsigned long old_to, to = cpuc->lbr_entries[0].to;
+- unsigned long ip = regs->ip;
++ unsigned long ip = ktva_ktla(regs->ip);
+ int is_64bit = 0;
+ void *kaddr;
+ int size;
+@@ -884,6 +884,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs)
+ } else {
+ kaddr = (void *)to;
+ }
++ kaddr = (void *)ktva_ktla((unsigned long)kaddr);
+
+ do {
+ struct insn insn;
+@@ -1032,7 +1033,7 @@ static void setup_pebs_sample_data(struct perf_event *event,
+ }
+
+ if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) {
+- regs->ip = pebs->real_ip;
++ set_linear_ip(regs, pebs->real_ip);
+ regs->flags |= PERF_EFLAGS_EXACT;
+ } else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(regs))
+ regs->flags |= PERF_EFLAGS_EXACT;
+diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+index b2c9475..7288a46 100644
+--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c
++++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c
+@@ -682,7 +682,7 @@ static int branch_type(unsigned long from, unsigned long to, int abort)
+ * Ensure we don't blindy read any address by validating it is
+ * a known text address.
+ */
+- if (kernel_text_address(from)) {
++ if (kernel_text_address(ktva_ktla(from))) {
+ addr = (void *)from;
+ /*
+ * Assume we can get the maximum possible size
+@@ -704,7 +704,7 @@ static int branch_type(unsigned long from, unsigned long to, int abort)
+ #ifdef CONFIG_X86_64
+ is64 = kernel_ip((unsigned long)addr) || !test_thread_flag(TIF_IA32);
+ #endif
+- insn_init(&insn, addr, bytes_read, is64);
++ insn_init(&insn, (void *)ktva_ktla((unsigned long)addr), bytes_read, is64);
+ insn_get_opcode(&insn);
+ if (!insn.opcode.got)
+ return X86_BR_ABORT;
diff --git a/arch/x86/kernel/cpu/perf_event_intel_pt.c b/arch/x86/kernel/cpu/perf_event_intel_pt.c
index 4216928..cdae603 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_pt.c
@@ -29230,9 +29441,18 @@ index c3f7602..f6033e1 100644
/*
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
-index bf4db6e..d491400 100644
+index bf4db6e..624137c 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
+@@ -287,7 +287,7 @@ static int uprobe_init_insn(struct arch_uprobe *auprobe, struct insn *insn, bool
+ {
+ u32 volatile *good_insns;
+
+- insn_init(insn, auprobe->insn, sizeof(auprobe->insn), x86_64);
++ insn_init(insn, (void *)ktva_ktla((unsigned long)auprobe->insn), sizeof(auprobe->insn), x86_64);
+ /* has the side-effect of processing the entire instruction */
+ insn_get_length(insn);
+ if (WARN_ON_ONCE(!insn_complete(insn)))
@@ -978,7 +978,7 @@ arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs
if (nleft != rasize) {
@@ -34681,9 +34901,18 @@ index 0057a7acc..95c7edd 100644
might_sleep();
if (is_enabled()) /* recheck and proper locking in *_core() */
diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c
-index 71fc79a..7388ad7 100644
+index 71fc79a..3dd1f49 100644
--- a/arch/x86/mm/mpx.c
+++ b/arch/x86/mm/mpx.c
+@@ -193,7 +193,7 @@ static int mpx_insn_decode(struct insn *insn,
+ */
+ if (!nr_copied)
+ return -EFAULT;
+- insn_init(insn, buf, nr_copied, x86_64);
++ insn_init(insn, (void *)ktva_ktla((unsigned long)buf), nr_copied, x86_64);
+ insn_get_length(insn);
+ /*
+ * copy_from_user() tries to get as many bytes as we could see in
@@ -292,11 +292,11 @@ siginfo_t *mpx_generate_siginfo(struct pt_regs *regs)
* We were not able to extract an address from the instruction,
* probably because there was something invalid in it.
@@ -42077,6 +42306,19 @@ index 5db3445..21414d5 100644
}
/*
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index 0d13e63..3f67919 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -2338,7 +2338,7 @@ static inline void amdgpu_unregister_atpx_handler(void) {}
+ * KMS
+ */
+ extern const struct drm_ioctl_desc amdgpu_ioctls_kms[];
+-extern int amdgpu_max_kms_ioctl;
++extern const int amdgpu_max_kms_ioctl;
+
+ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags);
+ int amdgpu_driver_unload_kms(struct drm_device *dev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
index 8e99514..3d68786 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
@@ -42174,6 +42416,35 @@ index 6068d82..7ecd87c 100644
}
static const struct vga_switcheroo_client_ops amdgpu_switcheroo_ops = {
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+index b190c2a..d1b18c2 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -544,8 +544,12 @@ static int __init amdgpu_init(void)
+ DRM_INFO("amdgpu kernel modesetting enabled.\n");
+ driver = &kms_driver;
+ pdriver = &amdgpu_kms_pci_driver;
+- driver->driver_features |= DRIVER_MODESET;
+- driver->num_ioctls = amdgpu_max_kms_ioctl;
++
++ pax_open_kernel();
++ *(u32 *)&driver->driver_features |= DRIVER_MODESET;
++ *(int *)&driver->num_ioctls = amdgpu_max_kms_ioctl;
++ pax_close_kernel();
++
+ amdgpu_register_atpx_handler();
+
+ amdgpu_amdkfd_init();
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+index 5d11e79..04cc53e 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+@@ -703,4 +703,4 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = {
+ DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(AMDGPU_GEM_USERPTR, amdgpu_gem_userptr_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ };
+-int amdgpu_max_kms_ioctl = ARRAY_SIZE(amdgpu_ioctls_kms);
++const int amdgpu_max_kms_ioctl = ARRAY_SIZE(amdgpu_ioctls_kms);
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index c6a1b4c..32873f8 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -42631,6 +42902,27 @@ index 7b69070..d7bd78b 100644
pqn->q);
if (retval != 0)
return retval;
+diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
+index 225034b..4bb9696 100644
+--- a/drivers/gpu/drm/armada/armada_drv.c
++++ b/drivers/gpu/drm/armada/armada_drv.c
+@@ -324,6 +324,7 @@ static struct drm_driver armada_drm_driver = {
+ .driver_features = DRIVER_GEM | DRIVER_MODESET |
+ DRIVER_HAVE_IRQ | DRIVER_PRIME,
+ .ioctls = armada_ioctls,
++ .num_ioctls = ARRAY_SIZE(armada_ioctls),
+ .fops = &armada_drm_fops,
+ };
+
+@@ -484,8 +485,6 @@ static int __init armada_drm_init(void)
+ {
+ int ret;
+
+- armada_drm_driver.num_ioctls = ARRAY_SIZE(armada_ioctls);
+-
+ ret = platform_driver_register(&armada_lcd_platform_driver);
+ if (ret)
+ return ret;
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 8328e70..fbd9db2 100644
--- a/drivers/gpu/drm/drm_crtc.c
@@ -42867,6 +43159,49 @@ index d93e737..edb8a4a 100644
unsigned int nr = DRM_IOCTL_NR(cmd);
int retcode = -EINVAL;
char stack_kdata[128];
+diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c
+index 1b1bd42..0e49027 100644
+--- a/drivers/gpu/drm/drm_pci.c
++++ b/drivers/gpu/drm/drm_pci.c
+@@ -305,7 +305,7 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
+ /* No locking needed since shadow-attach is single-threaded since it may
+ * only be called from the per-driver module init hook. */
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+- list_add_tail(&dev->legacy_dev_list, &driver->legacy_dev_list);
++ pax_list_add_tail(&dev->legacy_dev_list, (struct list_head *)&driver->legacy_dev_list);
+
+ return 0;
+
+@@ -340,7 +340,7 @@ int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
+ return pci_register_driver(pdriver);
+
+ /* If not using KMS, fall back to stealth mode manual scanning. */
+- INIT_LIST_HEAD(&driver->legacy_dev_list);
++ INIT_LIST_HEAD((struct list_head *)&driver->legacy_dev_list);
+ for (i = 0; pdriver->id_table[i].vendor != 0; i++) {
+ pid = &pdriver->id_table[i];
+
+@@ -446,7 +446,7 @@ void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
+ } else {
+ list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list,
+ legacy_dev_list) {
+- list_del(&dev->legacy_dev_list);
++ pax_list_del(&dev->legacy_dev_list);
+ drm_put_dev(dev);
+ }
+ }
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
+index ae9e6b2..80b2703 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
+@@ -614,7 +614,6 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
+ struct component_match *match;
+
+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+- exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
+
+ match = exynos_drm_match_add(&pdev->dev);
+ if (IS_ERR(match))
diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c b/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c
index d4813e0..6c1ab4d 100644
--- a/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c
@@ -42890,8 +43225,54 @@ index d4813e0..6c1ab4d 100644
if (pipe) {
pipeconf_reg = PIPECCONF;
dspcntr_reg = DSPCCNTR;
+diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
+index 92e7e57..f59f5d3 100644
+--- a/drivers/gpu/drm/gma500/psb_drv.c
++++ b/drivers/gpu/drm/gma500/psb_drv.c
+@@ -376,7 +376,10 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags)
+
+ dev->vblank_disable_allowed = true;
+ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
+- dev->driver->get_vblank_counter = psb_get_vblank_counter;
++
++ pax_open_kernel();
++ *(void **)&dev->driver->get_vblank_counter = psb_get_vblank_counter;
++ pax_close_kernel();
+
+ psb_modeset_init(dev);
+ psb_fbdev_init(dev);
+diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c
+index d918567..6cfd904 100644
+--- a/drivers/gpu/drm/i810/i810_dma.c
++++ b/drivers/gpu/drm/i810/i810_dma.c
+@@ -1250,7 +1250,7 @@ const struct drm_ioctl_desc i810_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED),
+ };
+
+-int i810_max_ioctl = ARRAY_SIZE(i810_ioctls);
++const int i810_max_ioctl = ARRAY_SIZE(i810_ioctls);
+
+ /**
+ * Determine if the device really is AGP or not.
+diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c
+index 44f4a13..0063c1b 100644
+--- a/drivers/gpu/drm/i810/i810_drv.c
++++ b/drivers/gpu/drm/i810/i810_drv.c
+@@ -87,7 +87,11 @@ static int __init i810_init(void)
+ pr_err("drm/i810 does not support SMP\n");
+ return -EINVAL;
+ }
+- driver.num_ioctls = i810_max_ioctl;
++
++ pax_open_kernel();
++ *(int *)&driver.num_ioctls = i810_max_ioctl;
++ pax_close_kernel();
++
+ return drm_pci_init(&driver, &i810_pci_driver);
+ }
+
diff --git a/drivers/gpu/drm/i810/i810_drv.h b/drivers/gpu/drm/i810/i810_drv.h
-index 93ec5dc..82acbaf 100644
+index 93ec5dc..204ec92 100644
--- a/drivers/gpu/drm/i810/i810_drv.h
+++ b/drivers/gpu/drm/i810/i810_drv.h
@@ -110,8 +110,8 @@ typedef struct drm_i810_private {
@@ -42905,8 +43286,17 @@ index 93ec5dc..82acbaf 100644
int front_offset;
} drm_i810_private_t;
+@@ -128,7 +128,7 @@ extern int i810_driver_device_is_agp(struct drm_device *dev);
+
+ extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+ extern const struct drm_ioctl_desc i810_ioctls[];
+-extern int i810_max_ioctl;
++extern const int i810_max_ioctl;
+
+ #define I810_BASE(reg) ((unsigned long) \
+ dev_priv->mmio_map->handle)
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
-index ab37d11..df030da 100644
+index ab37d11..5cbacc7 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -383,7 +383,7 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev)
@@ -42918,6 +43308,72 @@ index ab37d11..df030da 100644
}
static const struct vga_switcheroo_client_ops i915_switcheroo_ops = {
+@@ -1273,4 +1273,4 @@ const struct drm_ioctl_desc i915_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ };
+
+-int i915_max_ioctl = ARRAY_SIZE(i915_ioctls);
++const int i915_max_ioctl = ARRAY_SIZE(i915_ioctls);
+diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
+index ab64d68..e6be8e5 100644
+--- a/drivers/gpu/drm/i915/i915_drv.c
++++ b/drivers/gpu/drm/i915/i915_drv.c
+@@ -1697,25 +1697,27 @@ static struct pci_driver i915_pci_driver = {
+
+ static int __init i915_init(void)
+ {
+- driver.num_ioctls = i915_max_ioctl;
++ pax_open_kernel();
++ *(int *)&driver.num_ioctls = i915_max_ioctl;
+
+ /*
+ * Enable KMS by default, unless explicitly overriden by
+ * either the i915.modeset prarameter or by the
+ * vga_text_mode_force boot option.
+ */
+- driver.driver_features |= DRIVER_MODESET;
++ *(u32 *)&driver.driver_features |= DRIVER_MODESET;
+
+ if (i915.modeset == 0)
+- driver.driver_features &= ~DRIVER_MODESET;
++ *(u32 *)&driver.driver_features &= ~DRIVER_MODESET;
+
+ #ifdef CONFIG_VGA_CONSOLE
+ if (vgacon_text_force() && i915.modeset == -1)
+- driver.driver_features &= ~DRIVER_MODESET;
++ *(u32 *)&driver.driver_features &= ~DRIVER_MODESET;
+ #endif
+
+ if (!(driver.driver_features & DRIVER_MODESET)) {
+- driver.get_vblank_timestamp = NULL;
++ *(void **)&driver.get_vblank_timestamp = NULL;
++ pax_close_kernel();
+ /* Silently fail loading to not upset userspace. */
+ DRM_DEBUG_DRIVER("KMS and UMS disabled.\n");
+ return 0;
+@@ -1727,7 +1729,8 @@ static int __init i915_init(void)
+ * a single CRTC will actually work.
+ */
+ if (driver.driver_features & DRIVER_MODESET)
+- driver.driver_features |= DRIVER_ATOMIC;
++ *(u32 *)&driver.driver_features |= DRIVER_ATOMIC;
++ pax_close_kernel();
+
+ return drm_pci_init(&driver, &i915_pci_driver);
+ }
+diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
+index e1db8de..3abe8a4 100644
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -2601,7 +2601,7 @@ struct drm_i915_cmd_table {
+ #include "i915_trace.h"
+
+ extern const struct drm_ioctl_desc i915_ioctls[];
+-extern int i915_max_ioctl;
++extern const int i915_max_ioctl;
+
+ extern int i915_suspend_legacy(struct drm_device *dev, pm_message_t state);
+ extern int i915_resume_legacy(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index a953d49..bf179e7 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -43044,6 +43500,137 @@ index 97f3a56..32c712e 100644
else
ret = drm_ioctl(filp, cmd, arg);
+diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
+index 39d73db..b5187a1 100644
+--- a/drivers/gpu/drm/i915/i915_irq.c
++++ b/drivers/gpu/drm/i915/i915_irq.c
+@@ -4143,14 +4143,15 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
+
+ pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE);
+
++ pax_open_kernel();
+ if (IS_GEN2(dev_priv)) {
+ dev->max_vblank_count = 0;
+- dev->driver->get_vblank_counter = i8xx_get_vblank_counter;
++ *(void **)&dev->driver->get_vblank_counter = i8xx_get_vblank_counter;
+ } else if (IS_G4X(dev_priv) || INTEL_INFO(dev_priv)->gen >= 5) {
+ dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
+- dev->driver->get_vblank_counter = gm45_get_vblank_counter;
++ *(void **)&dev->driver->get_vblank_counter = gm45_get_vblank_counter;
+ } else {
+- dev->driver->get_vblank_counter = i915_get_vblank_counter;
++ *(void **)&dev->driver->get_vblank_counter = i915_get_vblank_counter;
+ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
+ }
+
+@@ -4162,66 +4163,67 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
+ if (!IS_GEN2(dev_priv))
+ dev->vblank_disable_immediate = true;
+
+- dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp;
+- dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
++ *(void **)&dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp;
++ *(void **)&dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
+
+ if (IS_CHERRYVIEW(dev_priv)) {
+- dev->driver->irq_handler = cherryview_irq_handler;
+- dev->driver->irq_preinstall = cherryview_irq_preinstall;
+- dev->driver->irq_postinstall = cherryview_irq_postinstall;
+- dev->driver->irq_uninstall = cherryview_irq_uninstall;
+- dev->driver->enable_vblank = valleyview_enable_vblank;
+- dev->driver->disable_vblank = valleyview_disable_vblank;
++ *(void **)&dev->driver->irq_handler = cherryview_irq_handler;
++ *(void **)&dev->driver->irq_preinstall = cherryview_irq_preinstall;
++ *(void **)&dev->driver->irq_postinstall = cherryview_irq_postinstall;
++ *(void **)&dev->driver->irq_uninstall = cherryview_irq_uninstall;
++ *(void **)&dev->driver->enable_vblank = valleyview_enable_vblank;
++ *(void **)&dev->driver->disable_vblank = valleyview_disable_vblank;
+ dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
+ } else if (IS_VALLEYVIEW(dev_priv)) {
+- dev->driver->irq_handler = valleyview_irq_handler;
+- dev->driver->irq_preinstall = valleyview_irq_preinstall;
+- dev->driver->irq_postinstall = valleyview_irq_postinstall;
+- dev->driver->irq_uninstall = valleyview_irq_uninstall;
+- dev->driver->enable_vblank = valleyview_enable_vblank;
+- dev->driver->disable_vblank = valleyview_disable_vblank;
++ *(void **)&dev->driver->irq_handler = valleyview_irq_handler;
++ *(void **)&dev->driver->irq_preinstall = valleyview_irq_preinstall;
++ *(void **)&dev->driver->irq_postinstall = valleyview_irq_postinstall;
++ *(void **)&dev->driver->irq_uninstall = valleyview_irq_uninstall;
++ *(void **)&dev->driver->enable_vblank = valleyview_enable_vblank;
++ *(void **)&dev->driver->disable_vblank = valleyview_disable_vblank;
+ dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
+ } else if (INTEL_INFO(dev_priv)->gen >= 8) {
+- dev->driver->irq_handler = gen8_irq_handler;
+- dev->driver->irq_preinstall = gen8_irq_reset;
+- dev->driver->irq_postinstall = gen8_irq_postinstall;
+- dev->driver->irq_uninstall = gen8_irq_uninstall;
+- dev->driver->enable_vblank = gen8_enable_vblank;
+- dev->driver->disable_vblank = gen8_disable_vblank;
++ *(void **)&dev->driver->irq_handler = gen8_irq_handler;
++ *(void **)&dev->driver->irq_preinstall = gen8_irq_reset;
++ *(void **)&dev->driver->irq_postinstall = gen8_irq_postinstall;
++ *(void **)&dev->driver->irq_uninstall = gen8_irq_uninstall;
++ *(void **)&dev->driver->enable_vblank = gen8_enable_vblank;
++ *(void **)&dev->driver->disable_vblank = gen8_disable_vblank;
+ if (HAS_PCH_SPLIT(dev))
+ dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup;
+ else
+ dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup;
+ } else if (HAS_PCH_SPLIT(dev)) {
+- dev->driver->irq_handler = ironlake_irq_handler;
+- dev->driver->irq_preinstall = ironlake_irq_reset;
+- dev->driver->irq_postinstall = ironlake_irq_postinstall;
+- dev->driver->irq_uninstall = ironlake_irq_uninstall;
+- dev->driver->enable_vblank = ironlake_enable_vblank;
+- dev->driver->disable_vblank = ironlake_disable_vblank;
++ *(void **)&dev->driver->irq_handler = ironlake_irq_handler;
++ *(void **)&dev->driver->irq_preinstall = ironlake_irq_reset;
++ *(void **)&dev->driver->irq_postinstall = ironlake_irq_postinstall;
++ *(void **)&dev->driver->irq_uninstall = ironlake_irq_uninstall;
++ *(void **)&dev->driver->enable_vblank = ironlake_enable_vblank;
++ *(void **)&dev->driver->disable_vblank = ironlake_disable_vblank;
+ dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup;
+ } else {
+ if (INTEL_INFO(dev_priv)->gen == 2) {
+- dev->driver->irq_preinstall = i8xx_irq_preinstall;
+- dev->driver->irq_postinstall = i8xx_irq_postinstall;
+- dev->driver->irq_handler = i8xx_irq_handler;
+- dev->driver->irq_uninstall = i8xx_irq_uninstall;
++ *(void **)&dev->driver->irq_preinstall = i8xx_irq_preinstall;
++ *(void **)&dev->driver->irq_postinstall = i8xx_irq_postinstall;
++ *(void **)&dev->driver->irq_handler = i8xx_irq_handler;
++ *(void **)&dev->driver->irq_uninstall = i8xx_irq_uninstall;
+ } else if (INTEL_INFO(dev_priv)->gen == 3) {
+- dev->driver->irq_preinstall = i915_irq_preinstall;
+- dev->driver->irq_postinstall = i915_irq_postinstall;
+- dev->driver->irq_uninstall = i915_irq_uninstall;
+- dev->driver->irq_handler = i915_irq_handler;
++ *(void **)&dev->driver->irq_preinstall = i915_irq_preinstall;
++ *(void **)&dev->driver->irq_postinstall = i915_irq_postinstall;
++ *(void **)&dev->driver->irq_uninstall = i915_irq_uninstall;
++ *(void **)&dev->driver->irq_handler = i915_irq_handler;
+ } else {
+- dev->driver->irq_preinstall = i965_irq_preinstall;
+- dev->driver->irq_postinstall = i965_irq_postinstall;
+- dev->driver->irq_uninstall = i965_irq_uninstall;
+- dev->driver->irq_handler = i965_irq_handler;
++ *(void **)&dev->driver->irq_preinstall = i965_irq_preinstall;
++ *(void **)&dev->driver->irq_postinstall = i965_irq_postinstall;
++ *(void **)&dev->driver->irq_uninstall = i965_irq_uninstall;
++ *(void **)&dev->driver->irq_handler = i965_irq_handler;
+ }
+ if (I915_HAS_HOTPLUG(dev_priv))
+ dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup;
+- dev->driver->enable_vblank = i915_enable_vblank;
+- dev->driver->disable_vblank = i915_disable_vblank;
++ *(void **)&dev->driver->enable_vblank = i915_enable_vblank;
++ *(void **)&dev->driver->disable_vblank = i915_disable_vblank;
+ }
++ pax_close_kernel();
+ }
+
+ /**
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b2270d5..e5c48fe 100644
--- a/drivers/gpu/drm/i915/intel_display.c
@@ -43108,8 +43695,24 @@ index 74f505b..21f6914 100644
return -EBUSY;
imx_drm_crtc = kzalloc(sizeof(*imx_drm_crtc), GFP_KERNEL);
+diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c
+index 5e2f131..d227dbc 100644
+--- a/drivers/gpu/drm/mga/mga_drv.c
++++ b/drivers/gpu/drm/mga/mga_drv.c
+@@ -92,7 +92,10 @@ static struct pci_driver mga_pci_driver = {
+
+ static int __init mga_init(void)
+ {
+- driver.num_ioctls = mga_max_ioctl;
++ pax_open_kernel();
++ *(int *)&driver.num_ioctls = mga_max_ioctl;
++ pax_close_kernel();
++
+ return drm_pci_init(&driver, &mga_pci_driver);
+ }
+
diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h
-index b4a20149..219ab78 100644
+index b4a20149..caa87d9 100644
--- a/drivers/gpu/drm/mga/mga_drv.h
+++ b/drivers/gpu/drm/mga/mga_drv.h
@@ -122,9 +122,9 @@ typedef struct drm_mga_private {
@@ -43124,6 +43727,15 @@ index b4a20149..219ab78 100644
u32 next_fence_to_post;
unsigned int fb_cpp;
+@@ -152,7 +152,7 @@ typedef struct drm_mga_private {
+ } drm_mga_private_t;
+
+ extern const struct drm_ioctl_desc mga_ioctls[];
+-extern int mga_max_ioctl;
++extern const int mga_max_ioctl;
+
+ /* mga_dma.c */
+ extern int mga_dma_bootstrap(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/mga/mga_ioc32.c b/drivers/gpu/drm/mga/mga_ioc32.c
index 729bfd5..14bae78 100644
--- a/drivers/gpu/drm/mga/mga_ioc32.c
@@ -43197,6 +43809,16 @@ index 1b071b8..de8601a 100644
- *sequence) <= (1 << 23)));
*sequence = cur_fence;
+diff --git a/drivers/gpu/drm/mga/mga_state.c b/drivers/gpu/drm/mga/mga_state.c
+index 792f924..aeb1334 100644
+--- a/drivers/gpu/drm/mga/mga_state.c
++++ b/drivers/gpu/drm/mga/mga_state.c
+@@ -1099,4 +1099,4 @@ const struct drm_ioctl_desc mga_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ };
+
+-int mga_max_ioctl = ARRAY_SIZE(mga_ioctls);
++const int mga_max_ioctl = ARRAY_SIZE(mga_ioctls);
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 4dca65a..3486961 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -43210,6 +43832,51 @@ index 4dca65a..3486961 100644
#define BIT_TABLE(id, funcid) ((struct bit_table){ id, parse_bit_##funcid##_tbl_entry })
+diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
+index ccefb64..a19593d 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
++++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
+@@ -76,7 +76,6 @@ MODULE_PARM_DESC(runpm, "disable (0), force enable (1), optimus only default (-1
+ int nouveau_runtime_pm = -1;
+ module_param_named(runpm, nouveau_runtime_pm, int, 0400);
+
+-static struct drm_driver driver_stub;
+ static struct drm_driver driver_pci;
+ static struct drm_driver driver_platform;
+
+@@ -917,7 +916,7 @@ nouveau_driver_fops = {
+ };
+
+ static struct drm_driver
+-driver_stub = {
++driver_pci = {
+ .driver_features =
+ DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_RENDER |
+ DRIVER_KMS_LEGACY_CONTEXT,
+@@ -929,6 +928,8 @@ driver_stub = {
+ .postclose = nouveau_drm_postclose,
+ .lastclose = nouveau_vga_lastclose,
+
++ .set_busid = drm_pci_set_busid,
++
+ #if defined(CONFIG_DEBUG_FS)
+ .debugfs_init = nouveau_debugfs_init,
+ .debugfs_cleanup = nouveau_debugfs_takedown,
+@@ -1065,10 +1066,10 @@ err_free:
+ static int __init
+ nouveau_drm_init(void)
+ {
+- driver_pci = driver_stub;
+- driver_pci.set_busid = drm_pci_set_busid;
+- driver_platform = driver_stub;
+- driver_platform.set_busid = drm_platform_set_busid;
++ pax_open_kernel();
++ memcpy((void *)&driver_platform, &driver_pci, sizeof driver_pci);
++ *(void **)&driver_platform.set_busid = drm_platform_set_busid;
++ pax_close_kernel();
+
+ nouveau_display_options();
+
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h
index 3c902c2..1b2d658 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.h
@@ -43371,6 +44038,32 @@ index 6911b8c..89d6867 100644
seq_printf(m, "%d\n", qdev->irq_received_error);
return 0;
}
+diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c
+index 83f6f0b..0d36693 100644
+--- a/drivers/gpu/drm/qxl/qxl_drv.c
++++ b/drivers/gpu/drm/qxl/qxl_drv.c
+@@ -37,7 +37,7 @@
+ #include "qxl_drv.h"
+ #include "qxl_object.h"
+
+-extern int qxl_max_ioctls;
++extern const int qxl_max_ioctls;
+ static const struct pci_device_id pciidlist[] = {
+ { 0x1b36, 0x100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8,
+ 0xffff00, 0 },
+@@ -278,7 +278,11 @@ static int __init qxl_init(void)
+
+ if (qxl_modeset == 0)
+ return -EINVAL;
+- qxl_driver.num_ioctls = qxl_max_ioctls;
++
++ pax_open_kernel();
++ *(int *)&qxl_driver.num_ioctls = qxl_max_ioctls;
++ pax_close_kernel();
++
+ return drm_pci_init(&qxl_driver, &qxl_pci_driver);
+ }
+
diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h
index 01a8694..584fb48 100644
--- a/drivers/gpu/drm/qxl/qxl_drv.h
@@ -43391,7 +44084,7 @@ index 01a8694..584fb48 100644
wait_queue_head_t display_event;
wait_queue_head_t cursor_event;
diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
-index bda5c5f..140ac46 100644
+index bda5c5f..aa09e3e 100644
--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
+++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
@@ -183,7 +183,7 @@ static int qxl_process_single_command(struct qxl_device *qdev,
@@ -43426,6 +44119,12 @@ index bda5c5f..140ac46 100644
sizeof(user_cmd)))
return -EFAULT;
+@@ -439,4 +439,4 @@ const struct drm_ioctl_desc qxl_ioctls[] = {
+ DRM_AUTH|DRM_UNLOCKED),
+ };
+
+-int qxl_max_ioctls = ARRAY_SIZE(qxl_ioctls);
++const int qxl_max_ioctls = ARRAY_SIZE(qxl_ioctls);
diff --git a/drivers/gpu/drm/qxl/qxl_irq.c b/drivers/gpu/drm/qxl/qxl_irq.c
index 0bf1e20..42a7310 100644
--- a/drivers/gpu/drm/qxl/qxl_irq.c
@@ -43547,8 +44246,23 @@ index 2c45ac9..5d740f8 100644
/* We don't support anything other than bus-mastering ring mode,
* but the ring can be in either AGP or PCI space for the ring
+diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c
+index c57b4de..2614d79 100644
+--- a/drivers/gpu/drm/r128/r128_drv.c
++++ b/drivers/gpu/drm/r128/r128_drv.c
+@@ -94,7 +94,9 @@ static struct pci_driver r128_pci_driver = {
+
+ static int __init r128_init(void)
+ {
+- driver.num_ioctls = r128_max_ioctl;
++ pax_open_kernel();
++ *(int *)&driver.num_ioctls = r128_max_ioctl;
++ pax_close_kernel();
+
+ return drm_pci_init(&driver, &r128_pci_driver);
+ }
diff --git a/drivers/gpu/drm/r128/r128_drv.h b/drivers/gpu/drm/r128/r128_drv.h
-index 723e5d6..102dbaf 100644
+index 723e5d6..6efb284 100644
--- a/drivers/gpu/drm/r128/r128_drv.h
+++ b/drivers/gpu/drm/r128/r128_drv.h
@@ -93,14 +93,14 @@ typedef struct drm_r128_private {
@@ -43568,6 +44282,15 @@ index 723e5d6..102dbaf 100644
u32 color_fmt;
unsigned int front_offset;
+@@ -135,7 +135,7 @@ typedef struct drm_r128_buf_priv {
+ } drm_r128_buf_priv_t;
+
+ extern const struct drm_ioctl_desc r128_ioctls[];
+-extern int r128_max_ioctl;
++extern const int r128_max_ioctl;
+
+ /* r128_cce.c */
+ extern int r128_cce_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
diff --git a/drivers/gpu/drm/r128/r128_ioc32.c b/drivers/gpu/drm/r128/r128_ioc32.c
index 663f38c..ec159a1 100644
--- a/drivers/gpu/drm/r128/r128_ioc32.c
@@ -43624,7 +44347,7 @@ index c2ae496..30b5993 100644
return IRQ_HANDLED;
}
diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c
-index 8fd2d9f..18c9660 100644
+index 8fd2d9f..4e99166 100644
--- a/drivers/gpu/drm/r128/r128_state.c
+++ b/drivers/gpu/drm/r128/r128_state.c
@@ -320,10 +320,10 @@ static void r128_clear_box(drm_r128_private_t *dev_priv,
@@ -43640,6 +44363,12 @@ index 8fd2d9f..18c9660 100644
}
#endif
+@@ -1641,4 +1641,4 @@ const struct drm_ioctl_desc r128_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(R128_GETPARAM, r128_getparam, DRM_AUTH),
+ };
+
+-int r128_max_ioctl = ARRAY_SIZE(r128_ioctls);
++const int r128_max_ioctl = ARRAY_SIZE(r128_ioctls);
diff --git a/drivers/gpu/drm/radeon/mkregtable.c b/drivers/gpu/drm/radeon/mkregtable.c
index b928c17..e5d9400 100644
--- a/drivers/gpu/drm/radeon/mkregtable.c
@@ -43674,8 +44403,50 @@ index f3f562f..0c099bb 100644
}
static const struct vga_switcheroo_client_ops radeon_switcheroo_ops = {
+diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
+index 5751446..f39a861 100644
+--- a/drivers/gpu/drm/radeon/radeon_drv.c
++++ b/drivers/gpu/drm/radeon/radeon_drv.c
+@@ -130,7 +130,7 @@ extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc,
+ ktime_t *etime);
+ extern bool radeon_is_px(struct drm_device *dev);
+ extern const struct drm_ioctl_desc radeon_ioctls_kms[];
+-extern int radeon_max_kms_ioctl;
++extern const int radeon_max_kms_ioctl;
+ int radeon_mmap(struct file *filp, struct vm_area_struct *vma);
+ int radeon_mode_dumb_mmap(struct drm_file *filp,
+ struct drm_device *dev,
+@@ -650,8 +650,12 @@ static int __init radeon_init(void)
+ DRM_INFO("radeon kernel modesetting enabled.\n");
+ driver = &kms_driver;
+ pdriver = &radeon_kms_pci_driver;
+- driver->driver_features |= DRIVER_MODESET;
+- driver->num_ioctls = radeon_max_kms_ioctl;
++
++ pax_open_kernel();
++ *(u32 *)&driver->driver_features |= DRIVER_MODESET;
++ *(int *)&driver->num_ioctls = radeon_max_kms_ioctl;
++ pax_close_kernel();
++
+ radeon_register_atpx_handler();
+
+ } else {
+@@ -659,8 +663,11 @@ static int __init radeon_init(void)
+ DRM_INFO("radeon userspace modesetting enabled.\n");
+ driver = &driver_old;
+ pdriver = &radeon_pci_driver;
+- driver->driver_features &= ~DRIVER_MODESET;
+- driver->num_ioctls = radeon_max_ioctl;
++
++ pax_open_kernel();
++ *(u32 *)&driver->driver_features &= ~DRIVER_MODESET;
++ *(int *)&driver->num_ioctls = radeon_max_ioctl;
++ pax_close_kernel();
+ #else
+ DRM_ERROR("No UMS support in radeon module!\n");
+ return -EINVAL;
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
-index 46bd393..6ae4719 100644
+index 46bd393..8f077b5 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.h
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -264,7 +264,7 @@ typedef struct drm_radeon_private {
@@ -43687,6 +44458,15 @@ index 46bd393..6ae4719 100644
int vblank_crtc;
uint32_t irq_enable_reg;
uint32_t r500_disp_irq_reg;
+@@ -336,7 +336,7 @@ typedef struct drm_radeon_kcmd_buffer {
+
+ extern int radeon_no_wb;
+ extern struct drm_ioctl_desc radeon_ioctls[];
+-extern int radeon_max_ioctl;
++extern const int radeon_max_ioctl;
+
+ extern u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv);
+ extern void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val);
diff --git a/drivers/gpu/drm/radeon/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c
index 0b98ea1..a3c770f 100644
--- a/drivers/gpu/drm/radeon/radeon_ioc32.c
@@ -43753,8 +44533,18 @@ index 244b19b..c19226d 100644
init_waitqueue_head(&dev_priv->swi_queue);
dev->max_vblank_count = 0x001fffff;
+diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
+index 0e932bf..3de01a7 100644
+--- a/drivers/gpu/drm/radeon/radeon_kms.c
++++ b/drivers/gpu/drm/radeon/radeon_kms.c
+@@ -932,4 +932,4 @@ const struct drm_ioctl_desc radeon_ioctls_kms[] = {
+ DRM_IOCTL_DEF_DRV(RADEON_GEM_OP, radeon_gem_op_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(RADEON_GEM_USERPTR, radeon_gem_userptr_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW),
+ };
+-int radeon_max_kms_ioctl = ARRAY_SIZE(radeon_ioctls_kms);
++const int radeon_max_kms_ioctl = ARRAY_SIZE(radeon_ioctls_kms);
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c
-index 15aee72..cda326e 100644
+index 15aee72..c6df119 100644
--- a/drivers/gpu/drm/radeon/radeon_state.c
+++ b/drivers/gpu/drm/radeon/radeon_state.c
@@ -2168,7 +2168,7 @@ static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *
@@ -43775,6 +44565,12 @@ index 15aee72..cda326e 100644
DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
+@@ -3258,4 +3258,4 @@ struct drm_ioctl_desc radeon_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH)
+ };
+
+-int radeon_max_ioctl = ARRAY_SIZE(radeon_ioctls);
++const int radeon_max_ioctl = ARRAY_SIZE(radeon_ioctls);
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 06ac59fe..57e0681 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -43799,6 +44595,83 @@ index 06ac59fe..57e0681 100644
}
vma->vm_ops = &radeon_ttm_vm_ops;
return 0;
+diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c
+index d47dff9..0752202 100644
+--- a/drivers/gpu/drm/savage/savage_bci.c
++++ b/drivers/gpu/drm/savage/savage_bci.c
+@@ -1080,4 +1080,4 @@ const struct drm_ioctl_desc savage_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(SAVAGE_BCI_EVENT_WAIT, savage_bci_event_wait, DRM_AUTH),
+ };
+
+-int savage_max_ioctl = ARRAY_SIZE(savage_ioctls);
++const int savage_max_ioctl = ARRAY_SIZE(savage_ioctls);
+diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c
+index 21aed1f..5db7419 100644
+--- a/drivers/gpu/drm/savage/savage_drv.c
++++ b/drivers/gpu/drm/savage/savage_drv.c
+@@ -76,7 +76,10 @@ static struct pci_driver savage_pci_driver = {
+
+ static int __init savage_init(void)
+ {
+- driver.num_ioctls = savage_max_ioctl;
++ pax_open_kernel();
++ *(int *)&driver.num_ioctls = savage_max_ioctl;
++ pax_close_kernel();
++
+ return drm_pci_init(&driver, &savage_pci_driver);
+ }
+
+diff --git a/drivers/gpu/drm/savage/savage_drv.h b/drivers/gpu/drm/savage/savage_drv.h
+index 37b6995..9b31aaf 100644
+--- a/drivers/gpu/drm/savage/savage_drv.h
++++ b/drivers/gpu/drm/savage/savage_drv.h
+@@ -107,7 +107,7 @@ enum savage_family {
+ };
+
+ extern const struct drm_ioctl_desc savage_ioctls[];
+-extern int savage_max_ioctl;
++extern const int savage_max_ioctl;
+
+ #define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX))
+
+diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c
+index 79bce76..4fd9a20 100644
+--- a/drivers/gpu/drm/sis/sis_drv.c
++++ b/drivers/gpu/drm/sis/sis_drv.c
+@@ -128,7 +128,10 @@ static struct pci_driver sis_pci_driver = {
+
+ static int __init sis_init(void)
+ {
+- driver.num_ioctls = sis_max_ioctl;
++ pax_open_kernel();
++ *(int *)&driver.num_ioctls = sis_max_ioctl;
++ pax_close_kernel();
++
+ return drm_pci_init(&driver, &sis_pci_driver);
+ }
+
+diff --git a/drivers/gpu/drm/sis/sis_drv.h b/drivers/gpu/drm/sis/sis_drv.h
+index 16f972b..4f46125 100644
+--- a/drivers/gpu/drm/sis/sis_drv.h
++++ b/drivers/gpu/drm/sis/sis_drv.h
+@@ -73,6 +73,6 @@ extern void sis_reclaim_buffers_locked(struct drm_device *dev,
+ extern void sis_lastclose(struct drm_device *dev);
+
+ extern const struct drm_ioctl_desc sis_ioctls[];
+-extern int sis_max_ioctl;
++extern const int sis_max_ioctl;
+
+ #endif
+diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c
+index 93ad8a5..48f0a57 100644
+--- a/drivers/gpu/drm/sis/sis_mm.c
++++ b/drivers/gpu/drm/sis/sis_mm.c
+@@ -359,4 +359,4 @@ const struct drm_ioctl_desc sis_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(SIS_FB_INIT, sis_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
+ };
+
+-int sis_max_ioctl = ARRAY_SIZE(sis_ioctls);
++const int sis_max_ioctl = ARRAY_SIZE(sis_ioctls);
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index ddefb85..9011500 100644
--- a/drivers/gpu/drm/tegra/dc.c
@@ -44080,8 +44953,34 @@ index 62c7b1d..2018818 100644
}
pr_warn("released /dev/fb%d user=%d count=%d\n",
+diff --git a/drivers/gpu/drm/via/via_dma.c b/drivers/gpu/drm/via/via_dma.c
+index d17d8f2..67e8e48b 100644
+--- a/drivers/gpu/drm/via/via_dma.c
++++ b/drivers/gpu/drm/via/via_dma.c
+@@ -737,4 +737,4 @@ const struct drm_ioctl_desc via_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH)
+ };
+
+-int via_max_ioctl = ARRAY_SIZE(via_ioctls);
++const int via_max_ioctl = ARRAY_SIZE(via_ioctls);
+diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c
+index ed8aa8f..16c84fc 100644
+--- a/drivers/gpu/drm/via/via_drv.c
++++ b/drivers/gpu/drm/via/via_drv.c
+@@ -107,7 +107,10 @@ static struct pci_driver via_pci_driver = {
+
+ static int __init via_init(void)
+ {
+- driver.num_ioctls = via_max_ioctl;
++ pax_open_kernel();
++ *(int *)&driver.num_ioctls = via_max_ioctl;
++ pax_close_kernel();
++
+ via_init_command_verifier();
+ return drm_pci_init(&driver, &via_pci_driver);
+ }
diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h
-index ef8c500..01030c8 100644
+index ef8c500..e0053ce 100644
--- a/drivers/gpu/drm/via/via_drv.h
+++ b/drivers/gpu/drm/via/via_drv.h
@@ -53,7 +53,7 @@ typedef struct drm_via_ring_buffer {
@@ -44102,6 +45001,15 @@ index ef8c500..01030c8 100644
drm_via_state_t hc_state;
char pci_buf[VIA_PCI_BUF_SIZE];
const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
+@@ -117,7 +117,7 @@ enum via_family {
+ #define VIA_WRITE8(reg, val) DRM_WRITE8(VIA_BASE, reg, val)
+
+ extern const struct drm_ioctl_desc via_ioctls[];
+-extern int via_max_ioctl;
++extern const int via_max_ioctl;
+
+ extern int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
+ extern int via_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv);
diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c
index 1319433..a993b0c 100644
--- a/drivers/gpu/drm/via/via_irq.c
@@ -51351,6 +52259,60 @@ index 445071c..6be9e60 100644
.kind = "geneve",
.maxtype = IFLA_GENEVE_MAX,
.policy = geneve_policy,
+diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
+index 7c4a415..5a1e985 100644
+--- a/drivers/net/hamradio/6pack.c
++++ b/drivers/net/hamradio/6pack.c
+@@ -683,14 +683,20 @@ static void sixpack_close(struct tty_struct *tty)
+ if (!atomic_dec_and_test(&sp->refcnt))
+ down(&sp->dead_sem);
+
+- unregister_netdev(sp->dev);
++ /* We must stop the queue to avoid potentially scribbling
++ * on the free buffers. The sp->dead_sem is not sufficient
++ * to protect us from sp->xbuff access.
++ */
++ netif_stop_queue(sp->dev);
+
+- del_timer(&sp->tx_t);
+- del_timer(&sp->resync_t);
++ del_timer_sync(&sp->tx_t);
++ del_timer_sync(&sp->resync_t);
+
+ /* Free all 6pack frame buffers. */
+ kfree(sp->rbuff);
+ kfree(sp->xbuff);
++
++ unregister_netdev(sp->dev);
+ }
+
+ /* Perform I/O control on an active 6pack channel. */
+diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
+index 216bfd3..85828f1 100644
+--- a/drivers/net/hamradio/mkiss.c
++++ b/drivers/net/hamradio/mkiss.c
+@@ -797,14 +797,19 @@ static void mkiss_close(struct tty_struct *tty)
+ */
+ if (!atomic_dec_and_test(&ax->refcnt))
+ down(&ax->dead_sem);
+-
+- unregister_netdev(ax->dev);
++ /*
++ * Halt the transmit queue so that a new transmit cannot scribble
++ * on our buffers
++ */
++ netif_stop_queue(ax->dev);
+
+ /* Free all AX25 frame buffers. */
+ kfree(ax->rbuff);
+ kfree(ax->xbuff);
+
+ ax->tty = NULL;
++
++ unregister_netdev(ax->dev);
+ }
+
+ /* Perform I/O control on an active ax25 channel. */
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 5fa98f5..322f0f8 100644
--- a/drivers/net/hyperv/hyperv_net.h
@@ -80831,7 +81793,7 @@ index 14db05d..687f6d8 100644
#define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
diff --git a/fs/namei.c b/fs/namei.c
-index 33e9495..0c1096b 100644
+index 33e9495..4b9d9fb 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -336,17 +336,32 @@ int generic_permission(struct inode *inode, int mask)
@@ -81111,17 +82073,7 @@ index 33e9495..0c1096b 100644
}
out_no_open:
path->dentry = dentry;
-@@ -3066,6 +3187,9 @@ static int do_last(struct nameidata *nd,
- if (error)
- return error;
-
-+ if (!gr_acl_handle_hidden_file(dir, nd->path.mnt))
-+ return -ENOENT;
-+
- audit_inode(nd->name, dir, LOOKUP_PARENT);
- /* trailing slashes? */
- if (unlikely(nd->last.name[nd->last.len]))
-@@ -3108,11 +3232,24 @@ retry_lookup:
+@@ -3108,11 +3229,24 @@ retry_lookup:
goto finish_open_created;
}
@@ -81147,7 +82099,7 @@ index 33e9495..0c1096b 100644
/*
* If atomic_open() acquired write access it is dropped now due to
-@@ -3148,6 +3285,11 @@ finish_lookup:
+@@ -3148,6 +3282,11 @@ finish_lookup:
if (unlikely(error))
return error;
@@ -81159,7 +82111,7 @@ index 33e9495..0c1096b 100644
if (unlikely(d_is_symlink(path.dentry)) && !(open_flag & O_PATH)) {
path_to_nameidata(&path, nd);
return -ELOOP;
-@@ -3170,6 +3312,12 @@ finish_open:
+@@ -3170,6 +3309,12 @@ finish_open:
path_put(&save_parent);
return error;
}
@@ -81172,7 +82124,7 @@ index 33e9495..0c1096b 100644
audit_inode(nd->name, nd->path.dentry, 0);
error = -EISDIR;
if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry))
-@@ -3436,9 +3584,11 @@ static struct dentry *filename_create(int dfd, struct filename *name,
+@@ -3436,9 +3581,11 @@ static struct dentry *filename_create(int dfd, struct filename *name,
goto unlock;
error = -EEXIST;
@@ -81186,7 +82138,7 @@ index 33e9495..0c1096b 100644
/*
* Special case - lookup gave negative, but... we had foo/bar/
* From the vfs_mknod() POV we just have a negative dentry -
-@@ -3492,6 +3642,20 @@ inline struct dentry *user_path_create(int dfd, const char __user *pathname,
+@@ -3492,6 +3639,20 @@ inline struct dentry *user_path_create(int dfd, const char __user *pathname,
}
EXPORT_SYMBOL(user_path_create);
@@ -81207,7 +82159,7 @@ index 33e9495..0c1096b 100644
int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
{
int error = may_create(dir, dentry);
-@@ -3555,6 +3719,17 @@ retry:
+@@ -3555,6 +3716,17 @@ retry:
if (!IS_POSIXACL(path.dentry->d_inode))
mode &= ~current_umask();
@@ -81225,7 +82177,7 @@ index 33e9495..0c1096b 100644
error = security_path_mknod(&path, dentry, mode, dev);
if (error)
goto out;
-@@ -3570,6 +3745,8 @@ retry:
+@@ -3570,6 +3742,8 @@ retry:
error = vfs_mknod(path.dentry->d_inode,dentry,mode,0);
break;
}
@@ -81234,7 +82186,7 @@ index 33e9495..0c1096b 100644
out:
done_path_create(&path, dentry);
if (retry_estale(error, lookup_flags)) {
-@@ -3624,9 +3801,16 @@ retry:
+@@ -3624,9 +3798,16 @@ retry:
if (!IS_POSIXACL(path.dentry->d_inode))
mode &= ~current_umask();
@@ -81251,7 +82203,7 @@ index 33e9495..0c1096b 100644
done_path_create(&path, dentry);
if (retry_estale(error, lookup_flags)) {
lookup_flags |= LOOKUP_REVAL;
-@@ -3659,7 +3843,7 @@ void dentry_unhash(struct dentry *dentry)
+@@ -3659,7 +3840,7 @@ void dentry_unhash(struct dentry *dentry)
{
shrink_dcache_parent(dentry);
spin_lock(&dentry->d_lock);
@@ -81260,7 +82212,7 @@ index 33e9495..0c1096b 100644
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
}
-@@ -3712,6 +3896,8 @@ static long do_rmdir(int dfd, const char __user *pathname)
+@@ -3712,6 +3893,8 @@ static long do_rmdir(int dfd, const char __user *pathname)
struct path path;
struct qstr last;
int type;
@@ -81269,7 +82221,7 @@ index 33e9495..0c1096b 100644
unsigned int lookup_flags = 0;
retry:
name = user_path_parent(dfd, pathname,
-@@ -3744,10 +3930,20 @@ retry:
+@@ -3744,10 +3927,20 @@ retry:
error = -ENOENT;
goto exit3;
}
@@ -81290,7 +82242,7 @@ index 33e9495..0c1096b 100644
exit3:
dput(dentry);
exit2:
-@@ -3842,6 +4038,8 @@ static long do_unlinkat(int dfd, const char __user *pathname)
+@@ -3842,6 +4035,8 @@ static long do_unlinkat(int dfd, const char __user *pathname)
int type;
struct inode *inode = NULL;
struct inode *delegated_inode = NULL;
@@ -81299,7 +82251,7 @@ index 33e9495..0c1096b 100644
unsigned int lookup_flags = 0;
retry:
name = user_path_parent(dfd, pathname,
-@@ -3868,10 +4066,21 @@ retry_deleg:
+@@ -3868,10 +4063,21 @@ retry_deleg:
if (d_is_negative(dentry))
goto slashes;
ihold(inode);
@@ -81321,7 +82273,7 @@ index 33e9495..0c1096b 100644
exit2:
dput(dentry);
}
-@@ -3960,9 +4169,17 @@ retry:
+@@ -3960,9 +4166,17 @@ retry:
if (IS_ERR(dentry))
goto out_putname;
@@ -81339,7 +82291,7 @@ index 33e9495..0c1096b 100644
done_path_create(&path, dentry);
if (retry_estale(error, lookup_flags)) {
lookup_flags |= LOOKUP_REVAL;
-@@ -4066,6 +4283,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
+@@ -4066,6 +4280,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
struct dentry *new_dentry;
struct path old_path, new_path;
struct inode *delegated_inode = NULL;
@@ -81347,7 +82299,7 @@ index 33e9495..0c1096b 100644
int how = 0;
int error;
-@@ -4089,7 +4307,7 @@ retry:
+@@ -4089,7 +4304,7 @@ retry:
if (error)
return error;
@@ -81356,7 +82308,7 @@ index 33e9495..0c1096b 100644
(how & LOOKUP_REVAL));
error = PTR_ERR(new_dentry);
if (IS_ERR(new_dentry))
-@@ -4101,11 +4319,26 @@ retry:
+@@ -4101,11 +4316,26 @@ retry:
error = may_linkat(&old_path);
if (unlikely(error))
goto out_dput;
@@ -81383,7 +82335,7 @@ index 33e9495..0c1096b 100644
done_path_create(&new_path, new_dentry);
if (delegated_inode) {
error = break_deleg_wait(&delegated_inode);
-@@ -4420,6 +4653,20 @@ retry_deleg:
+@@ -4420,6 +4650,20 @@ retry_deleg:
if (new_dentry == trap)
goto exit5;
@@ -81404,7 +82356,7 @@ index 33e9495..0c1096b 100644
error = security_path_rename(&old_path, old_dentry,
&new_path, new_dentry, flags);
if (error)
-@@ -4427,6 +4674,9 @@ retry_deleg:
+@@ -4427,6 +4671,9 @@ retry_deleg:
error = vfs_rename(old_path.dentry->d_inode, old_dentry,
new_path.dentry->d_inode, new_dentry,
&delegated_inode, flags);
@@ -81414,7 +82366,7 @@ index 33e9495..0c1096b 100644
exit5:
dput(new_dentry);
exit4:
-@@ -4483,14 +4733,24 @@ EXPORT_SYMBOL(vfs_whiteout);
+@@ -4483,14 +4730,24 @@ EXPORT_SYMBOL(vfs_whiteout);
int readlink_copy(char __user *buffer, int buflen, const char *link)
{
@@ -83243,7 +84195,7 @@ index 50493ed..248166b 100644
}
fs_initcall(proc_devices_init);
diff --git a/fs/proc/fd.c b/fs/proc/fd.c
-index 6e5fcd0..06ea074 100644
+index 6e5fcd0..3841f4e 100644
--- a/fs/proc/fd.c
+++ b/fs/proc/fd.c
@@ -27,7 +27,8 @@ static int seq_show(struct seq_file *m, void *v)
@@ -83256,7 +84208,15 @@ index 6e5fcd0..06ea074 100644
put_task_struct(task);
if (files) {
-@@ -291,11 +292,21 @@ static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
+@@ -258,6 +259,7 @@ static int proc_readfd_common(struct file *file, struct dir_context *ctx,
+ name, len, instantiate, p,
+ (void *)(unsigned long)fd))
+ goto out_fd_loop;
++ cond_resched();
+ rcu_read_lock();
+ }
+ rcu_read_unlock();
+@@ -291,11 +293,21 @@ static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry,
*/
int proc_fd_permission(struct inode *inode, int mask)
{
@@ -95423,10 +96383,10 @@ index 0000000..304c518
+}
diff --git a/grsecurity/grsec_sig.c b/grsecurity/grsec_sig.c
new file mode 100644
-index 0000000..3860c7e
+index 0000000..1e6f893
--- /dev/null
+++ b/grsecurity/grsec_sig.c
-@@ -0,0 +1,236 @@
+@@ -0,0 +1,243 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
@@ -95581,6 +96541,7 @@ index 0000000..3860c7e
+void gr_handle_kernel_exploit(void)
+{
+#ifdef CONFIG_GRKERNSEC_KERN_LOCKOUT
++ static unsigned int num_banned_users __read_only;
+ const struct cred *cred;
+ struct task_struct *tsk, *tsk2;
+ struct user_struct *user;
@@ -95594,6 +96555,12 @@ index 0000000..3860c7e
+ if (gr_is_global_root(uid))
+ panic("grsec: halting the system due to suspicious kernel crash caused by root");
+ else {
++ pax_open_kernel();
++ num_banned_users++;
++ pax_close_kernel();
++ if (num_banned_users > 8)
++ panic("grsec: halting the system due to suspicious kernel crash caused by a large number of different users");
++
+ /* kill all the processes of this user, hold a reference
+ to their creds struct, and prevent them from creating
+ another process until system reset
@@ -97263,7 +98230,7 @@ index c9fe145..9fb2337 100644
struct crypto_instance {
struct crypto_alg alg;
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
-index 8b5ce7c..984979b 100644
+index 8b5ce7c..a0ee191 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -59,6 +59,7 @@
@@ -97301,6 +98268,15 @@ index 8b5ce7c..984979b 100644
/**
* Creates a driver or general drm_ioctl_desc array entry for the given
+@@ -630,7 +633,7 @@ struct drm_driver {
+
+ /* List of devices hanging off this driver with stealth attach. */
+ struct list_head legacy_dev_list;
+-};
++} __do_const;
+
+ enum drm_minor_type {
+ DRM_MINOR_LEGACY,
@@ -648,7 +651,8 @@ struct drm_info_list {
int (*show)(struct seq_file*, void*); /** show callback */
u32 driver_features; /**< Required driver features for this entry */
@@ -98459,6 +99435,36 @@ index 674e3e2..f68af19 100644
void do_close_on_exec(struct files_struct *);
int iterate_fd(struct files_struct *, unsigned,
int (*)(const void *, struct file *, unsigned),
+diff --git a/include/linux/filter.h b/include/linux/filter.h
+index fa2cab9..d42a5b8 100644
+--- a/include/linux/filter.h
++++ b/include/linux/filter.h
+@@ -459,6 +459,25 @@ static inline void bpf_jit_free(struct bpf_prog *fp)
+
+ #define BPF_ANC BIT(15)
+
++static inline bool bpf_needs_clear_a(const struct sock_filter *first)
++{
++ switch (first->code) {
++ case BPF_RET | BPF_K:
++ case BPF_LD | BPF_W | BPF_LEN:
++ return false;
++
++ case BPF_LD | BPF_W | BPF_ABS:
++ case BPF_LD | BPF_H | BPF_ABS:
++ case BPF_LD | BPF_B | BPF_ABS:
++ if (first->k == SKF_AD_OFF + SKF_AD_ALU_XOR_X)
++ return true;
++ return false;
++
++ default:
++ return true;
++ }
++}
++
+ static inline u16 bpf_anc_helper(const struct sock_filter *ftest)
+ {
+ BUG_ON(ftest->code & BPF_ANC);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 72d8a84..4027250 100644
--- a/include/linux/fs.h
@@ -98630,6 +99636,18 @@ index 7ee1774..72505b8 100644
}
/*
+diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
+index 6cd8c0e..47420d4 100644
+--- a/include/linux/ftrace.h
++++ b/include/linux/ftrace.h
+@@ -575,6 +575,7 @@ extern int ftrace_arch_read_dyn_info(char *buf, int size);
+
+ extern int skip_trace(unsigned long ip);
+ extern void ftrace_module_init(struct module *mod);
++extern void ftrace_release_mod(struct module *mod);
+
+ extern void ftrace_disable_daemon(void);
+ extern void ftrace_enable_daemon(void);
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 2adbfa6..abfd2e6 100644
--- a/include/linux/genhd.h
@@ -102292,7 +103310,7 @@ index 556ec1e..38c19c9 100644
/*
diff --git a/include/linux/sched.h b/include/linux/sched.h
-index b7b9501..dc6b96f 100644
+index b7b9501..46d7e52 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -7,7 +7,7 @@
@@ -102359,7 +103377,14 @@ index b7b9501..dc6b96f 100644
/*
* Bits in flags field of signal_struct.
-@@ -836,6 +861,14 @@ struct user_struct {
+@@ -830,12 +855,21 @@ struct user_struct {
+ unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */
+ #endif
+ unsigned long locked_shm; /* How many pages of mlocked shm ? */
++ unsigned long unix_inflight; /* How many files in flight in unix sockets */
+
+ #ifdef CONFIG_KEYS
+ struct key *uid_keyring; /* UID specific keyring */
struct key *session_keyring; /* UID's default session keyring */
#endif
@@ -102374,7 +103399,7 @@ index b7b9501..dc6b96f 100644
/* Hash table maintenance information */
struct hlist_node uidhash_node;
kuid_t uid;
-@@ -843,7 +876,7 @@ struct user_struct {
+@@ -843,7 +877,7 @@ struct user_struct {
#ifdef CONFIG_PERF_EVENTS
atomic_long_t locked_vm;
#endif
@@ -102383,7 +103408,7 @@ index b7b9501..dc6b96f 100644
extern int uids_sysfs_init(void);
-@@ -1378,6 +1411,9 @@ struct tlbflush_unmap_batch {
+@@ -1378,6 +1412,9 @@ struct tlbflush_unmap_batch {
struct task_struct {
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
void *stack;
@@ -102393,7 +103418,7 @@ index b7b9501..dc6b96f 100644
atomic_t usage;
unsigned int flags; /* per process flags, defined below */
unsigned int ptrace;
-@@ -1510,8 +1546,8 @@ struct task_struct {
+@@ -1510,8 +1547,8 @@ struct task_struct {
struct list_head thread_node;
struct completion *vfork_done; /* for vfork() */
@@ -102404,7 +103429,7 @@ index b7b9501..dc6b96f 100644
cputime_t utime, stime, utimescaled, stimescaled;
cputime_t gtime;
-@@ -1534,11 +1570,6 @@ struct task_struct {
+@@ -1534,11 +1571,6 @@ struct task_struct {
struct task_cputime cputime_expires;
struct list_head cpu_timers[3];
@@ -102416,7 +103441,7 @@ index b7b9501..dc6b96f 100644
char comm[TASK_COMM_LEN]; /* executable name excluding path
- access with [gs]et_task_comm (which lock
it with task_lock())
-@@ -1554,6 +1585,8 @@ struct task_struct {
+@@ -1554,6 +1586,8 @@ struct task_struct {
/* hung task detection */
unsigned long last_switch_count;
#endif
@@ -102425,7 +103450,7 @@ index b7b9501..dc6b96f 100644
/* filesystem information */
struct fs_struct *fs;
/* open file information */
-@@ -1630,6 +1663,10 @@ struct task_struct {
+@@ -1630,6 +1664,10 @@ struct task_struct {
gfp_t lockdep_reclaim_gfp;
#endif
@@ -102436,7 +103461,7 @@ index b7b9501..dc6b96f 100644
/* journalling filesystem info */
void *journal_info;
-@@ -1668,6 +1705,10 @@ struct task_struct {
+@@ -1668,6 +1706,10 @@ struct task_struct {
/* cg_list protected by css_set_lock and tsk->alloc_lock */
struct list_head cg_list;
#endif
@@ -102447,7 +103472,7 @@ index b7b9501..dc6b96f 100644
#ifdef CONFIG_FUTEX
struct robust_list_head __user *robust_list;
#ifdef CONFIG_COMPAT
-@@ -1783,7 +1824,7 @@ struct task_struct {
+@@ -1783,7 +1825,7 @@ struct task_struct {
* Number of functions that haven't been traced
* because of depth overrun.
*/
@@ -102456,7 +103481,7 @@ index b7b9501..dc6b96f 100644
/* Pause for the tracing */
atomic_t tracing_graph_pause;
#endif
-@@ -1812,22 +1853,89 @@ struct task_struct {
+@@ -1812,22 +1854,89 @@ struct task_struct {
unsigned long task_state_change;
#endif
int pagefault_disabled;
@@ -102556,7 +103581,7 @@ index b7b9501..dc6b96f 100644
/* Future-safe accessor for struct task_struct's cpus_allowed. */
#define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed)
-@@ -1909,7 +2017,7 @@ struct pid_namespace;
+@@ -1909,7 +2018,7 @@ struct pid_namespace;
pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
struct pid_namespace *ns);
@@ -102565,7 +103590,7 @@ index b7b9501..dc6b96f 100644
{
return tsk->pid;
}
-@@ -2270,6 +2378,25 @@ extern u64 sched_clock_cpu(int cpu);
+@@ -2270,6 +2379,25 @@ extern u64 sched_clock_cpu(int cpu);
extern void sched_clock_init(void);
@@ -102591,7 +103616,7 @@ index b7b9501..dc6b96f 100644
#ifndef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK
static inline void sched_clock_tick(void)
{
-@@ -2398,7 +2525,9 @@ extern void set_curr_task(int cpu, struct task_struct *p);
+@@ -2398,7 +2526,9 @@ extern void set_curr_task(int cpu, struct task_struct *p);
void yield(void);
union thread_union {
@@ -102601,7 +103626,7 @@ index b7b9501..dc6b96f 100644
unsigned long stack[THREAD_SIZE/sizeof(long)];
};
-@@ -2431,6 +2560,7 @@ extern struct pid_namespace init_pid_ns;
+@@ -2431,6 +2561,7 @@ extern struct pid_namespace init_pid_ns;
*/
extern struct task_struct *find_task_by_vpid(pid_t nr);
@@ -102609,7 +103634,7 @@ index b7b9501..dc6b96f 100644
extern struct task_struct *find_task_by_pid_ns(pid_t nr,
struct pid_namespace *ns);
-@@ -2462,7 +2592,7 @@ extern void proc_caches_init(void);
+@@ -2462,7 +2593,7 @@ extern void proc_caches_init(void);
extern void flush_signals(struct task_struct *);
extern void ignore_signals(struct task_struct *);
extern void flush_signal_handlers(struct task_struct *, int force_default);
@@ -102618,7 +103643,7 @@ index b7b9501..dc6b96f 100644
static inline int dequeue_signal_lock(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
{
-@@ -2608,7 +2738,7 @@ extern void __cleanup_sighand(struct sighand_struct *);
+@@ -2608,7 +2739,7 @@ extern void __cleanup_sighand(struct sighand_struct *);
extern void exit_itimers(struct signal_struct *);
extern void flush_itimer_signals(void);
@@ -102627,7 +103652,7 @@ index b7b9501..dc6b96f 100644
extern int do_execve(struct filename *,
const char __user * const __user *,
-@@ -2723,11 +2853,13 @@ static inline int thread_group_empty(struct task_struct *p)
+@@ -2723,11 +2854,13 @@ static inline int thread_group_empty(struct task_struct *p)
* It must not be nested with write_lock_irq(&tasklist_lock),
* neither inside nor outside.
*/
@@ -102641,7 +103666,7 @@ index b7b9501..dc6b96f 100644
static inline void task_unlock(struct task_struct *p)
{
spin_unlock(&p->alloc_lock);
-@@ -2813,9 +2945,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p)
+@@ -2813,9 +2946,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p)
#define task_stack_end_corrupted(task) \
(*(end_of_stack(task)) != STACK_END_MAGIC)
@@ -106457,6 +107482,27 @@ index 35bac8e..8de1d69 100644
if (!access_ok(VERIFY_READ, uattr, 1))
return -EFAULT;
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index b074b23..36c6efe 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -1058,6 +1058,16 @@ static int check_alu_op(struct reg_state *regs, struct bpf_insn *insn)
+ return -EINVAL;
+ }
+
++ if ((opcode == BPF_LSH || opcode == BPF_RSH ||
++ opcode == BPF_ARSH) && BPF_SRC(insn->code) == BPF_K) {
++ int size = BPF_CLASS(insn->code) == BPF_ALU64 ? 64 : 32;
++
++ if (insn->imm < 0 || insn->imm >= size) {
++ verbose("invalid shift %d\n", insn->imm);
++ return -EINVAL;
++ }
++ }
++
+ /* pattern match 'bpf_add Rx, imm' instruction */
+ if (opcode == BPF_ADD && BPF_CLASS(insn->code) == BPF_ALU64 &&
+ regs[insn->dst_reg].type == FRAME_PTR &&
diff --git a/kernel/capability.c b/kernel/capability.c
index 45432b5..988f1e4 100644
--- a/kernel/capability.c
@@ -108612,7 +109658,7 @@ index 4cccea6..4382db9 100644
debug_mutex_free_waiter(&waiter);
mutex_release(&lock->dep_map, 1, ip);
diff --git a/kernel/module.c b/kernel/module.c
-index 8f051a1..07da01a 100644
+index 8f051a1..e1be102 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -59,6 +59,7 @@
@@ -109532,9 +110578,16 @@ index 8f051a1..07da01a 100644
free_unload:
module_unload_free(mod);
unlink_mod:
-@@ -3572,7 +3757,8 @@ static int load_module(struct load_info *info, const char __user *uargs,
+@@ -3571,8 +3756,15 @@ static int load_module(struct load_info *info, const char __user *uargs,
+ synchronize_sched();
mutex_unlock(&module_mutex);
free_module:
++ /*
++ * Ftrace needs to clean up what it initialized.
++ * This does nothing if ftrace_module_init() wasn't called,
++ * but it must be called outside of module_mutex.
++ */
++ ftrace_release_mod(mod);
/* Free lock-classes; relies on the preceding sync_rcu() */
- lockdep_free_key_range(mod->module_core, mod->core_size);
+ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
@@ -109542,7 +110595,7 @@ index 8f051a1..07da01a 100644
module_deallocate(mod, info);
free_copy:
-@@ -3649,10 +3835,16 @@ static const char *get_ksymbol(struct module *mod,
+@@ -3649,10 +3841,16 @@ static const char *get_ksymbol(struct module *mod,
unsigned long nextval;
/* At worse, next value is at end of module */
@@ -109562,7 +110615,7 @@ index 8f051a1..07da01a 100644
/* Scan for closest preceding symbol, and next symbol. (ELF
starts real symbols at 1). */
-@@ -3899,7 +4091,7 @@ static int m_show(struct seq_file *m, void *p)
+@@ -3899,7 +4097,7 @@ static int m_show(struct seq_file *m, void *p)
return 0;
seq_printf(m, "%s %u",
@@ -109571,7 +110624,7 @@ index 8f051a1..07da01a 100644
print_unload_info(m, mod);
/* Informative for users. */
-@@ -3908,7 +4100,7 @@ static int m_show(struct seq_file *m, void *p)
+@@ -3908,7 +4106,7 @@ static int m_show(struct seq_file *m, void *p)
mod->state == MODULE_STATE_COMING ? "Loading" :
"Live");
/* Used by oprofile and other similar tools. */
@@ -109580,7 +110633,7 @@ index 8f051a1..07da01a 100644
/* Taints info */
if (mod->taints)
-@@ -3944,7 +4136,17 @@ static const struct file_operations proc_modules_operations = {
+@@ -3944,7 +4142,17 @@ static const struct file_operations proc_modules_operations = {
static int __init proc_modules_init(void)
{
@@ -109598,7 +110651,7 @@ index 8f051a1..07da01a 100644
return 0;
}
module_init(proc_modules_init);
-@@ -4005,7 +4207,8 @@ struct module *__module_address(unsigned long addr)
+@@ -4005,7 +4213,8 @@ struct module *__module_address(unsigned long addr)
{
struct module *mod;
@@ -109608,7 +110661,7 @@ index 8f051a1..07da01a 100644
return NULL;
module_assert_mutex_or_preempt();
-@@ -4048,11 +4251,20 @@ bool is_module_text_address(unsigned long addr)
+@@ -4048,11 +4257,20 @@ bool is_module_text_address(unsigned long addr)
*/
struct module *__module_text_address(unsigned long addr)
{
@@ -117431,7 +118484,7 @@ index 48ce829..4c30cd3 100644
return -ENOMEM;
diff --git a/mm/slab.c b/mm/slab.c
-index 4fcc5dd..09e0eee 100644
+index 4fcc5dd..8fb1a86 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -116,6 +116,7 @@
@@ -117486,6 +118539,15 @@ index 4fcc5dd..09e0eee 100644
slab_state = PARTIAL_NODE;
setup_kmalloc_cache_index_table();
+@@ -1691,7 +1696,7 @@ static void store_stackinfo(struct kmem_cache *cachep, unsigned long *addr,
+
+ while (!kstack_end(sptr)) {
+ svalue = *sptr++;
+- if (kernel_text_address(svalue)) {
++ if (kernel_text_address(ktva_ktla(svalue))) {
+ *addr++ = svalue;
+ size -= sizeof(unsigned long);
+ if (size <= sizeof(unsigned long))
@@ -2074,7 +2079,7 @@ __kmem_cache_alias(const char *name, size_t size, size_t align,
cachep = find_mergeable(size, align, flags, name, ctor);
@@ -120234,8 +121296,27 @@ index b94b1d2..da3ed7c 100644
}
EXPORT_SYMBOL(dev_load);
+diff --git a/net/core/dst.c b/net/core/dst.c
+index d6a5a0b..8852021 100644
+--- a/net/core/dst.c
++++ b/net/core/dst.c
+@@ -301,12 +301,13 @@ void dst_release(struct dst_entry *dst)
+ {
+ if (dst) {
+ int newrefcnt;
++ unsigned short nocache = dst->flags & DST_NOCACHE;
+
+ newrefcnt = atomic_dec_return(&dst->__refcnt);
+ if (unlikely(newrefcnt < 0))
+ net_warn_ratelimited("%s: dst:%p refcnt:%d\n",
+ __func__, dst, newrefcnt);
+- if (!newrefcnt && unlikely(dst->flags & DST_NOCACHE))
++ if (!newrefcnt && unlikely(nocache))
+ call_rcu(&dst->rcu_head, dst_destroy_rcu);
+ }
+ }
diff --git a/net/core/filter.c b/net/core/filter.c
-index bb18c36..90998d5 100644
+index bb18c36..a0c92a7 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -584,7 +584,11 @@ do_pass:
@@ -120260,7 +121341,19 @@ index bb18c36..90998d5 100644
masks = kmalloc_array(flen, sizeof(*masks), GFP_KERNEL);
if (!masks)
-@@ -1057,7 +1061,7 @@ int bpf_prog_create(struct bpf_prog **pfp, struct sock_fprog_kern *fprog)
+@@ -781,6 +785,11 @@ static int bpf_check_classic(const struct sock_filter *filter,
+ if (ftest->k == 0)
+ return -EINVAL;
+ break;
++ case BPF_ALU | BPF_LSH | BPF_K:
++ case BPF_ALU | BPF_RSH | BPF_K:
++ if (ftest->k >= 32)
++ return -EINVAL;
++ break;
+ case BPF_LD | BPF_MEM:
+ case BPF_LDX | BPF_MEM:
+ case BPF_ST:
+@@ -1057,7 +1066,7 @@ int bpf_prog_create(struct bpf_prog **pfp, struct sock_fprog_kern *fprog)
if (!fp)
return -ENOMEM;
@@ -124776,7 +125869,7 @@ index 7ec667d..b5c2cf2 100644
sch->handle = handle;
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
-index e82a1ad..7def03d 100644
+index e82a1ad..a7df216b 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -349,7 +349,7 @@ void netif_carrier_on(struct net_device *dev)
@@ -124797,6 +125890,18 @@ index e82a1ad..7def03d 100644
linkwatch_fire_event(dev);
}
}
+@@ -658,8 +658,10 @@ static void qdisc_rcu_free(struct rcu_head *head)
+ {
+ struct Qdisc *qdisc = container_of(head, struct Qdisc, rcu_head);
+
+- if (qdisc_is_percpu_stats(qdisc))
++ if (qdisc_is_percpu_stats(qdisc)) {
+ free_percpu(qdisc->cpu_bstats);
++ free_percpu(qdisc->cpu_qstats);
++ }
+
+ kfree((char *) qdisc - qdisc->padded);
+ }
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index e917d27..13e2a4c 100644
--- a/net/sctp/ipv6.c
@@ -124872,9 +125977,18 @@ index 3d9ea9a..d3aee1a 100644
static int sctp_v4_protosw_init(void)
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
-index 6098d4c..9d87fbd 100644
+index 6098d4c..9920c54 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
+@@ -63,7 +63,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
+ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
+ sctp_state_t state,
+ struct sctp_endpoint *ep,
+- struct sctp_association *asoc,
++ struct sctp_association **asoc,
+ void *event_arg,
+ sctp_disposition_t status,
+ sctp_cmd_seq_t *commands,
@@ -443,7 +443,7 @@ static void sctp_generate_sack_event(unsigned long data)
sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_SACK);
}
@@ -124884,6 +125998,128 @@ index 6098d4c..9d87fbd 100644
NULL,
sctp_generate_t1_cookie_event,
sctp_generate_t1_init_event,
+@@ -1123,7 +1123,7 @@ int sctp_do_sm(struct net *net, sctp_event_t event_type, sctp_subtype_t subtype,
+ debug_post_sfn();
+
+ error = sctp_side_effects(event_type, subtype, state,
+- ep, asoc, event_arg, status,
++ ep, &asoc, event_arg, status,
+ &commands, gfp);
+ debug_post_sfx();
+
+@@ -1136,7 +1136,7 @@ int sctp_do_sm(struct net *net, sctp_event_t event_type, sctp_subtype_t subtype,
+ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
+ sctp_state_t state,
+ struct sctp_endpoint *ep,
+- struct sctp_association *asoc,
++ struct sctp_association **asoc,
+ void *event_arg,
+ sctp_disposition_t status,
+ sctp_cmd_seq_t *commands,
+@@ -1151,7 +1151,7 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
+ * disposition SCTP_DISPOSITION_CONSUME.
+ */
+ if (0 != (error = sctp_cmd_interpreter(event_type, subtype, state,
+- ep, asoc,
++ ep, *asoc,
+ event_arg, status,
+ commands, gfp)))
+ goto bail;
+@@ -1174,11 +1174,12 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype,
+ break;
+
+ case SCTP_DISPOSITION_DELETE_TCB:
++ case SCTP_DISPOSITION_ABORT:
+ /* This should now be a command. */
++ *asoc = NULL;
+ break;
+
+ case SCTP_DISPOSITION_CONSUME:
+- case SCTP_DISPOSITION_ABORT:
+ /*
+ * We should no longer have much work to do here as the
+ * real work has been done as explicit commands above.
+diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
+index d7eaa73..9042a5d 100644
+--- a/net/sctp/sm_statefuns.c
++++ b/net/sctp/sm_statefuns.c
+@@ -2976,7 +2976,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(struct net *net,
+ SCTP_INC_STATS(net, SCTP_MIB_IN_DATA_CHUNK_DISCARDS);
+ goto discard_force;
+ case SCTP_IERROR_NO_DATA:
+- goto consume;
++ return SCTP_DISPOSITION_ABORT;
+ case SCTP_IERROR_PROTO_VIOLATION:
+ return sctp_sf_abort_violation(net, ep, asoc, chunk, commands,
+ (u8 *)chunk->subh.data_hdr, sizeof(sctp_datahdr_t));
+@@ -3043,9 +3043,6 @@ discard_noforce:
+ sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, force);
+
+ return SCTP_DISPOSITION_DISCARD;
+-consume:
+- return SCTP_DISPOSITION_CONSUME;
+-
+ }
+
+ /*
+@@ -3093,7 +3090,7 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(struct net *net,
+ case SCTP_IERROR_BAD_STREAM:
+ break;
+ case SCTP_IERROR_NO_DATA:
+- goto consume;
++ return SCTP_DISPOSITION_ABORT;
+ case SCTP_IERROR_PROTO_VIOLATION:
+ return sctp_sf_abort_violation(net, ep, asoc, chunk, commands,
+ (u8 *)chunk->subh.data_hdr, sizeof(sctp_datahdr_t));
+@@ -3119,7 +3116,6 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(struct net *net,
+ SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
+ }
+
+-consume:
+ return SCTP_DISPOSITION_CONSUME;
+ }
+
+@@ -4825,9 +4821,6 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(
+ * if necessary to fill gaps.
+ */
+ struct sctp_chunk *abort = arg;
+- sctp_disposition_t retval;
+-
+- retval = SCTP_DISPOSITION_CONSUME;
+
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
+
+@@ -4844,7 +4837,7 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(
+ SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS);
+ SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB);
+
+- return retval;
++ return SCTP_DISPOSITION_ABORT;
+ }
+
+ /* We tried an illegal operation on an association which is closed. */
+@@ -4959,12 +4952,10 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(
+ sctp_cmd_seq_t *commands)
+ {
+ struct sctp_chunk *abort = arg;
+- sctp_disposition_t retval;
+
+ /* Stop T1-init timer */
+ sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
+ SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
+- retval = SCTP_DISPOSITION_CONSUME;
+
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
+
+@@ -4983,7 +4974,7 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(
+ sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
+ SCTP_PERR(SCTP_ERROR_USER_ABORT));
+
+- return retval;
++ return SCTP_DISPOSITION_ABORT;
+ }
+
+ /*
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 3ec88be..a8d9d222 100644
--- a/net/sctp/socket.c
@@ -125016,10 +126252,10 @@ index 3ec88be..a8d9d222 100644
return -ENOMEM;
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
-index 26d50c5..dfae665 100644
+index 26d50c5..289fe22 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
-@@ -317,7 +317,7 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
+@@ -317,10 +317,10 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write,
loff_t *ppos)
{
struct net *net = current->nsproxy->net_ns;
@@ -125027,7 +126263,11 @@ index 26d50c5..dfae665 100644
+ ctl_table_no_const tbl;
bool changed = false;
char *none = "none";
- char tmp[8];
+- char tmp[8];
++ char tmp[8] = {0};
+ int ret;
+
+ memset(&tbl, 0, sizeof(struct ctl_table));
@@ -365,7 +365,7 @@ static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
struct net *net = current->nsproxy->net_ns;
unsigned int min = *(unsigned int *) ctl->extra1;
@@ -125468,7 +126708,7 @@ index 621ca7b..78bf76b 100644
static int unix_gid_parse(struct cache_detail *cd,
char *mesg, int mlen)
diff --git a/net/sunrpc/xprtrdma/svc_rdma.c b/net/sunrpc/xprtrdma/svc_rdma.c
-index 2cd252f..eefac51 100644
+index 2cd252f..94dc8cb 100644
--- a/net/sunrpc/xprtrdma/svc_rdma.c
+++ b/net/sunrpc/xprtrdma/svc_rdma.c
@@ -61,15 +61,15 @@ unsigned int svcrdma_max_req_size = RPCRDMA_MAX_REQ_SIZE;
@@ -125496,6 +126736,27 @@ index 2cd252f..eefac51 100644
/* Temporary NFS request map and context caches */
struct kmem_cache *svc_rdma_map_cachep;
+@@ -87,17 +87,17 @@ static int read_reset_stat(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp,
+ loff_t *ppos)
+ {
+- atomic_t *stat = (atomic_t *)table->data;
++ atomic_unchecked_t *stat = (atomic_unchecked_t *)table->data;
+
+ if (!stat)
+ return -EINVAL;
+
+ if (write)
+- atomic_set(stat, 0);
++ atomic_set_unchecked(stat, 0);
+ else {
+ char str_buf[32];
+ char *data;
+- int len = snprintf(str_buf, 32, "%d\n", atomic_read(stat));
++ int len = snprintf(str_buf, 32, "%d\n", atomic_read_unchecked(stat));
+ if (len >= 32)
+ return -EFAULT;
+ len = strlen(str_buf);
@@ -109,7 +109,7 @@ static int read_reset_stat(struct ctl_table *table, int write,
len -= *ppos;
if (len > *lenp)
@@ -125749,7 +127010,7 @@ index 350cca3..a108fc5 100644
sub->evt.event = htohl(event, sub->swap);
sub->evt.found_lower = htohl(found_lower, sub->swap);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
-index 128b098..38013fc 100644
+index 128b098..b66988b 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -918,6 +918,12 @@ static struct sock *unix_find_other(struct net *net,
@@ -125913,7 +127174,52 @@ index 128b098..38013fc 100644
out:
return err;
}
-@@ -2772,9 +2805,13 @@ static int unix_seq_show(struct seq_file *seq, void *v)
+@@ -1498,6 +1531,21 @@ static void unix_destruct_scm(struct sk_buff *skb)
+ sock_wfree(skb);
+ }
+
++/*
++ * The "user->unix_inflight" variable is protected by the garbage
++ * collection lock, and we just read it locklessly here. If you go
++ * over the limit, there might be a tiny race in actually noticing
++ * it across threads. Tough.
++ */
++static inline bool too_many_unix_fds(struct task_struct *p)
++{
++ struct user_struct *user = current_user();
++
++ if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE)))
++ return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
++ return false;
++}
++
+ #define MAX_RECURSION_LEVEL 4
+
+ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+@@ -1506,6 +1554,9 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+ unsigned char max_level = 0;
+ int unix_sock_count = 0;
+
++ if (too_many_unix_fds(current))
++ return -ETOOMANYREFS;
++
+ for (i = scm->fp->count - 1; i >= 0; i--) {
+ struct sock *sk = unix_get_socket(scm->fp->fp[i]);
+
+@@ -1527,10 +1578,8 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+ if (!UNIXCB(skb).fp)
+ return -ENOMEM;
+
+- if (unix_sock_count) {
+- for (i = scm->fp->count - 1; i >= 0; i--)
+- unix_inflight(scm->fp->fp[i]);
+- }
++ for (i = scm->fp->count - 1; i >= 0; i--)
++ unix_inflight(scm->fp->fp[i]);
+ return max_level;
+ }
+
+@@ -2772,9 +2821,13 @@ static int unix_seq_show(struct seq_file *seq, void *v)
seq_puts(seq, "Num RefCount Protocol Flags Type St "
"Inode Path\n");
else {
@@ -125928,7 +127234,7 @@ index 128b098..38013fc 100644
seq_printf(seq, "%pK: %08X %08X %08X %04X %02X %5lu",
s,
-@@ -2799,10 +2836,29 @@ static int unix_seq_show(struct seq_file *seq, void *v)
+@@ -2799,10 +2852,29 @@ static int unix_seq_show(struct seq_file *seq, void *v)
seq_putc(seq, '@');
i++;
}
@@ -125962,6 +127268,56 @@ index 128b098..38013fc 100644
seq_putc(seq, '\n');
}
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index a73a226..8fcdc22 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -120,11 +120,11 @@ void unix_inflight(struct file *fp)
+ {
+ struct sock *s = unix_get_socket(fp);
+
++ spin_lock(&unix_gc_lock);
++
+ if (s) {
+ struct unix_sock *u = unix_sk(s);
+
+- spin_lock(&unix_gc_lock);
+-
+ if (atomic_long_inc_return(&u->inflight) == 1) {
+ BUG_ON(!list_empty(&u->link));
+ list_add_tail(&u->link, &gc_inflight_list);
+@@ -132,25 +132,28 @@ void unix_inflight(struct file *fp)
+ BUG_ON(list_empty(&u->link));
+ }
+ unix_tot_inflight++;
+- spin_unlock(&unix_gc_lock);
+ }
++ fp->f_cred->user->unix_inflight++;
++ spin_unlock(&unix_gc_lock);
+ }
+
+ void unix_notinflight(struct file *fp)
+ {
+ struct sock *s = unix_get_socket(fp);
+
++ spin_lock(&unix_gc_lock);
++
+ if (s) {
+ struct unix_sock *u = unix_sk(s);
+
+- spin_lock(&unix_gc_lock);
+ BUG_ON(list_empty(&u->link));
+
+ if (atomic_long_dec_and_test(&u->inflight))
+ list_del_init(&u->link);
+ unix_tot_inflight--;
+- spin_unlock(&unix_gc_lock);
+ }
++ fp->f_cred->user->unix_inflight--;
++ spin_unlock(&unix_gc_lock);
+ }
+
+ static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
diff --git a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c
index b3d5150..ff3a837 100644
--- a/net/unix/sysctl_net_unix.c
@@ -131812,12 +133168,12 @@ index 0000000..7514850
+fi
diff --git a/tools/gcc/initify_plugin.c b/tools/gcc/initify_plugin.c
new file mode 100644
-index 0000000..a518073
+index 0000000..9431b53
--- /dev/null
+++ b/tools/gcc/initify_plugin.c
-@@ -0,0 +1,581 @@
+@@ -0,0 +1,588 @@
+/*
-+ * Copyright 2011-2016 by Emese Revfy <re.emese@gmail.com>
++ * Copyright 2015-2016 by Emese Revfy <re.emese@gmail.com>
+ * Licensed under the GPL v2, or (at your option) v3
+ *
+ * Homepage:
@@ -131836,7 +133192,7 @@ index 0000000..a518073
+int plugin_is_GPL_compatible;
+
+static struct plugin_info initify_plugin_info = {
-+ .version = "20160104",
++ .version = "20160113",
+ .help = "initify_plugin\n",
+};
+
@@ -132022,11 +133378,18 @@ index 0000000..a518073
+
+static bool is_same_vardecl(const_tree op, const_tree vardecl)
+{
++ const_tree decl;
++
+ if (op == vardecl)
+ return true;
-+ if (!DECL_P(op))
++ if (TREE_CODE(op) == SSA_NAME)
++ decl = SSA_NAME_VAR(op);
++ else
++ decl = op;
++ if (decl == NULL_TREE || !DECL_P(decl))
+ return false;
-+ return DECL_NAME(op) && !strcmp(DECL_NAME_POINTER(op), DECL_NAME_POINTER(vardecl));
++
++ return DECL_NAME(decl) && !strcmp(DECL_NAME_POINTER(decl), DECL_NAME_POINTER(vardecl));
+}
+
+static bool search_same_vardecl(const_tree value, const_tree vardecl)
@@ -134607,10 +135970,10 @@ index 0000000..f74d85a
+targets += size_overflow_hash.h size_overflow_hash_aux.h disable_size_overflow_hash.h
diff --git a/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data b/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data
new file mode 100644
-index 0000000..5276d6e
+index 0000000..e141179
--- /dev/null
+++ b/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data
-@@ -0,0 +1,12433 @@
+@@ -0,0 +1,12434 @@
+disable_so_interrupt_pnode_gru_message_queue_desc_4 interrupt_pnode gru_message_queue_desc 0 4 NULL
+disable_so_bch_btree_insert_fndecl_12 bch_btree_insert fndecl 0 12 NULL
+disable_so_macvlan_sync_address_fndecl_22 macvlan_sync_address fndecl 0 22 NULL nohasharray
@@ -147044,6 +148407,7 @@ index 0000000..5276d6e
+enable_so_deh_location_reiserfs_de_head_7682 deh_location reiserfs_de_head 0 7682 NULL
+enable_so_deh_offset_reiserfs_de_head_42314 deh_offset reiserfs_de_head 0 42314 NULL
+enable_so_dsack_tcp_options_received_27706 dsack tcp_options_received 0 27706 NULL
++enable_so_inbufBits_bunzip_data_13788 inbufBits bunzip_data 0 13788 NULL
diff --git a/tools/gcc/size_overflow_plugin/generate_size_overflow_hash.sh b/tools/gcc/size_overflow_plugin/generate_size_overflow_hash.sh
new file mode 100644
index 0000000..be9724d
@@ -149287,10 +150651,10 @@ index 0000000..fc58e16
+}
diff --git a/tools/gcc/size_overflow_plugin/size_overflow_hash.data b/tools/gcc/size_overflow_plugin/size_overflow_hash.data
new file mode 100644
-index 0000000..3fc86c1
+index 0000000..0a36c4a
--- /dev/null
+++ b/tools/gcc/size_overflow_plugin/size_overflow_hash.data
-@@ -0,0 +1,21744 @@
+@@ -0,0 +1,21743 @@
+enable_so_recv_ctrl_pipe_us_data_0 recv_ctrl_pipe us_data 0 0 NULL
+enable_so___earlyonly_bootmem_alloc_fndecl_3 __earlyonly_bootmem_alloc fndecl 2-3-4 3 NULL
+enable_so_size_ttm_mem_reg_8 size ttm_mem_reg 0 8 NULL
@@ -153871,8 +155235,7 @@ index 0000000..3fc86c1
+enable_so_usbhs_dma_calc_received_size_fndecl_13783 usbhs_dma_calc_received_size fndecl 0-3 13783 NULL
+enable_so_build_data_key_fndecl_13784 build_data_key fndecl 2 13784 NULL
+enable_so_iwl_trans_read_mem32_fndecl_13786 iwl_trans_read_mem32 fndecl 0 13786 NULL
-+enable_so_ept_get_level1_sp_gpa_fndecl_13788 ept_get_level1_sp_gpa fndecl 0 13788 NULL nohasharray
-+enable_so_inbufBits_bunzip_data_13788 inbufBits bunzip_data 0 13788 &enable_so_ept_get_level1_sp_gpa_fndecl_13788
++enable_so_ept_get_level1_sp_gpa_fndecl_13788 ept_get_level1_sp_gpa fndecl 0 13788 NULL
+enable_so_smk_write_load_fndecl_13790 smk_write_load fndecl 3 13790 NULL
+enable_so_num_channels_xilly_endpoint_13791 num_channels xilly_endpoint 0 13791 NULL
+enable_so_tipc_conn_sendmsg_fndecl_13792 tipc_conn_sendmsg fndecl 5 13792 NULL
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [gentoo-commits] proj/hardened-patchset:master commit in: 4.3.3/
@ 2016-01-19 0:13 Anthony G. Basile
0 siblings, 0 replies; 7+ messages in thread
From: Anthony G. Basile @ 2016-01-19 0:13 UTC (permalink / raw
To: gentoo-commits
commit: 5aca1e28bedeb8f51a52cfc922e0749f75809504
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Tue Jan 19 00:20:58 2016 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Tue Jan 19 00:20:58 2016 +0000
URL: https://gitweb.gentoo.org/proj/hardened-patchset.git/commit/?id=5aca1e28
grsecurity-3.1-4.3.3-201601171913
4.3.3/0000_README | 2 +-
...> 4420_grsecurity-3.1-4.3.3-201601171913.patch} | 211 +++++++++++++--------
2 files changed, 135 insertions(+), 78 deletions(-)
diff --git a/4.3.3/0000_README b/4.3.3/0000_README
index 8ff755f..737c59b 100644
--- a/4.3.3/0000_README
+++ b/4.3.3/0000_README
@@ -2,7 +2,7 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 4420_grsecurity-3.1-4.3.3-201601161757.patch
+Patch: 4420_grsecurity-3.1-4.3.3-201601171913.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/4.3.3/4420_grsecurity-3.1-4.3.3-201601161757.patch b/4.3.3/4420_grsecurity-3.1-4.3.3-201601171913.patch
similarity index 99%
rename from 4.3.3/4420_grsecurity-3.1-4.3.3-201601161757.patch
rename to 4.3.3/4420_grsecurity-3.1-4.3.3-201601171913.patch
index 15482a1..c47605c 100644
--- a/4.3.3/4420_grsecurity-3.1-4.3.3-201601161757.patch
+++ b/4.3.3/4420_grsecurity-3.1-4.3.3-201601171913.patch
@@ -42417,24 +42417,58 @@ index 6068d82..7ecd87c 100644
static const struct vga_switcheroo_client_ops amdgpu_switcheroo_ops = {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
-index b190c2a..d1b18c2 100644
+index b190c2a..67a7707 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
-@@ -544,8 +544,12 @@ static int __init amdgpu_init(void)
+@@ -471,7 +471,7 @@ static struct drm_driver kms_driver = {
+ .driver_features =
+ DRIVER_USE_AGP |
+ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
+- DRIVER_PRIME | DRIVER_RENDER,
++ DRIVER_PRIME | DRIVER_RENDER | DRIVER_MODESET,
+ .dev_priv_size = 0,
+ .load = amdgpu_driver_load_kms,
+ .open = amdgpu_driver_open_kms,
+@@ -522,9 +522,6 @@ static struct drm_driver kms_driver = {
+ .patchlevel = KMS_DRIVER_PATCHLEVEL,
+ };
+
+-static struct drm_driver *driver;
+-static struct pci_driver *pdriver;
+-
+ static struct pci_driver amdgpu_kms_pci_driver = {
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
+@@ -542,22 +539,23 @@ static int __init amdgpu_init(void)
+ }
+ #endif
DRM_INFO("amdgpu kernel modesetting enabled.\n");
- driver = &kms_driver;
- pdriver = &amdgpu_kms_pci_driver;
+- driver = &kms_driver;
+- pdriver = &amdgpu_kms_pci_driver;
- driver->driver_features |= DRIVER_MODESET;
- driver->num_ioctls = amdgpu_max_kms_ioctl;
+
+ pax_open_kernel();
-+ *(u32 *)&driver->driver_features |= DRIVER_MODESET;
-+ *(int *)&driver->num_ioctls = amdgpu_max_kms_ioctl;
++ *(int *)&kms_driver.num_ioctls = amdgpu_max_kms_ioctl;
+ pax_close_kernel();
+
amdgpu_register_atpx_handler();
amdgpu_amdkfd_init();
+
+ /* let modprobe override vga console setting */
+- return drm_pci_init(driver, pdriver);
++ return drm_pci_init(&kms_driver, &amdgpu_kms_pci_driver);
+ }
+
+ static void __exit amdgpu_exit(void)
+ {
+ amdgpu_amdkfd_fini();
+- drm_pci_exit(driver, pdriver);
++ drm_pci_exit(&kms_driver, &amdgpu_kms_pci_driver);
+ amdgpu_unregister_atpx_handler();
+ }
+
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 5d11e79..04cc53e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -43160,7 +43194,7 @@ index d93e737..edb8a4a 100644
int retcode = -EINVAL;
char stack_kdata[128];
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c
-index 1b1bd42..0e49027 100644
+index 1b1bd42..2d28e80 100644
--- a/drivers/gpu/drm/drm_pci.c
+++ b/drivers/gpu/drm/drm_pci.c
@@ -305,7 +305,7 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
@@ -43172,16 +43206,19 @@ index 1b1bd42..0e49027 100644
return 0;
-@@ -340,7 +340,7 @@ int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
+@@ -340,7 +340,10 @@ int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
return pci_register_driver(pdriver);
/* If not using KMS, fall back to stealth mode manual scanning. */
- INIT_LIST_HEAD(&driver->legacy_dev_list);
++ pax_open_kernel();
+ INIT_LIST_HEAD((struct list_head *)&driver->legacy_dev_list);
++ pax_close_kernel();
++
for (i = 0; pdriver->id_table[i].vendor != 0; i++) {
pid = &pdriver->id_table[i];
-@@ -446,7 +446,7 @@ void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
+@@ -446,7 +449,7 @@ void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
} else {
list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list,
legacy_dev_list) {
@@ -43226,18 +43263,14 @@ index d4813e0..6c1ab4d 100644
pipeconf_reg = PIPECCONF;
dspcntr_reg = DSPCCNTR;
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
-index 92e7e57..f59f5d3 100644
+index 92e7e57..5d74ff5 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
-@@ -376,7 +376,10 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags)
+@@ -376,7 +376,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags)
dev->vblank_disable_allowed = true;
dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
- dev->driver->get_vblank_counter = psb_get_vblank_counter;
-+
-+ pax_open_kernel();
-+ *(void **)&dev->driver->get_vblank_counter = psb_get_vblank_counter;
-+ pax_close_kernel();
psb_modeset_init(dev);
psb_fbdev_init(dev);
@@ -43315,48 +43348,47 @@ index ab37d11..5cbacc7 100644
-int i915_max_ioctl = ARRAY_SIZE(i915_ioctls);
+const int i915_max_ioctl = ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
-index ab64d68..e6be8e5 100644
+index ab64d68..b74a68e 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
-@@ -1697,25 +1697,27 @@ static struct pci_driver i915_pci_driver = {
+@@ -40,7 +40,7 @@
+ #include <linux/pm_runtime.h>
+ #include <drm/drm_crtc_helper.h>
+
+-static struct drm_driver driver;
++static drm_driver_no_const driver;
+
+ #define GEN_DEFAULT_PIPEOFFSETS \
+ .pipe_offsets = { PIPE_A_OFFSET, PIPE_B_OFFSET, \
+@@ -1643,7 +1643,7 @@ static const struct file_operations i915_driver_fops = {
+ .llseek = noop_llseek,
+ };
+
+-static struct drm_driver driver = {
++static drm_driver_no_const driver __read_only = {
+ /* Don't use MTRRs here; the Xserver or userspace app should
+ * deal with them for Intel hardware.
+ */
+@@ -1697,6 +1697,7 @@ static struct pci_driver i915_pci_driver = {
static int __init i915_init(void)
{
-- driver.num_ioctls = i915_max_ioctl;
+ pax_open_kernel();
-+ *(int *)&driver.num_ioctls = i915_max_ioctl;
+ driver.num_ioctls = i915_max_ioctl;
/*
- * Enable KMS by default, unless explicitly overriden by
- * either the i915.modeset prarameter or by the
- * vga_text_mode_force boot option.
- */
-- driver.driver_features |= DRIVER_MODESET;
-+ *(u32 *)&driver.driver_features |= DRIVER_MODESET;
-
- if (i915.modeset == 0)
-- driver.driver_features &= ~DRIVER_MODESET;
-+ *(u32 *)&driver.driver_features &= ~DRIVER_MODESET;
-
- #ifdef CONFIG_VGA_CONSOLE
- if (vgacon_text_force() && i915.modeset == -1)
-- driver.driver_features &= ~DRIVER_MODESET;
-+ *(u32 *)&driver.driver_features &= ~DRIVER_MODESET;
- #endif
+@@ -1716,6 +1717,7 @@ static int __init i915_init(void)
if (!(driver.driver_features & DRIVER_MODESET)) {
-- driver.get_vblank_timestamp = NULL;
-+ *(void **)&driver.get_vblank_timestamp = NULL;
+ driver.get_vblank_timestamp = NULL;
+ pax_close_kernel();
/* Silently fail loading to not upset userspace. */
DRM_DEBUG_DRIVER("KMS and UMS disabled.\n");
return 0;
-@@ -1727,7 +1729,8 @@ static int __init i915_init(void)
- * a single CRTC will actually work.
+@@ -1728,6 +1730,7 @@ static int __init i915_init(void)
*/
if (driver.driver_features & DRIVER_MODESET)
-- driver.driver_features |= DRIVER_ATOMIC;
-+ *(u32 *)&driver.driver_features |= DRIVER_ATOMIC;
+ driver.driver_features |= DRIVER_ATOMIC;
+ pax_close_kernel();
return drm_pci_init(&driver, &i915_pci_driver);
@@ -43833,17 +43865,20 @@ index 4dca65a..3486961 100644
#define BIT_TABLE(id, funcid) ((struct bit_table){ id, parse_bit_##funcid##_tbl_entry })
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
-index ccefb64..a19593d 100644
+index ccefb64..10c4d33 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
-@@ -76,7 +76,6 @@ MODULE_PARM_DESC(runpm, "disable (0), force enable (1), optimus only default (-1
+@@ -76,9 +76,8 @@ MODULE_PARM_DESC(runpm, "disable (0), force enable (1), optimus only default (-1
int nouveau_runtime_pm = -1;
module_param_named(runpm, nouveau_runtime_pm, int, 0400);
-static struct drm_driver driver_stub;
static struct drm_driver driver_pci;
- static struct drm_driver driver_platform;
+-static struct drm_driver driver_platform;
++static drm_driver_no_const driver_platform __read_only;
+ static u64
+ nouveau_pci_name(struct pci_dev *pdev)
@@ -917,7 +916,7 @@ nouveau_driver_fops = {
};
@@ -43869,10 +43904,9 @@ index ccefb64..a19593d 100644
- driver_pci = driver_stub;
- driver_pci.set_busid = drm_pci_set_busid;
- driver_platform = driver_stub;
-- driver_platform.set_busid = drm_platform_set_busid;
+ pax_open_kernel();
-+ memcpy((void *)&driver_platform, &driver_pci, sizeof driver_pci);
-+ *(void **)&driver_platform.set_busid = drm_platform_set_busid;
++ driver_platform = driver_pci;
+ driver_platform.set_busid = drm_platform_set_busid;
+ pax_close_kernel();
nouveau_display_options();
@@ -44404,7 +44438,7 @@ index f3f562f..0c099bb 100644
static const struct vga_switcheroo_client_ops radeon_switcheroo_ops = {
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
-index 5751446..f39a861 100644
+index 5751446..2ec7c5d 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -130,7 +130,7 @@ extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc,
@@ -44416,7 +44450,16 @@ index 5751446..f39a861 100644
int radeon_mmap(struct file *filp, struct vm_area_struct *vma);
int radeon_mode_dumb_mmap(struct drm_file *filp,
struct drm_device *dev,
-@@ -650,8 +650,12 @@ static int __init radeon_init(void)
+@@ -566,7 +566,7 @@ static struct drm_driver kms_driver = {
+ .driver_features =
+ DRIVER_USE_AGP |
+ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
+- DRIVER_PRIME | DRIVER_RENDER,
++ DRIVER_PRIME | DRIVER_RENDER | DRIVER_MODESET,
+ .load = radeon_driver_load_kms,
+ .open = radeon_driver_open_kms,
+ .preclose = radeon_driver_preclose_kms,
+@@ -650,8 +650,11 @@ static int __init radeon_init(void)
DRM_INFO("radeon kernel modesetting enabled.\n");
driver = &kms_driver;
pdriver = &radeon_kms_pci_driver;
@@ -44424,14 +44467,13 @@ index 5751446..f39a861 100644
- driver->num_ioctls = radeon_max_kms_ioctl;
+
+ pax_open_kernel();
-+ *(u32 *)&driver->driver_features |= DRIVER_MODESET;
+ *(int *)&driver->num_ioctls = radeon_max_kms_ioctl;
+ pax_close_kernel();
+
radeon_register_atpx_handler();
} else {
-@@ -659,8 +663,11 @@ static int __init radeon_init(void)
+@@ -659,8 +662,10 @@ static int __init radeon_init(void)
DRM_INFO("radeon userspace modesetting enabled.\n");
driver = &driver_old;
pdriver = &radeon_pci_driver;
@@ -44439,7 +44481,6 @@ index 5751446..f39a861 100644
- driver->num_ioctls = radeon_max_ioctl;
+
+ pax_open_kernel();
-+ *(u32 *)&driver->driver_features &= ~DRIVER_MODESET;
+ *(int *)&driver->num_ioctls = radeon_max_ioctl;
+ pax_close_kernel();
#else
@@ -52677,6 +52718,20 @@ index 976aa97..c1efed2 100644
if (cmd == TUNSETIFF || cmd == TUNSETQUEUE || _IOC_TYPE(cmd) == 0x89) {
if (copy_from_user(&ifr, argp, ifreq_len))
return -EFAULT;
+diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c
+index 079069a..a11e690 100644
+--- a/drivers/net/usb/asix_common.c
++++ b/drivers/net/usb/asix_common.c
+@@ -108,7 +108,8 @@ int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
+ }
+
+ if (rx->size > skb->len - offset) {
+- remaining = rx->size - (skb->len - offset);
++ remaining = skb->len - offset;
++ remaining = rx->size - remaining;
+ rx->size = skb->len - offset;
+ }
+
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 111d907..1ee643e 100644
--- a/drivers/net/usb/hso.c
@@ -78448,7 +78503,7 @@ index e4141f2..d8263e8 100644
i += packet_length_size;
if (copy_to_user(&buf[i], msg_ctx->msg, msg_ctx->msg_size))
diff --git a/fs/exec.c b/fs/exec.c
-index b06623a..122301f 100644
+index b06623a..10a5c14 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -56,8 +56,20 @@
@@ -78494,7 +78549,7 @@ index b06623a..122301f 100644
static DEFINE_RWLOCK(binfmt_lock);
+extern int gr_process_kernel_exec_ban(void);
-+extern int gr_process_suid_exec_ban(const struct linux_binprm *bprm);
++extern int gr_process_sugid_exec_ban(const struct linux_binprm *bprm);
+
void __register_binfmt(struct linux_binfmt * fmt, int insert)
{
@@ -78874,7 +78929,7 @@ index b06623a..122301f 100644
+ current->signal->rlim[RLIMIT_STACK].rlim_cur = 8 * 1024 * 1024;
+#endif
+
-+ if (gr_process_kernel_exec_ban() || gr_process_suid_exec_ban(bprm)) {
++ if (gr_process_kernel_exec_ban() || gr_process_sugid_exec_ban(bprm)) {
+ retval = -EPERM;
+ goto out_fail;
+ }
@@ -96383,10 +96438,10 @@ index 0000000..304c518
+}
diff --git a/grsecurity/grsec_sig.c b/grsecurity/grsec_sig.c
new file mode 100644
-index 0000000..1e6f893
+index 0000000..528fd00
--- /dev/null
+++ b/grsecurity/grsec_sig.c
-@@ -0,0 +1,243 @@
+@@ -0,0 +1,244 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
@@ -96496,10 +96551,10 @@ index 0000000..1e6f893
+ user = find_user(uid);
+ if (user == NULL)
+ goto unlock;
-+ user->suid_banned = 1;
-+ user->suid_ban_expires = get_seconds() + GR_USER_BAN_TIME;
-+ if (user->suid_ban_expires == ~0UL)
-+ user->suid_ban_expires--;
++ user->sugid_banned = 1;
++ user->sugid_ban_expires = get_seconds() + GR_USER_BAN_TIME;
++ if (user->sugid_ban_expires == ~0UL)
++ user->sugid_ban_expires--;
+
+ /* only kill other threads of the same binary, from the same user */
+ do_each_thread(tsk2, tsk) {
@@ -96585,11 +96640,11 @@ index 0000000..1e6f893
+}
+
+#ifdef CONFIG_GRKERNSEC_BRUTE
-+static bool suid_ban_expired(struct user_struct *user)
++static bool sugid_ban_expired(struct user_struct *user)
+{
-+ if (user->suid_ban_expires != ~0UL && time_after_eq(get_seconds(), user->suid_ban_expires)) {
-+ user->suid_banned = 0;
-+ user->suid_ban_expires = 0;
++ if (user->sugid_ban_expires != ~0UL && time_after_eq(get_seconds(), user->sugid_ban_expires)) {
++ user->sugid_banned = 0;
++ user->sugid_ban_expires = 0;
+ free_uid(user);
+ return true;
+ }
@@ -96616,15 +96671,16 @@ index 0000000..1e6f893
+ return 0;
+}
+
-+int gr_process_suid_exec_ban(const struct linux_binprm *bprm)
++int gr_process_sugid_exec_ban(const struct linux_binprm *bprm)
+{
+#ifdef CONFIG_GRKERNSEC_BRUTE
+ struct user_struct *user = current->cred->user;
-+ if (unlikely(user->suid_banned)) {
-+ if (suid_ban_expired(user))
++ if (unlikely(user->sugid_banned)) {
++ if (sugid_ban_expired(user))
+ return 0;
-+ /* disallow execution of suid binaries only */
-+ else if (!uid_eq(bprm->cred->euid, current->cred->uid))
++ /* disallow execution of suid/sgid binaries only */
++ else if (!uid_eq(bprm->cred->euid, current->cred->uid) ||
++ !gid_eq(bprm->cred->egid, current->cred->gid))
+ return -EPERM;
+ }
+#endif
@@ -98230,7 +98286,7 @@ index c9fe145..9fb2337 100644
struct crypto_instance {
struct crypto_alg alg;
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
-index 8b5ce7c..a0ee191 100644
+index 8b5ce7c..89c5676 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -59,6 +59,7 @@
@@ -98268,16 +98324,17 @@ index 8b5ce7c..a0ee191 100644
/**
* Creates a driver or general drm_ioctl_desc array entry for the given
-@@ -630,7 +633,7 @@ struct drm_driver {
+@@ -630,7 +633,8 @@ struct drm_driver {
/* List of devices hanging off this driver with stealth attach. */
struct list_head legacy_dev_list;
-};
+} __do_const;
++typedef struct drm_driver __no_const drm_driver_no_const;
enum drm_minor_type {
DRM_MINOR_LEGACY,
-@@ -648,7 +651,8 @@ struct drm_info_list {
+@@ -648,7 +652,8 @@ struct drm_info_list {
int (*show)(struct seq_file*, void*); /** show callback */
u32 driver_features; /**< Required driver features for this entry */
void *data;
@@ -98287,7 +98344,7 @@ index 8b5ce7c..a0ee191 100644
/**
* debugfs node structure. This structure represents a debugfs file.
-@@ -735,7 +739,7 @@ struct drm_device {
+@@ -735,7 +740,7 @@ struct drm_device {
/** \name Usage Counters */
/*@{ */
@@ -103310,7 +103367,7 @@ index 556ec1e..38c19c9 100644
/*
diff --git a/include/linux/sched.h b/include/linux/sched.h
-index b7b9501..46d7e52 100644
+index b7b9501..ab1a134 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -7,7 +7,7 @@
@@ -103392,8 +103449,8 @@ index b7b9501..46d7e52 100644
+ unsigned char kernel_banned;
+#endif
+#ifdef CONFIG_GRKERNSEC_BRUTE
-+ unsigned char suid_banned;
-+ unsigned long suid_ban_expires;
++ unsigned char sugid_banned;
++ unsigned long sugid_ban_expires;
+#endif
+
/* Hash table maintenance information */
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [gentoo-commits] proj/hardened-patchset:master commit in: 4.3.3/
@ 2016-01-20 9:19 Anthony G. Basile
0 siblings, 0 replies; 7+ messages in thread
From: Anthony G. Basile @ 2016-01-20 9:19 UTC (permalink / raw
To: gentoo-commits
commit: c1427968c417e8fd39dac067208595ecd483e716
Author: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Wed Jan 20 09:26:30 2016 +0000
Commit: Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Wed Jan 20 09:26:30 2016 +0000
URL: https://gitweb.gentoo.org/proj/hardened-patchset.git/commit/?id=c1427968
grsecurity-3.1-4.3.3-201601192226
4.3.3/0000_README | 2 +-
...> 4420_grsecurity-3.1-4.3.3-201601192226.patch} | 939 ++++++++++++++++++++-
2 files changed, 916 insertions(+), 25 deletions(-)
diff --git a/4.3.3/0000_README b/4.3.3/0000_README
index 737c59b..a2a51bf 100644
--- a/4.3.3/0000_README
+++ b/4.3.3/0000_README
@@ -2,7 +2,7 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 4420_grsecurity-3.1-4.3.3-201601171913.patch
+Patch: 4420_grsecurity-3.1-4.3.3-201601192226.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/4.3.3/4420_grsecurity-3.1-4.3.3-201601171913.patch b/4.3.3/4420_grsecurity-3.1-4.3.3-201601192226.patch
similarity index 99%
rename from 4.3.3/4420_grsecurity-3.1-4.3.3-201601171913.patch
rename to 4.3.3/4420_grsecurity-3.1-4.3.3-201601192226.patch
index c47605c..e9f29bb 100644
--- a/4.3.3/4420_grsecurity-3.1-4.3.3-201601171913.patch
+++ b/4.3.3/4420_grsecurity-3.1-4.3.3-201601192226.patch
@@ -78014,19 +78014,386 @@ index 4d24d17..4f8c09e 100644
/*
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
-index 48851f6..6c79d32 100644
+index 48851f6..d6c96e5 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
-@@ -622,7 +622,7 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd,
+@@ -58,6 +58,8 @@
+ #include <linux/atalk.h>
+ #include <linux/gfp.h>
+
++#include "internal.h"
++
+ #include <net/bluetooth/bluetooth.h>
+ #include <net/bluetooth/hci_sock.h>
+ #include <net/bluetooth/rfcomm.h>
+@@ -115,19 +117,38 @@
+ #include <asm/fbio.h>
+ #endif
+
+-static int w_long(unsigned int fd, unsigned int cmd,
+- compat_ulong_t __user *argp)
++#define convert_in_user(srcptr, dstptr) \
++({ \
++ typeof(*srcptr) val; \
++ \
++ get_user(val, srcptr) || put_user(val, dstptr); \
++})
++
++static int do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ {
+- mm_segment_t old_fs = get_fs();
+ int err;
+- unsigned long val;
+
+- set_fs (KERNEL_DS);
+- err = sys_ioctl(fd, cmd, (unsigned long)&val);
+- set_fs (old_fs);
+- if (!err && put_user(val, argp))
++ err = security_file_ioctl(file, cmd, arg);
++ if (err)
++ return err;
++
++ return vfs_ioctl(file, cmd, arg);
++}
++
++static int w_long(struct file *file,
++ unsigned int cmd, compat_ulong_t __user *argp)
++{
++ int err;
++ unsigned long __user *valp = compat_alloc_user_space(sizeof(*valp));
++
++ if (valp == NULL)
++ return -EFAULT;
++ err = do_ioctl(file, cmd, (unsigned long)valp);
++ if (err)
++ return err;
++ if (convert_in_user(valp, argp))
+ return -EFAULT;
+- return err;
++ return 0;
+ }
+
+ struct compat_video_event {
+@@ -139,23 +160,23 @@ struct compat_video_event {
+ } u;
+ };
+
+-static int do_video_get_event(unsigned int fd, unsigned int cmd,
+- struct compat_video_event __user *up)
++static int do_video_get_event(struct file *file,
++ unsigned int cmd, struct compat_video_event __user *up)
+ {
+- struct video_event kevent;
+- mm_segment_t old_fs = get_fs();
++ struct video_event __user *kevent =
++ compat_alloc_user_space(sizeof(*kevent));
+ int err;
+
+- set_fs(KERNEL_DS);
+- err = sys_ioctl(fd, cmd, (unsigned long) &kevent);
+- set_fs(old_fs);
++ if (kevent == NULL)
++ return -EFAULT;
+
++ err = do_ioctl(file, cmd, (unsigned long)kevent);
+ if (!err) {
+- err = put_user(kevent.type, &up->type);
+- err |= put_user(kevent.timestamp, &up->timestamp);
+- err |= put_user(kevent.u.size.w, &up->u.size.w);
+- err |= put_user(kevent.u.size.h, &up->u.size.h);
+- err |= put_user(kevent.u.size.aspect_ratio,
++ err = convert_in_user(&kevent->type, &up->type);
++ err |= convert_in_user(&kevent->timestamp, &up->timestamp);
++ err |= convert_in_user(&kevent->u.size.w, &up->u.size.w);
++ err |= convert_in_user(&kevent->u.size.h, &up->u.size.h);
++ err |= convert_in_user(&kevent->u.size.aspect_ratio,
+ &up->u.size.aspect_ratio);
+ if (err)
+ err = -EFAULT;
+@@ -169,8 +190,8 @@ struct compat_video_still_picture {
+ int32_t size;
+ };
+
+-static int do_video_stillpicture(unsigned int fd, unsigned int cmd,
+- struct compat_video_still_picture __user *up)
++static int do_video_stillpicture(struct file *file,
++ unsigned int cmd, struct compat_video_still_picture __user *up)
+ {
+ struct video_still_picture __user *up_native;
+ compat_uptr_t fp;
+@@ -190,7 +211,7 @@ static int do_video_stillpicture(unsigned int fd, unsigned int cmd,
+ if (err)
+ return -EFAULT;
+
+- err = sys_ioctl(fd, cmd, (unsigned long) up_native);
++ err = do_ioctl(file, cmd, (unsigned long) up_native);
+
+ return err;
+ }
+@@ -200,8 +221,8 @@ struct compat_video_spu_palette {
+ compat_uptr_t palette;
+ };
+
+-static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd,
+- struct compat_video_spu_palette __user *up)
++static int do_video_set_spu_palette(struct file *file,
++ unsigned int cmd, struct compat_video_spu_palette __user *up)
+ {
+ struct video_spu_palette __user *up_native;
+ compat_uptr_t palp;
+@@ -218,7 +239,7 @@ static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd,
+ if (err)
+ return -EFAULT;
+
+- err = sys_ioctl(fd, cmd, (unsigned long) up_native);
++ err = do_ioctl(file, cmd, (unsigned long) up_native);
+
+ return err;
+ }
+@@ -276,7 +297,7 @@ static int sg_build_iovec(sg_io_hdr_t __user *sgio, void __user *dxferp, u16 iov
+ return 0;
+ }
+
+-static int sg_ioctl_trans(unsigned int fd, unsigned int cmd,
++static int sg_ioctl_trans(struct file *file, unsigned int cmd,
+ sg_io_hdr32_t __user *sgio32)
+ {
+ sg_io_hdr_t __user *sgio;
+@@ -289,7 +310,7 @@ static int sg_ioctl_trans(unsigned int fd, unsigned int cmd,
+ if (get_user(interface_id, &sgio32->interface_id))
+ return -EFAULT;
+ if (interface_id != 'S')
+- return sys_ioctl(fd, cmd, (unsigned long)sgio32);
++ return do_ioctl(file, cmd, (unsigned long)sgio32);
+
+ if (get_user(iovec_count, &sgio32->iovec_count))
+ return -EFAULT;
+@@ -349,7 +370,7 @@ static int sg_ioctl_trans(unsigned int fd, unsigned int cmd,
+ if (put_user(compat_ptr(data), &sgio->usr_ptr))
+ return -EFAULT;
+
+- err = sys_ioctl(fd, cmd, (unsigned long) sgio);
++ err = do_ioctl(file, cmd, (unsigned long) sgio);
+
+ if (err >= 0) {
+ void __user *datap;
+@@ -380,13 +401,13 @@ struct compat_sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */
+ int unused;
+ };
+
+-static int sg_grt_trans(unsigned int fd, unsigned int cmd, struct
+- compat_sg_req_info __user *o)
++static int sg_grt_trans(struct file *file,
++ unsigned int cmd, struct compat_sg_req_info __user *o)
+ {
+ int err, i;
+ sg_req_info_t __user *r;
+ r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE);
+- err = sys_ioctl(fd,cmd,(unsigned long)r);
++ err = do_ioctl(file, cmd, (unsigned long)r);
+ if (err < 0)
+ return err;
+ for (i = 0; i < SG_MAX_QUEUE; i++) {
+@@ -412,8 +433,8 @@ struct sock_fprog32 {
+ #define PPPIOCSPASS32 _IOW('t', 71, struct sock_fprog32)
+ #define PPPIOCSACTIVE32 _IOW('t', 70, struct sock_fprog32)
+
+-static int ppp_sock_fprog_ioctl_trans(unsigned int fd, unsigned int cmd,
+- struct sock_fprog32 __user *u_fprog32)
++static int ppp_sock_fprog_ioctl_trans(struct file *file,
++ unsigned int cmd, struct sock_fprog32 __user *u_fprog32)
+ {
+ struct sock_fprog __user *u_fprog64 = compat_alloc_user_space(sizeof(struct sock_fprog));
+ void __user *fptr64;
+@@ -435,7 +456,7 @@ static int ppp_sock_fprog_ioctl_trans(unsigned int fd, unsigned int cmd,
+ else
+ cmd = PPPIOCSACTIVE;
+
+- return sys_ioctl(fd, cmd, (unsigned long) u_fprog64);
++ return do_ioctl(file, cmd, (unsigned long) u_fprog64);
+ }
+
+ struct ppp_option_data32 {
+@@ -451,7 +472,7 @@ struct ppp_idle32 {
+ };
+ #define PPPIOCGIDLE32 _IOR('t', 63, struct ppp_idle32)
+
+-static int ppp_gidle(unsigned int fd, unsigned int cmd,
++static int ppp_gidle(struct file *file, unsigned int cmd,
+ struct ppp_idle32 __user *idle32)
+ {
+ struct ppp_idle __user *idle;
+@@ -460,7 +481,7 @@ static int ppp_gidle(unsigned int fd, unsigned int cmd,
+
+ idle = compat_alloc_user_space(sizeof(*idle));
+
+- err = sys_ioctl(fd, PPPIOCGIDLE, (unsigned long) idle);
++ err = do_ioctl(file, PPPIOCGIDLE, (unsigned long) idle);
+
+ if (!err) {
+ if (get_user(xmit, &idle->xmit_idle) ||
+@@ -472,7 +493,7 @@ static int ppp_gidle(unsigned int fd, unsigned int cmd,
+ return err;
+ }
+
+-static int ppp_scompress(unsigned int fd, unsigned int cmd,
++static int ppp_scompress(struct file *file, unsigned int cmd,
+ struct ppp_option_data32 __user *odata32)
+ {
+ struct ppp_option_data __user *odata;
+@@ -492,7 +513,7 @@ static int ppp_scompress(unsigned int fd, unsigned int cmd,
+ sizeof(__u32) + sizeof(int)))
+ return -EFAULT;
+
+- return sys_ioctl(fd, PPPIOCSCOMPRESS, (unsigned long) odata);
++ return do_ioctl(file, PPPIOCSCOMPRESS, (unsigned long) odata);
+ }
+
+ #ifdef CONFIG_BLOCK
+@@ -512,12 +533,13 @@ struct mtpos32 {
+ };
+ #define MTIOCPOS32 _IOR('m', 3, struct mtpos32)
+
+-static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, void __user *argp)
++static int mt_ioctl_trans(struct file *file,
++ unsigned int cmd, void __user *argp)
+ {
+- mm_segment_t old_fs = get_fs();
+- struct mtget get;
++ /* NULL initialization to make gcc shut up */
++ struct mtget __user *get = NULL;
+ struct mtget32 __user *umget32;
+- struct mtpos pos;
++ struct mtpos __user *pos = NULL;
+ struct mtpos32 __user *upos32;
+ unsigned long kcmd;
+ void *karg;
+@@ -526,32 +548,34 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, void __user *argp)
+ switch(cmd) {
+ case MTIOCPOS32:
+ kcmd = MTIOCPOS;
+- karg = &pos;
++ pos = compat_alloc_user_space(sizeof(*pos));
++ karg = pos;
+ break;
+ default: /* MTIOCGET32 */
+ kcmd = MTIOCGET;
+- karg = &get;
++ get = compat_alloc_user_space(sizeof(*get));
++ karg = get;
+ break;
+ }
+- set_fs (KERNEL_DS);
+- err = sys_ioctl (fd, kcmd, (unsigned long)karg);
+- set_fs (old_fs);
++ if (karg == NULL)
++ return -EFAULT;
++ err = do_ioctl(file, kcmd, (unsigned long)karg);
+ if (err)
+ return err;
+ switch (cmd) {
+ case MTIOCPOS32:
+ upos32 = argp;
+- err = __put_user(pos.mt_blkno, &upos32->mt_blkno);
++ err = convert_in_user(&pos->mt_blkno, &upos32->mt_blkno);
+ break;
+ case MTIOCGET32:
+ umget32 = argp;
+- err = __put_user(get.mt_type, &umget32->mt_type);
+- err |= __put_user(get.mt_resid, &umget32->mt_resid);
+- err |= __put_user(get.mt_dsreg, &umget32->mt_dsreg);
+- err |= __put_user(get.mt_gstat, &umget32->mt_gstat);
+- err |= __put_user(get.mt_erreg, &umget32->mt_erreg);
+- err |= __put_user(get.mt_fileno, &umget32->mt_fileno);
+- err |= __put_user(get.mt_blkno, &umget32->mt_blkno);
++ err = convert_in_user(&get->mt_type, &umget32->mt_type);
++ err |= convert_in_user(&get->mt_resid, &umget32->mt_resid);
++ err |= convert_in_user(&get->mt_dsreg, &umget32->mt_dsreg);
++ err |= convert_in_user(&get->mt_gstat, &umget32->mt_gstat);
++ err |= convert_in_user(&get->mt_erreg, &umget32->mt_erreg);
++ err |= convert_in_user(&get->mt_fileno, &umget32->mt_fileno);
++ err |= convert_in_user(&get->mt_blkno, &umget32->mt_blkno);
+ break;
+ }
+ return err ? -EFAULT: 0;
+@@ -605,42 +629,41 @@ struct serial_struct32 {
+ compat_int_t reserved[1];
+ };
+
+-static int serial_struct_ioctl(unsigned fd, unsigned cmd,
+- struct serial_struct32 __user *ss32)
++static int serial_struct_ioctl(struct file *file,
++ unsigned cmd, struct serial_struct32 __user *ss32)
+ {
+ typedef struct serial_struct32 SS32;
+ int err;
+- struct serial_struct ss;
+- mm_segment_t oldseg = get_fs();
++ struct serial_struct __user *ss = compat_alloc_user_space(sizeof(*ss));
+ __u32 udata;
+ unsigned int base;
++ unsigned char *iomem_base;
+
++ if (ss == NULL)
++ return -EFAULT;
+ if (cmd == TIOCSSERIAL) {
+- if (!access_ok(VERIFY_READ, ss32, sizeof(SS32)))
+- return -EFAULT;
+- if (__copy_from_user(&ss, ss32, offsetof(SS32, iomem_base)))
++ if (copy_in_user(ss, ss32, offsetof(SS32, iomem_base)) ||
++ get_user(udata, &ss32->iomem_base))
return -EFAULT;
- if (__get_user(udata, &ss32->iomem_base))
+- if (__get_user(udata, &ss32->iomem_base))
++ iomem_base = compat_ptr(udata);
++ if (put_user(iomem_base, &ss->iomem_base) ||
++ convert_in_user(&ss32->iomem_reg_shift,
++ &ss->iomem_reg_shift) ||
++ convert_in_user(&ss32->port_high, &ss->port_high) ||
++ put_user(0UL, &ss->iomap_base))
return -EFAULT;
- ss.iomem_base = compat_ptr(udata);
-+ ss.iomem_base = (unsigned char __force_kernel *)compat_ptr(udata);
- if (__get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift) ||
- __get_user(ss.port_high, &ss32->port_high))
+- if (__get_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift) ||
+- __get_user(ss.port_high, &ss32->port_high))
+- return -EFAULT;
+- ss.iomap_base = 0UL;
+ }
+- set_fs(KERNEL_DS);
+- err = sys_ioctl(fd,cmd,(unsigned long)(&ss));
+- set_fs(oldseg);
++ err = do_ioctl(file, cmd, (unsigned long)ss);
+ if (cmd == TIOCGSERIAL && err >= 0) {
+- if (!access_ok(VERIFY_WRITE, ss32, sizeof(SS32)))
+- return -EFAULT;
+- if (__copy_to_user(ss32,&ss,offsetof(SS32,iomem_base)))
++ if (copy_in_user(ss32, ss, offsetof(SS32, iomem_base)) ||
++ get_user(iomem_base, &ss->iomem_base))
+ return -EFAULT;
+- base = (unsigned long)ss.iomem_base >> 32 ?
+- 0xffffffff : (unsigned)(unsigned long)ss.iomem_base;
+- if (__put_user(base, &ss32->iomem_base) ||
+- __put_user(ss.iomem_reg_shift, &ss32->iomem_reg_shift) ||
+- __put_user(ss.port_high, &ss32->port_high))
++ base = (unsigned long)iomem_base >> 32 ?
++ 0xffffffff : (unsigned)(unsigned long)iomem_base;
++ if (put_user(base, &ss32->iomem_base) ||
++ convert_in_user(&ss->iomem_reg_shift,
++ &ss32->iomem_reg_shift) ||
++ convert_in_user(&ss->port_high, &ss32->port_high))
return -EFAULT;
-@@ -704,8 +704,8 @@ static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd,
+ }
+ return err;
+@@ -674,8 +697,8 @@ struct i2c_rdwr_aligned {
+ struct i2c_msg msgs[0];
+ };
+
+-static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd,
+- struct i2c_rdwr_ioctl_data32 __user *udata)
++static int do_i2c_rdwr_ioctl(struct file *file,
++ unsigned int cmd, struct i2c_rdwr_ioctl_data32 __user *udata)
+ {
+ struct i2c_rdwr_aligned __user *tdata;
+ struct i2c_msg __user *tmsgs;
+@@ -704,15 +727,15 @@ static int do_i2c_rdwr_ioctl(unsigned int fd, unsigned int cmd,
for (i = 0; i < nmsgs; i++) {
if (copy_in_user(&tmsgs[i].addr, &umsgs[i].addr, 3*sizeof(u16)))
return -EFAULT;
@@ -78036,8 +78403,67 @@ index 48851f6..6c79d32 100644
+ put_user(compat_ptr(datap), (u8 __user * __user *)&tmsgs[i].buf))
return -EFAULT;
}
- return sys_ioctl(fd, cmd, (unsigned long)tdata);
-@@ -798,7 +798,7 @@ static int compat_ioctl_preallocate(struct file *file,
+- return sys_ioctl(fd, cmd, (unsigned long)tdata);
++ return do_ioctl(file, cmd, (unsigned long)tdata);
+ }
+
+-static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd,
+- struct i2c_smbus_ioctl_data32 __user *udata)
++static int do_i2c_smbus_ioctl(struct file *file,
++ unsigned int cmd, struct i2c_smbus_ioctl_data32 __user *udata)
+ {
+ struct i2c_smbus_ioctl_data __user *tdata;
+ compat_caddr_t datap;
+@@ -734,7 +757,7 @@ static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd,
+ __put_user(compat_ptr(datap), &tdata->data))
+ return -EFAULT;
+
+- return sys_ioctl(fd, cmd, (unsigned long)tdata);
++ return do_ioctl(file, cmd, (unsigned long)tdata);
+ }
+
+ #define RTC_IRQP_READ32 _IOR('p', 0x0b, compat_ulong_t)
+@@ -742,29 +765,27 @@ static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd,
+ #define RTC_EPOCH_READ32 _IOR('p', 0x0d, compat_ulong_t)
+ #define RTC_EPOCH_SET32 _IOW('p', 0x0e, compat_ulong_t)
+
+-static int rtc_ioctl(unsigned fd, unsigned cmd, void __user *argp)
++static int rtc_ioctl(struct file *file,
++ unsigned cmd, void __user *argp)
+ {
+- mm_segment_t oldfs = get_fs();
+- compat_ulong_t val32;
+- unsigned long kval;
++ unsigned long __user *valp = compat_alloc_user_space(sizeof(*valp));
+ int ret;
+
++ if (valp == NULL)
++ return -EFAULT;
+ switch (cmd) {
+ case RTC_IRQP_READ32:
+ case RTC_EPOCH_READ32:
+- set_fs(KERNEL_DS);
+- ret = sys_ioctl(fd, (cmd == RTC_IRQP_READ32) ?
++ ret = do_ioctl(file, (cmd == RTC_IRQP_READ32) ?
+ RTC_IRQP_READ : RTC_EPOCH_READ,
+- (unsigned long)&kval);
+- set_fs(oldfs);
++ (unsigned long)valp);
+ if (ret)
+ return ret;
+- val32 = kval;
+- return put_user(val32, (unsigned int __user *)argp);
++ return convert_in_user(valp, (unsigned int __user *)argp);
+ case RTC_IRQP_SET32:
+- return sys_ioctl(fd, RTC_IRQP_SET, (unsigned long)argp);
++ return do_ioctl(file, RTC_IRQP_SET, (unsigned long)argp);
+ case RTC_EPOCH_SET32:
+- return sys_ioctl(fd, RTC_EPOCH_SET, (unsigned long)argp);
++ return do_ioctl(file, RTC_EPOCH_SET, (unsigned long)argp);
+ }
+
+ return -ENOIOCTLCMD;
+@@ -798,7 +819,7 @@ static int compat_ioctl_preallocate(struct file *file,
copy_in_user(&p->l_len, &p32->l_len, sizeof(s64)) ||
copy_in_user(&p->l_sysid, &p32->l_sysid, sizeof(s32)) ||
copy_in_user(&p->l_pid, &p32->l_pid, sizeof(u32)) ||
@@ -78046,7 +78472,94 @@ index 48851f6..6c79d32 100644
return -EFAULT;
return ioctl_preallocate(file, p);
-@@ -1621,8 +1621,8 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
+@@ -1436,53 +1457,53 @@ IGNORE_IOCTL(FBIOGCURSOR32)
+ * a compat_ioctl operation in the place that handleѕ the
+ * ioctl for the native case.
+ */
+-static long do_ioctl_trans(int fd, unsigned int cmd,
++static long do_ioctl_trans(unsigned int cmd,
+ unsigned long arg, struct file *file)
+ {
+ void __user *argp = compat_ptr(arg);
+
+ switch (cmd) {
+ case PPPIOCGIDLE32:
+- return ppp_gidle(fd, cmd, argp);
++ return ppp_gidle(file, cmd, argp);
+ case PPPIOCSCOMPRESS32:
+- return ppp_scompress(fd, cmd, argp);
++ return ppp_scompress(file, cmd, argp);
+ case PPPIOCSPASS32:
+ case PPPIOCSACTIVE32:
+- return ppp_sock_fprog_ioctl_trans(fd, cmd, argp);
++ return ppp_sock_fprog_ioctl_trans(file, cmd, argp);
+ #ifdef CONFIG_BLOCK
+ case SG_IO:
+- return sg_ioctl_trans(fd, cmd, argp);
++ return sg_ioctl_trans(file, cmd, argp);
+ case SG_GET_REQUEST_TABLE:
+- return sg_grt_trans(fd, cmd, argp);
++ return sg_grt_trans(file, cmd, argp);
+ case MTIOCGET32:
+ case MTIOCPOS32:
+- return mt_ioctl_trans(fd, cmd, argp);
++ return mt_ioctl_trans(file, cmd, argp);
+ #endif
+ /* Serial */
+ case TIOCGSERIAL:
+ case TIOCSSERIAL:
+- return serial_struct_ioctl(fd, cmd, argp);
++ return serial_struct_ioctl(file, cmd, argp);
+ /* i2c */
+ case I2C_FUNCS:
+- return w_long(fd, cmd, argp);
++ return w_long(file, cmd, argp);
+ case I2C_RDWR:
+- return do_i2c_rdwr_ioctl(fd, cmd, argp);
++ return do_i2c_rdwr_ioctl(file, cmd, argp);
+ case I2C_SMBUS:
+- return do_i2c_smbus_ioctl(fd, cmd, argp);
++ return do_i2c_smbus_ioctl(file, cmd, argp);
+ /* Not implemented in the native kernel */
+ case RTC_IRQP_READ32:
+ case RTC_IRQP_SET32:
+ case RTC_EPOCH_READ32:
+ case RTC_EPOCH_SET32:
+- return rtc_ioctl(fd, cmd, argp);
++ return rtc_ioctl(file, cmd, argp);
+
+ /* dvb */
+ case VIDEO_GET_EVENT:
+- return do_video_get_event(fd, cmd, argp);
++ return do_video_get_event(file, cmd, argp);
+ case VIDEO_STILLPICTURE:
+- return do_video_stillpicture(fd, cmd, argp);
++ return do_video_stillpicture(file, cmd, argp);
+ case VIDEO_SET_SPU_PALETTE:
+- return do_video_set_spu_palette(fd, cmd, argp);
++ return do_video_set_spu_palette(file, cmd, argp);
+ }
+
+ /*
+@@ -1513,7 +1534,7 @@ static long do_ioctl_trans(int fd, unsigned int cmd,
+ case NBD_SET_BLKSIZE:
+ case NBD_SET_SIZE:
+ case NBD_SET_SIZE_BLOCKS:
+- return do_vfs_ioctl(file, fd, cmd, arg);
++ return vfs_ioctl(file, cmd, arg);
+ }
+
+ return -ENOIOCTLCMD;
+@@ -1602,7 +1623,7 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
+ if (compat_ioctl_check_table(XFORM(cmd)))
+ goto found_handler;
+
+- error = do_ioctl_trans(fd, cmd, arg, f.file);
++ error = do_ioctl_trans(cmd, arg, f.file);
+ if (error == -ENOIOCTLCMD)
+ error = -ENOTTY;
+
+@@ -1621,8 +1642,8 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
static int __init init_sys32_ioctl_cmp(const void *p, const void *q)
{
unsigned int a, b;
@@ -79437,6 +79950,19 @@ index fd1f28b..eb832cf 100644
atomic_t s_lock_busy;
/* locality groups */
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 7f486e3..2d61649 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -862,7 +862,7 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block,
+ struct ext4_extent_header *eh;
+ struct buffer_head *bh;
+ struct ext4_ext_path *path = orig_path ? *orig_path : NULL;
+- short int depth, i, ppos = 0;
++ int depth, i, ppos = 0;
+ int ret;
+
+ eh = ext_inode_hdr(inode);
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 34b610e..ecc47cb 100644
--- a/fs/ext4/mballoc.c
@@ -81629,6 +82155,43 @@ index 78a17b8..fb43210 100644
*p = res;
put_cpu_var(last_ino);
return res;
+diff --git a/fs/internal.h b/fs/internal.h
+index 71859c4d..e38c08c 100644
+--- a/fs/internal.h
++++ b/fs/internal.h
+@@ -151,3 +151,10 @@ extern void mnt_pin_kill(struct mount *m);
+ * fs/nsfs.c
+ */
+ extern struct dentry_operations ns_dentry_operations;
++
++/*
++ * fs/ioctl.c
++ */
++extern int do_vfs_ioctl(struct file *file, unsigned int fd, unsigned int cmd,
++ unsigned long arg);
++extern long vfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+diff --git a/fs/ioctl.c b/fs/ioctl.c
+index 5d01d26..41c352e 100644
+--- a/fs/ioctl.c
++++ b/fs/ioctl.c
+@@ -15,6 +15,7 @@
+ #include <linux/writeback.h>
+ #include <linux/buffer_head.h>
+ #include <linux/falloc.h>
++#include "internal.h"
+
+ #include <asm/ioctls.h>
+
+@@ -32,8 +33,7 @@
+ *
+ * Returns 0 on success, -errno on error.
+ */
+-static long vfs_ioctl(struct file *filp, unsigned int cmd,
+- unsigned long arg)
++long vfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+ {
+ int error = -ENOTTY;
+
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index 4a6cf28..d3a29d3 100644
--- a/fs/jffs2/erase.c
@@ -96438,10 +97001,10 @@ index 0000000..304c518
+}
diff --git a/grsecurity/grsec_sig.c b/grsecurity/grsec_sig.c
new file mode 100644
-index 0000000..528fd00
+index 0000000..f50742d
--- /dev/null
+++ b/grsecurity/grsec_sig.c
-@@ -0,0 +1,244 @@
+@@ -0,0 +1,245 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
@@ -96449,6 +97012,7 @@ index 0000000..528fd00
+#include <linux/grsecurity.h>
+#include <linux/grinternal.h>
+#include <linux/hardirq.h>
++#include <asm/pgtable.h>
+
+char *signames[] = {
+ [SIGSEGV] = "Segmentation fault",
@@ -99523,7 +100087,7 @@ index fa2cab9..d42a5b8 100644
{
BUG_ON(ftest->code & BPF_ANC);
diff --git a/include/linux/fs.h b/include/linux/fs.h
-index 72d8a84..4027250 100644
+index 72d8a84..d67bd25 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -439,7 +439,7 @@ struct address_space {
@@ -99599,7 +100163,16 @@ index 72d8a84..4027250 100644
unsigned int count, const char *name);
extern void unregister_chrdev_region(dev_t, unsigned);
extern void chrdev_show(struct seq_file *,off_t);
-@@ -3040,4 +3041,14 @@ static inline bool dir_relax(struct inode *inode)
+@@ -2778,8 +2779,6 @@ extern int vfs_lstat(const char __user *, struct kstat *);
+ extern int vfs_fstat(unsigned int, struct kstat *);
+ extern int vfs_fstatat(int , const char __user *, struct kstat *, int);
+
+-extern int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd,
+- unsigned long arg);
+ extern int __generic_block_fiemap(struct inode *inode,
+ struct fiemap_extent_info *fieinfo,
+ loff_t start, loff_t len,
+@@ -3040,4 +3039,14 @@ static inline bool dir_relax(struct inode *inode)
extern bool path_noexec(const struct path *path);
@@ -101451,15 +102024,24 @@ index 6883e19..e854fcb 100644
/* This macro allows us to keep printk typechecking */
static __printf(1, 2)
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
-index ff9f1d3..6712be5 100644
+index ff9f1d3..77627d8 100644
--- a/include/linux/key-type.h
+++ b/include/linux/key-type.h
+@@ -47,7 +47,7 @@ struct key_preparsed_payload {
+ size_t quotalen; /* Quota length for proposed payload */
+ time_t expiry; /* Expiry time of key */
+ bool trusted; /* True if key is trusted */
+-};
++} __randomize_layout;
+
+ typedef int (*request_key_actor_t)(struct key_construction *key,
+ const char *op, void *aux);
@@ -152,7 +152,7 @@ struct key_type {
/* internal fields */
struct list_head link; /* link in types list */
struct lock_class_key lock_class; /* key->sem lock class */
-};
-+} __do_const;
++} __do_const __randomize_layout;
extern struct key_type key_type_keyring;
@@ -102798,10 +103380,10 @@ index 5df733b..d55f252 100644
/* config parameters */
#define PNP_CONFIG_NORMAL 0x0001
diff --git a/include/linux/poison.h b/include/linux/poison.h
-index 317e16d..924c034 100644
+index 317e16d..c5701ff 100644
--- a/include/linux/poison.h
+++ b/include/linux/poison.h
-@@ -19,8 +19,8 @@
+@@ -19,15 +19,15 @@
* under normal circumstances, used to verify that nobody uses
* non-initialized list entries.
*/
@@ -102812,6 +103394,14 @@ index 317e16d..924c034 100644
/********** include/linux/timer.h **********/
/*
+ * Magic number "tsta" to indicate a static timer initializer
+ * for the object debugging code.
+ */
+-#define TIMER_ENTRY_STATIC ((void *) 0x74737461)
++#define TIMER_ENTRY_STATIC ((void *) 0x300 + POISON_POINTER_DELTA)
+
+ /********** mm/debug-pagealloc.c **********/
+ #define PAGE_POISON 0xaa
diff --git a/include/linux/power/smartreflex.h b/include/linux/power/smartreflex.h
index d8b187c3..9a9257a 100644
--- a/include/linux/power/smartreflex.h
@@ -107280,6 +107870,28 @@ index 1471db9..dbdcf7f 100644
seq_printf(s,
"%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n",
+diff --git a/ipc/msgutil.c b/ipc/msgutil.c
+index 71f448e..5cb11f3 100644
+--- a/ipc/msgutil.c
++++ b/ipc/msgutil.c
+@@ -55,7 +55,7 @@ static struct msg_msg *alloc_msg(size_t len)
+ size_t alen;
+
+ alen = min(len, DATALEN_MSG);
+- msg = kmalloc(sizeof(*msg) + alen, GFP_KERNEL);
++ msg = kmalloc(sizeof(*msg) + alen, GFP_KERNEL|GFP_USERCOPY);
+ if (msg == NULL)
+ return NULL;
+
+@@ -67,7 +67,7 @@ static struct msg_msg *alloc_msg(size_t len)
+ while (len > 0) {
+ struct msg_msgseg *seg;
+ alen = min(len, DATALEN_SEG);
+- seg = kmalloc(sizeof(*seg) + alen, GFP_KERNEL);
++ seg = kmalloc(sizeof(*seg) + alen, GFP_KERNEL|GFP_USERCOPY);
+ if (seg == NULL)
+ goto out_err;
+ *pseg = seg;
diff --git a/ipc/sem.c b/ipc/sem.c
index b471e5a..cb0c603 100644
--- a/ipc/sem.c
@@ -124347,7 +124959,7 @@ index b9ac598..f88cc56 100644
return;
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
-index 918151c..5bbe95a 100644
+index 918151c..2186df8 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -686,10 +686,10 @@ static void __iucv_auto_name(struct iucv_sock *iucv)
@@ -124363,6 +124975,16 @@ index 918151c..5bbe95a 100644
}
memcpy(iucv->src_name, name, 8);
}
+@@ -709,6 +709,9 @@ static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr,
+ if (!addr || addr->sa_family != AF_IUCV)
+ return -EINVAL;
+
++ if (addr_len < sizeof(struct sockaddr_iucv))
++ return -EINVAL;
++
+ lock_sock(sk);
+ if (sk->sk_state != IUCV_OPEN) {
+ err = -EBADFD;
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index 2a6a1fd..6c112b0 100644
--- a/net/iucv/iucv.c
@@ -125371,6 +125993,42 @@ index fafe33b..8896912 100644
sock_i_ino(s)
);
+diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
+index dba635d..0d2884b 100644
+--- a/net/openvswitch/actions.c
++++ b/net/openvswitch/actions.c
+@@ -1159,17 +1159,26 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb,
+ const struct sw_flow_actions *acts,
+ struct sw_flow_key *key)
+ {
+- int level = this_cpu_read(exec_actions_level);
+- int err;
++ static const int ovs_recursion_limit = 5;
++ int err, level;
++
++ level = __this_cpu_inc_return(exec_actions_level);
++ if (unlikely(level > ovs_recursion_limit)) {
++ net_crit_ratelimited("ovs: recursion limit reached on datapath %s, probable configuration error\n",
++ ovs_dp_name(dp));
++ kfree_skb(skb);
++ err = -ENETDOWN;
++ goto out;
++ }
+
+- this_cpu_inc(exec_actions_level);
+ err = do_execute_actions(dp, skb, key,
+ acts->actions, acts->actions_len);
+
+- if (!level)
++ if (level == 1)
+ process_deferred_actions(dp);
+
+- this_cpu_dec(exec_actions_level);
++out:
++ __this_cpu_dec(exec_actions_level);
+ return err;
+ }
+
diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
index b393412..3b2f7eb 100644
--- a/net/openvswitch/vport-internal_dev.c
@@ -129759,7 +130417,7 @@ index 552705d..9920f4fb 100644
hlist_add_head_rcu(&qe->hnext, &ima_htable.queue[key]);
return 0;
diff --git a/security/keys/internal.h b/security/keys/internal.h
-index 5105c2c..fd59e52 100644
+index 5105c2c..a5010e6 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -90,12 +90,16 @@ extern void key_type_put(struct key_type *ktype);
@@ -129781,6 +130439,15 @@ index 5105c2c..fd59e52 100644
extern key_ref_t find_key_to_update(key_ref_t keyring_ref,
const struct keyring_index_key *index_key);
+@@ -191,7 +195,7 @@ struct request_key_auth {
+ void *callout_info;
+ size_t callout_len;
+ pid_t pid;
+-};
++} __randomize_layout;
+
+ extern struct key_type key_type_request_key_auth;
+ extern struct key *request_key_auth_new(struct key *target,
diff --git a/security/keys/key.c b/security/keys/key.c
index aee2ec5..c276071 100644
--- a/security/keys/key.c
@@ -129890,6 +130557,18 @@ index d334370..b03e5a8 100644
{
BUG_ON(index_key->type == NULL);
kenter("%d,%s,", keyring->serial, index_key->type->name);
+diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
+index 43b4cdd..7877e5c 100644
+--- a/security/keys/process_keys.c
++++ b/security/keys/process_keys.c
+@@ -794,6 +794,7 @@ long join_session_keyring(const char *name)
+ ret = PTR_ERR(keyring);
+ goto error2;
+ } else if (keyring == new->session_keyring) {
++ key_put(keyring);
+ ret = 0;
+ goto error2;
+ }
diff --git a/security/min_addr.c b/security/min_addr.c
index f728728..6457a0c 100644
--- a/security/min_addr.c
@@ -130207,6 +130886,27 @@ index ffd2025..df062c9 100644
/* PCM3052 register definitions */
+diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
+index f845ecf..656d9a9 100644
+--- a/sound/core/hrtimer.c
++++ b/sound/core/hrtimer.c
+@@ -90,7 +90,7 @@ static int snd_hrtimer_start(struct snd_timer *t)
+ struct snd_hrtimer *stime = t->private_data;
+
+ atomic_set(&stime->running, 0);
+- hrtimer_cancel(&stime->hrt);
++ hrtimer_try_to_cancel(&stime->hrt);
+ hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
+ HRTIMER_MODE_REL);
+ atomic_set(&stime->running, 1);
+@@ -101,6 +101,7 @@ static int snd_hrtimer_stop(struct snd_timer *t)
+ {
+ struct snd_hrtimer *stime = t->private_data;
+ atomic_set(&stime->running, 0);
++ hrtimer_try_to_cancel(&stime->hrt);
+ return 0;
+ }
+
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 58550cc..4687a93 100644
--- a/sound/core/oss/pcm_oss.c
@@ -130314,7 +131014,7 @@ index 75888dd..c940854 100644
default:
result = -EINVAL;
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
-index b64f20d..aff6c32 100644
+index b64f20d..a68addd 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -446,7 +446,7 @@ static ssize_t snd_seq_read(struct file *file, char __user *buf, size_t count,
@@ -130342,6 +131042,15 @@ index b64f20d..aff6c32 100644
event.data.ext.ptr = ptr;
}
#endif
+@@ -1962,7 +1962,7 @@ static int snd_seq_ioctl_remove_events(struct snd_seq_client *client,
+ * No restrictions so for a user client we can clear
+ * the whole fifo
+ */
+- if (client->type == USER_CLIENT)
++ if (client->type == USER_CLIENT && client->data.user.fifo)
+ snd_seq_fifo_clear(client->data.user.fifo);
+ }
+
@@ -2420,7 +2420,7 @@ int snd_seq_kernel_client_ctl(int clientid, unsigned int cmd, void *arg)
if (client == NULL)
return -ENXIO;
@@ -130395,6 +131104,21 @@ index 8010766..4bd361f 100644
err = -EFAULT;
goto __error;
}
+diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c
+index 7dfd0f4..0bec02e 100644
+--- a/sound/core/seq/seq_queue.c
++++ b/sound/core/seq/seq_queue.c
+@@ -142,8 +142,10 @@ static struct snd_seq_queue *queue_new(int owner, int locked)
+ static void queue_delete(struct snd_seq_queue *q)
+ {
+ /* stop and release the timer */
++ mutex_lock(&q->timer_mutex);
+ snd_seq_timer_stop(q->timer);
+ snd_seq_timer_close(q);
++ mutex_unlock(&q->timer_mutex);
+ /* wait until access free */
+ snd_use_lock_sync(&q->use_lock);
+ /* release resources... */
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 175f9e4..3518d31 100644
--- a/sound/core/sound.c
@@ -130408,6 +131132,171 @@ index 175f9e4..3518d31 100644
}
#endif /* modular kernel */
+diff --git a/sound/core/timer.c b/sound/core/timer.c
+index 31f40f0..4e8d7bf 100644
+--- a/sound/core/timer.c
++++ b/sound/core/timer.c
+@@ -73,7 +73,7 @@ struct snd_timer_user {
+ struct timespec tstamp; /* trigger tstamp */
+ wait_queue_head_t qchange_sleep;
+ struct fasync_struct *fasync;
+- struct mutex tread_sem;
++ struct mutex ioctl_lock;
+ };
+
+ /* list of timers */
+@@ -215,11 +215,13 @@ static void snd_timer_check_master(struct snd_timer_instance *master)
+ slave->slave_id == master->slave_id) {
+ list_move_tail(&slave->open_list, &master->slave_list_head);
+ spin_lock_irq(&slave_active_lock);
++ spin_lock(&master->timer->lock);
+ slave->master = master;
+ slave->timer = master->timer;
+ if (slave->flags & SNDRV_TIMER_IFLG_RUNNING)
+ list_add_tail(&slave->active_list,
+ &master->slave_active_head);
++ spin_unlock(&master->timer->lock);
+ spin_unlock_irq(&slave_active_lock);
+ }
+ }
+@@ -346,15 +348,18 @@ int snd_timer_close(struct snd_timer_instance *timeri)
+ timer->hw.close)
+ timer->hw.close(timer);
+ /* remove slave links */
++ spin_lock_irq(&slave_active_lock);
++ spin_lock(&timer->lock);
+ list_for_each_entry_safe(slave, tmp, &timeri->slave_list_head,
+ open_list) {
+- spin_lock_irq(&slave_active_lock);
+- _snd_timer_stop(slave, 1, SNDRV_TIMER_EVENT_RESOLUTION);
+ list_move_tail(&slave->open_list, &snd_timer_slave_list);
+ slave->master = NULL;
+ slave->timer = NULL;
+- spin_unlock_irq(&slave_active_lock);
++ list_del_init(&slave->ack_list);
++ list_del_init(&slave->active_list);
+ }
++ spin_unlock(&timer->lock);
++ spin_unlock_irq(&slave_active_lock);
+ mutex_unlock(®ister_mutex);
+ }
+ out:
+@@ -441,9 +446,12 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri)
+
+ spin_lock_irqsave(&slave_active_lock, flags);
+ timeri->flags |= SNDRV_TIMER_IFLG_RUNNING;
+- if (timeri->master)
++ if (timeri->master && timeri->timer) {
++ spin_lock(&timeri->timer->lock);
+ list_add_tail(&timeri->active_list,
+ &timeri->master->slave_active_head);
++ spin_unlock(&timeri->timer->lock);
++ }
+ spin_unlock_irqrestore(&slave_active_lock, flags);
+ return 1; /* delayed start */
+ }
+@@ -489,6 +497,8 @@ static int _snd_timer_stop(struct snd_timer_instance * timeri,
+ if (!keep_flag) {
+ spin_lock_irqsave(&slave_active_lock, flags);
+ timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
++ list_del_init(&timeri->ack_list);
++ list_del_init(&timeri->active_list);
+ spin_unlock_irqrestore(&slave_active_lock, flags);
+ }
+ goto __end;
+@@ -694,7 +704,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
+ } else {
+ ti->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
+ if (--timer->running)
+- list_del(&ti->active_list);
++ list_del_init(&ti->active_list);
+ }
+ if ((timer->hw.flags & SNDRV_TIMER_HW_TASKLET) ||
+ (ti->flags & SNDRV_TIMER_IFLG_FAST))
+@@ -1253,7 +1263,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file)
+ return -ENOMEM;
+ spin_lock_init(&tu->qlock);
+ init_waitqueue_head(&tu->qchange_sleep);
+- mutex_init(&tu->tread_sem);
++ mutex_init(&tu->ioctl_lock);
+ tu->ticks = 1;
+ tu->queue_size = 128;
+ tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read),
+@@ -1273,8 +1283,10 @@ static int snd_timer_user_release(struct inode *inode, struct file *file)
+ if (file->private_data) {
+ tu = file->private_data;
+ file->private_data = NULL;
++ mutex_lock(&tu->ioctl_lock);
+ if (tu->timeri)
+ snd_timer_close(tu->timeri);
++ mutex_unlock(&tu->ioctl_lock);
+ kfree(tu->queue);
+ kfree(tu->tqueue);
+ kfree(tu);
+@@ -1512,7 +1524,6 @@ static int snd_timer_user_tselect(struct file *file,
+ int err = 0;
+
+ tu = file->private_data;
+- mutex_lock(&tu->tread_sem);
+ if (tu->timeri) {
+ snd_timer_close(tu->timeri);
+ tu->timeri = NULL;
+@@ -1556,7 +1567,6 @@ static int snd_timer_user_tselect(struct file *file,
+ }
+
+ __err:
+- mutex_unlock(&tu->tread_sem);
+ return err;
+ }
+
+@@ -1769,7 +1779,7 @@ enum {
+ SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23),
+ };
+
+-static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
++static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+ {
+ struct snd_timer_user *tu;
+@@ -1786,17 +1796,11 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
+ {
+ int xarg;
+
+- mutex_lock(&tu->tread_sem);
+- if (tu->timeri) { /* too late */
+- mutex_unlock(&tu->tread_sem);
++ if (tu->timeri) /* too late */
+ return -EBUSY;
+- }
+- if (get_user(xarg, p)) {
+- mutex_unlock(&tu->tread_sem);
++ if (get_user(xarg, p))
+ return -EFAULT;
+- }
+ tu->tread = xarg ? 1 : 0;
+- mutex_unlock(&tu->tread_sem);
+ return 0;
+ }
+ case SNDRV_TIMER_IOCTL_GINFO:
+@@ -1829,6 +1833,18 @@ static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
+ return -ENOTTY;
+ }
+
++static long snd_timer_user_ioctl(struct file *file, unsigned int cmd,
++ unsigned long arg)
++{
++ struct snd_timer_user *tu = file->private_data;
++ long ret;
++
++ mutex_lock(&tu->ioctl_lock);
++ ret = __snd_timer_user_ioctl(file, cmd, arg);
++ mutex_unlock(&tu->ioctl_lock);
++ return ret;
++}
++
+ static int snd_timer_user_fasync(int fd, struct file * file, int on)
+ {
+ struct snd_timer_user *tu;
diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c
index 2a008a9..a1efb3f 100644
--- a/sound/drivers/mts64.c
@@ -150708,10 +151597,10 @@ index 0000000..fc58e16
+}
diff --git a/tools/gcc/size_overflow_plugin/size_overflow_hash.data b/tools/gcc/size_overflow_plugin/size_overflow_hash.data
new file mode 100644
-index 0000000..0a36c4a
+index 0000000..9da833a
--- /dev/null
+++ b/tools/gcc/size_overflow_plugin/size_overflow_hash.data
-@@ -0,0 +1,21743 @@
+@@ -0,0 +1,21745 @@
+enable_so_recv_ctrl_pipe_us_data_0 recv_ctrl_pipe us_data 0 0 NULL
+enable_so___earlyonly_bootmem_alloc_fndecl_3 __earlyonly_bootmem_alloc fndecl 2-3-4 3 NULL
+enable_so_size_ttm_mem_reg_8 size ttm_mem_reg 0 8 NULL
@@ -163535,7 +164424,8 @@ index 0000000..0a36c4a
+enable_so_prism2_ap_translate_scan_fndecl_38540 prism2_ap_translate_scan fndecl 0 38540 NULL
+enable_so_cx18_av_read_fndecl_38542 cx18_av_read fndecl 0 38542 NULL
+enable_so_hw_channels_sh_cmt_device_38544 hw_channels sh_cmt_device 0 38544 NULL
-+enable_so_clk_fd_set_rate_fndecl_38545 clk_fd_set_rate fndecl 2-3 38545 NULL
++enable_so_clk_fd_set_rate_fndecl_38545 clk_fd_set_rate fndecl 2-3 38545 NULL nohasharray
++enable_so_snd_timer_user_tselect_fndecl_38545 snd_timer_user_tselect fndecl 0 38545 &enable_so_clk_fd_set_rate_fndecl_38545
+enable_so_ulist_add_merge_fndecl_38547 ulist_add_merge fndecl 0-2 38547 NULL nohasharray
+enable_so_krb5_encrypt_fndecl_38547 krb5_encrypt fndecl 5 38547 &enable_so_ulist_add_merge_fndecl_38547
+enable_so_fb_base_phys_radeonfb_info_38551 fb_base_phys radeonfb_info 0 38551 NULL
@@ -168363,6 +169253,7 @@ index 0000000..0a36c4a
+enable_so_real_vram_size_radeon_mc_53132 real_vram_size radeon_mc 0 53132 NULL
+enable_so_fault_inject_read_fndecl_53133 fault_inject_read fndecl 3 53133 NULL
+enable_so_data_dma_td_53137 data_dma td 0 53137 NULL
++enable_so_snd_timer_user_params_fndecl_53139 snd_timer_user_params fndecl 0 53139 NULL
+enable_so_log_rq_size_mlx5e_params_53140 log_rq_size mlx5e_params 0 53140 NULL
+enable_so_mmc_spi_readbytes_fndecl_53146 mmc_spi_readbytes fndecl 2-0 53146 NULL
+enable_so_zlib_tr_stored_block_fndecl_53147 zlib_tr_stored_block fndecl 3 53147 NULL
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2016-01-20 9:19 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-12-23 7:52 [gentoo-commits] proj/hardened-patchset:master commit in: 4.3.3/ Anthony G. Basile
-- strict thread matches above, loose matches on Subject: below --
2016-01-20 9:19 Anthony G. Basile
2016-01-19 0:13 Anthony G. Basile
2016-01-17 19:13 Anthony G. Basile
2016-01-06 13:05 Anthony G. Basile
2015-12-31 12:24 Anthony G. Basile
2015-12-17 8:10 Anthony G. Basile
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox