--- /dev/null
+From 64dbc262b657daca4aa9d65bed298377f23994f0 Mon Sep 17 00:00:00 2001
+From: Daniel Borkmann <daniel@iogearbox.net>
+Date: Thu, 1 Nov 2018 22:29:53 +0100
+Subject: bpf: fix partial copy of map_ptr when dst is scalar
+
+commit 0962590e553331db2cc0aef2dc35c57f6300dbbe upstream.
+
+ALU operations on pointers such as scalar_reg += map_value_ptr are
+handled in adjust_ptr_min_max_vals(). Problem is however that map_ptr
+and range in the register state share a union, so transferring state
+through dst_reg->range = ptr_reg->range is just buggy as any new
+map_ptr in the dst_reg is then truncated (or null) for subsequent
+checks. Fix this by adding a raw member and use it for copying state
+over to dst_reg.
+
+Fixes: f1174f77b50c ("bpf/verifier: rework value tracking")
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Edward Cree <ecree@solarflare.com>
+Acked-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Edward Cree <ecree@solarflare.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/bpf_verifier.h | 3 +++
+ kernel/bpf/verifier.c | 10 ++++++----
+ 2 files changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
+index 38b04f559ad3..1fd6fa822d2c 100644
+--- a/include/linux/bpf_verifier.h
++++ b/include/linux/bpf_verifier.h
+@@ -50,6 +50,9 @@ struct bpf_reg_state {
+ * PTR_TO_MAP_VALUE_OR_NULL
+ */
+ struct bpf_map *map_ptr;
++
++ /* Max size from any of the above. */
++ unsigned long raw;
+ };
+ /* Fixed part of pointer offset, pointer types only */
+ s32 off;
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 82e8edef6ea0..b000686fa1a1 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -2731,7 +2731,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
+ dst_reg->umax_value = umax_ptr;
+ dst_reg->var_off = ptr_reg->var_off;
+ dst_reg->off = ptr_reg->off + smin_val;
+- dst_reg->range = ptr_reg->range;
++ dst_reg->raw = ptr_reg->raw;
+ break;
+ }
+ /* A new variable offset is created. Note that off_reg->off
+@@ -2761,10 +2761,11 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
+ }
+ dst_reg->var_off = tnum_add(ptr_reg->var_off, off_reg->var_off);
+ dst_reg->off = ptr_reg->off;
++ dst_reg->raw = ptr_reg->raw;
+ if (reg_is_pkt_pointer(ptr_reg)) {
+ dst_reg->id = ++env->id_gen;
+ /* something was added to pkt_ptr, set range to zero */
+- dst_reg->range = 0;
++ dst_reg->raw = 0;
+ }
+ break;
+ case BPF_SUB:
+@@ -2793,7 +2794,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
+ dst_reg->var_off = ptr_reg->var_off;
+ dst_reg->id = ptr_reg->id;
+ dst_reg->off = ptr_reg->off - smin_val;
+- dst_reg->range = ptr_reg->range;
++ dst_reg->raw = ptr_reg->raw;
+ break;
+ }
+ /* A new variable offset is created. If the subtrahend is known
+@@ -2819,11 +2820,12 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
+ }
+ dst_reg->var_off = tnum_sub(ptr_reg->var_off, off_reg->var_off);
+ dst_reg->off = ptr_reg->off;
++ dst_reg->raw = ptr_reg->raw;
+ if (reg_is_pkt_pointer(ptr_reg)) {
+ dst_reg->id = ++env->id_gen;
+ /* something was added to pkt_ptr, set range to zero */
+ if (smin_val < 0)
+- dst_reg->range = 0;
++ dst_reg->raw = 0;
+ }
+ break;
+ case BPF_AND:
+--
+2.17.1
+
--- /dev/null
+From 4fc7d6351b8743d20565ca9b9f3aada68de053e4 Mon Sep 17 00:00:00 2001
+From: Alan Chiang <alanx.chiang@intel.com>
+Date: Wed, 25 Jul 2018 11:20:22 +0800
+Subject: eeprom: at24: Add support for address-width property
+
+[ Upstream commit a2b3bf4846e5eed62ea6abb096af2c950961033c ]
+
+Provide a flexible way to determine the addressing bits of eeprom.
+Pass the addressing bits to driver through address-width property.
+
+Signed-off-by: Alan Chiang <alanx.chiang@intel.com>
+Signed-off-by: Andy Yeh <andy.yeh@intel.com>
+Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/eeprom/at24.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
+index f5cc517d1131..7e50e1d6f58c 100644
+--- a/drivers/misc/eeprom/at24.c
++++ b/drivers/misc/eeprom/at24.c
+@@ -478,6 +478,23 @@ static void at24_properties_to_pdata(struct device *dev,
+ if (device_property_present(dev, "no-read-rollover"))
+ chip->flags |= AT24_FLAG_NO_RDROL;
+
++ err = device_property_read_u32(dev, "address-width", &val);
++ if (!err) {
++ switch (val) {
++ case 8:
++ if (chip->flags & AT24_FLAG_ADDR16)
++ dev_warn(dev, "Override address width to be 8, while default is 16\n");
++ chip->flags &= ~AT24_FLAG_ADDR16;
++ break;
++ case 16:
++ chip->flags |= AT24_FLAG_ADDR16;
++ break;
++ default:
++ dev_warn(dev, "Bad \"address-width\" property: %u\n",
++ val);
++ }
++ }
++
+ err = device_property_read_u32(dev, "size", &val);
+ if (!err)
+ chip->byte_len = val;
+--
+2.17.1
+
--- /dev/null
+From 3e2ce0fd043394534bf58ca6ab557d5912f5e1a5 Mon Sep 17 00:00:00 2001
+From: Amir Goldstein <amir73il@gmail.com>
+Date: Mon, 22 Oct 2018 20:56:46 +0300
+Subject: vfs: swap names of {do,vfs}_clone_file_range()
+
+commit a725356b6659469d182d662f22d770d83d3bc7b5 upstream.
+
+Commit 031a072a0b8a ("vfs: call vfs_clone_file_range() under freeze
+protection") created a wrapper do_clone_file_range() around
+vfs_clone_file_range() moving the freeze protection to former, so
+overlayfs could call the latter.
+
+The more common vfs practice is to call do_xxx helpers from vfs_xxx
+helpers, where freeze protecction is taken in the vfs_xxx helper, so
+this anomality could be a source of confusion.
+
+It seems that commit 8ede205541ff ("ovl: add reflink/copyfile/dedup
+support") may have fallen a victim to this confusion -
+ovl_clone_file_range() calls the vfs_clone_file_range() helper in the
+hope of getting freeze protection on upper fs, but in fact results in
+overlayfs allowing to bypass upper fs freeze protection.
+
+Swap the names of the two helpers to conform to common vfs practice
+and call the correct helpers from overlayfs and nfsd.
+
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Fixes: 031a072a0b8a ("vfs: call vfs_clone_file_range() under freeze...")
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ioctl.c | 2 +-
+ fs/nfsd/vfs.c | 3 ++-
+ fs/overlayfs/copy_up.c | 2 +-
+ fs/read_write.c | 17 +++++++++++++++--
+ include/linux/fs.h | 17 +++--------------
+ 5 files changed, 22 insertions(+), 19 deletions(-)
+
+diff --git a/fs/ioctl.c b/fs/ioctl.c
+index b445b13fc59b..5444fec607ce 100644
+--- a/fs/ioctl.c
++++ b/fs/ioctl.c
+@@ -229,7 +229,7 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
+ ret = -EXDEV;
+ if (src_file.file->f_path.mnt != dst_file->f_path.mnt)
+ goto fdput;
+- ret = do_clone_file_range(src_file.file, off, dst_file, destoff, olen);
++ ret = vfs_clone_file_range(src_file.file, off, dst_file, destoff, olen);
+ fdput:
+ fdput(src_file);
+ return ret;
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index b0555d7d8200..613d2fe2dddd 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -541,7 +541,8 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp,
+ __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst,
+ u64 dst_pos, u64 count)
+ {
+- return nfserrno(do_clone_file_range(src, src_pos, dst, dst_pos, count));
++ return nfserrno(vfs_clone_file_range(src, src_pos, dst, dst_pos,
++ count));
+ }
+
+ ssize_t nfsd_copy_file_range(struct file *src, u64 src_pos, struct file *dst,
+diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
+index ddaddb4ce4c3..26b477f2538d 100644
+--- a/fs/overlayfs/copy_up.c
++++ b/fs/overlayfs/copy_up.c
+@@ -156,7 +156,7 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
+ }
+
+ /* Try to use clone_file_range to clone up within the same fs */
+- error = vfs_clone_file_range(old_file, 0, new_file, 0, len);
++ error = do_clone_file_range(old_file, 0, new_file, 0, len);
+ if (!error)
+ goto out;
+ /* Couldn't clone, so now we try to copy the data */
+diff --git a/fs/read_write.c b/fs/read_write.c
+index 153f8f690490..c9d489684335 100644
+--- a/fs/read_write.c
++++ b/fs/read_write.c
+@@ -1818,8 +1818,8 @@ int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in,
+ }
+ EXPORT_SYMBOL(vfs_clone_file_prep_inodes);
+
+-int vfs_clone_file_range(struct file *file_in, loff_t pos_in,
+- struct file *file_out, loff_t pos_out, u64 len)
++int do_clone_file_range(struct file *file_in, loff_t pos_in,
++ struct file *file_out, loff_t pos_out, u64 len)
+ {
+ struct inode *inode_in = file_inode(file_in);
+ struct inode *inode_out = file_inode(file_out);
+@@ -1866,6 +1866,19 @@ int vfs_clone_file_range(struct file *file_in, loff_t pos_in,
+
+ return ret;
+ }
++EXPORT_SYMBOL(do_clone_file_range);
++
++int vfs_clone_file_range(struct file *file_in, loff_t pos_in,
++ struct file *file_out, loff_t pos_out, u64 len)
++{
++ int ret;
++
++ file_start_write(file_out);
++ ret = do_clone_file_range(file_in, pos_in, file_out, pos_out, len);
++ file_end_write(file_out);
++
++ return ret;
++}
+ EXPORT_SYMBOL(vfs_clone_file_range);
+
+ /*
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index a3afa50bb79f..e73363bd8646 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1813,8 +1813,10 @@ extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *,
+ extern int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in,
+ struct inode *inode_out, loff_t pos_out,
+ u64 *len, bool is_dedupe);
++extern int do_clone_file_range(struct file *file_in, loff_t pos_in,
++ struct file *file_out, loff_t pos_out, u64 len);
+ extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in,
+- struct file *file_out, loff_t pos_out, u64 len);
++ struct file *file_out, loff_t pos_out, u64 len);
+ extern int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff,
+ struct inode *dest, loff_t destoff,
+ loff_t len, bool *is_same);
+@@ -2755,19 +2757,6 @@ static inline void file_end_write(struct file *file)
+ __sb_end_write(file_inode(file)->i_sb, SB_FREEZE_WRITE);
+ }
+
+-static inline int do_clone_file_range(struct file *file_in, loff_t pos_in,
+- struct file *file_out, loff_t pos_out,
+- u64 len)
+-{
+- int ret;
+-
+- file_start_write(file_out);
+- ret = vfs_clone_file_range(file_in, pos_in, file_out, pos_out, len);
+- file_end_write(file_out);
+-
+- return ret;
+-}
+-
+ /*
+ * get_write_access() gets write permission for a file.
+ * put_write_access() releases this write permission.
+--
+2.17.1
+