diff options
author | 2016-09-17 09:08:13 -0400 | |
---|---|---|
committer | 2016-09-17 09:08:13 -0400 | |
commit | 72854987a3764658e166ff21afbd8abfc4d9385f (patch) | |
tree | 79321fdf3be814f9c1fd8225d3580112e00786ea | |
parent | grsecurity-3.1-4.7.3-201609072139 (diff) | |
download | hardened-patchset-72854987a3764658e166ff21afbd8abfc4d9385f.tar.gz hardened-patchset-72854987a3764658e166ff21afbd8abfc4d9385f.tar.bz2 hardened-patchset-72854987a3764658e166ff21afbd8abfc4d9385f.zip |
grsecurity-3.1-4.7.4-20160915223420160915
-rw-r--r-- | 4.7.4/0000_README (renamed from 4.7.3/0000_README) | 6 | ||||
-rw-r--r-- | 4.7.4/1000_linux-4.7.1.patch (renamed from 4.7.3/1000_linux-4.7.1.patch) | 0 | ||||
-rw-r--r-- | 4.7.4/1001_linux-4.7.2.patch (renamed from 4.7.3/1001_linux-4.7.2.patch) | 0 | ||||
-rw-r--r-- | 4.7.4/1002_linux-4.7.3.patch (renamed from 4.7.3/1002_linux-4.7.3.patch) | 0 | ||||
-rw-r--r-- | 4.7.4/1003_linux-4.7.4.patch | 2424 | ||||
-rw-r--r-- | 4.7.4/4420_grsecurity-3.1-4.7.4-201609152234.patch (renamed from 4.7.3/4420_grsecurity-3.1-4.7.3-201609072139.patch) | 987 | ||||
-rw-r--r-- | 4.7.4/4425_grsec_remove_EI_PAX.patch (renamed from 4.7.3/4425_grsec_remove_EI_PAX.patch) | 0 | ||||
-rw-r--r-- | 4.7.4/4427_force_XATTR_PAX_tmpfs.patch (renamed from 4.7.3/4427_force_XATTR_PAX_tmpfs.patch) | 0 | ||||
-rw-r--r-- | 4.7.4/4430_grsec-remove-localversion-grsec.patch (renamed from 4.7.3/4430_grsec-remove-localversion-grsec.patch) | 0 | ||||
-rw-r--r-- | 4.7.4/4435_grsec-mute-warnings.patch (renamed from 4.7.3/4435_grsec-mute-warnings.patch) | 0 | ||||
-rw-r--r-- | 4.7.4/4440_grsec-remove-protected-paths.patch (renamed from 4.7.3/4440_grsec-remove-protected-paths.patch) | 0 | ||||
-rw-r--r-- | 4.7.4/4450_grsec-kconfig-default-gids.patch (renamed from 4.7.3/4450_grsec-kconfig-default-gids.patch) | 0 | ||||
-rw-r--r-- | 4.7.4/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 4.7.3/4465_selinux-avc_audit-log-curr_ip.patch) | 0 | ||||
-rw-r--r-- | 4.7.4/4470_disable-compat_vdso.patch (renamed from 4.7.3/4470_disable-compat_vdso.patch) | 0 | ||||
-rw-r--r-- | 4.7.4/4475_emutramp_default_on.patch (renamed from 4.7.3/4475_emutramp_default_on.patch) | 0 |
15 files changed, 2953 insertions, 464 deletions
diff --git a/4.7.3/0000_README b/4.7.4/0000_README index af5ddba..6374649 100644 --- a/4.7.3/0000_README +++ b/4.7.4/0000_README @@ -14,7 +14,11 @@ Patch: 1002_linux-4.7.3.patch From: http://www.kernel.org Desc: Linux 4.7.3 -Patch: 4420_grsecurity-3.1-4.7.3-201609072139.patch +Patch: 1003_linux-4.7.4.patch +From: http://www.kernel.org +Desc: Linux 4.7.4 + +Patch: 4420_grsecurity-3.1-4.7.4-201609152234.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/4.7.3/1000_linux-4.7.1.patch b/4.7.4/1000_linux-4.7.1.patch index 79c652a..79c652a 100644 --- a/4.7.3/1000_linux-4.7.1.patch +++ b/4.7.4/1000_linux-4.7.1.patch diff --git a/4.7.3/1001_linux-4.7.2.patch b/4.7.4/1001_linux-4.7.2.patch index d0ef798..d0ef798 100644 --- a/4.7.3/1001_linux-4.7.2.patch +++ b/4.7.4/1001_linux-4.7.2.patch diff --git a/4.7.3/1002_linux-4.7.3.patch b/4.7.4/1002_linux-4.7.3.patch index caac684..caac684 100644 --- a/4.7.3/1002_linux-4.7.3.patch +++ b/4.7.4/1002_linux-4.7.3.patch diff --git a/4.7.4/1003_linux-4.7.4.patch b/4.7.4/1003_linux-4.7.4.patch new file mode 100644 index 0000000..af6c1d4 --- /dev/null +++ b/4.7.4/1003_linux-4.7.4.patch @@ -0,0 +1,2424 @@ +diff --git a/Makefile b/Makefile +index 4afff18..ec3bd11 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 7 +-SUBLEVEL = 3 ++SUBLEVEL = 4 + EXTRAVERSION = + NAME = Psychotic Stoned Sheep + +diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c +index 60078a6..b15e1c1 100644 +--- a/arch/x86/kernel/apic/apic.c ++++ b/arch/x86/kernel/apic/apic.c +@@ -1597,6 +1597,9 @@ void __init enable_IR_x2apic(void) + unsigned long flags; + int ret, ir_stat; + ++ if (skip_ioapic_setup) ++ return; ++ + ir_stat = irq_remapping_prepare(); + if (ir_stat < 0 && !x2apic_supported()) + return; +diff --git a/block/blk-core.c b/block/blk-core.c +index 2475b1c7..b993f88 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -515,7 +515,9 @@ EXPORT_SYMBOL_GPL(blk_queue_bypass_end); + + void blk_set_queue_dying(struct request_queue *q) + { +- queue_flag_set_unlocked(QUEUE_FLAG_DYING, q); ++ spin_lock_irq(q->queue_lock); ++ queue_flag_set(QUEUE_FLAG_DYING, q); ++ spin_unlock_irq(q->queue_lock); + + if (q->mq_ops) + blk_mq_wake_waiters(q); +diff --git a/block/blk-merge.c b/block/blk-merge.c +index 2613531..bea9344 100644 +--- a/block/blk-merge.c ++++ b/block/blk-merge.c +@@ -94,9 +94,31 @@ static struct bio *blk_bio_segment_split(struct request_queue *q, + bool do_split = true; + struct bio *new = NULL; + const unsigned max_sectors = get_max_io_size(q, bio); ++ unsigned bvecs = 0; + + bio_for_each_segment(bv, bio, iter) { + /* ++ * With arbitrary bio size, the incoming bio may be very ++ * big. We have to split the bio into small bios so that ++ * each holds at most BIO_MAX_PAGES bvecs because ++ * bio_clone() can fail to allocate big bvecs. ++ * ++ * It should have been better to apply the limit per ++ * request queue in which bio_clone() is involved, ++ * instead of globally. The biggest blocker is the ++ * bio_clone() in bio bounce. ++ * ++ * If bio is splitted by this reason, we should have ++ * allowed to continue bios merging, but don't do ++ * that now for making the change simple. ++ * ++ * TODO: deal with bio bounce's bio_clone() gracefully ++ * and convert the global limit into per-queue limit. ++ */ ++ if (bvecs++ >= BIO_MAX_PAGES) ++ goto split; ++ ++ /* + * If the queue doesn't support SG gaps and adding this + * offset would create a gap, disallow it. + */ +diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c +index 84708a5..b206115 100644 +--- a/drivers/block/floppy.c ++++ b/drivers/block/floppy.c +@@ -3663,11 +3663,6 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) + + opened_bdev[drive] = bdev; + +- if (!(mode & (FMODE_READ|FMODE_WRITE))) { +- res = -EINVAL; +- goto out; +- } +- + res = -ENXIO; + + if (!floppy_track_buffer) { +@@ -3711,20 +3706,21 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) + if (UFDCS->rawcmd == 1) + UFDCS->rawcmd = 2; + +- UDRS->last_checked = 0; +- clear_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags); +- check_disk_change(bdev); +- if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags)) +- goto out; +- if (test_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags)) +- goto out; +- +- res = -EROFS; +- +- if ((mode & FMODE_WRITE) && +- !test_bit(FD_DISK_WRITABLE_BIT, &UDRS->flags)) +- goto out; +- ++ if (!(mode & FMODE_NDELAY)) { ++ if (mode & (FMODE_READ|FMODE_WRITE)) { ++ UDRS->last_checked = 0; ++ clear_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags); ++ check_disk_change(bdev); ++ if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags)) ++ goto out; ++ if (test_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags)) ++ goto out; ++ } ++ res = -EROFS; ++ if ((mode & FMODE_WRITE) && ++ !test_bit(FD_DISK_WRITABLE_BIT, &UDRS->flags)) ++ goto out; ++ } + mutex_unlock(&open_lock); + mutex_unlock(&floppy_mutex); + return 0; +diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c +index 0bb44d5..2ee40fd 100644 +--- a/drivers/cpufreq/cpufreq-dt-platdev.c ++++ b/drivers/cpufreq/cpufreq-dt-platdev.c +@@ -74,6 +74,8 @@ static const struct of_device_id machines[] __initconst = { + { .compatible = "ti,omap5", }, + + { .compatible = "xlnx,zynq-7000", }, ++ ++ { } + }; + + static int __init cpufreq_dt_platdev_init(void) +diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c +index 6dc5971..b304421 100644 +--- a/drivers/crypto/caam/caamalg.c ++++ b/drivers/crypto/caam/caamalg.c +@@ -556,7 +556,10 @@ skip_enc: + + /* Read and write assoclen bytes */ + append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ); +- append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ); ++ if (alg->caam.geniv) ++ append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM, ivsize); ++ else ++ append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ); + + /* Skip assoc data */ + append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF); +@@ -565,6 +568,14 @@ skip_enc: + append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG | + KEY_VLF); + ++ if (alg->caam.geniv) { ++ append_seq_load(desc, ivsize, LDST_CLASS_1_CCB | ++ LDST_SRCDST_BYTE_CONTEXT | ++ (ctx1_iv_off << LDST_OFFSET_SHIFT)); ++ append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO | ++ (ctx1_iv_off << MOVE_OFFSET_SHIFT) | ivsize); ++ } ++ + /* Load Counter into CONTEXT1 reg */ + if (is_rfc3686) + append_load_imm_u32(desc, be32_to_cpu(1), LDST_IMM | +@@ -2150,7 +2161,7 @@ static void init_authenc_job(struct aead_request *req, + + init_aead_job(req, edesc, all_contig, encrypt); + +- if (ivsize && (is_rfc3686 || !(alg->caam.geniv && encrypt))) ++ if (ivsize && ((is_rfc3686 && encrypt) || !alg->caam.geniv)) + append_load_as_imm(desc, req->iv, ivsize, + LDST_CLASS_1_CCB | + LDST_SRCDST_BYTE_CONTEXT | +@@ -2537,20 +2548,6 @@ static int aead_decrypt(struct aead_request *req) + return ret; + } + +-static int aead_givdecrypt(struct aead_request *req) +-{ +- struct crypto_aead *aead = crypto_aead_reqtfm(req); +- unsigned int ivsize = crypto_aead_ivsize(aead); +- +- if (req->cryptlen < ivsize) +- return -EINVAL; +- +- req->cryptlen -= ivsize; +- req->assoclen += ivsize; +- +- return aead_decrypt(req); +-} +- + /* + * allocate and map the ablkcipher extended descriptor for ablkcipher + */ +@@ -3210,7 +3207,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = MD5_DIGEST_SIZE, + }, +@@ -3256,7 +3253,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = SHA1_DIGEST_SIZE, + }, +@@ -3302,7 +3299,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = SHA224_DIGEST_SIZE, + }, +@@ -3348,7 +3345,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = SHA256_DIGEST_SIZE, + }, +@@ -3394,7 +3391,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = SHA384_DIGEST_SIZE, + }, +@@ -3440,7 +3437,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = SHA512_DIGEST_SIZE, + }, +@@ -3486,7 +3483,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = MD5_DIGEST_SIZE, + }, +@@ -3534,7 +3531,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = SHA1_DIGEST_SIZE, + }, +@@ -3582,7 +3579,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = SHA224_DIGEST_SIZE, + }, +@@ -3630,7 +3627,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = SHA256_DIGEST_SIZE, + }, +@@ -3678,7 +3675,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = SHA384_DIGEST_SIZE, + }, +@@ -3726,7 +3723,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = SHA512_DIGEST_SIZE, + }, +@@ -3772,7 +3769,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = DES_BLOCK_SIZE, + .maxauthsize = MD5_DIGEST_SIZE, + }, +@@ -3818,7 +3815,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = DES_BLOCK_SIZE, + .maxauthsize = SHA1_DIGEST_SIZE, + }, +@@ -3864,7 +3861,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = DES_BLOCK_SIZE, + .maxauthsize = SHA224_DIGEST_SIZE, + }, +@@ -3910,7 +3907,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = DES_BLOCK_SIZE, + .maxauthsize = SHA256_DIGEST_SIZE, + }, +@@ -3956,7 +3953,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = DES_BLOCK_SIZE, + .maxauthsize = SHA384_DIGEST_SIZE, + }, +@@ -4002,7 +3999,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = DES_BLOCK_SIZE, + .maxauthsize = SHA512_DIGEST_SIZE, + }, +@@ -4051,7 +4048,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = CTR_RFC3686_IV_SIZE, + .maxauthsize = MD5_DIGEST_SIZE, + }, +@@ -4102,7 +4099,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = CTR_RFC3686_IV_SIZE, + .maxauthsize = SHA1_DIGEST_SIZE, + }, +@@ -4153,7 +4150,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = CTR_RFC3686_IV_SIZE, + .maxauthsize = SHA224_DIGEST_SIZE, + }, +@@ -4204,7 +4201,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = CTR_RFC3686_IV_SIZE, + .maxauthsize = SHA256_DIGEST_SIZE, + }, +@@ -4255,7 +4252,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = CTR_RFC3686_IV_SIZE, + .maxauthsize = SHA384_DIGEST_SIZE, + }, +@@ -4306,7 +4303,7 @@ static struct caam_aead_alg driver_aeads[] = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, +- .decrypt = aead_givdecrypt, ++ .decrypt = aead_decrypt, + .ivsize = CTR_RFC3686_IV_SIZE, + .maxauthsize = SHA512_DIGEST_SIZE, + }, +diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c +index 9bb99e2..79a05a3 100644 +--- a/drivers/gpu/drm/drm_atomic.c ++++ b/drivers/gpu/drm/drm_atomic.c +@@ -465,7 +465,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, + val, + -1, + &replaced); +- state->color_mgmt_changed = replaced; ++ state->color_mgmt_changed |= replaced; + return ret; + } else if (property == config->ctm_property) { + ret = drm_atomic_replace_property_blob_from_id(crtc, +@@ -473,7 +473,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, + val, + sizeof(struct drm_color_ctm), + &replaced); +- state->color_mgmt_changed = replaced; ++ state->color_mgmt_changed |= replaced; + return ret; + } else if (property == config->gamma_lut_property) { + ret = drm_atomic_replace_property_blob_from_id(crtc, +@@ -481,7 +481,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, + val, + -1, + &replaced); +- state->color_mgmt_changed = replaced; ++ state->color_mgmt_changed |= replaced; + return ret; + } else if (crtc->funcs->atomic_set_property) + return crtc->funcs->atomic_set_property(crtc, state, property, val); +diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c +index 0e3cc66..a5cae1b 100644 +--- a/drivers/gpu/drm/drm_crtc.c ++++ b/drivers/gpu/drm/drm_crtc.c +@@ -5312,6 +5312,9 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, + struct drm_pending_vblank_event *e = NULL; + int ret = -EINVAL; + ++ if (!drm_core_check_feature(dev, DRIVER_MODESET)) ++ return -EINVAL; ++ + if (page_flip->flags & ~DRM_MODE_PAGE_FLIP_FLAGS || + page_flip->reserved != 0) + return -EINVAL; +diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c +index eb4bb8b..eb515f0 100644 +--- a/drivers/gpu/drm/msm/msm_gem_submit.c ++++ b/drivers/gpu/drm/msm/msm_gem_submit.c +@@ -62,6 +62,14 @@ void msm_gem_submit_free(struct msm_gem_submit *submit) + kfree(submit); + } + ++static inline unsigned long __must_check ++copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) ++{ ++ if (access_ok(VERIFY_READ, from, n)) ++ return __copy_from_user_inatomic(to, from, n); ++ return -EFAULT; ++} ++ + static int submit_lookup_objects(struct msm_gem_submit *submit, + struct drm_msm_gem_submit *args, struct drm_file *file) + { +@@ -69,6 +77,7 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, + int ret = 0; + + spin_lock(&file->table_lock); ++ pagefault_disable(); + + for (i = 0; i < args->nr_bos; i++) { + struct drm_msm_gem_submit_bo submit_bo; +@@ -82,10 +91,15 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, + */ + submit->bos[i].flags = 0; + +- ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo)); +- if (ret) { +- ret = -EFAULT; +- goto out_unlock; ++ ret = copy_from_user_inatomic(&submit_bo, userptr, sizeof(submit_bo)); ++ if (unlikely(ret)) { ++ pagefault_enable(); ++ spin_unlock(&file->table_lock); ++ ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo)); ++ if (ret) ++ goto out; ++ spin_lock(&file->table_lock); ++ pagefault_disable(); + } + + if (submit_bo.flags & ~MSM_SUBMIT_BO_FLAGS) { +@@ -125,9 +139,12 @@ static int submit_lookup_objects(struct msm_gem_submit *submit, + } + + out_unlock: +- submit->nr_bos = i; ++ pagefault_enable(); + spin_unlock(&file->table_lock); + ++out: ++ submit->nr_bos = i; ++ + return ret; + } + +diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c +index 259cd6e..17e3454 100644 +--- a/drivers/gpu/drm/radeon/atombios_crtc.c ++++ b/drivers/gpu/drm/radeon/atombios_crtc.c +@@ -627,7 +627,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, + if (radeon_crtc->ss.refdiv) { + radeon_crtc->pll_flags |= RADEON_PLL_USE_REF_DIV; + radeon_crtc->pll_reference_div = radeon_crtc->ss.refdiv; +- if (rdev->family >= CHIP_RV770) ++ if (ASIC_IS_AVIVO(rdev) && ++ rdev->family != CHIP_RS780 && ++ rdev->family != CHIP_RS880) + radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV; + } + } +diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c +index 590b037..0ab76dd 100644 +--- a/drivers/gpu/drm/radeon/radeon_ttm.c ++++ b/drivers/gpu/drm/radeon/radeon_ttm.c +@@ -263,8 +263,8 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, + + rdev = radeon_get_rdev(bo->bdev); + ridx = radeon_copy_ring_index(rdev); +- old_start = old_mem->start << PAGE_SHIFT; +- new_start = new_mem->start << PAGE_SHIFT; ++ old_start = (u64)old_mem->start << PAGE_SHIFT; ++ new_start = (u64)new_mem->start << PAGE_SHIFT; + + switch (old_mem->mem_type) { + case TTM_PL_VRAM: +diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h +index 37cac59..2e24616 100644 +--- a/drivers/gpu/drm/vc4/vc4_drv.h ++++ b/drivers/gpu/drm/vc4/vc4_drv.h +@@ -321,6 +321,15 @@ vc4_first_render_job(struct vc4_dev *vc4) + struct vc4_exec_info, head); + } + ++static inline struct vc4_exec_info * ++vc4_last_render_job(struct vc4_dev *vc4) ++{ ++ if (list_empty(&vc4->render_job_list)) ++ return NULL; ++ return list_last_entry(&vc4->render_job_list, ++ struct vc4_exec_info, head); ++} ++ + /** + * struct vc4_texture_sample_info - saves the offsets into the UBO for texture + * setup parameters. +diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c +index 46899d6..78ab08e 100644 +--- a/drivers/gpu/drm/vc4/vc4_gem.c ++++ b/drivers/gpu/drm/vc4/vc4_gem.c +@@ -574,8 +574,8 @@ vc4_cl_lookup_bos(struct drm_device *dev, + spin_unlock(&file_priv->table_lock); + + fail: +- kfree(handles); +- return 0; ++ drm_free_large(handles); ++ return ret; + } + + static int +diff --git a/drivers/gpu/drm/vc4/vc4_irq.c b/drivers/gpu/drm/vc4/vc4_irq.c +index b0104a34..094bc6a 100644 +--- a/drivers/gpu/drm/vc4/vc4_irq.c ++++ b/drivers/gpu/drm/vc4/vc4_irq.c +@@ -83,8 +83,10 @@ vc4_overflow_mem_work(struct work_struct *work) + + spin_lock_irqsave(&vc4->job_lock, irqflags); + current_exec = vc4_first_bin_job(vc4); ++ if (!current_exec) ++ current_exec = vc4_last_render_job(vc4); + if (current_exec) { +- vc4->overflow_mem->seqno = vc4->finished_seqno + 1; ++ vc4->overflow_mem->seqno = current_exec->seqno; + list_add_tail(&vc4->overflow_mem->unref_head, + ¤t_exec->unref_list); + vc4->overflow_mem = NULL; +diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c +index 70ed1d0..d3ef0fc 100644 +--- a/drivers/irqchip/irq-mips-gic.c ++++ b/drivers/irqchip/irq-mips-gic.c +@@ -713,9 +713,6 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq, + unsigned long flags; + int i; + +- irq_set_chip_and_handler(virq, &gic_level_irq_controller, +- handle_level_irq); +- + spin_lock_irqsave(&gic_lock, flags); + gic_map_to_pin(intr, gic_cpu_pin); + gic_map_to_vpe(intr, mips_cm_vp_id(vpe)); +@@ -732,6 +729,10 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int virq, + { + if (GIC_HWIRQ_TO_LOCAL(hw) < GIC_NUM_LOCAL_INTRS) + return gic_local_irq_domain_map(d, virq, hw); ++ ++ irq_set_chip_and_handler(virq, &gic_level_irq_controller, ++ handle_level_irq); ++ + return gic_shared_irq_domain_map(d, virq, hw, 0); + } + +@@ -771,11 +772,13 @@ static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq, + hwirq = GIC_SHARED_TO_HWIRQ(base_hwirq + i); + + ret = irq_domain_set_hwirq_and_chip(d, virq + i, hwirq, +- &gic_edge_irq_controller, ++ &gic_level_irq_controller, + NULL); + if (ret) + goto error; + ++ irq_set_handler(virq + i, handle_level_irq); ++ + ret = gic_shared_irq_domain_map(d, virq + i, hwirq, cpu); + if (ret) + goto error; +@@ -890,10 +893,17 @@ void gic_dev_domain_free(struct irq_domain *d, unsigned int virq, + return; + } + ++static void gic_dev_domain_activate(struct irq_domain *domain, ++ struct irq_data *d) ++{ ++ gic_shared_irq_domain_map(domain, d->irq, d->hwirq, 0); ++} ++ + static struct irq_domain_ops gic_dev_domain_ops = { + .xlate = gic_dev_domain_xlate, + .alloc = gic_dev_domain_alloc, + .free = gic_dev_domain_free, ++ .activate = gic_dev_domain_activate, + }; + + static int gic_ipi_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, +diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c +index f5dbb4e..5d3b231 100644 +--- a/drivers/md/bcache/super.c ++++ b/drivers/md/bcache/super.c +@@ -1818,7 +1818,7 @@ static int cache_alloc(struct cache_sb *sb, struct cache *ca) + free = roundup_pow_of_two(ca->sb.nbuckets) >> 10; + + if (!init_fifo(&ca->free[RESERVE_BTREE], 8, GFP_KERNEL) || +- !init_fifo(&ca->free[RESERVE_PRIO], prio_buckets(ca), GFP_KERNEL) || ++ !init_fifo_exact(&ca->free[RESERVE_PRIO], prio_buckets(ca), GFP_KERNEL) || + !init_fifo(&ca->free[RESERVE_MOVINGGC], free, GFP_KERNEL) || + !init_fifo(&ca->free[RESERVE_NONE], free, GFP_KERNEL) || + !init_fifo(&ca->free_inc, free << 2, GFP_KERNEL) || +diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c +index e2fb44c..dc3a854 100644 +--- a/drivers/misc/mei/hw-me.c ++++ b/drivers/misc/mei/hw-me.c +@@ -1263,8 +1263,14 @@ static bool mei_me_fw_type_nm(struct pci_dev *pdev) + static bool mei_me_fw_type_sps(struct pci_dev *pdev) + { + u32 reg; +- /* Read ME FW Status check for SPS Firmware */ +- pci_read_config_dword(pdev, PCI_CFG_HFS_1, ®); ++ unsigned int devfn; ++ ++ /* ++ * Read ME FW Status register to check for SPS Firmware ++ * The SPS FW is only signaled in pci function 0 ++ */ ++ devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0); ++ pci_bus_read_config_dword(pdev->bus, devfn, PCI_CFG_HFS_1, ®); + trace_mei_pci_cfg_read(&pdev->dev, "PCI_CFG_HFS_1", PCI_CFG_HFS_1, reg); + /* if bits [19:16] = 15, running SPS Firmware */ + return (reg & 0xf0000) == 0xf0000; +diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c +index 64e64da..71cea9b 100644 +--- a/drivers/misc/mei/pci-me.c ++++ b/drivers/misc/mei/pci-me.c +@@ -85,8 +85,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = { + + {MEI_PCI_DEVICE(MEI_DEV_ID_SPT, mei_me_pch8_cfg)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_2, mei_me_pch8_cfg)}, +- {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, mei_me_pch8_cfg)}, +- {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, mei_me_pch8_cfg)}, ++ {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, mei_me_pch8_sps_cfg)}, ++ {MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, mei_me_pch8_sps_cfg)}, + + {MEI_PCI_DEVICE(MEI_DEV_ID_BXT_M, mei_me_pch8_cfg)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_APL_I, mei_me_pch8_cfg)}, +diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c +index 83458f7..6dc96c8 100644 +--- a/drivers/scsi/constants.c ++++ b/drivers/scsi/constants.c +@@ -361,8 +361,9 @@ static const char * const snstext[] = { + + /* Get sense key string or NULL if not available */ + const char * +-scsi_sense_key_string(unsigned char key) { +- if (key <= 0xE) ++scsi_sense_key_string(unsigned char key) ++{ ++ if (key < ARRAY_SIZE(snstext)) + return snstext[key]; + return NULL; + } +diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c +index 0a4d54a..591e520 100644 +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1196,6 +1196,8 @@ static int acm_probe(struct usb_interface *intf, + } + + if (!buflen) { ++ if (!intf->cur_altsetting || !intf->cur_altsetting->endpoint) ++ return -EINVAL; + if (intf->cur_altsetting->endpoint && + intf->cur_altsetting->endpoint->extralen && + intf->cur_altsetting->endpoint->extra) { +@@ -1276,6 +1278,8 @@ next_desc: + data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num)); + control_interface = intf; + } else { ++ if (!intf->cur_altsetting) ++ return -ENODEV; + if (intf->cur_altsetting->desc.bNumEndpoints != 3) { + dev_dbg(&intf->dev,"No union descriptor, giving up\n"); + return -ENODEV; +@@ -1305,15 +1309,22 @@ next_desc: + combined_interfaces = 1; + /* a popular other OS doesn't use it */ + quirks |= NO_CAP_LINE; ++ if (!data_interface->cur_altsetting) ++ return -EINVAL; + if (data_interface->cur_altsetting->desc.bNumEndpoints != 3) { + dev_err(&intf->dev, "This needs exactly 3 endpoints\n"); + return -EINVAL; + } + look_for_collapsed_interface: ++ if (!data_interface->cur_altsetting) ++ return -EINVAL; + for (i = 0; i < 3; i++) { + struct usb_endpoint_descriptor *ep; + ep = &data_interface->cur_altsetting->endpoint[i].desc; + ++ if (!ep) ++ return -ENODEV; ++ + if (usb_endpoint_is_int_in(ep)) + epctrl = ep; + else if (usb_endpoint_is_bulk_out(ep)) +@@ -1332,8 +1343,12 @@ look_for_collapsed_interface: + skip_normal_probe: + + /*workaround for switched interfaces */ ++ if (!data_interface->cur_altsetting) ++ return -EINVAL; + if (data_interface->cur_altsetting->desc.bInterfaceClass + != CDC_DATA_INTERFACE_TYPE) { ++ if (!control_interface->cur_altsetting) ++ return -EINVAL; + if (control_interface->cur_altsetting->desc.bInterfaceClass + == CDC_DATA_INTERFACE_TYPE) { + dev_dbg(&intf->dev, +@@ -1356,6 +1371,7 @@ skip_normal_probe: + + + if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 || ++ !control_interface->cur_altsetting || + control_interface->cur_altsetting->desc.bNumEndpoints == 0) + return -EINVAL; + +@@ -1363,6 +1379,8 @@ skip_normal_probe: + epread = &data_interface->cur_altsetting->endpoint[0].desc; + epwrite = &data_interface->cur_altsetting->endpoint[1].desc; + ++ if (!epctrl || !epread || !epwrite) ++ return -ENODEV; + + /* workaround for switched endpoints */ + if (!usb_endpoint_dir_in(epread)) { +diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c +index 9d6320e..6e29d05 100644 +--- a/drivers/vhost/scsi.c ++++ b/drivers/vhost/scsi.c +@@ -88,7 +88,7 @@ struct vhost_scsi_cmd { + struct scatterlist *tvc_prot_sgl; + struct page **tvc_upages; + /* Pointer to response header iovec */ +- struct iovec *tvc_resp_iov; ++ struct iovec tvc_resp_iov; + /* Pointer to vhost_scsi for our device */ + struct vhost_scsi *tvc_vhost; + /* Pointer to vhost_virtqueue for the cmd */ +@@ -547,7 +547,7 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work) + memcpy(v_rsp.sense, cmd->tvc_sense_buf, + se_cmd->scsi_sense_length); + +- iov_iter_init(&iov_iter, READ, cmd->tvc_resp_iov, ++ iov_iter_init(&iov_iter, READ, &cmd->tvc_resp_iov, + cmd->tvc_in_iovs, sizeof(v_rsp)); + ret = copy_to_iter(&v_rsp, sizeof(v_rsp), &iov_iter); + if (likely(ret == sizeof(v_rsp))) { +@@ -1044,7 +1044,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) + } + cmd->tvc_vhost = vs; + cmd->tvc_vq = vq; +- cmd->tvc_resp_iov = &vq->iov[out]; ++ cmd->tvc_resp_iov = vq->iov[out]; + cmd->tvc_in_iovs = in; + + pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n", +diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c +index 7487971..c1010f01 100644 +--- a/drivers/xen/xenbus/xenbus_dev_frontend.c ++++ b/drivers/xen/xenbus/xenbus_dev_frontend.c +@@ -316,7 +316,7 @@ static int xenbus_write_transaction(unsigned msg_type, + rc = -ENOMEM; + goto out; + } +- } else { ++ } else if (msg_type == XS_TRANSACTION_END) { + list_for_each_entry(trans, &u->transactions, list) + if (trans->handle.id == u->u.msg.tx_id) + break; +diff --git a/fs/block_dev.c b/fs/block_dev.c +index 71ccab1..b1495fa 100644 +--- a/fs/block_dev.c ++++ b/fs/block_dev.c +@@ -659,7 +659,7 @@ static struct dentry *bd_mount(struct file_system_type *fs_type, + { + struct dentry *dent; + dent = mount_pseudo(fs_type, "bdev:", &bdev_sops, NULL, BDEVFS_MAGIC); +- if (dent) ++ if (!IS_ERR(dent)) + dent->d_sb->s_iflags |= SB_I_CGROUPWB; + return dent; + } +diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c +index 0f9961e..f96547f 100644 +--- a/fs/crypto/policy.c ++++ b/fs/crypto/policy.c +@@ -95,10 +95,15 @@ static int create_encryption_context_from_policy(struct inode *inode, + int fscrypt_process_policy(struct inode *inode, + const struct fscrypt_policy *policy) + { ++ if (!inode_owner_or_capable(inode)) ++ return -EACCES; ++ + if (policy->version != 0) + return -EINVAL; + + if (!inode_has_encryption_context(inode)) { ++ if (!S_ISDIR(inode->i_mode)) ++ return -EINVAL; + if (!inode->i_sb->s_cop->empty_dir) + return -EOPNOTSUPP; + if (!inode->i_sb->s_cop->empty_dir(inode)) +diff --git a/fs/ext4/crypto_policy.c b/fs/ext4/crypto_policy.c +index ad05069..8a9feb3 100644 +--- a/fs/ext4/crypto_policy.c ++++ b/fs/ext4/crypto_policy.c +@@ -102,6 +102,9 @@ static int ext4_create_encryption_context_from_policy( + int ext4_process_policy(const struct ext4_encryption_policy *policy, + struct inode *inode) + { ++ if (!inode_owner_or_capable(inode)) ++ return -EACCES; ++ + if (policy->version != 0) + return -EINVAL; + +diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c +index b747ec0..ea628af 100644 +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -51,25 +51,31 @@ static __u32 ext4_inode_csum(struct inode *inode, struct ext4_inode *raw, + struct ext4_inode_info *ei) + { + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); +- __u16 csum_lo; +- __u16 csum_hi = 0; + __u32 csum; ++ __u16 dummy_csum = 0; ++ int offset = offsetof(struct ext4_inode, i_checksum_lo); ++ unsigned int csum_size = sizeof(dummy_csum); + +- csum_lo = le16_to_cpu(raw->i_checksum_lo); +- raw->i_checksum_lo = 0; +- if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE && +- EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) { +- csum_hi = le16_to_cpu(raw->i_checksum_hi); +- raw->i_checksum_hi = 0; +- } ++ csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)raw, offset); ++ csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, csum_size); ++ offset += csum_size; ++ csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, ++ EXT4_GOOD_OLD_INODE_SIZE - offset); + +- csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)raw, +- EXT4_INODE_SIZE(inode->i_sb)); +- +- raw->i_checksum_lo = cpu_to_le16(csum_lo); +- if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE && +- EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) +- raw->i_checksum_hi = cpu_to_le16(csum_hi); ++ if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { ++ offset = offsetof(struct ext4_inode, i_checksum_hi); ++ csum = ext4_chksum(sbi, csum, (__u8 *)raw + ++ EXT4_GOOD_OLD_INODE_SIZE, ++ offset - EXT4_GOOD_OLD_INODE_SIZE); ++ if (EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) { ++ csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, ++ csum_size); ++ offset += csum_size; ++ csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, ++ EXT4_INODE_SIZE(inode->i_sb) - ++ offset); ++ } ++ } + + return csum; + } +@@ -5460,8 +5466,6 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) + sbi->s_want_extra_isize, + iloc, handle); + if (ret) { +- ext4_set_inode_state(inode, +- EXT4_STATE_NO_EXPAND); + if (mnt_count != + le16_to_cpu(sbi->s_es->s_mnt_count)) { + ext4_warning(inode->i_sb, +diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c +index ec4c399..5bb46b6 100644 +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -420,15 +420,14 @@ static __le32 ext4_dx_csum(struct inode *inode, struct ext4_dir_entry *dirent, + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); + struct ext4_inode_info *ei = EXT4_I(inode); + __u32 csum; +- __le32 save_csum; + int size; ++ __u32 dummy_csum = 0; ++ int offset = offsetof(struct dx_tail, dt_checksum); + + size = count_offset + (count * sizeof(struct dx_entry)); +- save_csum = t->dt_checksum; +- t->dt_checksum = 0; + csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)dirent, size); +- csum = ext4_chksum(sbi, csum, (__u8 *)t, sizeof(struct dx_tail)); +- t->dt_checksum = save_csum; ++ csum = ext4_chksum(sbi, csum, (__u8 *)t, offset); ++ csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, sizeof(dummy_csum)); + + return cpu_to_le32(csum); + } +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 639bd756..d4505f8 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2068,23 +2068,25 @@ failed: + static __le16 ext4_group_desc_csum(struct super_block *sb, __u32 block_group, + struct ext4_group_desc *gdp) + { +- int offset; ++ int offset = offsetof(struct ext4_group_desc, bg_checksum); + __u16 crc = 0; + __le32 le_group = cpu_to_le32(block_group); + struct ext4_sb_info *sbi = EXT4_SB(sb); + + if (ext4_has_metadata_csum(sbi->s_sb)) { + /* Use new metadata_csum algorithm */ +- __le16 save_csum; + __u32 csum32; ++ __u16 dummy_csum = 0; + +- save_csum = gdp->bg_checksum; +- gdp->bg_checksum = 0; + csum32 = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&le_group, + sizeof(le_group)); +- csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp, +- sbi->s_desc_size); +- gdp->bg_checksum = save_csum; ++ csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp, offset); ++ csum32 = ext4_chksum(sbi, csum32, (__u8 *)&dummy_csum, ++ sizeof(dummy_csum)); ++ offset += sizeof(dummy_csum); ++ if (offset < sbi->s_desc_size) ++ csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp + offset, ++ sbi->s_desc_size - offset); + + crc = csum32 & 0xFFFF; + goto out; +@@ -2094,8 +2096,6 @@ static __le16 ext4_group_desc_csum(struct super_block *sb, __u32 block_group, + if (!ext4_has_feature_gdt_csum(sb)) + return 0; + +- offset = offsetof(struct ext4_group_desc, bg_checksum); +- + crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid)); + crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group)); + crc = crc16(crc, (__u8 *)gdp, offset); +@@ -2131,6 +2131,7 @@ void ext4_group_desc_csum_set(struct super_block *sb, __u32 block_group, + + /* Called at mount-time, super-block is locked */ + static int ext4_check_descriptors(struct super_block *sb, ++ ext4_fsblk_t sb_block, + ext4_group_t *first_not_zeroed) + { + struct ext4_sb_info *sbi = EXT4_SB(sb); +@@ -2161,6 +2162,11 @@ static int ext4_check_descriptors(struct super_block *sb, + grp = i; + + block_bitmap = ext4_block_bitmap(sb, gdp); ++ if (block_bitmap == sb_block) { ++ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " ++ "Block bitmap for group %u overlaps " ++ "superblock", i); ++ } + if (block_bitmap < first_block || block_bitmap > last_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Block bitmap for group %u not in group " +@@ -2168,6 +2174,11 @@ static int ext4_check_descriptors(struct super_block *sb, + return 0; + } + inode_bitmap = ext4_inode_bitmap(sb, gdp); ++ if (inode_bitmap == sb_block) { ++ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " ++ "Inode bitmap for group %u overlaps " ++ "superblock", i); ++ } + if (inode_bitmap < first_block || inode_bitmap > last_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " + "Inode bitmap for group %u not in group " +@@ -2175,6 +2186,11 @@ static int ext4_check_descriptors(struct super_block *sb, + return 0; + } + inode_table = ext4_inode_table(sb, gdp); ++ if (inode_table == sb_block) { ++ ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " ++ "Inode table for group %u overlaps " ++ "superblock", i); ++ } + if (inode_table < first_block || + inode_table + sbi->s_itb_per_group - 1 > last_block) { + ext4_msg(sb, KERN_ERR, "ext4_check_descriptors: " +@@ -3677,7 +3693,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) + goto failed_mount2; + } + } +- if (!ext4_check_descriptors(sb, &first_not_zeroed)) { ++ if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { + ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); + ret = -EFSCORRUPTED; + goto failed_mount2; +diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c +index e79bd32..2eb935c 100644 +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -121,17 +121,18 @@ static __le32 ext4_xattr_block_csum(struct inode *inode, + { + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); + __u32 csum; +- __le32 save_csum; + __le64 dsk_block_nr = cpu_to_le64(block_nr); ++ __u32 dummy_csum = 0; ++ int offset = offsetof(struct ext4_xattr_header, h_checksum); + +- save_csum = hdr->h_checksum; +- hdr->h_checksum = 0; + csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&dsk_block_nr, + sizeof(dsk_block_nr)); +- csum = ext4_chksum(sbi, csum, (__u8 *)hdr, +- EXT4_BLOCK_SIZE(inode->i_sb)); ++ csum = ext4_chksum(sbi, csum, (__u8 *)hdr, offset); ++ csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, sizeof(dummy_csum)); ++ offset += sizeof(dummy_csum); ++ csum = ext4_chksum(sbi, csum, (__u8 *)hdr + offset, ++ EXT4_BLOCK_SIZE(inode->i_sb) - offset); + +- hdr->h_checksum = save_csum; + return cpu_to_le32(csum); + } + +@@ -1352,15 +1353,19 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, + size_t min_offs, free; + int total_ino; + void *base, *start, *end; +- int extra_isize = 0, error = 0, tried_min_extra_isize = 0; ++ int error = 0, tried_min_extra_isize = 0; + int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize); ++ int isize_diff; /* How much do we need to grow i_extra_isize */ + + down_write(&EXT4_I(inode)->xattr_sem); ++ /* ++ * Set EXT4_STATE_NO_EXPAND to avoid recursion when marking inode dirty ++ */ ++ ext4_set_inode_state(inode, EXT4_STATE_NO_EXPAND); + retry: +- if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) { +- up_write(&EXT4_I(inode)->xattr_sem); +- return 0; +- } ++ isize_diff = new_extra_isize - EXT4_I(inode)->i_extra_isize; ++ if (EXT4_I(inode)->i_extra_isize >= new_extra_isize) ++ goto out; + + header = IHDR(inode, raw_inode); + entry = IFIRST(header); +@@ -1381,7 +1386,7 @@ retry: + goto cleanup; + + free = ext4_xattr_free_space(last, &min_offs, base, &total_ino); +- if (free >= new_extra_isize) { ++ if (free >= isize_diff) { + entry = IFIRST(header); + ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize + - new_extra_isize, (void *)raw_inode + +@@ -1389,8 +1394,7 @@ retry: + (void *)header, total_ino, + inode->i_sb->s_blocksize); + EXT4_I(inode)->i_extra_isize = new_extra_isize; +- error = 0; +- goto cleanup; ++ goto out; + } + + /* +@@ -1413,7 +1417,7 @@ retry: + end = bh->b_data + bh->b_size; + min_offs = end - base; + free = ext4_xattr_free_space(first, &min_offs, base, NULL); +- if (free < new_extra_isize) { ++ if (free < isize_diff) { + if (!tried_min_extra_isize && s_min_extra_isize) { + tried_min_extra_isize++; + new_extra_isize = s_min_extra_isize; +@@ -1427,7 +1431,7 @@ retry: + free = inode->i_sb->s_blocksize; + } + +- while (new_extra_isize > 0) { ++ while (isize_diff > 0) { + size_t offs, size, entry_size; + struct ext4_xattr_entry *small_entry = NULL; + struct ext4_xattr_info i = { +@@ -1458,7 +1462,7 @@ retry: + EXT4_XATTR_SIZE(le32_to_cpu(last->e_value_size)) + + EXT4_XATTR_LEN(last->e_name_len); + if (total_size <= free && total_size < min_total_size) { +- if (total_size < new_extra_isize) { ++ if (total_size < isize_diff) { + small_entry = last; + } else { + entry = last; +@@ -1513,22 +1517,22 @@ retry: + error = ext4_xattr_ibody_set(handle, inode, &i, is); + if (error) + goto cleanup; ++ total_ino -= entry_size; + + entry = IFIRST(header); +- if (entry_size + EXT4_XATTR_SIZE(size) >= new_extra_isize) +- shift_bytes = new_extra_isize; ++ if (entry_size + EXT4_XATTR_SIZE(size) >= isize_diff) ++ shift_bytes = isize_diff; + else +- shift_bytes = entry_size + size; ++ shift_bytes = entry_size + EXT4_XATTR_SIZE(size); + /* Adjust the offsets and shift the remaining entries ahead */ +- ext4_xattr_shift_entries(entry, EXT4_I(inode)->i_extra_isize - +- shift_bytes, (void *)raw_inode + +- EXT4_GOOD_OLD_INODE_SIZE + extra_isize + shift_bytes, +- (void *)header, total_ino - entry_size, +- inode->i_sb->s_blocksize); ++ ext4_xattr_shift_entries(entry, -shift_bytes, ++ (void *)raw_inode + EXT4_GOOD_OLD_INODE_SIZE + ++ EXT4_I(inode)->i_extra_isize + shift_bytes, ++ (void *)header, total_ino, inode->i_sb->s_blocksize); + +- extra_isize += shift_bytes; +- new_extra_isize -= shift_bytes; +- EXT4_I(inode)->i_extra_isize = extra_isize; ++ isize_diff -= shift_bytes; ++ EXT4_I(inode)->i_extra_isize += shift_bytes; ++ header = IHDR(inode, raw_inode); + + i.name = b_entry_name; + i.value = buffer; +@@ -1550,6 +1554,8 @@ retry: + kfree(bs); + } + brelse(bh); ++out: ++ ext4_clear_inode_state(inode, EXT4_STATE_NO_EXPAND); + up_write(&EXT4_I(inode)->xattr_sem); + return 0; + +@@ -1561,6 +1567,10 @@ cleanup: + kfree(is); + kfree(bs); + brelse(bh); ++ /* ++ * We deliberately leave EXT4_STATE_NO_EXPAND set here since inode ++ * size expansion failed. ++ */ + up_write(&EXT4_I(inode)->xattr_sem); + return error; + } +diff --git a/fs/namei.c b/fs/namei.c +index 70580ab..9281b2b 100644 +--- a/fs/namei.c ++++ b/fs/namei.c +@@ -901,6 +901,7 @@ static inline int may_follow_link(struct nameidata *nd) + { + const struct inode *inode; + const struct inode *parent; ++ kuid_t puid; + + if (!sysctl_protected_symlinks) + return 0; +@@ -916,7 +917,8 @@ static inline int may_follow_link(struct nameidata *nd) + return 0; + + /* Allowed if parent directory and link owner match. */ +- if (uid_eq(parent->i_uid, inode->i_uid)) ++ puid = parent->i_uid; ++ if (uid_valid(puid) && uid_eq(puid, inode->i_uid)) + return 0; + + if (nd->flags & LOOKUP_RCU) +diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c +index 80aa6f1..4133aa7 100644 +--- a/fs/overlayfs/copy_up.c ++++ b/fs/overlayfs/copy_up.c +@@ -80,6 +80,8 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new) + } + + for (name = buf; name < (buf + list_size); name += strlen(name) + 1) { ++ if (ovl_is_private_xattr(name)) ++ continue; + retry: + size = vfs_getxattr(old, name, value, value_size); + if (size == -ERANGE) +diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c +index d1cdc60..ac98a71 100644 +--- a/fs/overlayfs/inode.c ++++ b/fs/overlayfs/inode.c +@@ -231,7 +231,7 @@ static int ovl_readlink(struct dentry *dentry, char __user *buf, int bufsiz) + } + + +-static bool ovl_is_private_xattr(const char *name) ++bool ovl_is_private_xattr(const char *name) + { + return strncmp(name, OVL_XATTR_PRE_NAME, OVL_XATTR_PRE_LEN) == 0; + } +@@ -279,24 +279,27 @@ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size) + { + struct dentry *realdentry = ovl_dentry_real(dentry); + ssize_t res; +- int off; ++ size_t len; ++ char *s; + + res = vfs_listxattr(realdentry, list, size); + if (res <= 0 || size == 0) + return res; + + /* filter out private xattrs */ +- for (off = 0; off < res;) { +- char *s = list + off; +- size_t slen = strlen(s) + 1; ++ for (s = list, len = res; len;) { ++ size_t slen = strnlen(s, len) + 1; + +- BUG_ON(off + slen > res); ++ /* underlying fs providing us with an broken xattr list? */ ++ if (WARN_ON(slen > len)) ++ return -EIO; + ++ len -= slen; + if (ovl_is_private_xattr(s)) { + res -= slen; +- memmove(s, s + slen, res - off); ++ memmove(s, s + slen, len); + } else { +- off += slen; ++ s += slen; + } + } + +diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h +index cfbca53..d8ddc31 100644 +--- a/fs/overlayfs/overlayfs.h ++++ b/fs/overlayfs/overlayfs.h +@@ -168,6 +168,8 @@ int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list); + void ovl_cleanup_whiteouts(struct dentry *upper, struct list_head *list); + void ovl_cache_free(struct list_head *list); + int ovl_check_d_type_supported(struct path *realpath); ++void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt, ++ struct dentry *dentry, int level); + + /* inode.c */ + int ovl_setattr(struct dentry *dentry, struct iattr *attr); +@@ -180,6 +182,7 @@ ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode, + ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size); + int ovl_removexattr(struct dentry *dentry, const char *name); + struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags); ++bool ovl_is_private_xattr(const char *name); + + struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, + struct ovl_entry *oe); +diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c +index cf37fc7..f241b4e 100644 +--- a/fs/overlayfs/readdir.c ++++ b/fs/overlayfs/readdir.c +@@ -248,7 +248,7 @@ static inline int ovl_dir_read(struct path *realpath, + err = rdd->err; + } while (!err && rdd->count); + +- if (!err && rdd->first_maybe_whiteout) ++ if (!err && rdd->first_maybe_whiteout && rdd->dentry) + err = ovl_check_whiteouts(realpath->dentry, rdd); + + fput(realfile); +@@ -606,3 +606,64 @@ int ovl_check_d_type_supported(struct path *realpath) + + return rdd.d_type_supported; + } ++ ++static void ovl_workdir_cleanup_recurse(struct path *path, int level) ++{ ++ int err; ++ struct inode *dir = path->dentry->d_inode; ++ LIST_HEAD(list); ++ struct ovl_cache_entry *p; ++ struct ovl_readdir_data rdd = { ++ .ctx.actor = ovl_fill_merge, ++ .dentry = NULL, ++ .list = &list, ++ .root = RB_ROOT, ++ .is_lowest = false, ++ }; ++ ++ err = ovl_dir_read(path, &rdd); ++ if (err) ++ goto out; ++ ++ inode_lock_nested(dir, I_MUTEX_PARENT); ++ list_for_each_entry(p, &list, l_node) { ++ struct dentry *dentry; ++ ++ if (p->name[0] == '.') { ++ if (p->len == 1) ++ continue; ++ if (p->len == 2 && p->name[1] == '.') ++ continue; ++ } ++ dentry = lookup_one_len(p->name, path->dentry, p->len); ++ if (IS_ERR(dentry)) ++ continue; ++ if (dentry->d_inode) ++ ovl_workdir_cleanup(dir, path->mnt, dentry, level); ++ dput(dentry); ++ } ++ inode_unlock(dir); ++out: ++ ovl_cache_free(&list); ++} ++ ++void ovl_workdir_cleanup(struct inode *dir, struct vfsmount *mnt, ++ struct dentry *dentry, int level) ++{ ++ int err; ++ ++ if (!d_is_dir(dentry) || level > 1) { ++ ovl_cleanup(dir, dentry); ++ return; ++ } ++ ++ err = ovl_do_rmdir(dir, dentry); ++ if (err) { ++ struct path path = { .mnt = mnt, .dentry = dentry }; ++ ++ inode_unlock(dir); ++ ovl_workdir_cleanup_recurse(&path, level + 1); ++ inode_lock_nested(dir, I_MUTEX_PARENT); ++ ovl_cleanup(dir, dentry); ++ } ++} +diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c +index 6db75cb..86f2025 100644 +--- a/fs/overlayfs/super.c ++++ b/fs/overlayfs/super.c +@@ -798,6 +798,10 @@ retry: + struct kstat stat = { + .mode = S_IFDIR | 0, + }; ++ struct iattr attr = { ++ .ia_valid = ATTR_MODE, ++ .ia_mode = stat.mode, ++ }; + + if (work->d_inode) { + err = -EEXIST; +@@ -805,7 +809,7 @@ retry: + goto out_dput; + + retried = true; +- ovl_cleanup(dir, work); ++ ovl_workdir_cleanup(dir, mnt, work, 0); + dput(work); + goto retry; + } +@@ -813,6 +817,21 @@ retry: + err = ovl_create_real(dir, work, &stat, NULL, NULL, true); + if (err) + goto out_dput; ++ ++ err = vfs_removexattr(work, XATTR_NAME_POSIX_ACL_DEFAULT); ++ if (err && err != -ENODATA && err != -EOPNOTSUPP) ++ goto out_dput; ++ ++ err = vfs_removexattr(work, XATTR_NAME_POSIX_ACL_ACCESS); ++ if (err && err != -ENODATA && err != -EOPNOTSUPP) ++ goto out_dput; ++ ++ /* Clear any inherited mode bits */ ++ inode_lock(work->d_inode); ++ err = notify_change(work, &attr, NULL); ++ inode_unlock(work->d_inode); ++ if (err) ++ goto out_dput; + } + out_unlock: + inode_unlock(dir); +diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c +index b45345d..51157da 100644 +--- a/fs/ubifs/tnc_commit.c ++++ b/fs/ubifs/tnc_commit.c +@@ -370,7 +370,7 @@ static int layout_in_gaps(struct ubifs_info *c, int cnt) + + p = c->gap_lebs; + do { +- ubifs_assert(p < c->gap_lebs + sizeof(int) * c->lst.idx_lebs); ++ ubifs_assert(p < c->gap_lebs + c->lst.idx_lebs); + written = layout_leb_in_gaps(c, p); + if (written < 0) { + err = written; +diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c +index b5fc279..c63710f 100644 +--- a/fs/ubifs/xattr.c ++++ b/fs/ubifs/xattr.c +@@ -575,7 +575,8 @@ static int ubifs_xattr_get(const struct xattr_handler *handler, + dbg_gen("xattr '%s', ino %lu ('%pd'), buf size %zd", name, + inode->i_ino, dentry, size); + +- return __ubifs_getxattr(inode, name, buffer, size); ++ name = xattr_full_name(handler, name); ++ return __ubifs_getxattr(inode, name, buffer, size); + } + + static int ubifs_xattr_set(const struct xattr_handler *handler, +@@ -586,6 +587,8 @@ static int ubifs_xattr_set(const struct xattr_handler *handler, + dbg_gen("xattr '%s', host ino %lu ('%pd'), size %zd", + name, inode->i_ino, dentry, size); + ++ name = xattr_full_name(handler, name); ++ + if (value) + return __ubifs_setxattr(inode, name, value, size, flags); + else +diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c +index 12ca867..85bdf3d 100644 +--- a/fs/xfs/libxfs/xfs_sb.c ++++ b/fs/xfs/libxfs/xfs_sb.c +@@ -581,7 +581,8 @@ xfs_sb_verify( + * Only check the in progress field for the primary superblock as + * mkfs.xfs doesn't clear it from secondary superblocks. + */ +- return xfs_mount_validate_sb(mp, &sb, bp->b_bn == XFS_SB_DADDR, ++ return xfs_mount_validate_sb(mp, &sb, ++ bp->b_maps[0].bm_bn == XFS_SB_DADDR, + check_version); + } + +diff --git a/include/linux/capability.h b/include/linux/capability.h +index 00690ff..5f3c63d 100644 +--- a/include/linux/capability.h ++++ b/include/linux/capability.h +@@ -206,6 +206,7 @@ extern bool has_ns_capability_noaudit(struct task_struct *t, + struct user_namespace *ns, int cap); + extern bool capable(int cap); + extern bool ns_capable(struct user_namespace *ns, int cap); ++extern bool ns_capable_noaudit(struct user_namespace *ns, int cap); + #else + static inline bool has_capability(struct task_struct *t, int cap) + { +@@ -233,6 +234,10 @@ static inline bool ns_capable(struct user_namespace *ns, int cap) + { + return true; + } ++static inline bool ns_capable_noaudit(struct user_namespace *ns, int cap) ++{ ++ return true; ++} + #endif /* CONFIG_MULTIUSER */ + extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap); + extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap); +diff --git a/kernel/capability.c b/kernel/capability.c +index 45432b5..00411c8 100644 +--- a/kernel/capability.c ++++ b/kernel/capability.c +@@ -361,6 +361,24 @@ bool has_capability_noaudit(struct task_struct *t, int cap) + return has_ns_capability_noaudit(t, &init_user_ns, cap); + } + ++static bool ns_capable_common(struct user_namespace *ns, int cap, bool audit) ++{ ++ int capable; ++ ++ if (unlikely(!cap_valid(cap))) { ++ pr_crit("capable() called with invalid cap=%u\n", cap); ++ BUG(); ++ } ++ ++ capable = audit ? security_capable(current_cred(), ns, cap) : ++ security_capable_noaudit(current_cred(), ns, cap); ++ if (capable == 0) { ++ current->flags |= PF_SUPERPRIV; ++ return true; ++ } ++ return false; ++} ++ + /** + * ns_capable - Determine if the current task has a superior capability in effect + * @ns: The usernamespace we want the capability in +@@ -374,19 +392,27 @@ bool has_capability_noaudit(struct task_struct *t, int cap) + */ + bool ns_capable(struct user_namespace *ns, int cap) + { +- if (unlikely(!cap_valid(cap))) { +- pr_crit("capable() called with invalid cap=%u\n", cap); +- BUG(); +- } +- +- if (security_capable(current_cred(), ns, cap) == 0) { +- current->flags |= PF_SUPERPRIV; +- return true; +- } +- return false; ++ return ns_capable_common(ns, cap, true); + } + EXPORT_SYMBOL(ns_capable); + ++/** ++ * ns_capable_noaudit - Determine if the current task has a superior capability ++ * (unaudited) in effect ++ * @ns: The usernamespace we want the capability in ++ * @cap: The capability to be tested for ++ * ++ * Return true if the current task has the given superior capability currently ++ * available for use, false if not. ++ * ++ * This sets PF_SUPERPRIV on the task if the capability is available on the ++ * assumption that it's about to be used. ++ */ ++bool ns_capable_noaudit(struct user_namespace *ns, int cap) ++{ ++ return ns_capable_common(ns, cap, false); ++} ++EXPORT_SYMBOL(ns_capable_noaudit); + + /** + * capable - Determine if the current task has a superior capability in effect +diff --git a/kernel/cred.c b/kernel/cred.c +index 0c0cd8a..5f264fb 100644 +--- a/kernel/cred.c ++++ b/kernel/cred.c +@@ -689,6 +689,8 @@ EXPORT_SYMBOL(set_security_override_from_ctx); + */ + int set_create_files_as(struct cred *new, struct inode *inode) + { ++ if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid)) ++ return -EINVAL; + new->fsuid = inode->i_uid; + new->fsgid = inode->i_gid; + return security_kernel_create_files_as(new, inode); +diff --git a/kernel/fork.c b/kernel/fork.c +index 4a7ec0c..aea4f4d 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -1406,7 +1406,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, + p->real_start_time = ktime_get_boot_ns(); + p->io_context = NULL; + p->audit_context = NULL; +- threadgroup_change_begin(current); + cgroup_fork(p); + #ifdef CONFIG_NUMA + p->mempolicy = mpol_dup(p->mempolicy); +@@ -1558,6 +1557,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, + INIT_LIST_HEAD(&p->thread_group); + p->task_works = NULL; + ++ threadgroup_change_begin(current); + /* + * Ensure that the cgroup subsystem policies allow the new process to be + * forked. It should be noted the the new process's css_set can be changed +@@ -1658,6 +1658,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, + bad_fork_cancel_cgroup: + cgroup_cancel_fork(p); + bad_fork_free_pid: ++ threadgroup_change_end(current); + if (pid != &init_struct_pid) + free_pid(pid); + bad_fork_cleanup_thread: +@@ -1690,7 +1691,6 @@ bad_fork_cleanup_policy: + mpol_put(p->mempolicy); + bad_fork_cleanup_threadgroup_lock: + #endif +- threadgroup_change_end(current); + delayacct_tsk_free(p); + bad_fork_cleanup_count: + atomic_dec(&p->cred->user->processes); +diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c +index 479d25c..b6c3945 100644 +--- a/kernel/time/timekeeping.c ++++ b/kernel/time/timekeeping.c +@@ -401,7 +401,10 @@ static __always_inline u64 __ktime_get_fast_ns(struct tk_fast *tkf) + do { + seq = raw_read_seqcount_latch(&tkf->seq); + tkr = tkf->base + (seq & 0x01); +- now = ktime_to_ns(tkr->base) + timekeeping_get_ns(tkr); ++ now = ktime_to_ns(tkr->base); ++ ++ now += clocksource_delta(tkr->read(tkr->clock), ++ tkr->cycle_last, tkr->mask); + } while (read_seqcount_retry(&tkf->seq, seq)); + + return now; +diff --git a/kernel/time/timekeeping_debug.c b/kernel/time/timekeeping_debug.c +index f6bd652..107310a 100644 +--- a/kernel/time/timekeeping_debug.c ++++ b/kernel/time/timekeeping_debug.c +@@ -23,7 +23,9 @@ + + #include "timekeeping_internal.h" + +-static unsigned int sleep_time_bin[32] = {0}; ++#define NUM_BINS 32 ++ ++static unsigned int sleep_time_bin[NUM_BINS] = {0}; + + static int tk_debug_show_sleep_time(struct seq_file *s, void *data) + { +@@ -69,6 +71,9 @@ late_initcall(tk_debug_sleep_time_init); + + void tk_debug_account_sleep_time(struct timespec64 *t) + { +- sleep_time_bin[fls(t->tv_sec)]++; ++ /* Cap bin index so we don't overflow the array */ ++ int bin = min(fls(t->tv_sec), NUM_BINS-1); ++ ++ sleep_time_bin[bin]++; + } + +diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c +index c094754..f02ab80 100644 +--- a/net/sunrpc/xprtrdma/frwr_ops.c ++++ b/net/sunrpc/xprtrdma/frwr_ops.c +@@ -125,17 +125,16 @@ __frwr_reset_mr(struct rpcrdma_ia *ia, struct rpcrdma_mw *r) + } + + static void +-__frwr_reset_and_unmap(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mw *mw) ++__frwr_reset_and_unmap(struct rpcrdma_mw *mw) + { ++ struct rpcrdma_xprt *r_xprt = mw->mw_xprt; + struct rpcrdma_ia *ia = &r_xprt->rx_ia; +- struct rpcrdma_frmr *f = &mw->frmr; + int rc; + + rc = __frwr_reset_mr(ia, mw); +- ib_dma_unmap_sg(ia->ri_device, f->fr_sg, f->fr_nents, f->fr_dir); ++ ib_dma_unmap_sg(ia->ri_device, mw->mw_sg, mw->mw_nents, mw->mw_dir); + if (rc) + return; +- + rpcrdma_put_mw(r_xprt, mw); + } + +@@ -152,8 +151,7 @@ __frwr_recovery_worker(struct work_struct *work) + struct rpcrdma_mw *r = container_of(work, struct rpcrdma_mw, + mw_work); + +- __frwr_reset_and_unmap(r->mw_xprt, r); +- return; ++ __frwr_reset_and_unmap(r); + } + + /* A broken MR was discovered in a context that can't sleep. +@@ -167,8 +165,7 @@ __frwr_queue_recovery(struct rpcrdma_mw *r) + } + + static int +-__frwr_init(struct rpcrdma_mw *r, struct ib_pd *pd, struct ib_device *device, +- unsigned int depth) ++__frwr_init(struct rpcrdma_mw *r, struct ib_pd *pd, unsigned int depth) + { + struct rpcrdma_frmr *f = &r->frmr; + int rc; +@@ -177,11 +174,11 @@ __frwr_init(struct rpcrdma_mw *r, struct ib_pd *pd, struct ib_device *device, + if (IS_ERR(f->fr_mr)) + goto out_mr_err; + +- f->fr_sg = kcalloc(depth, sizeof(*f->fr_sg), GFP_KERNEL); +- if (!f->fr_sg) ++ r->mw_sg = kcalloc(depth, sizeof(*r->mw_sg), GFP_KERNEL); ++ if (!r->mw_sg) + goto out_list_err; + +- sg_init_table(f->fr_sg, depth); ++ sg_init_table(r->mw_sg, depth); + + init_completion(&f->fr_linv_done); + +@@ -210,7 +207,7 @@ __frwr_release(struct rpcrdma_mw *r) + if (rc) + dprintk("RPC: %s: ib_dereg_mr status %i\n", + __func__, rc); +- kfree(r->frmr.fr_sg); ++ kfree(r->mw_sg); + } + + static int +@@ -350,7 +347,6 @@ static int + frwr_op_init(struct rpcrdma_xprt *r_xprt) + { + struct rpcrdma_buffer *buf = &r_xprt->rx_buf; +- struct ib_device *device = r_xprt->rx_ia.ri_device; + unsigned int depth = r_xprt->rx_ia.ri_max_frmr_depth; + struct ib_pd *pd = r_xprt->rx_ia.ri_pd; + int i; +@@ -372,7 +368,7 @@ frwr_op_init(struct rpcrdma_xprt *r_xprt) + if (!r) + return -ENOMEM; + +- rc = __frwr_init(r, pd, device, depth); ++ rc = __frwr_init(r, pd, depth); + if (rc) { + kfree(r); + return rc; +@@ -386,7 +382,7 @@ frwr_op_init(struct rpcrdma_xprt *r_xprt) + return 0; + } + +-/* Post a FAST_REG Work Request to register a memory region ++/* Post a REG_MR Work Request to register a memory region + * for remote access via RDMA READ or RDMA WRITE. + */ + static int +@@ -394,8 +390,6 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, + int nsegs, bool writing) + { + struct rpcrdma_ia *ia = &r_xprt->rx_ia; +- struct ib_device *device = ia->ri_device; +- enum dma_data_direction direction = rpcrdma_data_dir(writing); + struct rpcrdma_mr_seg *seg1 = seg; + struct rpcrdma_mw *mw; + struct rpcrdma_frmr *frmr; +@@ -421,15 +415,14 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, + + if (nsegs > ia->ri_max_frmr_depth) + nsegs = ia->ri_max_frmr_depth; +- + for (i = 0; i < nsegs;) { + if (seg->mr_page) +- sg_set_page(&frmr->fr_sg[i], ++ sg_set_page(&mw->mw_sg[i], + seg->mr_page, + seg->mr_len, + offset_in_page(seg->mr_offset)); + else +- sg_set_buf(&frmr->fr_sg[i], seg->mr_offset, ++ sg_set_buf(&mw->mw_sg[i], seg->mr_offset, + seg->mr_len); + + ++seg; +@@ -440,26 +433,20 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, + offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len)) + break; + } +- frmr->fr_nents = i; +- frmr->fr_dir = direction; +- +- dma_nents = ib_dma_map_sg(device, frmr->fr_sg, frmr->fr_nents, direction); +- if (!dma_nents) { +- pr_err("RPC: %s: failed to dma map sg %p sg_nents %u\n", +- __func__, frmr->fr_sg, frmr->fr_nents); +- return -ENOMEM; +- } ++ mw->mw_nents = i; ++ mw->mw_dir = rpcrdma_data_dir(writing); + +- n = ib_map_mr_sg(mr, frmr->fr_sg, frmr->fr_nents, NULL, PAGE_SIZE); +- if (unlikely(n != frmr->fr_nents)) { +- pr_err("RPC: %s: failed to map mr %p (%u/%u)\n", +- __func__, frmr->fr_mr, n, frmr->fr_nents); +- rc = n < 0 ? n : -EINVAL; +- goto out_senderr; +- } ++ dma_nents = ib_dma_map_sg(ia->ri_device, ++ mw->mw_sg, mw->mw_nents, mw->mw_dir); ++ if (!dma_nents) ++ goto out_dmamap_err; ++ ++ n = ib_map_mr_sg(mr, mw->mw_sg, mw->mw_nents, NULL, PAGE_SIZE); ++ if (unlikely(n != mw->mw_nents)) ++ goto out_mapmr_err; + + dprintk("RPC: %s: Using frmr %p to map %u segments (%u bytes)\n", +- __func__, mw, frmr->fr_nents, mr->length); ++ __func__, mw, mw->mw_nents, mr->length); + + key = (u8)(mr->rkey & 0x000000FF); + ib_update_fast_reg_key(mr, ++key); +@@ -484,13 +471,25 @@ frwr_op_map(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr_seg *seg, + seg1->rl_mw = mw; + seg1->mr_rkey = mr->rkey; + seg1->mr_base = mr->iova; +- seg1->mr_nsegs = frmr->fr_nents; ++ seg1->mr_nsegs = mw->mw_nents; + seg1->mr_len = mr->length; + +- return frmr->fr_nents; ++ return mw->mw_nents; ++ ++out_dmamap_err: ++ pr_err("rpcrdma: failed to dma map sg %p sg_nents %u\n", ++ mw->mw_sg, mw->mw_nents); ++ return -ENOMEM; ++ ++out_mapmr_err: ++ pr_err("rpcrdma: failed to map mr %p (%u/%u)\n", ++ frmr->fr_mr, n, mw->mw_nents); ++ rc = n < 0 ? n : -EIO; ++ __frwr_queue_recovery(mw); ++ return rc; + + out_senderr: +- dprintk("RPC: %s: ib_post_send status %i\n", __func__, rc); ++ pr_err("rpcrdma: ib_post_send status %i\n", rc); + __frwr_queue_recovery(mw); + return rc; + } +@@ -582,8 +581,8 @@ unmap: + mw = seg->rl_mw; + seg->rl_mw = NULL; + +- ib_dma_unmap_sg(ia->ri_device, f->fr_sg, f->fr_nents, +- f->fr_dir); ++ ib_dma_unmap_sg(ia->ri_device, ++ mw->mw_sg, mw->mw_nents, mw->mw_dir); + rpcrdma_put_mw(r_xprt, mw); + + i += seg->mr_nsegs; +@@ -630,7 +629,7 @@ frwr_op_unmap_safe(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req, + mw = seg->rl_mw; + + if (sync) +- __frwr_reset_and_unmap(r_xprt, mw); ++ __frwr_reset_and_unmap(mw); + else + __frwr_queue_recovery(mw); + +diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h +index 95cdc66..c53abd1 100644 +--- a/net/sunrpc/xprtrdma/xprt_rdma.h ++++ b/net/sunrpc/xprtrdma/xprt_rdma.h +@@ -221,9 +221,6 @@ enum rpcrdma_frmr_state { + }; + + struct rpcrdma_frmr { +- struct scatterlist *fr_sg; +- int fr_nents; +- enum dma_data_direction fr_dir; + struct ib_mr *fr_mr; + struct ib_cqe fr_cqe; + enum rpcrdma_frmr_state fr_state; +@@ -240,13 +237,16 @@ struct rpcrdma_fmr { + }; + + struct rpcrdma_mw { ++ struct list_head mw_list; ++ struct scatterlist *mw_sg; ++ int mw_nents; ++ enum dma_data_direction mw_dir; + union { + struct rpcrdma_fmr fmr; + struct rpcrdma_frmr frmr; + }; + struct work_struct mw_work; + struct rpcrdma_xprt *mw_xprt; +- struct list_head mw_list; + struct list_head mw_all; + }; + +diff --git a/net/sysctl_net.c b/net/sysctl_net.c +index ed98c1f..46a71c7 100644 +--- a/net/sysctl_net.c ++++ b/net/sysctl_net.c +@@ -46,7 +46,7 @@ static int net_ctl_permissions(struct ctl_table_header *head, + kgid_t root_gid = make_kgid(net->user_ns, 0); + + /* Allow network administrator to have same access as root. */ +- if (ns_capable(net->user_ns, CAP_NET_ADMIN) || ++ if (ns_capable_noaudit(net->user_ns, CAP_NET_ADMIN) || + uid_eq(root_uid, current_euid())) { + int mode = (table->mode >> 6) & 7; + return (mode << 6) | (mode << 3) | mode; +diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c +index 705c287..7347fcc 100644 +--- a/security/apparmor/policy.c ++++ b/security/apparmor/policy.c +@@ -766,7 +766,9 @@ struct aa_profile *aa_find_child(struct aa_profile *parent, const char *name) + struct aa_profile *profile; + + rcu_read_lock(); +- profile = aa_get_profile(__find_child(&parent->base.profiles, name)); ++ do { ++ profile = __find_child(&parent->base.profiles, name); ++ } while (profile && !aa_get_profile_not0(profile)); + rcu_read_unlock(); + + /* refcount released by caller */ +diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c +index 795437b..b450a27 100644 +--- a/sound/core/rawmidi.c ++++ b/sound/core/rawmidi.c +@@ -1633,11 +1633,13 @@ static int snd_rawmidi_dev_register(struct snd_device *device) + return -EBUSY; + } + list_add_tail(&rmidi->list, &snd_rawmidi_devices); ++ mutex_unlock(®ister_mutex); + err = snd_register_device(SNDRV_DEVICE_TYPE_RAWMIDI, + rmidi->card, rmidi->device, + &snd_rawmidi_f_ops, rmidi, &rmidi->dev); + if (err < 0) { + rmidi_err(rmidi, "unable to register\n"); ++ mutex_lock(®ister_mutex); + list_del(&rmidi->list); + mutex_unlock(®ister_mutex); + return err; +@@ -1645,6 +1647,7 @@ static int snd_rawmidi_dev_register(struct snd_device *device) + if (rmidi->ops && rmidi->ops->dev_register && + (err = rmidi->ops->dev_register(rmidi)) < 0) { + snd_unregister_device(&rmidi->dev); ++ mutex_lock(®ister_mutex); + list_del(&rmidi->list); + mutex_unlock(®ister_mutex); + return err; +@@ -1677,7 +1680,6 @@ static int snd_rawmidi_dev_register(struct snd_device *device) + } + } + #endif /* CONFIG_SND_OSSEMUL */ +- mutex_unlock(®ister_mutex); + sprintf(name, "midi%d", rmidi->device); + entry = snd_info_create_card_entry(rmidi->card, name, rmidi->card->proc_root); + if (entry) { +diff --git a/sound/core/timer.c b/sound/core/timer.c +index 9a6157e..fc144f4 100644 +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -35,6 +35,9 @@ + #include <sound/initval.h> + #include <linux/kmod.h> + ++/* internal flags */ ++#define SNDRV_TIMER_IFLG_PAUSED 0x00010000 ++ + #if IS_ENABLED(CONFIG_SND_HRTIMER) + #define DEFAULT_TIMER_LIMIT 4 + #else +@@ -294,8 +297,21 @@ int snd_timer_open(struct snd_timer_instance **ti, + get_device(&timer->card->card_dev); + timeri->slave_class = tid->dev_sclass; + timeri->slave_id = slave_id; +- if (list_empty(&timer->open_list_head) && timer->hw.open) +- timer->hw.open(timer); ++ ++ if (list_empty(&timer->open_list_head) && timer->hw.open) { ++ int err = timer->hw.open(timer); ++ if (err) { ++ kfree(timeri->owner); ++ kfree(timeri); ++ ++ if (timer->card) ++ put_device(&timer->card->card_dev); ++ module_put(timer->module); ++ mutex_unlock(®ister_mutex); ++ return err; ++ } ++ } ++ + list_add_tail(&timeri->open_list, &timer->open_list_head); + snd_timer_check_master(timeri); + mutex_unlock(®ister_mutex); +@@ -526,6 +542,10 @@ static int snd_timer_stop1(struct snd_timer_instance *timeri, bool stop) + } + } + timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START); ++ if (stop) ++ timeri->flags &= ~SNDRV_TIMER_IFLG_PAUSED; ++ else ++ timeri->flags |= SNDRV_TIMER_IFLG_PAUSED; + snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP : + SNDRV_TIMER_EVENT_CONTINUE); + unlock: +@@ -587,6 +607,10 @@ int snd_timer_stop(struct snd_timer_instance *timeri) + */ + int snd_timer_continue(struct snd_timer_instance *timeri) + { ++ /* timer can continue only after pause */ ++ if (!(timeri->flags & SNDRV_TIMER_IFLG_PAUSED)) ++ return -EINVAL; ++ + if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) + return snd_timer_start_slave(timeri, false); + else +@@ -813,6 +837,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid, + timer->tmr_subdevice = tid->subdevice; + if (id) + strlcpy(timer->id, id, sizeof(timer->id)); ++ timer->sticks = 1; + INIT_LIST_HEAD(&timer->device_list); + INIT_LIST_HEAD(&timer->open_list_head); + INIT_LIST_HEAD(&timer->active_list_head); +@@ -1817,6 +1842,9 @@ static int snd_timer_user_continue(struct file *file) + tu = file->private_data; + if (!tu->timeri) + return -EBADFD; ++ /* start timer instead of continue if it's not used before */ ++ if (!(tu->timeri->flags & SNDRV_TIMER_IFLG_PAUSED)) ++ return snd_timer_user_start(file); + tu->timeri->lost = 0; + return (err = snd_timer_continue(tu->timeri)) < 0 ? err : 0; + } +@@ -1958,6 +1986,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, + tu->qused--; + spin_unlock_irq(&tu->qlock); + ++ mutex_lock(&tu->ioctl_lock); + if (tu->tread) { + if (copy_to_user(buffer, &tu->tqueue[qhead], + sizeof(struct snd_timer_tread))) +@@ -1967,6 +1996,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer, + sizeof(struct snd_timer_read))) + err = -EFAULT; + } ++ mutex_unlock(&tu->ioctl_lock); + + spin_lock_irq(&tu->qlock); + if (err < 0) +diff --git a/sound/firewire/fireworks/fireworks.h b/sound/firewire/fireworks/fireworks.h +index 03ed352..d73c12b 100644 +--- a/sound/firewire/fireworks/fireworks.h ++++ b/sound/firewire/fireworks/fireworks.h +@@ -108,7 +108,6 @@ struct snd_efw { + u8 *resp_buf; + u8 *pull_ptr; + u8 *push_ptr; +- unsigned int resp_queues; + }; + + int snd_efw_transaction_cmd(struct fw_unit *unit, +diff --git a/sound/firewire/fireworks/fireworks_hwdep.c b/sound/firewire/fireworks/fireworks_hwdep.c +index 33df865..2e1d9a2 100644 +--- a/sound/firewire/fireworks/fireworks_hwdep.c ++++ b/sound/firewire/fireworks/fireworks_hwdep.c +@@ -25,6 +25,7 @@ hwdep_read_resp_buf(struct snd_efw *efw, char __user *buf, long remained, + { + unsigned int length, till_end, type; + struct snd_efw_transaction *t; ++ u8 *pull_ptr; + long count = 0; + + if (remained < sizeof(type) + sizeof(struct snd_efw_transaction)) +@@ -38,8 +39,17 @@ hwdep_read_resp_buf(struct snd_efw *efw, char __user *buf, long remained, + buf += sizeof(type); + + /* write into buffer as many responses as possible */ +- while (efw->resp_queues > 0) { +- t = (struct snd_efw_transaction *)(efw->pull_ptr); ++ spin_lock_irq(&efw->lock); ++ ++ /* ++ * When another task reaches here during this task's access to user ++ * space, it picks up current position in buffer and can read the same ++ * series of responses. ++ */ ++ pull_ptr = efw->pull_ptr; ++ ++ while (efw->push_ptr != pull_ptr) { ++ t = (struct snd_efw_transaction *)(pull_ptr); + length = be32_to_cpu(t->length) * sizeof(__be32); + + /* confirm enough space for this response */ +@@ -49,26 +59,39 @@ hwdep_read_resp_buf(struct snd_efw *efw, char __user *buf, long remained, + /* copy from ring buffer to user buffer */ + while (length > 0) { + till_end = snd_efw_resp_buf_size - +- (unsigned int)(efw->pull_ptr - efw->resp_buf); ++ (unsigned int)(pull_ptr - efw->resp_buf); + till_end = min_t(unsigned int, length, till_end); + +- if (copy_to_user(buf, efw->pull_ptr, till_end)) ++ spin_unlock_irq(&efw->lock); ++ ++ if (copy_to_user(buf, pull_ptr, till_end)) + return -EFAULT; + +- efw->pull_ptr += till_end; +- if (efw->pull_ptr >= efw->resp_buf + +- snd_efw_resp_buf_size) +- efw->pull_ptr -= snd_efw_resp_buf_size; ++ spin_lock_irq(&efw->lock); ++ ++ pull_ptr += till_end; ++ if (pull_ptr >= efw->resp_buf + snd_efw_resp_buf_size) ++ pull_ptr -= snd_efw_resp_buf_size; + + length -= till_end; + buf += till_end; + count += till_end; + remained -= till_end; + } +- +- efw->resp_queues--; + } + ++ /* ++ * All of tasks can read from the buffer nearly simultaneously, but the ++ * last position for each task is different depending on the length of ++ * given buffer. Here, for simplicity, a position of buffer is set by ++ * the latest task. It's better for a listening application to allow one ++ * thread to read from the buffer. Unless, each task can read different ++ * sequence of responses depending on variation of buffer length. ++ */ ++ efw->pull_ptr = pull_ptr; ++ ++ spin_unlock_irq(&efw->lock); ++ + return count; + } + +@@ -76,14 +99,17 @@ static long + hwdep_read_locked(struct snd_efw *efw, char __user *buf, long count, + loff_t *offset) + { +- union snd_firewire_event event; ++ union snd_firewire_event event = { ++ .lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS, ++ }; + +- memset(&event, 0, sizeof(event)); ++ spin_lock_irq(&efw->lock); + +- event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; + event.lock_status.status = (efw->dev_lock_count > 0); + efw->dev_lock_changed = false; + ++ spin_unlock_irq(&efw->lock); ++ + count = min_t(long, count, sizeof(event.lock_status)); + + if (copy_to_user(buf, &event, count)) +@@ -98,10 +124,15 @@ hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, + { + struct snd_efw *efw = hwdep->private_data; + DEFINE_WAIT(wait); ++ bool dev_lock_changed; ++ bool queued; + + spin_lock_irq(&efw->lock); + +- while ((!efw->dev_lock_changed) && (efw->resp_queues == 0)) { ++ dev_lock_changed = efw->dev_lock_changed; ++ queued = efw->push_ptr != efw->pull_ptr; ++ ++ while (!dev_lock_changed && !queued) { + prepare_to_wait(&efw->hwdep_wait, &wait, TASK_INTERRUPTIBLE); + spin_unlock_irq(&efw->lock); + schedule(); +@@ -109,15 +140,17 @@ hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, + if (signal_pending(current)) + return -ERESTARTSYS; + spin_lock_irq(&efw->lock); ++ dev_lock_changed = efw->dev_lock_changed; ++ queued = efw->push_ptr != efw->pull_ptr; + } + +- if (efw->dev_lock_changed) ++ spin_unlock_irq(&efw->lock); ++ ++ if (dev_lock_changed) + count = hwdep_read_locked(efw, buf, count, offset); +- else if (efw->resp_queues > 0) ++ else if (queued) + count = hwdep_read_resp_buf(efw, buf, count, offset); + +- spin_unlock_irq(&efw->lock); +- + return count; + } + +@@ -160,7 +193,7 @@ hwdep_poll(struct snd_hwdep *hwdep, struct file *file, poll_table *wait) + poll_wait(file, &efw->hwdep_wait, wait); + + spin_lock_irq(&efw->lock); +- if (efw->dev_lock_changed || (efw->resp_queues > 0)) ++ if (efw->dev_lock_changed || efw->pull_ptr != efw->push_ptr) + events = POLLIN | POLLRDNORM; + else + events = 0; +diff --git a/sound/firewire/fireworks/fireworks_proc.c b/sound/firewire/fireworks/fireworks_proc.c +index 0639dcb..beb0a0f 100644 +--- a/sound/firewire/fireworks/fireworks_proc.c ++++ b/sound/firewire/fireworks/fireworks_proc.c +@@ -188,8 +188,8 @@ proc_read_queues_state(struct snd_info_entry *entry, + else + consumed = (unsigned int)(efw->push_ptr - efw->pull_ptr); + +- snd_iprintf(buffer, "%d %d/%d\n", +- efw->resp_queues, consumed, snd_efw_resp_buf_size); ++ snd_iprintf(buffer, "%d/%d\n", ++ consumed, snd_efw_resp_buf_size); + } + + static void +diff --git a/sound/firewire/fireworks/fireworks_transaction.c b/sound/firewire/fireworks/fireworks_transaction.c +index f550808..36a08ba 100644 +--- a/sound/firewire/fireworks/fireworks_transaction.c ++++ b/sound/firewire/fireworks/fireworks_transaction.c +@@ -121,11 +121,11 @@ copy_resp_to_buf(struct snd_efw *efw, void *data, size_t length, int *rcode) + size_t capacity, till_end; + struct snd_efw_transaction *t; + +- spin_lock_irq(&efw->lock); +- + t = (struct snd_efw_transaction *)data; + length = min_t(size_t, be32_to_cpu(t->length) * sizeof(u32), length); + ++ spin_lock_irq(&efw->lock); ++ + if (efw->push_ptr < efw->pull_ptr) + capacity = (unsigned int)(efw->pull_ptr - efw->push_ptr); + else +@@ -155,7 +155,6 @@ copy_resp_to_buf(struct snd_efw *efw, void *data, size_t length, int *rcode) + } + + /* for hwdep */ +- efw->resp_queues++; + wake_up(&efw->hwdep_wait); + + *rcode = RCODE_COMPLETE; +diff --git a/sound/firewire/tascam/tascam-hwdep.c b/sound/firewire/tascam/tascam-hwdep.c +index 131267c..106406c 100644 +--- a/sound/firewire/tascam/tascam-hwdep.c ++++ b/sound/firewire/tascam/tascam-hwdep.c +@@ -16,31 +16,14 @@ + + #include "tascam.h" + +-static long hwdep_read_locked(struct snd_tscm *tscm, char __user *buf, +- long count) +-{ +- union snd_firewire_event event; +- +- memset(&event, 0, sizeof(event)); +- +- event.lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS; +- event.lock_status.status = (tscm->dev_lock_count > 0); +- tscm->dev_lock_changed = false; +- +- count = min_t(long, count, sizeof(event.lock_status)); +- +- if (copy_to_user(buf, &event, count)) +- return -EFAULT; +- +- return count; +-} +- + static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, + loff_t *offset) + { + struct snd_tscm *tscm = hwdep->private_data; + DEFINE_WAIT(wait); +- union snd_firewire_event event; ++ union snd_firewire_event event = { ++ .lock_status.type = SNDRV_FIREWIRE_EVENT_LOCK_STATUS, ++ }; + + spin_lock_irq(&tscm->lock); + +@@ -54,10 +37,16 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, + spin_lock_irq(&tscm->lock); + } + +- memset(&event, 0, sizeof(event)); +- count = hwdep_read_locked(tscm, buf, count); ++ event.lock_status.status = (tscm->dev_lock_count > 0); ++ tscm->dev_lock_changed = false; ++ + spin_unlock_irq(&tscm->lock); + ++ count = min_t(long, count, sizeof(event.lock_status)); ++ ++ if (copy_to_user(buf, &event, count)) ++ return -EFAULT; ++ + return count; + } + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index f25479b..eaee626 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -4840,6 +4840,7 @@ enum { + ALC221_FIXUP_HP_FRONT_MIC, + ALC292_FIXUP_TPT460, + ALC298_FIXUP_SPK_VOLUME, ++ ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER, + }; + + static const struct hda_fixup alc269_fixups[] = { +@@ -5501,6 +5502,15 @@ static const struct hda_fixup alc269_fixups[] = { + .chained = true, + .chain_id = ALC298_FIXUP_DELL1_MIC_NO_PRESENCE, + }, ++ [ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER] = { ++ .type = HDA_FIXUP_PINS, ++ .v.pins = (const struct hda_pintbl[]) { ++ { 0x1b, 0x90170151 }, ++ { } ++ }, ++ .chained = true, ++ .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE ++ }, + }; + + static const struct snd_pci_quirk alc269_fixup_tbl[] = { +@@ -5545,6 +5555,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), + SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK), + SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), ++ SND_PCI_QUIRK(0x1028, 0x0706, "Dell Inspiron 7559", ALC256_FIXUP_DELL_INSPIRON_7559_SUBWOOFER), + SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE), + SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE), + SND_PCI_QUIRK(0x1028, 0x075d, "Dell AIO", ALC298_FIXUP_SPK_VOLUME), +@@ -5879,6 +5890,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { + {0x12, 0x90a60170}, + {0x14, 0x90170120}, + {0x21, 0x02211030}), ++ SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell Inspiron 5468", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, ++ {0x12, 0x90a60180}, ++ {0x14, 0x90170120}, ++ {0x21, 0x02211030}), + SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, + ALC256_STANDARD_PINS), + SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4, +diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c +index 1267e1a..633d54ca 100644 +--- a/sound/soc/atmel/atmel_ssc_dai.c ++++ b/sound/soc/atmel/atmel_ssc_dai.c +@@ -299,8 +299,9 @@ static int atmel_ssc_startup(struct snd_pcm_substream *substream, + clk_enable(ssc_p->ssc->clk); + ssc_p->mck_rate = clk_get_rate(ssc_p->ssc->clk); + +- /* Reset the SSC to keep it at a clean status */ +- ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST)); ++ /* Reset the SSC unless initialized to keep it in a clean state */ ++ if (!ssc_p->initialized) ++ ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST)); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + dir = 0; +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 6cf1f35..152292e 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -1141,6 +1141,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) + case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */ + case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */ + case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */ ++ case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */ + case USB_ID(0x1de7, 0x0013): /* Phoenix Audio MT202exe */ + case USB_ID(0x1de7, 0x0014): /* Phoenix Audio TMX320 */ + case USB_ID(0x1de7, 0x0114): /* Phoenix Audio MT202pcs */ diff --git a/4.7.3/4420_grsecurity-3.1-4.7.3-201609072139.patch b/4.7.4/4420_grsecurity-3.1-4.7.4-201609152234.patch index 34c7fa0..84d74fa 100644 --- a/4.7.3/4420_grsecurity-3.1-4.7.3-201609072139.patch +++ b/4.7.4/4420_grsecurity-3.1-4.7.4-201609152234.patch @@ -420,7 +420,7 @@ index a3683ce..5ec8bf4 100644 A toggle value indicating if modules are allowed to be loaded diff --git a/Makefile b/Makefile -index 4afff18..1c6d3b2 100644 +index ec3bd11..35d4d88 100644 --- a/Makefile +++ b/Makefile @@ -302,7 +302,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -956,7 +956,7 @@ index d50430c..01cc53b 100644 # but it is being used too early to link to meaningful stack_chk logic. nossp_flags := $(call cc-option, -fno-stack-protector) diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h -index 9e10c45..2feb375 100644 +index 9e10c45..688ea8b 100644 --- a/arch/arm/include/asm/atomic.h +++ b/arch/arm/include/asm/atomic.h @@ -18,17 +18,41 @@ @@ -1404,15 +1404,14 @@ index 9e10c45..2feb375 100644 static inline long long atomic64_cmpxchg_relaxed(atomic64_t *ptr, long long old, long long new) -@@ -361,6 +555,31 @@ atomic64_cmpxchg_relaxed(atomic64_t *ptr, long long old, long long new) +@@ -361,6 +555,30 @@ 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_relaxed atomic64_cmpxchg_unchecked_relaxed + +static inline long long -+atomic64_cmpxchg_unchecked_relaxed(atomic64_unchecked_t *ptr, long long old, -+ long long new) ++atomic64_cmpxchg_unchecked_relaxed(atomic64_unchecked_t *ptr, long long old, long long new) +{ + long long oldval; + unsigned long res; @@ -1436,7 +1435,7 @@ index 9e10c45..2feb375 100644 static inline long long atomic64_xchg_relaxed(atomic64_t *ptr, long long new) { -@@ -380,26 +599,60 @@ static inline long long atomic64_xchg_relaxed(atomic64_t *ptr, long long new) +@@ -380,26 +598,60 @@ static inline long long atomic64_xchg_relaxed(atomic64_t *ptr, long long new) return result; } @@ -1503,7 +1502,7 @@ index 9e10c45..2feb375 100644 : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) : "r" (&v->counter) : "cc"); -@@ -423,13 +676,25 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) +@@ -423,13 +675,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" @@ -1532,7 +1531,7 @@ index 9e10c45..2feb375 100644 : "=&r" (val), "+r" (ret), "=&r" (tmp), "+Qo" (v->counter) : "r" (&v->counter), "r" (u), "r" (a) : "cc"); -@@ -442,10 +707,13 @@ static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) +@@ -442,10 +706,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)) @@ -1601,20 +1600,28 @@ index 524692f..a8871ec 100644 /* * Fold a partial checksum without adding pseudo headers diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h -index 97882f9..0cc6ef1 100644 +index 97882f9..ff9d6ac 100644 --- a/arch/arm/include/asm/cmpxchg.h +++ b/arch/arm/include/asm/cmpxchg.h @@ -117,6 +117,10 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size (__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), \ sizeof(*(ptr))); \ }) -+#define xchg_unchecked(ptr, x) ({ \ ++#define xchg_unchecked_relaxed(ptr, x) ({ \ + (__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), \ + sizeof(*(ptr))); \ +}) #include <asm-generic/cmpxchg-local.h> +@@ -128,6 +132,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size + #endif + + #define xchg xchg_relaxed ++#define xchg_unchecked xchg_unchecked_relaxed + + /* + * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make diff --git a/arch/arm/include/asm/cpuidle.h b/arch/arm/include/asm/cpuidle.h index baefe1d..29cb35a 100644 --- a/arch/arm/include/asm/cpuidle.h @@ -5041,19 +5048,6 @@ index 2a43012..3409956 100644 } static const char *esr_class_str[] = { -diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c -index c566ec8..3e01953 100644 ---- a/arch/arm64/mm/dma-mapping.c -+++ b/arch/arm64/mm/dma-mapping.c -@@ -132,7 +132,7 @@ static void __dma_free_coherent(struct device *dev, size_t size, - phys_to_page(paddr), - size >> PAGE_SHIFT); - if (!freed) -- swiotlb_free_coherent(dev, size, vaddr, dma_handle); -+ swiotlb_free_coherent(dev, size, vaddr, dma_handle, attrs); - } - - static void *__dma_alloc(struct device *dev, size_t size, diff --git a/arch/avr32/include/asm/cache.h b/arch/avr32/include/asm/cache.h index c3a58a1..78fbf54 100644 --- a/arch/avr32/include/asm/cache.h @@ -5879,19 +5873,6 @@ index ac91939..a1df96d 100644 help kexec is a system call that implements the ability to shutdown your current kernel, and to start another kernel. It is like a reboot -diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c -index 2cd45f5..d0f4900 100644 ---- a/arch/mips/cavium-octeon/dma-octeon.c -+++ b/arch/mips/cavium-octeon/dma-octeon.c -@@ -191,7 +191,7 @@ static void *octeon_dma_alloc_coherent(struct device *dev, size_t size, - static void octeon_dma_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle, struct dma_attrs *attrs) - { -- swiotlb_free_coherent(dev, size, vaddr, dma_handle); -+ swiotlb_free_coherent(dev, size, vaddr, dma_handle, attrs); - } - - static dma_addr_t octeon_unity_phys_to_dma(struct device *dev, phys_addr_t paddr) diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index 835b402..347a797 100644 --- a/arch/mips/include/asm/atomic.h @@ -8400,17 +8381,30 @@ index ae0751e..06b108a 100644 2:" : "=&r" (t) diff --git a/arch/powerpc/include/asm/book3s/32/hash.h b/arch/powerpc/include/asm/book3s/32/hash.h -index 880db13..017716c 100644 +index 880db13..bb4ed4a 100644 --- a/arch/powerpc/include/asm/book3s/32/hash.h +++ b/arch/powerpc/include/asm/book3s/32/hash.h @@ -20,6 +20,7 @@ #define _PAGE_HASHPTE 0x002 /* hash_page has made an HPTE for this pte */ #define _PAGE_USER 0x004 /* usermode access allowed */ #define _PAGE_GUARDED 0x008 /* G: prohibit speculative access */ -+#define _PAGE_EXEC _PAGE_GUARDED ++#define _PAGE_NX _PAGE_GUARDED #define _PAGE_COHERENT 0x010 /* M: enforce memory coherence (SMP systems) */ #define _PAGE_NO_CACHE 0x020 /* I: cache inhibit */ #define _PAGE_WRITETHRU 0x040 /* W: cache write-through */ +diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h +index 38b33dc..945d1f1 100644 +--- a/arch/powerpc/include/asm/book3s/32/pgtable.h ++++ b/arch/powerpc/include/asm/book3s/32/pgtable.h +@@ -226,7 +226,7 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, + static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry) + { + unsigned long set = pte_val(entry) & +- (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC); ++ (_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC | _PAGE_NX); + unsigned long clr = ~pte_val(entry) & _PAGE_RO; + + pte_update(ptep, clr, set); diff --git a/arch/powerpc/include/asm/book3s/64/pgalloc.h b/arch/powerpc/include/asm/book3s/64/pgalloc.h index cd5e7aa..7709061 100644 --- a/arch/powerpc/include/asm/book3s/64/pgalloc.h @@ -8696,6 +8690,73 @@ index ee09e99..7e580ee 100644 #ifndef __ASSEMBLY__ #include <linux/mmdebug.h> #include <linux/mmzone.h> +diff --git a/arch/powerpc/include/asm/pte-common.h b/arch/powerpc/include/asm/pte-common.h +index 2eeaf80..c75d4fb 100644 +--- a/arch/powerpc/include/asm/pte-common.h ++++ b/arch/powerpc/include/asm/pte-common.h +@@ -16,6 +16,9 @@ + #ifndef _PAGE_EXEC + #define _PAGE_EXEC 0 + #endif ++#ifndef _PAGE_NX ++#define _PAGE_NX 0 ++#endif + #ifndef _PAGE_ENDIAN + #define _PAGE_ENDIAN 0 + #endif +@@ -53,13 +56,13 @@ + #define PMD_PAGE_SIZE(pmd) bad_call_to_PMD_PAGE_SIZE() + #endif + #ifndef _PAGE_KERNEL_RO +-#define _PAGE_KERNEL_RO (_PAGE_RO) ++#define _PAGE_KERNEL_RO (_PAGE_RO | _PAGE_NX) + #endif + #ifndef _PAGE_KERNEL_ROX + #define _PAGE_KERNEL_ROX (_PAGE_EXEC | _PAGE_RO) + #endif + #ifndef _PAGE_KERNEL_RW +-#define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE) ++#define _PAGE_KERNEL_RW (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE | _PAGE_NX) + #endif + #ifndef _PAGE_KERNEL_RWX + #define _PAGE_KERNEL_RWX (_PAGE_DIRTY | _PAGE_RW | _PAGE_HWWRITE | _PAGE_EXEC) +@@ -142,15 +145,12 @@ static inline bool pte_user(pte_t pte) + * Note due to the way vm flags are laid out, the bits are XWR + */ + #define PAGE_NONE __pgprot(_PAGE_BASE) +-#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW) +-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | \ +- _PAGE_EXEC) +-#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RO) +-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RO | \ +- _PAGE_EXEC) +-#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RO) +-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RO | \ +- _PAGE_EXEC) ++#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_NX) ++#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC) ++#define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RO | _PAGE_NX) ++#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RO | _PAGE_EXEC) ++#define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RO | _PAGE_NX) ++#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RO | _PAGE_EXEC) + + #define __P000 PAGE_NONE + #define __P001 PAGE_READONLY +@@ -171,11 +171,9 @@ static inline bool pte_user(pte_t pte) + #define __S111 PAGE_SHARED_X + + /* Permission masks used for kernel mappings */ +-#define PAGE_KERNEL __pgprot(_PAGE_BASE | _PAGE_KERNEL_RW) +-#define PAGE_KERNEL_NC __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \ +- _PAGE_NO_CACHE) +-#define PAGE_KERNEL_NCG __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | \ +- _PAGE_NO_CACHE | _PAGE_GUARDED) ++#define PAGE_KERNEL __pgprot(_PAGE_BASE | _PAGE_KERNEL_RW | _PAGE_NX) ++#define PAGE_KERNEL_NC __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | _PAGE_NO_CACHE) ++#define PAGE_KERNEL_NCG __pgprot(_PAGE_BASE_NC | _PAGE_KERNEL_RW | _PAGE_NO_CACHE | _PAGE_GUARDED) + #define PAGE_KERNEL_X __pgprot(_PAGE_BASE | _PAGE_KERNEL_RWX) + #define PAGE_KERNEL_RO __pgprot(_PAGE_BASE | _PAGE_KERNEL_RO) + #define PAGE_KERNEL_ROX __pgprot(_PAGE_BASE | _PAGE_KERNEL_ROX) diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index a0948f4..ddcf6be 100644 --- a/arch/powerpc/include/asm/reg.h @@ -14648,6 +14709,72 @@ index 50e6847..bf7c2d8 100644 static void cast6_xts_enc(void *ctx, u128 *dst, const u128 *src, le128 *iv) { +diff --git a/arch/x86/crypto/crc32-pclmul_asm.S b/arch/x86/crypto/crc32-pclmul_asm.S +index f247304..b500391 100644 +--- a/arch/x86/crypto/crc32-pclmul_asm.S ++++ b/arch/x86/crypto/crc32-pclmul_asm.S +@@ -102,6 +102,12 @@ + * size_t len, uint crc32) + */ + ++#ifndef __x86_64__ ++__i686_get_pc_thunk_cx: ++ mov (%esp),%ecx ++ ret ++#endif ++ + ENTRY(crc32_pclmul_le_16) /* buffer and buffer size are 16 bytes aligned */ + movdqa (BUF), %xmm1 + movdqa 0x10(BUF), %xmm2 +@@ -113,9 +119,8 @@ ENTRY(crc32_pclmul_le_16) /* buffer and buffer size are 16 bytes aligned */ + add $0x40, BUF + #ifndef __x86_64__ + /* This is for position independent code(-fPIC) support for 32bit */ +- call delta ++ call __i686_get_pc_thunk_cx + delta: +- pop %ecx + #endif + cmp $0x40, LEN + jb less_64 +@@ -123,7 +128,7 @@ delta: + #ifdef __x86_64__ + movdqa .Lconstant_R2R1(%rip), CONSTANT + #else +- movdqa .Lconstant_R2R1 - delta(%ecx), CONSTANT ++ movdqa %cs:.Lconstant_R2R1 - delta (%ecx), CONSTANT + #endif + + loop_64:/* 64 bytes Full cache line folding */ +@@ -172,7 +177,7 @@ less_64:/* Folding cache line into 128bit */ + #ifdef __x86_64__ + movdqa .Lconstant_R4R3(%rip), CONSTANT + #else +- movdqa .Lconstant_R4R3 - delta(%ecx), CONSTANT ++ movdqa %cs:.Lconstant_R4R3 - delta(%ecx), CONSTANT + #endif + prefetchnta (BUF) + +@@ -220,8 +225,8 @@ fold_64: + movdqa .Lconstant_R5(%rip), CONSTANT + movdqa .Lconstant_mask32(%rip), %xmm3 + #else +- movdqa .Lconstant_R5 - delta(%ecx), CONSTANT +- movdqa .Lconstant_mask32 - delta(%ecx), %xmm3 ++ movdqa %cs:.Lconstant_R5 - delta(%ecx), CONSTANT ++ movdqa %cs:.Lconstant_mask32 - delta(%ecx), %xmm3 + #endif + psrldq $0x04, %xmm2 + pand %xmm3, %xmm1 +@@ -232,7 +237,7 @@ fold_64: + #ifdef __x86_64__ + movdqa .Lconstant_RUpoly(%rip), CONSTANT + #else +- movdqa .Lconstant_RUpoly - delta(%ecx), CONSTANT ++ movdqa %cs:.Lconstant_RUpoly - delta(%ecx), CONSTANT + #endif + movdqa %xmm1, %xmm2 + pand %xmm3, %xmm1 diff --git a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S index dc05f010..23c8bfd 100644 --- a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S @@ -23343,6 +23470,27 @@ index 1549caa0..aa9ebe1 100644 #define __USER32_CS (GDT_ENTRY_DEFAULT_USER32_CS*8 + 3) #define __USER_DS (GDT_ENTRY_DEFAULT_USER_DS*8 + 3) #define __USER32_DS __USER_DS +diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h +index ac1d5da..6c4be50 100644 +--- a/arch/x86/include/asm/setup.h ++++ b/arch/x86/include/asm/setup.h +@@ -61,6 +61,7 @@ static inline void x86_ce4100_early_setup(void) { } + #ifndef _SETUP + + #include <asm/espfix.h> ++#include <asm/uaccess.h> + #include <linux/kernel.h> + + /* +@@ -76,7 +77,7 @@ static inline bool kaslr_enabled(void) + + static inline unsigned long kaslr_offset(void) + { +- return (unsigned long)&_text - __START_KERNEL; ++ return ktla_ktva((unsigned long)&_text) - __START_KERNEL; + } + + /* diff --git a/arch/x86/include/asm/smap.h b/arch/x86/include/asm/smap.h index db33330..e9521fb 100644 --- a/arch/x86/include/asm/smap.h @@ -23927,7 +24075,7 @@ index c3496619..3f3a7dc 100644 asmlinkage void smp_deferred_error_interrupt(void); #endif diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h -index 2982387..8adcc96 100644 +index 2982387..35d07f4 100644 --- a/arch/x86/include/asm/uaccess.h +++ b/arch/x86/include/asm/uaccess.h @@ -8,6 +8,7 @@ @@ -24130,16 +24278,23 @@ index 2982387..8adcc96 100644 break; \ case 4: \ __get_user_asm_ex(x, ptr, "l", "k", "=r"); \ -@@ -412,7 +464,7 @@ do { \ +@@ -412,9 +464,13 @@ do { \ } while (0) #define __get_user_asm_ex(x, addr, itype, rtype, ltype) \ - asm volatile("1: mov"itype" %1,%"rtype"0\n" \ + asm volatile("1: "__copyuser_seg"mov"itype" %1,%"rtype"0\n"\ "2:\n" \ - _ASM_EXTABLE_EX(1b, 2b) \ +- _ASM_EXTABLE_EX(1b, 2b) \ ++ ".section .fixup,\"ax\"\n" \ ++ "3:xorl %k0,%k0\n" \ ++ " jmp 2b\n" \ ++ ".previous\n" \ ++ _ASM_EXTABLE_EX(1b, 3b) \ : ltype(x) : "m" (__m(addr))) -@@ -433,13 +485,24 @@ do { \ + + #define __put_user_nocheck(x, ptr, size) \ +@@ -433,13 +489,24 @@ do { \ __uaccess_begin(); \ __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \ __uaccess_end(); \ @@ -24166,7 +24321,7 @@ index 2982387..8adcc96 100644 /* * Tell gcc we read from memory instead of writing: this is because -@@ -447,8 +510,10 @@ struct __large_struct { unsigned long buf[100]; }; +@@ -447,8 +514,10 @@ struct __large_struct { unsigned long buf[100]; }; * aliasing issues. */ #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \ @@ -24178,7 +24333,7 @@ index 2982387..8adcc96 100644 "2:\n" \ ".section .fixup,\"ax\"\n" \ "3: mov %3,%0\n" \ -@@ -456,10 +521,12 @@ struct __large_struct { unsigned long buf[100]; }; +@@ -456,10 +525,12 @@ struct __large_struct { unsigned long buf[100]; }; ".previous\n" \ _ASM_EXTABLE(1b, 3b) \ : "=r"(err) \ @@ -24193,7 +24348,7 @@ index 2982387..8adcc96 100644 "2:\n" \ _ASM_EXTABLE_EX(1b, 2b) \ : : ltype(x), "m" (__m(addr))) -@@ -469,11 +536,13 @@ struct __large_struct { unsigned long buf[100]; }; +@@ -469,11 +540,13 @@ struct __large_struct { unsigned long buf[100]; }; */ #define uaccess_try do { \ current_thread_info()->uaccess_err = 0; \ @@ -24207,7 +24362,7 @@ index 2982387..8adcc96 100644 (err) |= (current_thread_info()->uaccess_err ? -EFAULT : 0); \ } while (0) -@@ -499,8 +568,12 @@ struct __large_struct { unsigned long buf[100]; }; +@@ -499,8 +572,12 @@ struct __large_struct { unsigned long buf[100]; }; * On error, the variable @x is set to zero. */ @@ -24220,7 +24375,7 @@ index 2982387..8adcc96 100644 /** * __put_user: - Write a simple value into user space, with less checking. -@@ -523,8 +596,12 @@ struct __large_struct { unsigned long buf[100]; }; +@@ -523,8 +600,12 @@ struct __large_struct { unsigned long buf[100]; }; * Returns zero on success, or -EFAULT on error. */ @@ -24233,7 +24388,7 @@ index 2982387..8adcc96 100644 #define __get_user_unaligned __get_user #define __put_user_unaligned __put_user -@@ -542,7 +619,7 @@ struct __large_struct { unsigned long buf[100]; }; +@@ -542,7 +623,7 @@ struct __large_struct { unsigned long buf[100]; }; #define get_user_ex(x, ptr) do { \ unsigned long __gue_val; \ __get_user_size_ex((__gue_val), (ptr), (sizeof(*(ptr)))); \ @@ -24242,7 +24397,7 @@ index 2982387..8adcc96 100644 } while (0) #define put_user_try uaccess_try -@@ -560,7 +637,7 @@ extern __must_check long strlen_user(const char __user *str); +@@ -560,7 +641,7 @@ extern __must_check long strlen_user(const char __user *str); extern __must_check long strnlen_user(const char __user *str, long n); unsigned long __must_check clear_user(void __user *mem, unsigned long len); @@ -24251,7 +24406,7 @@ index 2982387..8adcc96 100644 extern void __cmpxchg_wrong_size(void) __compiletime_error("Bad argument size for cmpxchg"); -@@ -568,22 +645,23 @@ extern void __cmpxchg_wrong_size(void) +@@ -568,22 +649,23 @@ extern void __cmpxchg_wrong_size(void) #define __user_atomic_cmpxchg_inatomic(uval, ptr, old, new, size) \ ({ \ int __ret = 0; \ @@ -24280,7 +24435,7 @@ index 2982387..8adcc96 100644 : "i" (-EFAULT), "q" (__new), "1" (__old) \ : "memory" \ ); \ -@@ -592,14 +670,14 @@ extern void __cmpxchg_wrong_size(void) +@@ -592,14 +674,14 @@ extern void __cmpxchg_wrong_size(void) case 2: \ { \ asm volatile("\n" \ @@ -24297,7 +24452,7 @@ index 2982387..8adcc96 100644 : "i" (-EFAULT), "r" (__new), "1" (__old) \ : "memory" \ ); \ -@@ -608,14 +686,14 @@ extern void __cmpxchg_wrong_size(void) +@@ -608,14 +690,14 @@ extern void __cmpxchg_wrong_size(void) case 4: \ { \ asm volatile("\n" \ @@ -24314,7 +24469,7 @@ index 2982387..8adcc96 100644 : "i" (-EFAULT), "r" (__new), "1" (__old) \ : "memory" \ ); \ -@@ -627,14 +705,14 @@ extern void __cmpxchg_wrong_size(void) +@@ -627,14 +709,14 @@ extern void __cmpxchg_wrong_size(void) __cmpxchg_wrong_size(); \ \ asm volatile("\n" \ @@ -24331,7 +24486,7 @@ index 2982387..8adcc96 100644 : "i" (-EFAULT), "r" (__new), "1" (__old) \ : "memory" \ ); \ -@@ -644,6 +722,7 @@ extern void __cmpxchg_wrong_size(void) +@@ -644,6 +726,7 @@ extern void __cmpxchg_wrong_size(void) __cmpxchg_wrong_size(); \ } \ __uaccess_end(); \ @@ -24339,7 +24494,7 @@ index 2982387..8adcc96 100644 *__uval = __old; \ __ret; \ }) -@@ -667,17 +746,6 @@ extern struct movsl_mask { +@@ -667,17 +750,6 @@ extern struct movsl_mask { #define ARCH_HAS_NOCACHE_UACCESS 1 @@ -24357,7 +24512,7 @@ index 2982387..8adcc96 100644 #ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS # define copy_user_diag __compiletime_error #else -@@ -687,7 +755,7 @@ unsigned long __must_check _copy_to_user(void __user *to, const void *from, +@@ -687,7 +759,7 @@ unsigned long __must_check _copy_to_user(void __user *to, const void *from, extern void copy_user_diag("copy_from_user() buffer size is too small") copy_from_user_overflow(void); extern void copy_user_diag("copy_to_user() buffer size is too small") @@ -24366,7 +24521,7 @@ index 2982387..8adcc96 100644 #undef copy_user_diag -@@ -700,7 +768,7 @@ __copy_from_user_overflow(void) __asm__("copy_from_user_overflow"); +@@ -700,7 +772,7 @@ __copy_from_user_overflow(void) __asm__("copy_from_user_overflow"); extern void __compiletime_warning("copy_to_user() buffer size is not provably correct") @@ -24375,7 +24530,7 @@ index 2982387..8adcc96 100644 #define __copy_to_user_overflow(size, count) __copy_to_user_overflow() #else -@@ -715,10 +783,16 @@ __copy_from_user_overflow(int size, unsigned long count) +@@ -715,10 +787,16 @@ __copy_from_user_overflow(int size, unsigned long count) #endif @@ -24393,7 +24548,7 @@ index 2982387..8adcc96 100644 might_fault(); -@@ -742,12 +816,15 @@ copy_from_user(void *to, const void __user *from, unsigned long n) +@@ -742,12 +820,15 @@ copy_from_user(void *to, const void __user *from, unsigned long n) * case, and do only runtime checking for non-constant sizes. */ @@ -24415,7 +24570,7 @@ index 2982387..8adcc96 100644 return n; } -@@ -755,19 +832,20 @@ copy_from_user(void *to, const void __user *from, unsigned long n) +@@ -755,19 +836,20 @@ copy_from_user(void *to, const void __user *from, unsigned long n) static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n) { @@ -25284,7 +25439,7 @@ index 5cb272a..2bcff83 100644 bp_int3_handler = handler; bp_int3_addr = (u8 *)addr + sizeof(int3); diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c -index 60078a6..b9fb105 100644 +index b15e1c1..42cf1f5 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -177,7 +177,7 @@ int first_system_vector = FIRST_SYSTEM_VECTOR; @@ -25296,7 +25451,7 @@ index 60078a6..b9fb105 100644 int pic_mode; -@@ -1878,7 +1878,7 @@ static void __smp_error_interrupt(struct pt_regs *regs) +@@ -1881,7 +1881,7 @@ static void __smp_error_interrupt(struct pt_regs *regs) apic_write(APIC_ESR, 0); v = apic_read(APIC_ESR); ack_APIC_irq(); @@ -29000,7 +29155,7 @@ index 61924222..0e4856e 100644 +ENDPROC(return_to_handler) #endif diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c -index 477ae80..c8e40a3 100644 +index 477ae80..a280c67 100644 --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -76,17 +76,17 @@ static unsigned long int get_module_load_offset(void) @@ -29050,7 +29205,7 @@ index 477ae80..c8e40a3 100644 + return NULL; + + area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_EXEC_VADDR, (unsigned long)&MODULES_EXEC_END); -+return area ? area->addr : NULL; ++ return area ? area->addr : NULL; +} +EXPORT_SYMBOL(module_alloc_exec); + @@ -29659,19 +29814,6 @@ index f712dfd..0172a75 100644 #define DEBUG 1 -diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c -index 7c577a1..3557b10 100644 ---- a/arch/x86/kernel/pci-swiotlb.c -+++ b/arch/x86/kernel/pci-swiotlb.c -@@ -40,7 +40,7 @@ void x86_swiotlb_free_coherent(struct device *dev, size_t size, - struct dma_attrs *attrs) - { - if (is_swiotlb_buffer(dma_to_phys(dev, dma_addr))) -- swiotlb_free_coherent(dev, size, vaddr, dma_addr); -+ swiotlb_free_coherent(dev, size, vaddr, dma_addr, attrs); - else - dma_generic_free_coherent(dev, size, vaddr, dma_addr, attrs); - } diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 96becbb..a18444b 100644 --- a/arch/x86/kernel/process.c @@ -32118,7 +32260,7 @@ index 8326d68..3cc3895 100644 .disabled_by_bios = vmx_disabled_by_bios, .hardware_setup = hardware_setup, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c -index fea2c57..19b3e60 100644 +index fea2c57..5c02643 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1941,8 +1941,8 @@ static int xen_hvm_config(struct kvm_vcpu *vcpu, u64 data) @@ -32177,6 +32319,15 @@ index fea2c57..19b3e60 100644 guest_xsave->region, sizeof(struct fxregs_state)); } return 0; +@@ -5728,7 +5730,7 @@ static unsigned long kvm_get_guest_ip(void) + unsigned long ip = 0; + + if (__this_cpu_read(current_vcpu)) +- ip = kvm_rip_read(__this_cpu_read(current_vcpu)); ++ ip = kvm_get_linear_rip(__this_cpu_read(current_vcpu)); + + return ip; + } @@ -6450,6 +6452,7 @@ void kvm_arch_mmu_notifier_invalidate_page(struct kvm *kvm, * exiting to the userspace. Otherwise, the value will be returned to the * userspace. @@ -35069,46 +35220,10 @@ index 99bfb19..237fb1d 100644 } else { walk_pud_level(m, &st, *start, diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c -index 4bb53b8..7e79b52 100644 +index 4bb53b8..0828f20 100644 --- a/arch/x86/mm/extable.c +++ b/arch/x86/mm/extable.c -@@ -1,6 +1,7 @@ - #include <linux/module.h> - #include <asm/uaccess.h> - #include <asm/traps.h> -+#include <asm/boot.h> - - typedef bool (*ex_handler_t)(const struct exception_table_entry *, - struct pt_regs *, int); -@@ -8,12 +9,25 @@ typedef bool (*ex_handler_t)(const struct exception_table_entry *, - static inline unsigned long - ex_fixup_addr(const struct exception_table_entry *x) - { -- return (unsigned long)&x->fixup + x->fixup; -+ unsigned long reloc = 0; -+ -+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) -+ reloc = ____LOAD_PHYSICAL_ADDR - LOAD_PHYSICAL_ADDR; -+#endif -+ -+ return (unsigned long)&x->fixup + x->fixup + reloc; - } -+ - static inline ex_handler_t - ex_fixup_handler(const struct exception_table_entry *x) - { -- return (ex_handler_t)((unsigned long)&x->handler + x->handler); -+ unsigned long reloc = 0; -+ -+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) -+ reloc = ____LOAD_PHYSICAL_ADDR - LOAD_PHYSICAL_ADDR; -+#endif -+ -+ return (ex_handler_t)((unsigned long)&x->handler + x->handler + reloc); - } - - bool ex_handler_default(const struct exception_table_entry *fixup, -@@ -99,7 +113,7 @@ int fixup_exception(struct pt_regs *regs, int trapnr) +@@ -99,7 +99,7 @@ int fixup_exception(struct pt_regs *regs, int trapnr) ex_handler_t handler; #ifdef CONFIG_PNPBIOS @@ -36982,7 +37097,7 @@ index 9c086c5..421e25b 100644 unsigned long uninitialized_var(pfn_align); int i, nid; diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c -index 7a1f7bb..62a6748 100644 +index 7a1f7bb..5b4b5cc 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c @@ -258,7 +258,7 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address, @@ -37093,6 +37208,16 @@ index 7a1f7bb..62a6748 100644 cpa->flags |= CPA_FLUSHTLB; } cpa->numpages = 1; +@@ -1336,7 +1362,8 @@ static int cpa_process_alias(struct cpa_data *cpa) + + static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) + { +- int ret, numpages = cpa->numpages; ++ int ret; ++ unsigned long numpages = cpa->numpages; + + while (numpages) { + /* diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index fb0604f..b9e0399 100644 --- a/arch/x86/mm/pat.c @@ -39205,7 +39330,7 @@ index c7b15f3..cc09a65 100644 This is the Linux Xen port. Enabling this will allow the kernel to boot in a paravirtualized environment under the diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c -index 760789a..dbf5054 100644 +index 760789a..0aef1ec 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -131,8 +131,6 @@ EXPORT_SYMBOL_GPL(xen_start_info); @@ -39311,11 +39436,21 @@ index 760789a..dbf5054 100644 pv_cpu_ops.write_gdt_entry = xen_write_gdt_entry; pv_cpu_ops.load_gdt = xen_load_gdt; -@@ -1583,7 +1582,17 @@ asmlinkage __visible void __init xen_start_kernel(void) +@@ -1582,9 +1581,6 @@ asmlinkage __visible void __init xen_start_kernel(void) + */ __userpte_alloc_gfp &= ~__GFP_HIGHMEM; - /* Work out if we support NX */ +- /* Work out if we support NX */ - x86_configure_nx(); +- + /* Get mfn list */ + xen_build_dynamic_phys_to_machine(); + +@@ -1594,6 +1590,19 @@ asmlinkage __visible void __init xen_start_kernel(void) + */ + xen_setup_gdt(0); + ++ /* Work out if we support NX */ +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) + if ((cpuid_eax(0x80000000) & 0xffff0000) == 0x80000000 && + (cpuid_edx(0x80000001) & (1U << (X86_FEATURE_NX & 31)))) { @@ -39327,9 +39462,10 @@ index 760789a..dbf5054 100644 + wrmsr(MSR_EFER, l, h); + } +#endif ++ + xen_init_irq_ops(); + xen_init_cpuid_mask(); - /* Get mfn list */ - xen_build_dynamic_phys_to_machine(); @@ -1611,13 +1620,6 @@ asmlinkage __visible void __init xen_start_kernel(void) machine_ops = xen_machine_ops; @@ -39426,6 +39562,18 @@ index 6743371..26347de 100644 .alloc_pud = xen_alloc_pmd_init, .release_pud = xen_release_pmd_init, +diff --git a/arch/x86/xen/pmu.c b/arch/x86/xen/pmu.c +index 9466354..b33bb13 100644 +--- a/arch/x86/xen/pmu.c ++++ b/arch/x86/xen/pmu.c +@@ -444,6 +444,7 @@ static unsigned long xen_get_guest_ip(void) + return 0; + } + ++ // TODO: adjust with the segment base + return xenpmu_data->pmu.r.regs.ip; + } + diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 719cf29..8a13fd8 100644 --- a/arch/x86/xen/smp.c @@ -42615,7 +42763,7 @@ index 4d87499..1e2bcce 100644 device->rs_last_events = (int)part_stat_read(&disk->part0, sectors[0]) + diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c -index 84708a5..95c0e55 100644 +index b206115..dcb469b 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -961,6 +961,10 @@ static void empty(void) @@ -46312,7 +46460,7 @@ index 207a2cb..666b75a 100644 { struct bochs_device *bochs = diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c -index 0e3cc66..005ade8 100644 +index a5cae1b..2b89b96 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -4285,7 +4285,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, @@ -48325,7 +48473,7 @@ index 414953c..1b26674 100644 -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_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c -index 590b037..2755d23 100644 +index 0ab76dd..62359ea 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -970,7 +970,7 @@ void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size) @@ -55020,7 +55168,7 @@ index adbff14..018c2d2 100644 struct cache_stat_collector collector; diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c -index f5dbb4e..26a4c2e 100644 +index 5d3b231..6a0cbd8 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -241,8 +241,9 @@ static void __write_super(struct cache_sb *sb, struct bio *bio) @@ -75244,7 +75392,7 @@ index ec21d8c..1c2e09c 100644 return _SUCCESS; } diff --git a/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h b/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h -index 8990748..7727f80 100644 +index 8990748..7727f804 100644 --- a/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h +++ b/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h @@ -200,17 +200,9 @@ void PHY_GetTxPowerLevel8188E(struct adapter *adapter, u32 *powerlevel); @@ -96960,7 +97108,7 @@ index 2035893..f42edf1 100644 for (i = 0; i < numnote; i++) sz += notesize(notes + i); diff --git a/fs/block_dev.c b/fs/block_dev.c -index 71ccab1..8e55e4e 100644 +index b1495fa..256330e 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -852,7 +852,7 @@ static bool bd_may_claim(struct block_device *bdev, struct block_device *whole, @@ -100117,59 +100265,6 @@ index d7ccb7f..1b9329a 100644 int ret; eh = ext_inode_hdr(inode); -diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c -index b747ec0..ea39d19 100644 ---- a/fs/ext4/inode.c -+++ b/fs/ext4/inode.c -@@ -51,26 +51,32 @@ static __u32 ext4_inode_csum(struct inode *inode, struct ext4_inode *raw, - struct ext4_inode_info *ei) - { - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); -- __u16 csum_lo; -- __u16 csum_hi = 0; - __u32 csum; -+ __u16 dummy_csum = 0; -+ int offset = offsetof(struct ext4_inode, i_checksum_lo); -+ unsigned int csum_size = sizeof(dummy_csum); - -- csum_lo = le16_to_cpu(raw->i_checksum_lo); -- raw->i_checksum_lo = 0; -- if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE && -- EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) { -- csum_hi = le16_to_cpu(raw->i_checksum_hi); -- raw->i_checksum_hi = 0; -+ csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)raw, offset); -+ csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, csum_size); -+ offset += csum_size; -+ csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, -+ EXT4_GOOD_OLD_INODE_SIZE - offset); -+ -+ if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE) { -+ offset = offsetof(struct ext4_inode, i_checksum_hi); -+ csum = ext4_chksum(sbi, csum, (__u8 *)raw + -+ EXT4_GOOD_OLD_INODE_SIZE, -+ offset - EXT4_GOOD_OLD_INODE_SIZE); -+ if (EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) { -+ csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, -+ csum_size); -+ offset += csum_size; -+ csum = ext4_chksum(sbi, csum, (__u8 *)raw + offset, -+ EXT4_INODE_SIZE(inode->i_sb) - -+ offset); -+ } - } - -- csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)raw, -- EXT4_INODE_SIZE(inode->i_sb)); -- -- raw->i_checksum_lo = cpu_to_le16(csum_lo); -- if (EXT4_INODE_SIZE(inode->i_sb) > EXT4_GOOD_OLD_INODE_SIZE && -- EXT4_FITS_IN_INODE(raw, ei, i_checksum_hi)) -- raw->i_checksum_hi = cpu_to_le16(csum_hi); -- - return csum; - } - diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 7f42eda..0150cd7 100644 --- a/fs/ext4/mballoc.c @@ -100287,30 +100382,6 @@ index 7f42eda..0150cd7 100644 trace_ext4_mballoc_discard(sb, NULL, group, bit, pa->pa_len); return 0; -diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c -index ec4c399..5bb46b6 100644 ---- a/fs/ext4/namei.c -+++ b/fs/ext4/namei.c -@@ -420,15 +420,14 @@ static __le32 ext4_dx_csum(struct inode *inode, struct ext4_dir_entry *dirent, - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); - struct ext4_inode_info *ei = EXT4_I(inode); - __u32 csum; -- __le32 save_csum; - int size; -+ __u32 dummy_csum = 0; -+ int offset = offsetof(struct dx_tail, dt_checksum); - - size = count_offset + (count * sizeof(struct dx_entry)); -- save_csum = t->dt_checksum; -- t->dt_checksum = 0; - csum = ext4_chksum(sbi, ei->i_csum_seed, (__u8 *)dirent, size); -- csum = ext4_chksum(sbi, csum, (__u8 *)t, sizeof(struct dx_tail)); -- t->dt_checksum = save_csum; -+ csum = ext4_chksum(sbi, csum, (__u8 *)t, offset); -+ csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, sizeof(dummy_csum)); - - return cpu_to_le32(csum); - } diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index cf68100..f96c5c0 100644 --- a/fs/ext4/resize.c @@ -100354,7 +100425,7 @@ index cf68100..f96c5c0 100644 err = ext4_handle_dirty_metadata(handle, NULL, bh); if (unlikely(err)) diff --git a/fs/ext4/super.c b/fs/ext4/super.c -index 639bd756..7cbfe75 100644 +index d4505f8..7f73c190 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1307,7 +1307,7 @@ static ext4_fsblk_t get_sb_block(void **data) @@ -100366,48 +100437,6 @@ index 639bd756..7cbfe75 100644 "Contact linux-ext4@vger.kernel.org if you think we should keep it.\n"; #ifdef CONFIG_QUOTA -@@ -2068,23 +2068,25 @@ failed: - static __le16 ext4_group_desc_csum(struct super_block *sb, __u32 block_group, - struct ext4_group_desc *gdp) - { -- int offset; -+ int offset = offsetof(struct ext4_group_desc, bg_checksum); - __u16 crc = 0; - __le32 le_group = cpu_to_le32(block_group); - struct ext4_sb_info *sbi = EXT4_SB(sb); - - if (ext4_has_metadata_csum(sbi->s_sb)) { - /* Use new metadata_csum algorithm */ -- __le16 save_csum; - __u32 csum32; -+ __u16 dummy_csum = 0; - -- save_csum = gdp->bg_checksum; -- gdp->bg_checksum = 0; - csum32 = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&le_group, - sizeof(le_group)); -- csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp, -- sbi->s_desc_size); -- gdp->bg_checksum = save_csum; -+ csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp, offset); -+ csum32 = ext4_chksum(sbi, csum32, (__u8 *)&dummy_csum, -+ sizeof(dummy_csum)); -+ offset += sizeof(dummy_csum); -+ if (offset < sbi->s_desc_size) -+ csum32 = ext4_chksum(sbi, csum32, (__u8 *)gdp + offset, -+ sbi->s_desc_size - offset); - - crc = csum32 & 0xFFFF; - goto out; -@@ -2094,8 +2096,6 @@ static __le16 ext4_group_desc_csum(struct super_block *sb, __u32 block_group, - if (!ext4_has_feature_gdt_csum(sb)) - return 0; - -- offset = offsetof(struct ext4_group_desc, bg_checksum); -- - crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid)); - crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group)); - crc = crc16(crc, (__u8 *)gdp, offset); diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c index 1420a3c..e87523c 100644 --- a/fs/ext4/sysfs.c @@ -100422,35 +100451,10 @@ index 1420a3c..e87523c 100644 static ssize_t session_write_kbytes_show(struct ext4_attr *a, struct ext4_sb_info *sbi, char *buf) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c -index e79bd32..1a4826d 100644 +index 2eb935c..2fda99e 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c -@@ -121,17 +121,18 @@ static __le32 ext4_xattr_block_csum(struct inode *inode, - { - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); - __u32 csum; -- __le32 save_csum; - __le64 dsk_block_nr = cpu_to_le64(block_nr); -+ __u32 dummy_csum = 0; -+ int offset = offsetof(struct ext4_xattr_header, h_checksum); - -- save_csum = hdr->h_checksum; -- hdr->h_checksum = 0; - csum = ext4_chksum(sbi, sbi->s_csum_seed, (__u8 *)&dsk_block_nr, - sizeof(dsk_block_nr)); -- csum = ext4_chksum(sbi, csum, (__u8 *)hdr, -- EXT4_BLOCK_SIZE(inode->i_sb)); -+ csum = ext4_chksum(sbi, csum, (__u8 *)hdr, offset); -+ csum = ext4_chksum(sbi, csum, (__u8 *)&dummy_csum, sizeof(dummy_csum)); -+ offset += sizeof(dummy_csum); -+ csum = ext4_chksum(sbi, csum, (__u8 *)hdr + offset, -+ EXT4_BLOCK_SIZE(inode->i_sb) - offset); - -- hdr->h_checksum = save_csum; - return cpu_to_le32(csum); - } - -@@ -417,7 +418,7 @@ static int +@@ -418,7 +418,7 @@ static int ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry, char *buffer, size_t buffer_size) { @@ -100459,7 +100463,7 @@ index e79bd32..1a4826d 100644 for (; !IS_LAST_ENTRY(entry); entry = EXT4_XATTR_NEXT(entry)) { const struct xattr_handler *handler = -@@ -438,9 +439,10 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry, +@@ -439,9 +439,10 @@ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry, *buffer++ = 0; } rest -= size; @@ -104199,7 +104203,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 70580ab..cdede72 100644 +index 9281b2b..657fdb3 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -337,17 +337,32 @@ int generic_permission(struct inode *inode, int mask) @@ -104358,7 +104362,7 @@ index 70580ab..cdede72 100644 if (nd->root.mnt && !(nd->flags & LOOKUP_ROOT)) { path_put(&nd->root); nd->root.mnt = NULL; -@@ -1015,6 +1082,9 @@ const char *get_link(struct nameidata *nd) +@@ -1017,6 +1084,9 @@ const char *get_link(struct nameidata *nd) if (unlikely(error)) return ERR_PTR(error); @@ -104368,7 +104372,7 @@ index 70580ab..cdede72 100644 nd->last_type = LAST_BIND; res = inode->i_link; if (!res) { -@@ -1701,6 +1771,23 @@ static int pick_link(struct nameidata *nd, struct path *link, +@@ -1703,6 +1773,23 @@ static int pick_link(struct nameidata *nd, struct path *link, } } @@ -104392,7 +104396,7 @@ index 70580ab..cdede72 100644 last = nd->stack + nd->depth++; last->link = *link; clear_delayed_call(&last->done); -@@ -1938,7 +2025,7 @@ EXPORT_SYMBOL(hashlen_string); +@@ -1940,7 +2027,7 @@ EXPORT_SYMBOL(hashlen_string); static inline u64 hash_name(const char *name) { unsigned long a = 0, b, x = 0, y = 0, adata, bdata, mask, len; @@ -104401,7 +104405,7 @@ index 70580ab..cdede72 100644 len = -sizeof(unsigned long); do { -@@ -2120,6 +2207,10 @@ static const char *path_init(struct nameidata *nd, unsigned flags) +@@ -2122,6 +2209,10 @@ static const char *path_init(struct nameidata *nd, unsigned flags) nd->last_type = LAST_ROOT; /* if there are only slashes... */ nd->flags = flags | LOOKUP_JUMPED | LOOKUP_PARENT; nd->depth = 0; @@ -104412,7 +104416,7 @@ index 70580ab..cdede72 100644 if (flags & LOOKUP_ROOT) { struct dentry *root = nd->root.dentry; struct inode *inode = root->d_inode; -@@ -2251,6 +2342,14 @@ static int path_lookupat(struct nameidata *nd, unsigned flags, struct path *path +@@ -2253,6 +2344,14 @@ static int path_lookupat(struct nameidata *nd, unsigned flags, struct path *path if (!err) err = complete_walk(nd); @@ -104427,7 +104431,7 @@ index 70580ab..cdede72 100644 if (!err && nd->flags & LOOKUP_DIRECTORY) if (!d_can_lookup(nd->path.dentry)) err = -ENOTDIR; -@@ -2299,6 +2398,14 @@ static int path_parentat(struct nameidata *nd, unsigned flags, +@@ -2301,6 +2400,14 @@ static int path_parentat(struct nameidata *nd, unsigned flags, err = link_path_walk(s, nd); if (!err) err = complete_walk(nd); @@ -104442,7 +104446,7 @@ index 70580ab..cdede72 100644 if (!err) { *parent = nd->path; nd->path.mnt = NULL; -@@ -2926,6 +3033,13 @@ static int may_open(struct path *path, int acc_mode, int flag) +@@ -2928,6 +3035,13 @@ static int may_open(struct path *path, int acc_mode, int flag) if (flag & O_NOATIME && !inode_owner_or_capable(inode)) return -EPERM; @@ -104456,7 +104460,7 @@ index 70580ab..cdede72 100644 return 0; } -@@ -3165,6 +3279,20 @@ no_open: +@@ -3167,6 +3281,20 @@ no_open: /* Negative dentry, just create the file */ if (!dentry->d_inode && (open_flag & O_CREAT)) { @@ -104477,7 +104481,7 @@ index 70580ab..cdede72 100644 *opened |= FILE_CREATED; audit_inode_child(dir_inode, dentry, AUDIT_TYPE_CHILD_CREATE); if (!dir_inode->i_op->create) { -@@ -3175,6 +3303,7 @@ no_open: +@@ -3177,6 +3305,7 @@ no_open: open_flag & O_EXCL); if (error) goto out_dput; @@ -104485,7 +104489,7 @@ index 70580ab..cdede72 100644 fsnotify_create(dir_inode, dentry); } if (unlikely(create_error) && !dentry->d_inode) { -@@ -3289,6 +3418,11 @@ static int do_last(struct nameidata *nd, +@@ -3291,6 +3420,11 @@ static int do_last(struct nameidata *nd, goto finish_open_created; } @@ -104497,7 +104501,7 @@ index 70580ab..cdede72 100644 /* * If atomic_open() acquired write access it is dropped now due to * possible mount and symlink following (this might be optimized away if -@@ -3308,6 +3442,13 @@ static int do_last(struct nameidata *nd, +@@ -3310,6 +3444,13 @@ static int do_last(struct nameidata *nd, return -ENOENT; } @@ -104511,7 +104515,7 @@ index 70580ab..cdede72 100644 /* * create/update audit record if it already exists. */ -@@ -3336,6 +3477,21 @@ finish_open: +@@ -3338,6 +3479,21 @@ finish_open: error = complete_walk(nd); if (error) return error; @@ -104533,7 +104537,7 @@ index 70580ab..cdede72 100644 audit_inode(nd->name, nd->path.dentry, 0); error = -EISDIR; if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry)) -@@ -3592,9 +3748,11 @@ static struct dentry *filename_create(int dfd, struct filename *name, +@@ -3594,9 +3750,11 @@ static struct dentry *filename_create(int dfd, struct filename *name, goto unlock; error = -EEXIST; @@ -104547,7 +104551,7 @@ index 70580ab..cdede72 100644 /* * Special case - lookup gave negative, but... we had foo/bar/ * From the vfs_mknod() POV we just have a negative dentry - -@@ -3648,6 +3806,20 @@ inline struct dentry *user_path_create(int dfd, const char __user *pathname, +@@ -3650,6 +3808,20 @@ inline struct dentry *user_path_create(int dfd, const char __user *pathname, } EXPORT_SYMBOL(user_path_create); @@ -104568,7 +104572,7 @@ index 70580ab..cdede72 100644 int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) { int error = may_create(dir, dentry); -@@ -3711,6 +3883,17 @@ retry: +@@ -3713,6 +3885,17 @@ retry: if (!IS_POSIXACL(path.dentry->d_inode)) mode &= ~current_umask(); @@ -104586,7 +104590,7 @@ index 70580ab..cdede72 100644 error = security_path_mknod(&path, dentry, mode, dev); if (error) goto out; -@@ -3728,6 +3911,8 @@ retry: +@@ -3730,6 +3913,8 @@ retry: error = vfs_mknod(path.dentry->d_inode,dentry,mode,0); break; } @@ -104595,7 +104599,7 @@ index 70580ab..cdede72 100644 out: done_path_create(&path, dentry); if (retry_estale(error, lookup_flags)) { -@@ -3782,9 +3967,16 @@ retry: +@@ -3784,9 +3969,16 @@ retry: if (!IS_POSIXACL(path.dentry->d_inode)) mode &= ~current_umask(); @@ -104612,7 +104616,7 @@ index 70580ab..cdede72 100644 done_path_create(&path, dentry); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; -@@ -3845,6 +4037,8 @@ static long do_rmdir(int dfd, const char __user *pathname) +@@ -3847,6 +4039,8 @@ static long do_rmdir(int dfd, const char __user *pathname) struct path path; struct qstr last; int type; @@ -104621,7 +104625,7 @@ index 70580ab..cdede72 100644 unsigned int lookup_flags = 0; retry: name = user_path_parent(dfd, pathname, -@@ -3877,10 +4071,20 @@ retry: +@@ -3879,10 +4073,20 @@ retry: error = -ENOENT; goto exit3; } @@ -104642,7 +104646,7 @@ index 70580ab..cdede72 100644 exit3: dput(dentry); exit2: -@@ -3975,6 +4179,8 @@ static long do_unlinkat(int dfd, const char __user *pathname) +@@ -3977,6 +4181,8 @@ static long do_unlinkat(int dfd, const char __user *pathname) int type; struct inode *inode = NULL; struct inode *delegated_inode = NULL; @@ -104651,7 +104655,7 @@ index 70580ab..cdede72 100644 unsigned int lookup_flags = 0; retry: name = user_path_parent(dfd, pathname, -@@ -4001,10 +4207,21 @@ retry_deleg: +@@ -4003,10 +4209,21 @@ retry_deleg: if (d_is_negative(dentry)) goto slashes; ihold(inode); @@ -104673,7 +104677,7 @@ index 70580ab..cdede72 100644 exit2: dput(dentry); } -@@ -4093,9 +4310,17 @@ retry: +@@ -4095,9 +4312,17 @@ retry: if (IS_ERR(dentry)) goto out_putname; @@ -104691,7 +104695,7 @@ index 70580ab..cdede72 100644 done_path_create(&path, dentry); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; -@@ -4199,6 +4424,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, +@@ -4201,6 +4426,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; @@ -104699,7 +104703,7 @@ index 70580ab..cdede72 100644 int how = 0; int error; -@@ -4222,7 +4448,7 @@ retry: +@@ -4224,7 +4450,7 @@ retry: if (error) return error; @@ -104708,7 +104712,7 @@ index 70580ab..cdede72 100644 (how & LOOKUP_REVAL)); error = PTR_ERR(new_dentry); if (IS_ERR(new_dentry)) -@@ -4234,11 +4460,26 @@ retry: +@@ -4236,11 +4462,26 @@ retry: error = may_linkat(&old_path); if (unlikely(error)) goto out_dput; @@ -104735,7 +104739,7 @@ index 70580ab..cdede72 100644 done_path_create(&new_path, new_dentry); if (delegated_inode) { error = break_deleg_wait(&delegated_inode); -@@ -4557,6 +4798,20 @@ retry_deleg: +@@ -4559,6 +4800,20 @@ retry_deleg: if (new_dentry == trap) goto exit5; @@ -104756,7 +104760,7 @@ index 70580ab..cdede72 100644 error = security_path_rename(&old_path, old_dentry, &new_path, new_dentry, flags); if (error) -@@ -4564,6 +4819,9 @@ retry_deleg: +@@ -4566,6 +4821,9 @@ retry_deleg: error = vfs_rename(old_path.dentry->d_inode, old_dentry, new_path.dentry->d_inode, new_dentry, &delegated_inode, flags); @@ -104766,7 +104770,7 @@ index 70580ab..cdede72 100644 exit5: dput(new_dentry); exit4: -@@ -4620,14 +4878,24 @@ EXPORT_SYMBOL(vfs_whiteout); +@@ -4622,14 +4880,24 @@ EXPORT_SYMBOL(vfs_whiteout); int readlink_copy(char __user *buffer, int buflen, const char *link) { @@ -113513,10 +113517,10 @@ index 93ae3cd..6cee098 100644 } putname(tmp); diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c -index 80aa6f1..bf87501 100644 +index 4133aa7..5468804 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c -@@ -185,7 +185,7 @@ static char *ovl_read_symlink(struct dentry *realdentry) +@@ -187,7 +187,7 @@ static char *ovl_read_symlink(struct dentry *realdentry) set_fs(get_ds()); /* The cast to a user pointer is valid due to the set_fs() */ res = inode->i_op->readlink(realdentry, @@ -113526,10 +113530,10 @@ index 80aa6f1..bf87501 100644 if (res < 0) { free_page((unsigned long) buf); diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c -index d1cdc60..38f2608 100644 +index ac98a71..48f2b72 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c -@@ -360,6 +360,9 @@ struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags) +@@ -363,6 +363,9 @@ struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags) if (d_is_dir(dentry)) return d_backing_inode(dentry); @@ -113540,7 +113544,7 @@ index d1cdc60..38f2608 100644 if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) { err = ovl_want_write(dentry); diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c -index 6db75cb..b2fe139 100644 +index 86f2025..8a2a0b8 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -196,7 +196,7 @@ void ovl_path_lower(struct dentry *dentry, struct path *path) @@ -113552,7 +113556,7 @@ index 6db75cb..b2fe139 100644 } int ovl_want_write(struct dentry *dentry) -@@ -953,8 +953,8 @@ static unsigned int ovl_split_lowerdirs(char *str) +@@ -972,8 +972,8 @@ static unsigned int ovl_split_lowerdirs(char *str) static int ovl_fill_super(struct super_block *sb, void *data, int silent) { @@ -115396,7 +115400,7 @@ index 510413eb..34d9a8c 100644 seq_printf(p, "softirq %llu", (unsigned long long)sum_softirq); diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c -index 4648c7f..9f5a541 100644 +index 4648c7f..1cd9ac3 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -15,12 +15,19 @@ @@ -115469,12 +115473,25 @@ index 4648c7f..9f5a541 100644 if (IS_ERR(priv->mm)) { int err = PTR_ERR(priv->mm); -@@ -281,11 +309,11 @@ static int is_stack(struct proc_maps_private *priv, - stack = vma_is_stack_for_task(vma, task); - rcu_read_unlock(); - } -- return stack; -+ return stack || (vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)); +@@ -263,14 +291,15 @@ static int do_maps_open(struct inode *inode, struct file *file, + * Indicate if the VMA is a stack for the given task; for + * /proc/PID/maps that is the stack of the main task. + */ +-static int is_stack(struct proc_maps_private *priv, ++static bool is_stack(struct proc_maps_private *priv, + struct vm_area_struct *vma, int is_pid) + { +- int stack = 0; ++ bool stack = false; + + if (is_pid) { + stack = vma->vm_start <= vma->vm_mm->start_stack && + vma->vm_end >= vma->vm_mm->start_stack; ++ stack |= vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP); + } else { + struct inode *inode = priv->inode; + struct task_struct *task; +@@ -285,7 +314,7 @@ static int is_stack(struct proc_maps_private *priv, } static void @@ -115483,7 +115500,7 @@ index 4648c7f..9f5a541 100644 { struct mm_struct *mm = vma->vm_mm; struct file *file = vma->vm_file; -@@ -304,13 +332,8 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) +@@ -304,13 +333,8 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT; } @@ -115499,7 +115516,7 @@ index 4648c7f..9f5a541 100644 seq_setwidth(m, 25 + sizeof(void *) * 6 - 1); seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ", -@@ -320,7 +343,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) +@@ -320,7 +344,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) flags & VM_WRITE ? 'w' : '-', flags & VM_EXEC ? 'x' : '-', flags & VM_MAYSHARE ? 's' : 'p', @@ -115508,7 +115525,7 @@ index 4648c7f..9f5a541 100644 MAJOR(dev), MINOR(dev), ino); /* -@@ -329,7 +352,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) +@@ -329,7 +353,7 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid) */ if (file) { seq_pad(m, ' '); @@ -115517,7 +115534,7 @@ index 4648c7f..9f5a541 100644 goto done; } -@@ -366,7 +389,20 @@ done: +@@ -366,7 +390,20 @@ done: static int show_map(struct seq_file *m, void *v, int is_pid) { @@ -115539,7 +115556,7 @@ index 4648c7f..9f5a541 100644 m_cache_vma(m, v); return 0; } -@@ -646,6 +682,9 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma) +@@ -646,6 +683,9 @@ static void show_smap_vma_flags(struct seq_file *m, struct vm_area_struct *vma) [ilog2(VM_RAND_READ)] = "rr", [ilog2(VM_DONTCOPY)] = "dc", [ilog2(VM_DONTEXPAND)] = "de", @@ -115549,7 +115566,7 @@ index 4648c7f..9f5a541 100644 [ilog2(VM_ACCOUNT)] = "ac", [ilog2(VM_NORESERVE)] = "nr", [ilog2(VM_HUGETLB)] = "ht", -@@ -727,7 +766,14 @@ static int show_smap(struct seq_file *m, void *v, int is_pid) +@@ -727,7 +767,14 @@ static int show_smap(struct seq_file *m, void *v, int is_pid) .mm = vma->vm_mm, .private = &mss, }; @@ -115564,7 +115581,7 @@ index 4648c7f..9f5a541 100644 memset(&mss, 0, sizeof mss); #ifdef CONFIG_SHMEM -@@ -754,10 +800,15 @@ static int show_smap(struct seq_file *m, void *v, int is_pid) +@@ -754,10 +801,15 @@ static int show_smap(struct seq_file *m, void *v, int is_pid) } #endif @@ -115583,7 +115600,7 @@ index 4648c7f..9f5a541 100644 seq_printf(m, "Size: %8lu kB\n" -@@ -777,7 +828,7 @@ static int show_smap(struct seq_file *m, void *v, int is_pid) +@@ -777,7 +829,7 @@ static int show_smap(struct seq_file *m, void *v, int is_pid) "KernelPageSize: %8lu kB\n" "MMUPageSize: %8lu kB\n" "Locked: %8lu kB\n", @@ -115592,7 +115609,7 @@ index 4648c7f..9f5a541 100644 mss.resident >> 10, (unsigned long)(mss.pss >> (10 + PSS_SHIFT)), mss.shared_clean >> 10, -@@ -1433,7 +1484,7 @@ static int pagemap_open(struct inode *inode, struct file *file) +@@ -1433,7 +1485,7 @@ static int pagemap_open(struct inode *inode, struct file *file) { struct mm_struct *mm; @@ -115601,7 +115618,7 @@ index 4648c7f..9f5a541 100644 if (IS_ERR(mm)) return PTR_ERR(mm); file->private_data = mm; -@@ -1636,6 +1687,13 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) +@@ -1636,6 +1688,13 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) char buffer[64]; int nid; @@ -115615,7 +115632,7 @@ index 4648c7f..9f5a541 100644 if (!mm) return 0; -@@ -1650,11 +1708,15 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) +@@ -1650,11 +1709,15 @@ static int show_numa_map(struct seq_file *m, void *v, int is_pid) mpol_to_str(buffer, sizeof(buffer), proc_priv->task_mempolicy); } @@ -126381,7 +126398,7 @@ index 0000000..6822208 +} diff --git a/grsecurity/grsec_ipc.c b/grsecurity/grsec_ipc.c new file mode 100644 -index 0000000..1773300 +index 0000000..6a8ed69 --- /dev/null +++ b/grsecurity/grsec_ipc.c @@ -0,0 +1,48 @@ @@ -126426,7 +126443,7 @@ index 0000000..1773300 + orig_granted_mode = 0; + } + if (!(requested_mode & ~granted_mode & 0007) && (requested_mode & ~orig_granted_mode & 0007) && -+ !ns_capable_nolog(ns->user_ns, CAP_IPC_OWNER)) { ++ !ns_capable_noaudit(ns->user_ns, CAP_IPC_OWNER)) { + gr_log_str_int(GR_DONT_AUDIT, GR_IPC_DENIED_MSG, write ? "write" : "read", GR_GLOBAL_UID(ipcp->cuid)); + return 0; + } @@ -128339,7 +128356,7 @@ index 5bdab6b..9ae82fe 100644 #define pud_none(pud) 0 #define pud_bad(pud) 0 diff --git a/include/asm-generic/atomic-long.h b/include/asm-generic/atomic-long.h -index 5e1f345..74a91f8 100644 +index 5e1f345..e3fb6e2 100644 --- a/include/asm-generic/atomic-long.h +++ b/include/asm-generic/atomic-long.h @@ -22,6 +22,12 @@ @@ -128548,7 +128565,7 @@ index 5e1f345..74a91f8 100644 #undef ATOMIC_LONG_INC_DEC_OP -@@ -187,4 +229,59 @@ static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u) +@@ -187,4 +229,60 @@ static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u) #define atomic_long_inc_not_zero(l) \ ATOMIC_LONG_PFX(_inc_not_zero)((ATOMIC_LONG_PFX(_t) *)(l)) @@ -128596,6 +128613,7 @@ index 5e1f345..74a91f8 100644 +#ifndef atomic_xchg_unchecked +#define atomic_xchg_unchecked(v, i) atomic_xchg((v), (i)) +#endif ++ +#define atomic_long_read_unchecked(v) atomic_long_read(v) +#define atomic_long_set_unchecked(v, i) atomic_long_set((v), (i)) +#define atomic_long_add_unchecked(i, v) atomic_long_add((i), (v)) @@ -129640,10 +129658,10 @@ index 1be04f8..9c2d3e2 100644 #define __ro_after_init __attribute__((__section__(".data..ro_after_init"))) #endif diff --git a/include/linux/capability.h b/include/linux/capability.h -index 00690ff..b9c971b 100644 +index 5f3c63d..b874083 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h -@@ -229,15 +229,28 @@ static inline bool capable(int cap) +@@ -230,6 +230,10 @@ static inline bool capable(int cap) { return true; } @@ -129654,17 +129672,13 @@ index 00690ff..b9c971b 100644 static inline bool ns_capable(struct user_namespace *ns, int cap) { return true; +@@ -240,9 +244,13 @@ static inline bool ns_capable_noaudit(struct user_namespace *ns, int cap) } -+static inline bool ns_capable_nolog(struct user_namespace *ns, int cap) -+{ -+ return true; -+} #endif /* CONFIG_MULTIUSER */ extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap); +extern bool capable_wrt_inode_uidgid_nolog(const struct inode *inode, int cap); extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap); +extern bool capable_nolog(int cap); -+extern bool ns_capable_nolog(struct user_namespace *ns, int cap); /* audit system wants to get cap info from files as well */ extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps); @@ -132307,19 +132321,23 @@ index ba7a9b0..33a0237 100644 extern int register_pppox_proto(int proto_num, const struct pppox_proto *pp); extern void unregister_pppox_proto(int proto_num); diff --git a/include/linux/init.h b/include/linux/init.h -index aedb254..71b67e5 100644 +index aedb254..a398315 100644 --- a/include/linux/init.h +++ b/include/linux/init.h -@@ -39,7 +39,7 @@ +@@ -37,9 +37,11 @@ + * section. + */ ++#define add_init_latent_entropy __latent_entropy ++ /* These are for everybody (although not all archs will actually discard it in modules) */ -#define __init __section(.init.text) __cold notrace -+#define __init __section(.init.text) __cold notrace __latent_entropy ++#define __init __section(.init.text) __cold notrace add_init_latent_entropy #define __initdata __section(.init.data) #define __initconst __constsection(.init.rodata) #define __exitdata __section(.exit.data) -@@ -92,7 +92,7 @@ +@@ -92,7 +94,7 @@ #define __exit __section(.exit.text) __exitused __cold notrace /* Used for MEMORY_HOTPLUG */ @@ -132328,7 +132346,7 @@ index aedb254..71b67e5 100644 #define __meminitdata __section(.meminit.data) #define __meminitconst __constsection(.meminit.rodata) #define __memexit __section(.memexit.text) __exitused __cold notrace -@@ -117,6 +117,12 @@ +@@ -117,6 +119,12 @@ #define __REFDATA .section ".ref.data", "aw" #define __REFCONST .section ".ref.rodata", "a" @@ -132902,6 +132920,33 @@ index 5356f4d..c99970b 100644 /** * list_move - delete from one list and add as another's head * @list: the entry to move +diff --git a/include/linux/llist.h b/include/linux/llist.h +index fd4ca0b..d77d4a8 100644 +--- a/include/linux/llist.h ++++ b/include/linux/llist.h +@@ -168,6 +168,10 @@ static inline struct llist_node *llist_next(struct llist_node *node) + extern bool llist_add_batch(struct llist_node *new_first, + struct llist_node *new_last, + struct llist_head *head); ++ ++extern bool pax_llist_add_batch(struct llist_node *new_first, ++ struct llist_node *new_last, ++ struct llist_head *head); + /** + * llist_add - add a new entry + * @new: new entry to be added +@@ -180,6 +184,11 @@ static inline bool llist_add(struct llist_node *new, struct llist_head *head) + return llist_add_batch(new, new, head); + } + ++static inline bool pax_llist_add(struct llist_node *new, struct llist_head *head) ++{ ++ return pax_llist_add_batch(new, new, head); ++} ++ + /** + * llist_del_all - delete all entries from lock-less list + * @head: the head of lock-less list to delete all entries diff --git a/include/linux/lockd/xdr.h b/include/linux/lockd/xdr.h index d39ed1c..8b5d98f 100644 --- a/include/linux/lockd/xdr.h @@ -133162,7 +133207,7 @@ index 4429d25..ae5ab54 100644 static inline int vma_dup_policy(struct vm_area_struct *src, struct vm_area_struct *dst) diff --git a/include/linux/mm.h b/include/linux/mm.h -index ece042d..d7834bf 100644 +index ece042d..8115afb 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -107,6 +107,7 @@ extern int mmap_rnd_compat_bits __read_mostly; @@ -133228,7 +133273,7 @@ index ece042d..d7834bf 100644 long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, unsigned long nr_pages, -@@ -1331,39 +1338,11 @@ int clear_page_dirty_for_io(struct page *page); +@@ -1331,40 +1338,12 @@ int clear_page_dirty_for_io(struct page *page); int get_cmdline(struct task_struct *task, char *buffer, int buflen); @@ -133265,9 +133310,11 @@ index ece042d..d7834bf 100644 - !vma_growsup(vma->vm_next, addr); -} - - int vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t); +-int vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t); ++bool vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t); extern unsigned long move_page_tables(struct vm_area_struct *vma, + unsigned long old_addr, struct vm_area_struct *new_vma, @@ -1508,8 +1487,15 @@ static inline int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, { return 0; @@ -136120,20 +136167,6 @@ index 5c3a5f3..84a8bef 100644 } #else -diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h -index 017fced..d4a9fc9 100644 ---- a/include/linux/swiotlb.h -+++ b/include/linux/swiotlb.h -@@ -63,7 +63,8 @@ extern void - - extern void - swiotlb_free_coherent(struct device *hwdev, size_t size, -- void *vaddr, dma_addr_t dma_handle); -+ void *vaddr, dma_addr_t dma_handle, -+ struct dma_attrs *attrs); - - extern dma_addr_t swiotlb_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index d022390..80f9811 100644 --- a/include/linux/syscalls.h @@ -139633,7 +139666,7 @@ index 46ecce4..46c1a1a 100644 if (!access_ok(VERIFY_READ, uattr, 1)) return -EFAULT; diff --git a/kernel/capability.c b/kernel/capability.c -index 45432b5..7d860f7 100644 +index 00411c8..aaad585 100644 --- a/kernel/capability.c +++ b/kernel/capability.c @@ -193,6 +193,9 @@ SYSCALL_DEFINE2(capget, cap_user_header_t, header, cap_user_data_t, dataptr) @@ -139673,51 +139706,34 @@ index 45432b5..7d860f7 100644 } /** -@@ -379,7 +383,7 @@ bool ns_capable(struct user_namespace *ns, int cap) +@@ -370,9 +374,9 @@ static bool ns_capable_common(struct user_namespace *ns, int cap, bool audit) BUG(); } -- if (security_capable(current_cred(), ns, cap) == 0) { -+ if (security_capable(current_cred(), ns, cap) == 0 && gr_is_capable(cap)) { +- capable = audit ? security_capable(current_cred(), ns, cap) : +- security_capable_noaudit(current_cred(), ns, cap); +- if (capable == 0) { ++ capable = audit ? (security_capable(current_cred(), ns, cap) == 0 && gr_is_capable(cap)) : ++ (security_capable_noaudit(current_cred(), ns, cap) == 0 && gr_is_capable_nolog(cap)) ; ++ if (capable) { current->flags |= PF_SUPERPRIV; return true; } -@@ -387,6 +391,20 @@ bool ns_capable(struct user_namespace *ns, int cap) - } - EXPORT_SYMBOL(ns_capable); - -+bool ns_capable_nolog(struct user_namespace *ns, int cap) -+{ -+ if (unlikely(!cap_valid(cap))) { -+ pr_crit("capable_nolog() called with invalid cap=%u\n", cap); -+ BUG(); -+ } -+ -+ if (security_capable_noaudit(current_cred(), ns, cap) == 0 && gr_is_capable_nolog(cap)) { -+ current->flags |= PF_SUPERPRIV; -+ return true; -+ } -+ return false; -+} -+EXPORT_SYMBOL(ns_capable_nolog); - - /** - * capable - Determine if the current task has a superior capability in effect -@@ -403,6 +421,13 @@ bool capable(int cap) +@@ -429,6 +433,13 @@ bool capable(int cap) return ns_capable(&init_user_ns, cap); } EXPORT_SYMBOL(capable); + +bool capable_nolog(int cap) +{ -+ return ns_capable_nolog(&init_user_ns, cap); ++ return ns_capable_noaudit(&init_user_ns, cap); +} +EXPORT_SYMBOL(capable_nolog); + #endif /* CONFIG_MULTIUSER */ /** -@@ -447,3 +472,12 @@ bool capable_wrt_inode_uidgid(const struct inode *inode, int cap) +@@ -473,3 +484,12 @@ bool capable_wrt_inode_uidgid(const struct inode *inode, int cap) kgid_has_mapping(ns, inode->i_gid); } EXPORT_SYMBOL(capable_wrt_inode_uidgid); @@ -139726,7 +139742,7 @@ index 45432b5..7d860f7 100644 +{ + struct user_namespace *ns = current_user_ns(); + -+ return ns_capable_nolog(ns, cap) && kuid_has_mapping(ns, inode->i_uid) && ++ return ns_capable_noaudit(ns, cap) && kuid_has_mapping(ns, inode->i_uid) && + kgid_has_mapping(ns, inode->i_gid); +} +EXPORT_SYMBOL(capable_wrt_inode_uidgid_nolog); @@ -140015,7 +140031,7 @@ index c18b1f1..b9a0132 100644 return -ENOMEM; diff --git a/kernel/cred.c b/kernel/cred.c -index 0c0cd8a..faf7245 100644 +index 5f264fb..8fc856b 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -172,6 +172,15 @@ void exit_creds(struct task_struct *tsk) @@ -140644,8 +140660,45 @@ index 9e6e135..4af378d 100644 if (wo->wo_flags & __WNOTHREAD) break; +diff --git a/kernel/extable.c b/kernel/extable.c +index e820cce..72195de 100644 +--- a/kernel/extable.c ++++ b/kernel/extable.c +@@ -23,6 +23,7 @@ + + #include <asm/sections.h> + #include <asm/uaccess.h> ++#include <asm/setup.h> + + /* + * mutex protecting text section modification (dynamic code patching). +@@ -41,10 +42,22 @@ u32 __initdata __visible main_extable_sort_needed = 1; + /* Sort the kernel's built-in exception table */ + void __init sort_main_extable(void) + { +- if (main_extable_sort_needed && __stop___ex_table > __start___ex_table) { ++ struct exception_table_entry *start = __start___ex_table; ++ ++ if (main_extable_sort_needed && __stop___ex_table > start) { + pr_notice("Sorting __ex_table...\n"); +- sort_extable(__start___ex_table, __stop___ex_table); ++ sort_extable(start, __stop___ex_table); + } ++ ++#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) ++ while (start < __stop___ex_table) { ++ start->insn -= kaslr_offset(); ++ start->fixup -= kaslr_offset(); ++ start->handler -= kaslr_offset(); ++ start++; ++ } ++#endif ++ + } + + /* Given an address, look for it in the exception tables. */ diff --git a/kernel/fork.c b/kernel/fork.c -index 4a7ec0c..c49705c 100644 +index aea4f4d..59d599e 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -197,12 +197,55 @@ static void free_thread_stack(unsigned long *stack) @@ -141806,7 +141859,7 @@ index a0f61ef..b6aef3c 100644 seq_printf(m, "%40s %14lu %29s %pS\n", name, stats->contending_point[i], diff --git a/kernel/module.c b/kernel/module.c -index 6458a2f..ebdeb641 100644 +index 6458a2f..3edf977 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -60,6 +60,7 @@ @@ -142747,17 +142800,24 @@ index 6458a2f..ebdeb641 100644 return 0; } module_init(proc_modules_init); -@@ -4118,7 +4328,8 @@ struct module *__module_address(unsigned long addr) +@@ -4118,7 +4328,15 @@ struct module *__module_address(unsigned long addr) { struct module *mod; - if (addr < module_addr_min || addr > module_addr_max) ++#ifdef CONFIG_X86_32 ++ unsigned long vaddr = ktla_ktva(addr); ++ ++ if (module_addr_min_rx <= vaddr && vaddr <= module_addr_max_rx) ++ addr = vaddr; ++#endif ++ + if ((addr < module_addr_min_rx || addr > module_addr_max_rx) && + (addr < module_addr_min_rw || addr > module_addr_max_rw)) return NULL; module_assert_mutex_or_preempt(); -@@ -4161,11 +4372,21 @@ bool is_module_text_address(unsigned long addr) +@@ -4161,11 +4379,21 @@ bool is_module_text_address(unsigned long addr) */ struct module *__module_text_address(unsigned long addr) { @@ -142782,6 +142842,15 @@ index 6458a2f..ebdeb641 100644 mod = NULL; } return mod; +@@ -4195,7 +4423,7 @@ void print_modules(void) + #ifdef CONFIG_MODVERSIONS + /* Generate the signature for all relevant module structures here. + * If these change, we don't want to try to parse the module. */ +-void module_layout(struct module *mod, ++__visible void module_layout(struct module *mod, + struct modversion_info *ver, + struct kernel_param *kp, + struct kernel_symbol *ks, diff --git a/kernel/notifier.c b/kernel/notifier.c index fd2c9ac..6263e05 100644 --- a/kernel/notifier.c @@ -143155,7 +143224,7 @@ index c2199e9..ce5d89c 100644 } diff --git a/kernel/ptrace.c b/kernel/ptrace.c -index d49bfa1..5eb9a32 100644 +index d49bfa1..10a4c38 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -206,12 +206,32 @@ static int ptrace_check_attach(struct task_struct *child, bool ignore_state) @@ -143217,7 +143286,7 @@ index d49bfa1..5eb9a32 100644 flags |= PT_SEIZED; rcu_read_lock(); - if (ns_capable(__task_cred(task)->user_ns, CAP_SYS_PTRACE)) -+ if (ns_capable_nolog(__task_cred(task)->user_ns, CAP_SYS_PTRACE)) ++ if (ns_capable_noaudit(__task_cred(task)->user_ns, CAP_SYS_PTRACE)) flags |= PT_PTRACE_CAP; rcu_read_unlock(); task->ptrace = flags; @@ -145399,7 +145468,7 @@ index 667b933..1668952 100644 update_vsyscall_tz(); if (firsttime) { diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c -index 479d25c..7c25647 100644 +index b6c3945..373f21e 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -15,6 +15,7 @@ @@ -145410,7 +145479,7 @@ index 479d25c..7c25647 100644 #include <linux/syscore_ops.h> #include <linux/clocksource.h> #include <linux/jiffies.h> -@@ -1164,6 +1165,8 @@ int do_settimeofday64(const struct timespec64 *ts) +@@ -1167,6 +1168,8 @@ int do_settimeofday64(const struct timespec64 *ts) if (!timespec64_valid_strict(ts)) return -EINVAL; @@ -146859,34 +146928,6 @@ index 51a76af..7caf15b 100644 err_printk(dev, NULL, "DMA-API: device driver maps memory from " "stack [addr=%p]\n", addr); } -diff --git a/lib/extable.c b/lib/extable.c -index 0be02ad5..c2ad286 100644 ---- a/lib/extable.c -+++ b/lib/extable.c -@@ -13,13 +13,22 @@ - #include <linux/init.h> - #include <linux/sort.h> - #include <asm/uaccess.h> -+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) -+#include <asm/boot.h> -+#endif - - #ifndef ARCH_HAS_RELATIVE_EXTABLE - #define ex_to_insn(x) ((x)->insn) - #else - static inline unsigned long ex_to_insn(const struct exception_table_entry *x) - { -- return (unsigned long)&x->insn + x->insn; -+ unsigned long reloc = 0; -+ -+#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC) -+ reloc = ____LOAD_PHYSICAL_ADDR - LOAD_PHYSICAL_ADDR; -+#endif -+ -+ return (unsigned long)&x->insn + x->insn + reloc; - } - #endif - diff --git a/lib/inflate.c b/lib/inflate.c index 013a761..c28f3fc 100644 --- a/lib/inflate.c @@ -147186,6 +147227,41 @@ index 3859bf6..818741d6 100644 + pax_close_kernel(); +} +EXPORT_SYMBOL(pax_list_del_rcu); +diff --git a/lib/llist.c b/lib/llist.c +index ae5872b..63a9698 100644 +--- a/lib/llist.c ++++ b/lib/llist.c +@@ -25,6 +25,7 @@ + #include <linux/kernel.h> + #include <linux/export.h> + #include <linux/llist.h> ++#include <linux/mm.h> + + + /** +@@ -48,6 +49,22 @@ bool llist_add_batch(struct llist_node *new_first, struct llist_node *new_last, + } + EXPORT_SYMBOL_GPL(llist_add_batch); + ++bool pax_llist_add_batch(struct llist_node *new_first, struct llist_node *new_last, ++ struct llist_head *head) ++{ ++ struct llist_node *first; ++ ++ do { ++ first = ACCESS_ONCE(head->first); ++ pax_open_kernel(); ++ new_last->next = first; ++ pax_close_kernel(); ++ } while (cmpxchg(&head->first, first, new_first) != first); ++ ++ return !first; ++} ++EXPORT_SYMBOL_GPL(pax_llist_add_batch); ++ + /** + * llist_del_first - delete the first entry of lock-less list + * @head: the head for your lock-less list diff --git a/lib/lockref.c b/lib/lockref.c index 5a92189..d77978d 100644 --- a/lib/lockref.c @@ -147469,19 +147545,6 @@ index 2625943..1541382 100644 long align, res = 0; unsigned long c; -diff --git a/lib/swiotlb.c b/lib/swiotlb.c -index 76f29ec..1a5316f 100644 ---- a/lib/swiotlb.c -+++ b/lib/swiotlb.c -@@ -690,7 +690,7 @@ EXPORT_SYMBOL(swiotlb_alloc_coherent); - - void - swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, -- dma_addr_t dev_addr) -+ dma_addr_t dev_addr, struct dma_attrs *attrs) - { - phys_addr_t paddr = dma_to_phys(hwdev, dev_addr); - diff --git a/lib/usercopy.c b/lib/usercopy.c index 4f5b1dd..7cab418 100644 --- a/lib/usercopy.c @@ -152776,9 +152839,18 @@ index 031713ab..f2c0e55 100644 if (S_ISREG(inode->i_mode)) diff --git a/mm/util.c b/mm/util.c -index 917e0e3..6873e84 100644 +index 917e0e3..1c9f20c 100644 --- a/mm/util.c +++ b/mm/util.c +@@ -230,7 +230,7 @@ void __vma_link_list(struct mm_struct *mm, struct vm_area_struct *vma, + } + + /* Check if the vma is being used as a stack by this task */ +-int vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t) ++bool vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t) + { + return (vma->vm_start <= KSTK_ESP(t) && vma->vm_end >= KSTK_ESP(t)); + } @@ -239,6 +239,12 @@ int vma_is_stack_for_task(struct vm_area_struct *vma, struct task_struct *t) void arch_pick_mmap_layout(struct mm_struct *mm) { @@ -152811,7 +152883,7 @@ index 917e0e3..6873e84 100644 arg_start = mm->arg_start; arg_end = mm->arg_end; diff --git a/mm/vmalloc.c b/mm/vmalloc.c -index e11475c..3650eb9 100644 +index e11475c..eef1387 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -43,20 +43,65 @@ struct vfree_deferred { @@ -153065,7 +153137,7 @@ index e11475c..3650eb9 100644 + return; + if (unlikely(in_interrupt())) { + struct vfree_deferred *p = this_cpu_ptr(&vunmap_deferred); -+ if (llist_add((struct llist_node *)addr, &p->list)) ++ if (pax_llist_add((struct llist_node *)addr, &p->list)) + schedule_work(&p->wq); + } else { + might_sleep(); @@ -162233,19 +162305,6 @@ index dd94401..9540398 100644 /* Wait until SQ WR available if SQ still full */ wait_event(xprt->sc_send_wait, -diff --git a/net/sysctl_net.c b/net/sysctl_net.c -index ed98c1f..f74b659 100644 ---- a/net/sysctl_net.c -+++ b/net/sysctl_net.c -@@ -46,7 +46,7 @@ static int net_ctl_permissions(struct ctl_table_header *head, - kgid_t root_gid = make_kgid(net->user_ns, 0); - - /* Allow network administrator to have same access as root. */ -- if (ns_capable(net->user_ns, CAP_NET_ADMIN) || -+ if (ns_capable_nolog(net->user_ns, CAP_NET_ADMIN) || - uid_eq(root_uid, current_euid())) { - int mode = (table->mode >> 6) & 7; - return (mode << 6) | (mode << 3) | mode; diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 1fd4647..ebf12ff 100644 --- a/net/tipc/netlink_compat.c @@ -166879,10 +166938,10 @@ index 0000000..7514850 +fi diff --git a/scripts/gcc-plugins/initify_plugin.c b/scripts/gcc-plugins/initify_plugin.c new file mode 100644 -index 0000000..5a01d10 +index 0000000..fd7b918 --- /dev/null +++ b/scripts/gcc-plugins/initify_plugin.c -@@ -0,0 +1,537 @@ +@@ -0,0 +1,538 @@ +/* + * Copyright 2015-2016 by Emese Revfy <re.emese@gmail.com> + * Licensed under the GPL v2, or (at your option) v3 @@ -167063,6 +167122,7 @@ index 0000000..5a01d10 + int fntype_arg_len; + const_tree fndecl = gimple_call_fndecl(stmt); + ++// gcc_assert(DECL_ABSTRACT_ORIGIN(fndecl) == NULL_TREE); + if (DECL_ABSTRACT_ORIGIN(fndecl) != NULL_TREE) + return false; + @@ -185662,10 +185722,10 @@ index 0000000..00c7430 +} diff --git a/scripts/gcc-plugins/size_overflow_plugin/size_overflow_hash.data b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_hash.data new file mode 100644 -index 0000000..9d7e744 +index 0000000..d9ac611 --- /dev/null +++ b/scripts/gcc-plugins/size_overflow_plugin/size_overflow_hash.data -@@ -0,0 +1,22256 @@ +@@ -0,0 +1,22257 @@ +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_v9fs_xattr_get_acl_fndecl_4 v9fs_xattr_get_acl fndecl 5 4 NULL @@ -195481,6 +195541,7 @@ index 0000000..9d7e744 +enable_so_cur_offset_drm_dp_sideband_msg_tx_28655 cur_offset drm_dp_sideband_msg_tx 0 28655 &enable_so_alt_port_num_ib_qp_attr_28655 +enable_so_alloc_size_chunk_28657 alloc_size chunk 0 28657 NULL +enable_so_bfad_iocmd_lunmask_fndecl_28667 bfad_iocmd_lunmask fndecl 0 28667 NULL ++enable_so___frwr_init_fndecl_28674 __frwr_init fndecl 3 28674 NULL +enable_so_x25_create_facilities_fndecl_28684 x25_create_facilities fndecl 0 28684 NULL +enable_so_fill_isoc_urb_fndecl_28690 fill_isoc_urb fndecl 6-5-3 28690 NULL +enable_so_stolen_size_psb_gtt_28693 stolen_size psb_gtt 0 28693 NULL @@ -214381,7 +214442,7 @@ index 7798e16..1079224 100644 int i; if (!capable(CAP_MAC_ADMIN)) diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c -index 705c287..81257f1 100644 +index 7347fcc..b7f3f22 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c @@ -298,7 +298,7 @@ static struct aa_namespace *alloc_namespace(const char *prefix, @@ -215021,7 +215082,7 @@ index c61fd50f7..3081340 100644 default: result = -EINVAL; diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c -index 795437b..3650746 100644 +index b450a27..28c8238 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -871,9 +871,10 @@ static int snd_rawmidi_control_ioctl(struct snd_card *card, diff --git a/4.7.3/4425_grsec_remove_EI_PAX.patch b/4.7.4/4425_grsec_remove_EI_PAX.patch index ba92792..ba92792 100644 --- a/4.7.3/4425_grsec_remove_EI_PAX.patch +++ b/4.7.4/4425_grsec_remove_EI_PAX.patch diff --git a/4.7.3/4427_force_XATTR_PAX_tmpfs.patch b/4.7.4/4427_force_XATTR_PAX_tmpfs.patch index b4714fc..b4714fc 100644 --- a/4.7.3/4427_force_XATTR_PAX_tmpfs.patch +++ b/4.7.4/4427_force_XATTR_PAX_tmpfs.patch diff --git a/4.7.3/4430_grsec-remove-localversion-grsec.patch b/4.7.4/4430_grsec-remove-localversion-grsec.patch index 31cf878..31cf878 100644 --- a/4.7.3/4430_grsec-remove-localversion-grsec.patch +++ b/4.7.4/4430_grsec-remove-localversion-grsec.patch diff --git a/4.7.3/4435_grsec-mute-warnings.patch b/4.7.4/4435_grsec-mute-warnings.patch index 8929222..8929222 100644 --- a/4.7.3/4435_grsec-mute-warnings.patch +++ b/4.7.4/4435_grsec-mute-warnings.patch diff --git a/4.7.3/4440_grsec-remove-protected-paths.patch b/4.7.4/4440_grsec-remove-protected-paths.patch index 741546d..741546d 100644 --- a/4.7.3/4440_grsec-remove-protected-paths.patch +++ b/4.7.4/4440_grsec-remove-protected-paths.patch diff --git a/4.7.3/4450_grsec-kconfig-default-gids.patch b/4.7.4/4450_grsec-kconfig-default-gids.patch index e892c8a..e892c8a 100644 --- a/4.7.3/4450_grsec-kconfig-default-gids.patch +++ b/4.7.4/4450_grsec-kconfig-default-gids.patch diff --git a/4.7.3/4465_selinux-avc_audit-log-curr_ip.patch b/4.7.4/4465_selinux-avc_audit-log-curr_ip.patch index 7248385..7248385 100644 --- a/4.7.3/4465_selinux-avc_audit-log-curr_ip.patch +++ b/4.7.4/4465_selinux-avc_audit-log-curr_ip.patch diff --git a/4.7.3/4470_disable-compat_vdso.patch b/4.7.4/4470_disable-compat_vdso.patch index 0f82d7e..0f82d7e 100644 --- a/4.7.3/4470_disable-compat_vdso.patch +++ b/4.7.4/4470_disable-compat_vdso.patch diff --git a/4.7.3/4475_emutramp_default_on.patch b/4.7.4/4475_emutramp_default_on.patch index 2db58ab..2db58ab 100644 --- a/4.7.3/4475_emutramp_default_on.patch +++ b/4.7.4/4475_emutramp_default_on.patch |