From 9029a4f67f48e9574aa18d1e69441c33c750a37c Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 18 Sep 2014 02:32:30 +0000 Subject: [PATCH] Update to 3.16.3 svn path=/dists/sid/linux/; revision=21865 --- debian/changelog | 94 ++++- ...s-mfd-rtsx_usb.c-export-device-table.patch | 33 -- ...ibceph-add-process_one_ticket-helper.patch | 275 ------------- ...do-not-hard-code-max-auth-ticket-len.patch | 195 --------- ...ly-handle-large-reply-messages-from-.patch | 36 -- ..._piece-in-ceph_msg_data_pages_cursor.patch | 50 --- ...r-unprivileged-remount-cases-that-ha.patch | 315 -------------- ...efault-remount-atime-from-relatime-t.patch | 53 --- ...rect-permission-checks-in-do_remount.patch | 125 ------ ...t-for-MNT_LOCK_READONLY-from-change_.patch | 50 --- ...user-settable-mount-flags-in-remount.patch | 48 --- ...x-use-after-free-in-journal-teardown.patch | 86 ---- ...ruption-introduced-by-balance_leaf-r.patch | 383 ------------------ ...Fix-bug-which-can-cause-incorrect-sy.patch | 61 --- ...EON-make-get_system_type-thread-safe.patch | 66 --- ...Remove-BUG_ON-is_fpu_owner-in-do_ade.patch | 63 --- ...nt-user-from-setting-FCSR-cause-bits.patch | 50 --- ...-fix-a-missing-statement-for-HUGETLB.patch | 35 -- debian/patches/series | 17 - 19 files changed, 83 insertions(+), 1952 deletions(-) delete mode 100644 debian/patches/bugfix/all/drivers-mfd-rtsx_usb.c-export-device-table.patch delete mode 100644 debian/patches/bugfix/all/libceph-add-process_one_ticket-helper.patch delete mode 100644 debian/patches/bugfix/all/libceph-do-not-hard-code-max-auth-ticket-len.patch delete mode 100644 debian/patches/bugfix/all/libceph-gracefully-handle-large-reply-messages-from-.patch delete mode 100644 debian/patches/bugfix/all/libceph-set-last_piece-in-ceph_msg_data_pages_cursor.patch delete mode 100644 debian/patches/bugfix/all/mnt-Add-tests-for-unprivileged-remount-cases-that-ha.patch delete mode 100644 debian/patches/bugfix/all/mnt-Change-the-default-remount-atime-from-relatime-t.patch delete mode 100644 debian/patches/bugfix/all/mnt-Correct-permission-checks-in-do_remount.patch delete mode 100644 debian/patches/bugfix/all/mnt-Move-the-test-for-MNT_LOCK_READONLY-from-change_.patch delete mode 100644 debian/patches/bugfix/all/mnt-Only-change-user-settable-mount-flags-in-remount.patch delete mode 100644 debian/patches/bugfix/all/reiserfs-Fix-use-after-free-in-journal-teardown.patch delete mode 100644 debian/patches/bugfix/all/reiserfs-fix-corruption-introduced-by-balance_leaf-r.patch delete mode 100644 debian/patches/bugfix/mips/MIPS-O32-32-bit-Fix-bug-which-can-cause-incorrect-sy.patch delete mode 100644 debian/patches/bugfix/mips/MIPS-OCTEON-make-get_system_type-thread-safe.patch delete mode 100644 debian/patches/bugfix/mips/MIPS-Remove-BUG_ON-is_fpu_owner-in-do_ade.patch delete mode 100644 debian/patches/bugfix/mips/MIPS-prevent-user-from-setting-FCSR-cause-bits.patch delete mode 100644 debian/patches/bugfix/mips/MIPS-tlbex-fix-a-missing-statement-for-HUGETLB.patch diff --git a/debian/changelog b/debian/changelog index bf5657fff..1caba2c05 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,11 +1,88 @@ -linux (3.16.2-4) UNRELEASED; urgency=medium +linux (3.16.3-1) UNRELEASED; urgency=medium + + * New upstream stable update: + https://www.kernel.org/pub/linux/kernel/v3.x/ChangeLog-3.16.3 + - reiserfs: fix corruption introduced by balance_leaf refactor + (regression in 3.16) (Closes: #761457) + - reiserfs: Fix use after free in journal teardown + - media: v4l: vb2: Fix stream start and buffer completion race + - [x86] iommu/vt-d: Exclude devices using RMRRs from IOMMU API domains + - [powerpc*] powerpc/powernv: Fix IOMMU group lost (regression in 3.15) + - [x86] iommu/vt-d: Defer domain removal if device is assigned to a driver + - [x86] iommu/amd: Fix cleanup_domain for mass device removal + - [s390*] locking: Reenable optimistic spinning + - firmware: Do not use WARN_ON(!spin_is_locked()) + - CAPABILITIES: remove undefined caps from all processes + - fanotify: fix double free of pending permission events + - ocfs2: do not write error flag to user structure we cannot copy from/to + - [powerpc*] mm: fix potential infinite loop in dissolve_free_huge_pages() + - drivers/mfd/rtsx_usb.c: export device table (Closes: #761428) + - [powerpc*] mm: Use read barrier when creating real_pte + - [powerpc*] thp: Add write barrier after updating the valid bit + - [powerpc*] thp: Invalidate old 64K based hash page mapping before insert + of 4k pte + - [powerpc*] thp: Handle combo pages in invalidate + - [powerpc*] thp: Invalidate with vpn in loop + - [powerpc*] thp: Use ACCESS_ONCE when loading pmdp + - SCSI: save command pool address of Scsi_Host (regression in 3.15) + - fix regression in SCSI_IOCTL_SEND_COMMAND (regression in 3.16) + - [mips*] GIC: Prevent array overrun + - [mips*] ptrace: Test correct task's flags in task_user_regset_view() + - [mips*] ptrace: Change GP regset to use correct core dump register layout + - [mips*] ptrace: Avoid smp_processor_id() when retrieving FPU IR + - [mips*] syscall: Fix AUDIT value for O32 processes on MIPS64 + - [mips*] scall64-o32: Fix indirect syscall detection + - [mips,powerpc] bfa: Fix undefined bit shift on big-endian architectures + with 32-bit DMA address + - ACPI / hotplug: Check scan handlers in acpi_scan_hot_remove() + (regression in 3.14) + - ACPI: Run fixed event device notifications in process context + (regression in 3.15) + - ACPI / scan: Allow ACPI drivers to bind to PNP device objects + (regression in 3.16) + - ACPI / EC: Add support to disallow QR_EC to be issued when SCI_EVT isn't + set (regression in 3.14.13, 3.16) + - ACPI / EC: Add support to disallow QR_EC to be issued before completing + previous QR_EC (regression in 3.14.13, 3.16) + - ACPI / scan: not cache _SUN value in struct acpi_device_pnp + (regression in 3.14) + - ACPI / video: Add a disable_native_backlight quirk + - ACPI / video: Disable native_backlight on HP ENVY 15 Notebook PC + - ring-buffer: Always reset iterator to reader page + - ring-buffer: Up rb_iter_peek() loop count to 3 + - vfs: get rid of propagate_umount() mistakenly treating slaves as busy. + (regression in 3.15) + - Bluetooth: Fix tracking local SSP authentication requirement + - Bluetooth: Avoid use of session socket after the session gets freed + - vfs: __generic_file_write_iter(): fix handling of sync error after DIO + (regression in 3.16) + - rbd: rework rbd_request_fn() (regression in 3.15) + - vfs: fix copy_tree() regression (regression in 3.14) + - md/raid1,raid10: always abort recover on write error. + - md/raid5: avoid livelock caused by non-aligned writes. + (regression in 3.16) + - md/raid6: avoid data corruption during recovery of double-degraded RAID6 + - md/raid10: fix memory leak when reshaping a RAID10. + - xfs: ensure verifiers are attached to recovered buffers + - xfs: quotacheck leaves dquot buffers without verifiers + - xfs: don't dirty buffers beyond EOF + - xfs: don't zero partial page cache pages during O_DIRECT writes + - xfs: don't zero partial page cache pages during O_DIRECT reads + - libceph: set last_piece in ceph_msg_data_pages_cursor_init() correctly + - libceph: gracefully handle large reply messages from the mon + - libceph: do not hard code max auth ticket len (CVE-2014-6416, + CVE-2014-6417, CVE-2014-6418) + - CIFS: Fix async reading on reconnects + - CIFS: Possible null ptr deref in SMB2_tcon + - CIFS: Fix wrong directory attributes after rename + - mtd/ftl: fix the double free of the buffers allocated in build_maps() + - mtd: nand: omap: Fix 1-bit Hamming code scheme, omap_calculate_ecc() + - dm table: propagate QUEUE_FLAG_NO_SG_MERGE (regression in 3.16) + - KEYS: Fix use-after-free in assoc_array_gc() + - KEYS: Fix termination condition in assoc array garbage collection + (CVE-2014-3631) [ Ben Hutchings ] - * drivers/mfd/rtsx_usb.c: export device table (Closes: #761428) - * reiserfs: Apply critical fixes: - - fix corruption introduced by balance_leaf refactor (regression in 3.16) - (Closes: #761457) - - Fix use after free in journal teardown * sfc: Adding PCI ID for Solarflare 7000 series 40G network adapter. * sfc: Add 40G link capability decoding * Bump ABI to 2 (Closes: #761874) @@ -101,11 +178,6 @@ linux (3.16.2-3) unstable; urgency=medium practice this meant we didn't see them until they appeared in unstable * udeb: Fix typo in dependencies of speakup-modules (fixes FTBFS on mips64el due to interaction with another bug in kernel-wedge) - * libceph: Apply critical fixes: - - set last_piece in ceph_msg_data_pages_cursor_init() correctly - - gracefully handle large reply messages from the mon - - add process_one_ticket() helper - - do not hard code max auth ticket len [ Ian Campbell ] * [armel/orion5x] udeb: Include mvmdio in nic-modules udeb. diff --git a/debian/patches/bugfix/all/drivers-mfd-rtsx_usb.c-export-device-table.patch b/debian/patches/bugfix/all/drivers-mfd-rtsx_usb.c-export-device-table.patch deleted file mode 100644 index 59570a732..000000000 --- a/debian/patches/bugfix/all/drivers-mfd-rtsx_usb.c-export-device-table.patch +++ /dev/null @@ -1,33 +0,0 @@ -From: Jeff Mahoney -Date: Tue, 12 Aug 2014 13:46:09 -0700 -Subject: drivers/mfd/rtsx_usb.c: export device table -Origin: https://git.kernel.org/linus/1813908986e36119228c158aae1c6a0267c99e77 - -The rtsx_usb driver contains the table for the devices it supports but -doesn't export it. As a result, no alias is generated and it doesn't -get loaded automatically. - -Via https://bugzilla.novell.com/show_bug.cgi?id=890096 - -Signed-off-by: Jeff Mahoney -Reported-by: Marcel Witte -Cc: Roger Tseng -Cc: -Signed-off-by: Andrew Morton -Signed-off-by: Linus Torvalds ---- - drivers/mfd/rtsx_usb.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c -index 6352bec..71f387c 100644 ---- a/drivers/mfd/rtsx_usb.c -+++ b/drivers/mfd/rtsx_usb.c -@@ -744,6 +744,7 @@ static struct usb_device_id rtsx_usb_usb_ids[] = { - { USB_DEVICE(0x0BDA, 0x0140) }, - { } - }; -+MODULE_DEVICE_TABLE(usb, rtsx_usb_usb_ids); - - static struct usb_driver rtsx_usb_driver = { - .name = "rtsx_usb", diff --git a/debian/patches/bugfix/all/libceph-add-process_one_ticket-helper.patch b/debian/patches/bugfix/all/libceph-add-process_one_ticket-helper.patch deleted file mode 100644 index 8d97981b1..000000000 --- a/debian/patches/bugfix/all/libceph-add-process_one_ticket-helper.patch +++ /dev/null @@ -1,275 +0,0 @@ -From: Ilya Dryomov -Date: Mon, 8 Sep 2014 17:25:34 +0400 -Subject: libceph: add process_one_ticket() helper -Origin: https://git.kernel.org/linus/597cda357716a3cf8d994cb11927af917c8d71fa - -Add a helper for processing individual cephx auth tickets. Needed for -the next commit, which deals with allocating ticket buffers. (Most of -the diff here is whitespace - view with git diff -b). - -Cc: stable@vger.kernel.org -Signed-off-by: Ilya Dryomov -Reviewed-by: Sage Weil ---- - net/ceph/auth_x.c | 228 +++++++++++++++++++++++++++++------------------------- - 1 file changed, 124 insertions(+), 104 deletions(-) - -diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c -index 96238ba..0eb146d 100644 ---- a/net/ceph/auth_x.c -+++ b/net/ceph/auth_x.c -@@ -129,17 +129,131 @@ static void remove_ticket_handler(struct ceph_auth_client *ac, - kfree(th); - } - -+static int process_one_ticket(struct ceph_auth_client *ac, -+ struct ceph_crypto_key *secret, -+ void **p, void *end, -+ void *dbuf, void *ticket_buf) -+{ -+ struct ceph_x_info *xi = ac->private; -+ int type; -+ u8 tkt_struct_v, blob_struct_v; -+ struct ceph_x_ticket_handler *th; -+ void *dp, *dend; -+ int dlen; -+ char is_enc; -+ struct timespec validity; -+ struct ceph_crypto_key old_key; -+ void *tp, *tpend; -+ struct ceph_timespec new_validity; -+ struct ceph_crypto_key new_session_key; -+ struct ceph_buffer *new_ticket_blob; -+ unsigned long new_expires, new_renew_after; -+ u64 new_secret_id; -+ int ret; -+ -+ ceph_decode_need(p, end, sizeof(u32) + 1, bad); -+ -+ type = ceph_decode_32(p); -+ dout(" ticket type %d %s\n", type, ceph_entity_type_name(type)); -+ -+ tkt_struct_v = ceph_decode_8(p); -+ if (tkt_struct_v != 1) -+ goto bad; -+ -+ th = get_ticket_handler(ac, type); -+ if (IS_ERR(th)) { -+ ret = PTR_ERR(th); -+ goto out; -+ } -+ -+ /* blob for me */ -+ dlen = ceph_x_decrypt(secret, p, end, dbuf, -+ TEMP_TICKET_BUF_LEN); -+ if (dlen <= 0) { -+ ret = dlen; -+ goto out; -+ } -+ dout(" decrypted %d bytes\n", dlen); -+ dp = dbuf; -+ dend = dp + dlen; -+ -+ tkt_struct_v = ceph_decode_8(&dp); -+ if (tkt_struct_v != 1) -+ goto bad; -+ -+ memcpy(&old_key, &th->session_key, sizeof(old_key)); -+ ret = ceph_crypto_key_decode(&new_session_key, &dp, dend); -+ if (ret) -+ goto out; -+ -+ ceph_decode_copy(&dp, &new_validity, sizeof(new_validity)); -+ ceph_decode_timespec(&validity, &new_validity); -+ new_expires = get_seconds() + validity.tv_sec; -+ new_renew_after = new_expires - (validity.tv_sec / 4); -+ dout(" expires=%lu renew_after=%lu\n", new_expires, -+ new_renew_after); -+ -+ /* ticket blob for service */ -+ ceph_decode_8_safe(p, end, is_enc, bad); -+ tp = ticket_buf; -+ if (is_enc) { -+ /* encrypted */ -+ dout(" encrypted ticket\n"); -+ dlen = ceph_x_decrypt(&old_key, p, end, ticket_buf, -+ TEMP_TICKET_BUF_LEN); -+ if (dlen < 0) { -+ ret = dlen; -+ goto out; -+ } -+ dlen = ceph_decode_32(&tp); -+ } else { -+ /* unencrypted */ -+ ceph_decode_32_safe(p, end, dlen, bad); -+ ceph_decode_need(p, end, dlen, bad); -+ ceph_decode_copy(p, ticket_buf, dlen); -+ } -+ tpend = tp + dlen; -+ dout(" ticket blob is %d bytes\n", dlen); -+ ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); -+ blob_struct_v = ceph_decode_8(&tp); -+ new_secret_id = ceph_decode_64(&tp); -+ ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend); -+ if (ret) -+ goto out; -+ -+ /* all is well, update our ticket */ -+ ceph_crypto_key_destroy(&th->session_key); -+ if (th->ticket_blob) -+ ceph_buffer_put(th->ticket_blob); -+ th->session_key = new_session_key; -+ th->ticket_blob = new_ticket_blob; -+ th->validity = new_validity; -+ th->secret_id = new_secret_id; -+ th->expires = new_expires; -+ th->renew_after = new_renew_after; -+ dout(" got ticket service %d (%s) secret_id %lld len %d\n", -+ type, ceph_entity_type_name(type), th->secret_id, -+ (int)th->ticket_blob->vec.iov_len); -+ xi->have_keys |= th->service; -+ -+out: -+ return ret; -+ -+bad: -+ ret = -EINVAL; -+ goto out; -+} -+ - static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, - struct ceph_crypto_key *secret, - void *buf, void *end) - { -- struct ceph_x_info *xi = ac->private; -- int num; - void *p = buf; -- int ret; - char *dbuf; - char *ticket_buf; - u8 reply_struct_v; -+ u32 num; -+ int ret; - - dbuf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS); - if (!dbuf) -@@ -150,112 +264,18 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, - if (!ticket_buf) - goto out_dbuf; - -- ceph_decode_need(&p, end, 1 + sizeof(u32), bad); -- reply_struct_v = ceph_decode_8(&p); -+ ceph_decode_8_safe(&p, end, reply_struct_v, bad); - if (reply_struct_v != 1) -- goto bad; -- num = ceph_decode_32(&p); -- dout("%d tickets\n", num); -- while (num--) { -- int type; -- u8 tkt_struct_v, blob_struct_v; -- struct ceph_x_ticket_handler *th; -- void *dp, *dend; -- int dlen; -- char is_enc; -- struct timespec validity; -- struct ceph_crypto_key old_key; -- void *tp, *tpend; -- struct ceph_timespec new_validity; -- struct ceph_crypto_key new_session_key; -- struct ceph_buffer *new_ticket_blob; -- unsigned long new_expires, new_renew_after; -- u64 new_secret_id; -- -- ceph_decode_need(&p, end, sizeof(u32) + 1, bad); -- -- type = ceph_decode_32(&p); -- dout(" ticket type %d %s\n", type, ceph_entity_type_name(type)); -- -- tkt_struct_v = ceph_decode_8(&p); -- if (tkt_struct_v != 1) -- goto bad; -- -- th = get_ticket_handler(ac, type); -- if (IS_ERR(th)) { -- ret = PTR_ERR(th); -- goto out; -- } -- -- /* blob for me */ -- dlen = ceph_x_decrypt(secret, &p, end, dbuf, -- TEMP_TICKET_BUF_LEN); -- if (dlen <= 0) { -- ret = dlen; -- goto out; -- } -- dout(" decrypted %d bytes\n", dlen); -- dend = dbuf + dlen; -- dp = dbuf; -- -- tkt_struct_v = ceph_decode_8(&dp); -- if (tkt_struct_v != 1) -- goto bad; -+ return -EINVAL; - -- memcpy(&old_key, &th->session_key, sizeof(old_key)); -- ret = ceph_crypto_key_decode(&new_session_key, &dp, dend); -- if (ret) -- goto out; -+ ceph_decode_32_safe(&p, end, num, bad); -+ dout("%d tickets\n", num); - -- ceph_decode_copy(&dp, &new_validity, sizeof(new_validity)); -- ceph_decode_timespec(&validity, &new_validity); -- new_expires = get_seconds() + validity.tv_sec; -- new_renew_after = new_expires - (validity.tv_sec / 4); -- dout(" expires=%lu renew_after=%lu\n", new_expires, -- new_renew_after); -- -- /* ticket blob for service */ -- ceph_decode_8_safe(&p, end, is_enc, bad); -- tp = ticket_buf; -- if (is_enc) { -- /* encrypted */ -- dout(" encrypted ticket\n"); -- dlen = ceph_x_decrypt(&old_key, &p, end, ticket_buf, -- TEMP_TICKET_BUF_LEN); -- if (dlen < 0) { -- ret = dlen; -- goto out; -- } -- dlen = ceph_decode_32(&tp); -- } else { -- /* unencrypted */ -- ceph_decode_32_safe(&p, end, dlen, bad); -- ceph_decode_need(&p, end, dlen, bad); -- ceph_decode_copy(&p, ticket_buf, dlen); -- } -- tpend = tp + dlen; -- dout(" ticket blob is %d bytes\n", dlen); -- ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); -- blob_struct_v = ceph_decode_8(&tp); -- new_secret_id = ceph_decode_64(&tp); -- ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend); -+ while (num--) { -+ ret = process_one_ticket(ac, secret, &p, end, -+ dbuf, ticket_buf); - if (ret) - goto out; -- -- /* all is well, update our ticket */ -- ceph_crypto_key_destroy(&th->session_key); -- if (th->ticket_blob) -- ceph_buffer_put(th->ticket_blob); -- th->session_key = new_session_key; -- th->ticket_blob = new_ticket_blob; -- th->validity = new_validity; -- th->secret_id = new_secret_id; -- th->expires = new_expires; -- th->renew_after = new_renew_after; -- dout(" got ticket service %d (%s) secret_id %lld len %d\n", -- type, ceph_entity_type_name(type), th->secret_id, -- (int)th->ticket_blob->vec.iov_len); -- xi->have_keys |= th->service; - } - - ret = 0; diff --git a/debian/patches/bugfix/all/libceph-do-not-hard-code-max-auth-ticket-len.patch b/debian/patches/bugfix/all/libceph-do-not-hard-code-max-auth-ticket-len.patch deleted file mode 100644 index 2166f246b..000000000 --- a/debian/patches/bugfix/all/libceph-do-not-hard-code-max-auth-ticket-len.patch +++ /dev/null @@ -1,195 +0,0 @@ -From: Ilya Dryomov -Date: Tue, 9 Sep 2014 19:39:15 +0400 -Subject: libceph: do not hard code max auth ticket len -Origin: https://git.kernel.org/linus/c27a3e4d667fdcad3db7b104f75659478e0c68d8 - -We hard code cephx auth ticket buffer size to 256 bytes. This isn't -enough for any moderate setups and, in case tickets themselves are not -encrypted, leads to buffer overflows (ceph_x_decrypt() errors out, but -ceph_decode_copy() doesn't - it's just a memcpy() wrapper). Since the -buffer is allocated dynamically anyway, allocated it a bit later, at -the point where we know how much is going to be needed. - -Fixes: http://tracker.ceph.com/issues/8979 - -Cc: stable@vger.kernel.org -Signed-off-by: Ilya Dryomov -Reviewed-by: Sage Weil ---- - net/ceph/auth_x.c | 64 +++++++++++++++++++++++++------------------------------ - 1 file changed, 29 insertions(+), 35 deletions(-) - -diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c -index 0eb146d..de6662b 100644 ---- a/net/ceph/auth_x.c -+++ b/net/ceph/auth_x.c -@@ -13,8 +13,6 @@ - #include "auth_x.h" - #include "auth_x_protocol.h" - --#define TEMP_TICKET_BUF_LEN 256 -- - static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed); - - static int ceph_x_is_authenticated(struct ceph_auth_client *ac) -@@ -64,7 +62,7 @@ static int ceph_x_encrypt(struct ceph_crypto_key *secret, - } - - static int ceph_x_decrypt(struct ceph_crypto_key *secret, -- void **p, void *end, void *obuf, size_t olen) -+ void **p, void *end, void **obuf, size_t olen) - { - struct ceph_x_encrypt_header head; - size_t head_len = sizeof(head); -@@ -75,8 +73,14 @@ static int ceph_x_decrypt(struct ceph_crypto_key *secret, - return -EINVAL; - - dout("ceph_x_decrypt len %d\n", len); -- ret = ceph_decrypt2(secret, &head, &head_len, obuf, &olen, -- *p, len); -+ if (*obuf == NULL) { -+ *obuf = kmalloc(len, GFP_NOFS); -+ if (!*obuf) -+ return -ENOMEM; -+ olen = len; -+ } -+ -+ ret = ceph_decrypt2(secret, &head, &head_len, *obuf, &olen, *p, len); - if (ret) - return ret; - if (head.struct_v != 1 || le64_to_cpu(head.magic) != CEPHX_ENC_MAGIC) -@@ -131,18 +135,19 @@ static void remove_ticket_handler(struct ceph_auth_client *ac, - - static int process_one_ticket(struct ceph_auth_client *ac, - struct ceph_crypto_key *secret, -- void **p, void *end, -- void *dbuf, void *ticket_buf) -+ void **p, void *end) - { - struct ceph_x_info *xi = ac->private; - int type; - u8 tkt_struct_v, blob_struct_v; - struct ceph_x_ticket_handler *th; -+ void *dbuf = NULL; - void *dp, *dend; - int dlen; - char is_enc; - struct timespec validity; - struct ceph_crypto_key old_key; -+ void *ticket_buf = NULL; - void *tp, *tpend; - struct ceph_timespec new_validity; - struct ceph_crypto_key new_session_key; -@@ -167,8 +172,7 @@ static int process_one_ticket(struct ceph_auth_client *ac, - } - - /* blob for me */ -- dlen = ceph_x_decrypt(secret, p, end, dbuf, -- TEMP_TICKET_BUF_LEN); -+ dlen = ceph_x_decrypt(secret, p, end, &dbuf, 0); - if (dlen <= 0) { - ret = dlen; - goto out; -@@ -195,20 +199,25 @@ static int process_one_ticket(struct ceph_auth_client *ac, - - /* ticket blob for service */ - ceph_decode_8_safe(p, end, is_enc, bad); -- tp = ticket_buf; - if (is_enc) { - /* encrypted */ - dout(" encrypted ticket\n"); -- dlen = ceph_x_decrypt(&old_key, p, end, ticket_buf, -- TEMP_TICKET_BUF_LEN); -+ dlen = ceph_x_decrypt(&old_key, p, end, &ticket_buf, 0); - if (dlen < 0) { - ret = dlen; - goto out; - } -+ tp = ticket_buf; - dlen = ceph_decode_32(&tp); - } else { - /* unencrypted */ - ceph_decode_32_safe(p, end, dlen, bad); -+ ticket_buf = kmalloc(dlen, GFP_NOFS); -+ if (!ticket_buf) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ tp = ticket_buf; - ceph_decode_need(p, end, dlen, bad); - ceph_decode_copy(p, ticket_buf, dlen); - } -@@ -237,6 +246,8 @@ static int process_one_ticket(struct ceph_auth_client *ac, - xi->have_keys |= th->service; - - out: -+ kfree(ticket_buf); -+ kfree(dbuf); - return ret; - - bad: -@@ -249,21 +260,10 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, - void *buf, void *end) - { - void *p = buf; -- char *dbuf; -- char *ticket_buf; - u8 reply_struct_v; - u32 num; - int ret; - -- dbuf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS); -- if (!dbuf) -- return -ENOMEM; -- -- ret = -ENOMEM; -- ticket_buf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS); -- if (!ticket_buf) -- goto out_dbuf; -- - ceph_decode_8_safe(&p, end, reply_struct_v, bad); - if (reply_struct_v != 1) - return -EINVAL; -@@ -272,22 +272,15 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, - dout("%d tickets\n", num); - - while (num--) { -- ret = process_one_ticket(ac, secret, &p, end, -- dbuf, ticket_buf); -+ ret = process_one_ticket(ac, secret, &p, end); - if (ret) -- goto out; -+ return ret; - } - -- ret = 0; --out: -- kfree(ticket_buf); --out_dbuf: -- kfree(dbuf); -- return ret; -+ return 0; - - bad: -- ret = -EINVAL; -- goto out; -+ return -EINVAL; - } - - static int ceph_x_build_authorizer(struct ceph_auth_client *ac, -@@ -603,13 +596,14 @@ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac, - struct ceph_x_ticket_handler *th; - int ret = 0; - struct ceph_x_authorize_reply reply; -+ void *preply = &reply; - void *p = au->reply_buf; - void *end = p + sizeof(au->reply_buf); - - th = get_ticket_handler(ac, au->service); - if (IS_ERR(th)) - return PTR_ERR(th); -- ret = ceph_x_decrypt(&th->session_key, &p, end, &reply, sizeof(reply)); -+ ret = ceph_x_decrypt(&th->session_key, &p, end, &preply, sizeof(reply)); - if (ret < 0) - return ret; - if (ret != sizeof(reply)) diff --git a/debian/patches/bugfix/all/libceph-gracefully-handle-large-reply-messages-from-.patch b/debian/patches/bugfix/all/libceph-gracefully-handle-large-reply-messages-from-.patch deleted file mode 100644 index 1244951d2..000000000 --- a/debian/patches/bugfix/all/libceph-gracefully-handle-large-reply-messages-from-.patch +++ /dev/null @@ -1,36 +0,0 @@ -From: Sage Weil -Date: Mon, 4 Aug 2014 07:01:54 -0700 -Subject: libceph: gracefully handle large reply messages from the mon -Origin: https://git.kernel.org/linus/73c3d4812b4c755efeca0140f606f83772a39ce4 - -We preallocate a few of the message types we get back from the mon. If we -get a larger message than we are expecting, fall back to trying to allocate -a new one instead of blindly using the one we have. - -CC: stable@vger.kernel.org -Signed-off-by: Sage Weil -Reviewed-by: Ilya Dryomov ---- - net/ceph/mon_client.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c -index 067d3af..61fcfc3 100644 ---- a/net/ceph/mon_client.c -+++ b/net/ceph/mon_client.c -@@ -1181,7 +1181,15 @@ static struct ceph_msg *mon_alloc_msg(struct ceph_connection *con, - if (!m) { - pr_info("alloc_msg unknown type %d\n", type); - *skip = 1; -+ } else if (front_len > m->front_alloc_len) { -+ pr_warning("mon_alloc_msg front %d > prealloc %d (%u#%llu)\n", -+ front_len, m->front_alloc_len, -+ (unsigned int)con->peer_name.type, -+ le64_to_cpu(con->peer_name.num)); -+ ceph_msg_put(m); -+ m = ceph_msg_new(type, front_len, GFP_NOFS, false); - } -+ - return m; - } - diff --git a/debian/patches/bugfix/all/libceph-set-last_piece-in-ceph_msg_data_pages_cursor.patch b/debian/patches/bugfix/all/libceph-set-last_piece-in-ceph_msg_data_pages_cursor.patch deleted file mode 100644 index fda0fc14c..000000000 --- a/debian/patches/bugfix/all/libceph-set-last_piece-in-ceph_msg_data_pages_cursor.patch +++ /dev/null @@ -1,50 +0,0 @@ -From: Ilya Dryomov -Date: Fri, 8 Aug 2014 12:43:39 +0400 -Subject: libceph: set last_piece in ceph_msg_data_pages_cursor_init() - correctly -Origin: https://git.kernel.org/linus/5f740d7e1531099b888410e6bab13f68da9b1a4d - -Determining ->last_piece based on the value of ->page_offset + length -is incorrect because length here is the length of the entire message. -->last_piece set to false even if page array data item length is <= -PAGE_SIZE, which results in invalid length passed to -ceph_tcp_{send,recv}page() and causes various asserts to fire. - - # cat pages-cursor-init.sh - #!/bin/bash - rbd create --size 10 --image-format 2 foo - FOO_DEV=$(rbd map foo) - dd if=/dev/urandom of=$FOO_DEV bs=1M &>/dev/null - rbd snap create foo@snap - rbd snap protect foo@snap - rbd clone foo@snap bar - # rbd_resize calls librbd rbd_resize(), size is in bytes - ./rbd_resize bar $(((4 << 20) + 512)) - rbd resize --size 10 bar - BAR_DEV=$(rbd map bar) - # trigger a 512-byte copyup -- 512-byte page array data item - dd if=/dev/urandom of=$BAR_DEV bs=1M count=1 seek=5 - -The problem exists only in ceph_msg_data_pages_cursor_init(), -ceph_msg_data_pages_advance() does the right thing. The size_t cast is -unnecessary. - -Cc: stable@vger.kernel.org # 3.10+ -Signed-off-by: Ilya Dryomov -Reviewed-by: Sage Weil -Reviewed-by: Alex Elder ---- - net/ceph/messenger.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/net/ceph/messenger.c -+++ b/net/ceph/messenger.c -@@ -900,7 +900,7 @@ static void ceph_msg_data_pages_cursor_i - BUG_ON(page_count > (int)USHRT_MAX); - cursor->page_count = (unsigned short)page_count; - BUG_ON(length > SIZE_MAX - cursor->page_offset); -- cursor->last_piece = (size_t)cursor->page_offset + length <= PAGE_SIZE; -+ cursor->last_piece = cursor->page_offset + cursor->resid <= PAGE_SIZE; - } - - static struct page * diff --git a/debian/patches/bugfix/all/mnt-Add-tests-for-unprivileged-remount-cases-that-ha.patch b/debian/patches/bugfix/all/mnt-Add-tests-for-unprivileged-remount-cases-that-ha.patch deleted file mode 100644 index e4460e8d6..000000000 --- a/debian/patches/bugfix/all/mnt-Add-tests-for-unprivileged-remount-cases-that-ha.patch +++ /dev/null @@ -1,315 +0,0 @@ -From: "Eric W. Biederman" -Date: Tue, 29 Jul 2014 15:50:44 -0700 -Subject: [5/5] mnt: Add tests for unprivileged remount cases that have found - to be faulty -Origin: https://git.kernel.org/linus/db181ce011e3c033328608299cd6fac06ea50130 - -Kenton Varda discovered that by remounting a -read-only bind mount read-only in a user namespace the -MNT_LOCK_READONLY bit would be cleared, allowing an unprivileged user -to the remount a read-only mount read-write. - -Upon review of the code in remount it was discovered that the code allowed -nosuid, noexec, and nodev to be cleared. It was also discovered that -the code was allowing the per mount atime flags to be changed. - -The first naive patch to fix these issues contained the flaw that using -default atime settings when remounting a filesystem could be disallowed. - -To avoid this problems in the future add tests to ensure unprivileged -remounts are succeeding and failing at the appropriate times. - -Cc: stable@vger.kernel.org -Acked-by: Serge E. Hallyn -Signed-off-by: "Eric W. Biederman" ---- - tools/testing/selftests/Makefile | 1 + - tools/testing/selftests/mount/Makefile | 17 ++ - .../selftests/mount/unprivileged-remount-test.c | 242 +++++++++++++++++++++ - 3 files changed, 260 insertions(+) - create mode 100644 tools/testing/selftests/mount/Makefile - create mode 100644 tools/testing/selftests/mount/unprivileged-remount-test.c - -diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile -index e66e710..0a8a9db 100644 ---- a/tools/testing/selftests/Makefile -+++ b/tools/testing/selftests/Makefile -@@ -4,6 +4,7 @@ TARGETS += efivarfs - TARGETS += kcmp - TARGETS += memory-hotplug - TARGETS += mqueue -+TARGETS += mount - TARGETS += net - TARGETS += ptrace - TARGETS += timers -diff --git a/tools/testing/selftests/mount/Makefile b/tools/testing/selftests/mount/Makefile -new file mode 100644 -index 0000000..337d853 ---- /dev/null -+++ b/tools/testing/selftests/mount/Makefile -@@ -0,0 +1,17 @@ -+# Makefile for mount selftests. -+ -+all: unprivileged-remount-test -+ -+unprivileged-remount-test: unprivileged-remount-test.c -+ gcc -Wall -O2 unprivileged-remount-test.c -o unprivileged-remount-test -+ -+# Allow specific tests to be selected. -+test_unprivileged_remount: unprivileged-remount-test -+ @if [ -f /proc/self/uid_map ] ; then ./unprivileged-remount-test ; fi -+ -+run_tests: all test_unprivileged_remount -+ -+clean: -+ rm -f unprivileged-remount-test -+ -+.PHONY: all test_unprivileged_remount -diff --git a/tools/testing/selftests/mount/unprivileged-remount-test.c b/tools/testing/selftests/mount/unprivileged-remount-test.c -new file mode 100644 -index 0000000..1b3ff2f ---- /dev/null -+++ b/tools/testing/selftests/mount/unprivileged-remount-test.c -@@ -0,0 +1,242 @@ -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifndef CLONE_NEWNS -+# define CLONE_NEWNS 0x00020000 -+#endif -+#ifndef CLONE_NEWUTS -+# define CLONE_NEWUTS 0x04000000 -+#endif -+#ifndef CLONE_NEWIPC -+# define CLONE_NEWIPC 0x08000000 -+#endif -+#ifndef CLONE_NEWNET -+# define CLONE_NEWNET 0x40000000 -+#endif -+#ifndef CLONE_NEWUSER -+# define CLONE_NEWUSER 0x10000000 -+#endif -+#ifndef CLONE_NEWPID -+# define CLONE_NEWPID 0x20000000 -+#endif -+ -+#ifndef MS_RELATIME -+#define MS_RELATIME (1 << 21) -+#endif -+#ifndef MS_STRICTATIME -+#define MS_STRICTATIME (1 << 24) -+#endif -+ -+static void die(char *fmt, ...) -+{ -+ va_list ap; -+ va_start(ap, fmt); -+ vfprintf(stderr, fmt, ap); -+ va_end(ap); -+ exit(EXIT_FAILURE); -+} -+ -+static void write_file(char *filename, char *fmt, ...) -+{ -+ char buf[4096]; -+ int fd; -+ ssize_t written; -+ int buf_len; -+ va_list ap; -+ -+ va_start(ap, fmt); -+ buf_len = vsnprintf(buf, sizeof(buf), fmt, ap); -+ va_end(ap); -+ if (buf_len < 0) { -+ die("vsnprintf failed: %s\n", -+ strerror(errno)); -+ } -+ if (buf_len >= sizeof(buf)) { -+ die("vsnprintf output truncated\n"); -+ } -+ -+ fd = open(filename, O_WRONLY); -+ if (fd < 0) { -+ die("open of %s failed: %s\n", -+ filename, strerror(errno)); -+ } -+ written = write(fd, buf, buf_len); -+ if (written != buf_len) { -+ if (written >= 0) { -+ die("short write to %s\n", filename); -+ } else { -+ die("write to %s failed: %s\n", -+ filename, strerror(errno)); -+ } -+ } -+ if (close(fd) != 0) { -+ die("close of %s failed: %s\n", -+ filename, strerror(errno)); -+ } -+} -+ -+static void create_and_enter_userns(void) -+{ -+ uid_t uid; -+ gid_t gid; -+ -+ uid = getuid(); -+ gid = getgid(); -+ -+ if (unshare(CLONE_NEWUSER) !=0) { -+ die("unshare(CLONE_NEWUSER) failed: %s\n", -+ strerror(errno)); -+ } -+ -+ write_file("/proc/self/uid_map", "0 %d 1", uid); -+ write_file("/proc/self/gid_map", "0 %d 1", gid); -+ -+ if (setgroups(0, NULL) != 0) { -+ die("setgroups failed: %s\n", -+ strerror(errno)); -+ } -+ if (setgid(0) != 0) { -+ die ("setgid(0) failed %s\n", -+ strerror(errno)); -+ } -+ if (setuid(0) != 0) { -+ die("setuid(0) failed %s\n", -+ strerror(errno)); -+ } -+} -+ -+static -+bool test_unpriv_remount(int mount_flags, int remount_flags, int invalid_flags) -+{ -+ pid_t child; -+ -+ child = fork(); -+ if (child == -1) { -+ die("fork failed: %s\n", -+ strerror(errno)); -+ } -+ if (child != 0) { /* parent */ -+ pid_t pid; -+ int status; -+ pid = waitpid(child, &status, 0); -+ if (pid == -1) { -+ die("waitpid failed: %s\n", -+ strerror(errno)); -+ } -+ if (pid != child) { -+ die("waited for %d got %d\n", -+ child, pid); -+ } -+ if (!WIFEXITED(status)) { -+ die("child did not terminate cleanly\n"); -+ } -+ return WEXITSTATUS(status) == EXIT_SUCCESS ? true : false; -+ } -+ -+ create_and_enter_userns(); -+ if (unshare(CLONE_NEWNS) != 0) { -+ die("unshare(CLONE_NEWNS) failed: %s\n", -+ strerror(errno)); -+ } -+ -+ if (mount("testing", "/tmp", "ramfs", mount_flags, NULL) != 0) { -+ die("mount of /tmp failed: %s\n", -+ strerror(errno)); -+ } -+ -+ create_and_enter_userns(); -+ -+ if (unshare(CLONE_NEWNS) != 0) { -+ die("unshare(CLONE_NEWNS) failed: %s\n", -+ strerror(errno)); -+ } -+ -+ if (mount("/tmp", "/tmp", "none", -+ MS_REMOUNT | MS_BIND | remount_flags, NULL) != 0) { -+ /* system("cat /proc/self/mounts"); */ -+ die("remount of /tmp failed: %s\n", -+ strerror(errno)); -+ } -+ -+ if (mount("/tmp", "/tmp", "none", -+ MS_REMOUNT | MS_BIND | invalid_flags, NULL) == 0) { -+ /* system("cat /proc/self/mounts"); */ -+ die("remount of /tmp with invalid flags " -+ "succeeded unexpectedly\n"); -+ } -+ exit(EXIT_SUCCESS); -+} -+ -+static bool test_unpriv_remount_simple(int mount_flags) -+{ -+ return test_unpriv_remount(mount_flags, mount_flags, 0); -+} -+ -+static bool test_unpriv_remount_atime(int mount_flags, int invalid_flags) -+{ -+ return test_unpriv_remount(mount_flags, mount_flags, invalid_flags); -+} -+ -+int main(int argc, char **argv) -+{ -+ if (!test_unpriv_remount_simple(MS_RDONLY|MS_NODEV)) { -+ die("MS_RDONLY malfunctions\n"); -+ } -+ if (!test_unpriv_remount_simple(MS_NODEV)) { -+ die("MS_NODEV malfunctions\n"); -+ } -+ if (!test_unpriv_remount_simple(MS_NOSUID|MS_NODEV)) { -+ die("MS_NOSUID malfunctions\n"); -+ } -+ if (!test_unpriv_remount_simple(MS_NOEXEC|MS_NODEV)) { -+ die("MS_NOEXEC malfunctions\n"); -+ } -+ if (!test_unpriv_remount_atime(MS_RELATIME|MS_NODEV, -+ MS_NOATIME|MS_NODEV)) -+ { -+ die("MS_RELATIME malfunctions\n"); -+ } -+ if (!test_unpriv_remount_atime(MS_STRICTATIME|MS_NODEV, -+ MS_NOATIME|MS_NODEV)) -+ { -+ die("MS_STRICTATIME malfunctions\n"); -+ } -+ if (!test_unpriv_remount_atime(MS_NOATIME|MS_NODEV, -+ MS_STRICTATIME|MS_NODEV)) -+ { -+ die("MS_RELATIME malfunctions\n"); -+ } -+ if (!test_unpriv_remount_atime(MS_RELATIME|MS_NODIRATIME|MS_NODEV, -+ MS_NOATIME|MS_NODEV)) -+ { -+ die("MS_RELATIME malfunctions\n"); -+ } -+ if (!test_unpriv_remount_atime(MS_STRICTATIME|MS_NODIRATIME|MS_NODEV, -+ MS_NOATIME|MS_NODEV)) -+ { -+ die("MS_RELATIME malfunctions\n"); -+ } -+ if (!test_unpriv_remount_atime(MS_NOATIME|MS_NODIRATIME|MS_NODEV, -+ MS_STRICTATIME|MS_NODEV)) -+ { -+ die("MS_RELATIME malfunctions\n"); -+ } -+ if (!test_unpriv_remount(MS_STRICTATIME|MS_NODEV, MS_NODEV, -+ MS_NOATIME|MS_NODEV)) -+ { -+ die("Default atime malfunctions\n"); -+ } -+ return EXIT_SUCCESS; -+} diff --git a/debian/patches/bugfix/all/mnt-Change-the-default-remount-atime-from-relatime-t.patch b/debian/patches/bugfix/all/mnt-Change-the-default-remount-atime-from-relatime-t.patch deleted file mode 100644 index be7082cab..000000000 --- a/debian/patches/bugfix/all/mnt-Change-the-default-remount-atime-from-relatime-t.patch +++ /dev/null @@ -1,53 +0,0 @@ -From: "Eric W. Biederman" -Date: Mon, 28 Jul 2014 17:36:04 -0700 -Subject: [4/5] mnt: Change the default remount atime from relatime to the - existing value -Origin: https://git.kernel.org/linus/ffbc6f0ead47fa5a1dc9642b0331cb75c20a640e - -Since March 2009 the kernel has treated the state that if no -MS_..ATIME flags are passed then the kernel defaults to relatime. - -Defaulting to relatime instead of the existing atime state during a -remount is silly, and causes problems in practice for people who don't -specify any MS_...ATIME flags and to get the default filesystem atime -setting. Those users may encounter a permission error because the -default atime setting does not work. - -A default that does not work and causes permission problems is -ridiculous, so preserve the existing value to have a default -atime setting that is always guaranteed to work. - -Using the default atime setting in this way is particularly -interesting for applications built to run in restricted userspace -environments without /proc mounted, as the existing atime mount -options of a filesystem can not be read from /proc/mounts. - -In practice this fixes user space that uses the default atime -setting on remount that are broken by the permission checks -keeping less privileged users from changing more privileged users -atime settings. - -Cc: stable@vger.kernel.org -Acked-by: Serge E. Hallyn -Signed-off-by: "Eric W. Biederman" ---- - fs/namespace.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -2475,6 +2475,14 @@ long do_mount(const char *dev_name, cons - if (flags & MS_RDONLY) - mnt_flags |= MNT_READONLY; - -+ /* The default atime for remount is preservation */ -+ if ((flags & MS_REMOUNT) && -+ ((flags & (MS_NOATIME | MS_NODIRATIME | MS_RELATIME | -+ MS_STRICTATIME)) == 0)) { -+ mnt_flags &= ~MNT_ATIME_MASK; -+ mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK; -+ } -+ - flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN | - MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT | - MS_STRICTATIME); diff --git a/debian/patches/bugfix/all/mnt-Correct-permission-checks-in-do_remount.patch b/debian/patches/bugfix/all/mnt-Correct-permission-checks-in-do_remount.patch deleted file mode 100644 index 88be03a5a..000000000 --- a/debian/patches/bugfix/all/mnt-Correct-permission-checks-in-do_remount.patch +++ /dev/null @@ -1,125 +0,0 @@ -From: "Eric W. Biederman" -Date: Mon, 28 Jul 2014 17:26:07 -0700 -Subject: [3/5] mnt: Correct permission checks in do_remount -Origin: https://git.kernel.org/linus/9566d6742852c527bf5af38af5cbb878dad75705 - -While invesgiating the issue where in "mount --bind -oremount,ro ..." -would result in later "mount --bind -oremount,rw" succeeding even if -the mount started off locked I realized that there are several -additional mount flags that should be locked and are not. - -In particular MNT_NOSUID, MNT_NODEV, MNT_NOEXEC, and the atime -flags in addition to MNT_READONLY should all be locked. These -flags are all per superblock, can all be changed with MS_BIND, -and should not be changable if set by a more privileged user. - -The following additions to the current logic are added in this patch. -- nosuid may not be clearable by a less privileged user. -- nodev may not be clearable by a less privielged user. -- noexec may not be clearable by a less privileged user. -- atime flags may not be changeable by a less privileged user. - -The logic with atime is that always setting atime on access is a -global policy and backup software and auditing software could break if -atime bits are not updated (when they are configured to be updated), -and serious performance degradation could result (DOS attack) if atime -updates happen when they have been explicitly disabled. Therefore an -unprivileged user should not be able to mess with the atime bits set -by a more privileged user. - -The additional restrictions are implemented with the addition of -MNT_LOCK_NOSUID, MNT_LOCK_NODEV, MNT_LOCK_NOEXEC, and MNT_LOCK_ATIME -mnt flags. - -Taken together these changes and the fixes for MNT_LOCK_READONLY -should make it safe for an unprivileged user to create a user -namespace and to call "mount --bind -o remount,... ..." without -the danger of mount flags being changed maliciously. - -Cc: stable@vger.kernel.org -Acked-by: Serge E. Hallyn -Signed-off-by: "Eric W. Biederman" ---- - fs/namespace.c | 36 +++++++++++++++++++++++++++++++++--- - include/linux/mount.h | 5 +++++ - 2 files changed, 38 insertions(+), 3 deletions(-) - ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -891,8 +891,21 @@ static struct mount *clone_mnt(struct mo - - mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~(MNT_WRITE_HOLD|MNT_MARKED); - /* Don't allow unprivileged users to change mount flags */ -- if ((flag & CL_UNPRIVILEGED) && (mnt->mnt.mnt_flags & MNT_READONLY)) -- mnt->mnt.mnt_flags |= MNT_LOCK_READONLY; -+ if (flag & CL_UNPRIVILEGED) { -+ mnt->mnt.mnt_flags |= MNT_LOCK_ATIME; -+ -+ if (mnt->mnt.mnt_flags & MNT_READONLY) -+ mnt->mnt.mnt_flags |= MNT_LOCK_READONLY; -+ -+ if (mnt->mnt.mnt_flags & MNT_NODEV) -+ mnt->mnt.mnt_flags |= MNT_LOCK_NODEV; -+ -+ if (mnt->mnt.mnt_flags & MNT_NOSUID) -+ mnt->mnt.mnt_flags |= MNT_LOCK_NOSUID; -+ -+ if (mnt->mnt.mnt_flags & MNT_NOEXEC) -+ mnt->mnt.mnt_flags |= MNT_LOCK_NOEXEC; -+ } - - /* Don't allow unprivileged users to reveal what is under a mount */ - if ((flag & CL_UNPRIVILEGED) && list_empty(&old->mnt_expire)) -@@ -1933,6 +1946,23 @@ static int do_remount(struct path *path, - !(mnt_flags & MNT_READONLY)) { - return -EPERM; - } -+ if ((mnt->mnt.mnt_flags & MNT_LOCK_NODEV) && -+ !(mnt_flags & MNT_NODEV)) { -+ return -EPERM; -+ } -+ if ((mnt->mnt.mnt_flags & MNT_LOCK_NOSUID) && -+ !(mnt_flags & MNT_NOSUID)) { -+ return -EPERM; -+ } -+ if ((mnt->mnt.mnt_flags & MNT_LOCK_NOEXEC) && -+ !(mnt_flags & MNT_NOEXEC)) { -+ return -EPERM; -+ } -+ if ((mnt->mnt.mnt_flags & MNT_LOCK_ATIME) && -+ ((mnt->mnt.mnt_flags & MNT_ATIME_MASK) != (mnt_flags & MNT_ATIME_MASK))) { -+ return -EPERM; -+ } -+ - err = security_sb_remount(sb, data); - if (err) - return err; -@@ -2131,7 +2161,7 @@ static int do_new_mount(struct path *pat - */ - if (!(type->fs_flags & FS_USERNS_DEV_MOUNT)) { - flags |= MS_NODEV; -- mnt_flags |= MNT_NODEV; -+ mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV; - } - } - ---- a/include/linux/mount.h -+++ b/include/linux/mount.h -@@ -45,12 +45,17 @@ struct mnt_namespace; - #define MNT_USER_SETTABLE_MASK (MNT_NOSUID | MNT_NODEV | MNT_NOEXEC \ - | MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME \ - | MNT_READONLY) -+#define MNT_ATIME_MASK (MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME ) - - #define MNT_INTERNAL_FLAGS (MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL | \ - MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED) - - #define MNT_INTERNAL 0x4000 - -+#define MNT_LOCK_ATIME 0x040000 -+#define MNT_LOCK_NOEXEC 0x080000 -+#define MNT_LOCK_NOSUID 0x100000 -+#define MNT_LOCK_NODEV 0x200000 - #define MNT_LOCK_READONLY 0x400000 - #define MNT_LOCKED 0x800000 - #define MNT_DOOMED 0x1000000 diff --git a/debian/patches/bugfix/all/mnt-Move-the-test-for-MNT_LOCK_READONLY-from-change_.patch b/debian/patches/bugfix/all/mnt-Move-the-test-for-MNT_LOCK_READONLY-from-change_.patch deleted file mode 100644 index c5f911701..000000000 --- a/debian/patches/bugfix/all/mnt-Move-the-test-for-MNT_LOCK_READONLY-from-change_.patch +++ /dev/null @@ -1,50 +0,0 @@ -From: "Eric W. Biederman" -Date: Mon, 28 Jul 2014 17:10:56 -0700 -Subject: [2/5] mnt: Move the test for MNT_LOCK_READONLY from - change_mount_flags into do_remount -Origin: https://git.kernel.org/linus/07b645589dcda8b7a5249e096fece2a67556f0f4 - -There are no races as locked mount flags are guaranteed to never change. - -Moving the test into do_remount makes it more visible, and ensures all -filesystem remounts pass the MNT_LOCK_READONLY permission check. This -second case is not an issue today as filesystem remounts are guarded -by capable(CAP_DAC_ADMIN) and thus will always fail in less privileged -mount namespaces, but it could become an issue in the future. - -Cc: stable@vger.kernel.org -Acked-by: Serge E. Hallyn -Signed-off-by: "Eric W. Biederman" ---- - fs/namespace.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -1898,9 +1898,6 @@ static int change_mount_flags(struct vfs - if (readonly_request == __mnt_is_readonly(mnt)) - return 0; - -- if (mnt->mnt_flags & MNT_LOCK_READONLY) -- return -EPERM; -- - if (readonly_request) - error = mnt_make_readonly(real_mount(mnt)); - else -@@ -1926,6 +1923,16 @@ static int do_remount(struct path *path, - if (path->dentry != path->mnt->mnt_root) - return -EINVAL; - -+ /* Don't allow changing of locked mnt flags. -+ * -+ * No locks need to be held here while testing the various -+ * MNT_LOCK flags because those flags can never be cleared -+ * once they are set. -+ */ -+ if ((mnt->mnt.mnt_flags & MNT_LOCK_READONLY) && -+ !(mnt_flags & MNT_READONLY)) { -+ return -EPERM; -+ } - err = security_sb_remount(sb, data); - if (err) - return err; diff --git a/debian/patches/bugfix/all/mnt-Only-change-user-settable-mount-flags-in-remount.patch b/debian/patches/bugfix/all/mnt-Only-change-user-settable-mount-flags-in-remount.patch deleted file mode 100644 index 87489f5c2..000000000 --- a/debian/patches/bugfix/all/mnt-Only-change-user-settable-mount-flags-in-remount.patch +++ /dev/null @@ -1,48 +0,0 @@ -From: "Eric W. Biederman" -Date: Mon, 28 Jul 2014 16:26:53 -0700 -Subject: [1/5] mnt: Only change user settable mount flags in remount -Origin: https://git.kernel.org/linus/a6138db815df5ee542d848318e5dae681590fccd - -Kenton Varda discovered that by remounting a -read-only bind mount read-only in a user namespace the -MNT_LOCK_READONLY bit would be cleared, allowing an unprivileged user -to the remount a read-only mount read-write. - -Correct this by replacing the mask of mount flags to preserve -with a mask of mount flags that may be changed, and preserve -all others. This ensures that any future bugs with this mask and -remount will fail in an easy to detect way where new mount flags -simply won't change. - -Cc: stable@vger.kernel.org -Acked-by: Serge E. Hallyn -Signed-off-by: "Eric W. Biederman" ---- - fs/namespace.c | 2 +- - include/linux/mount.h | 4 +++- - 2 files changed, 4 insertions(+), 2 deletions(-) - ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -1939,7 +1939,7 @@ static int do_remount(struct path *path, - err = do_remount_sb(sb, flags, data, 0); - if (!err) { - lock_mount_hash(); -- mnt_flags |= mnt->mnt.mnt_flags & MNT_PROPAGATION_MASK; -+ mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK; - mnt->mnt.mnt_flags = mnt_flags; - touch_mnt_namespace(mnt->mnt_ns); - unlock_mount_hash(); ---- a/include/linux/mount.h -+++ b/include/linux/mount.h -@@ -42,7 +42,9 @@ struct mnt_namespace; - * flag, consider how it interacts with shared mounts. - */ - #define MNT_SHARED_MASK (MNT_UNBINDABLE) --#define MNT_PROPAGATION_MASK (MNT_SHARED | MNT_UNBINDABLE) -+#define MNT_USER_SETTABLE_MASK (MNT_NOSUID | MNT_NODEV | MNT_NOEXEC \ -+ | MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME \ -+ | MNT_READONLY) - - #define MNT_INTERNAL_FLAGS (MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL | \ - MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED) diff --git a/debian/patches/bugfix/all/reiserfs-Fix-use-after-free-in-journal-teardown.patch b/debian/patches/bugfix/all/reiserfs-Fix-use-after-free-in-journal-teardown.patch deleted file mode 100644 index c5713b093..000000000 --- a/debian/patches/bugfix/all/reiserfs-Fix-use-after-free-in-journal-teardown.patch +++ /dev/null @@ -1,86 +0,0 @@ -From: Jan Kara -Date: Wed, 6 Aug 2014 19:43:56 +0200 -Subject: [2/2] reiserfs: Fix use after free in journal teardown -Origin: https://git.kernel.org/linus/01777836c87081e4f68c4a43c9abe6114805f91e - -If do_journal_release() races with do_journal_end() which requeues -delayed works for transaction flushing, we can leave work items for -flushing outstanding transactions queued while freeing them. That -results in use after free and possible crash in run_timers_softirq(). - -Fix the problem by not requeueing works if superblock is being shut down -(MS_ACTIVE not set) and using cancel_delayed_work_sync() in -do_journal_release(). - -CC: stable@vger.kernel.org -Signed-off-by: Jan Kara ---- - fs/reiserfs/journal.c | 22 ++++++++++++++++------ - fs/reiserfs/super.c | 6 +++++- - 2 files changed, 21 insertions(+), 7 deletions(-) - -diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c -index e8870de..a88b1b3 100644 ---- a/fs/reiserfs/journal.c -+++ b/fs/reiserfs/journal.c -@@ -1947,8 +1947,6 @@ static int do_journal_release(struct reiserfs_transaction_handle *th, - } - } - -- /* wait for all commits to finish */ -- cancel_delayed_work(&SB_JOURNAL(sb)->j_work); - - /* - * We must release the write lock here because -@@ -1956,8 +1954,14 @@ static int do_journal_release(struct reiserfs_transaction_handle *th, - */ - reiserfs_write_unlock(sb); - -+ /* -+ * Cancel flushing of old commits. Note that neither of these works -+ * will be requeued because superblock is being shutdown and doesn't -+ * have MS_ACTIVE set. -+ */ - cancel_delayed_work_sync(&REISERFS_SB(sb)->old_work); -- flush_workqueue(REISERFS_SB(sb)->commit_wq); -+ /* wait for all commits to finish */ -+ cancel_delayed_work_sync(&SB_JOURNAL(sb)->j_work); - - free_journal_ram(sb); - -@@ -4292,9 +4296,15 @@ static int do_journal_end(struct reiserfs_transaction_handle *th, int flags) - if (flush) { - flush_commit_list(sb, jl, 1); - flush_journal_list(sb, jl, 1); -- } else if (!(jl->j_state & LIST_COMMIT_PENDING)) -- queue_delayed_work(REISERFS_SB(sb)->commit_wq, -- &journal->j_work, HZ / 10); -+ } else if (!(jl->j_state & LIST_COMMIT_PENDING)) { -+ /* -+ * Avoid queueing work when sb is being shut down. Transaction -+ * will be flushed on journal shutdown. -+ */ -+ if (sb->s_flags & MS_ACTIVE) -+ queue_delayed_work(REISERFS_SB(sb)->commit_wq, -+ &journal->j_work, HZ / 10); -+ } - - /* - * if the next transaction has any chance of wrapping, flush -diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c -index a392cef..5fd8f57 100644 ---- a/fs/reiserfs/super.c -+++ b/fs/reiserfs/super.c -@@ -100,7 +100,11 @@ void reiserfs_schedule_old_flush(struct super_block *s) - struct reiserfs_sb_info *sbi = REISERFS_SB(s); - unsigned long delay; - -- if (s->s_flags & MS_RDONLY) -+ /* -+ * Avoid scheduling flush when sb is being shut down. It can race -+ * with journal shutdown and free still queued delayed work. -+ */ -+ if (s->s_flags & MS_RDONLY || !(s->s_flags & MS_ACTIVE)) - return; - - spin_lock(&sbi->old_work_lock); diff --git a/debian/patches/bugfix/all/reiserfs-fix-corruption-introduced-by-balance_leaf-r.patch b/debian/patches/bugfix/all/reiserfs-fix-corruption-introduced-by-balance_leaf-r.patch deleted file mode 100644 index e2b667a52..000000000 --- a/debian/patches/bugfix/all/reiserfs-fix-corruption-introduced-by-balance_leaf-r.patch +++ /dev/null @@ -1,383 +0,0 @@ -From: Jeff Mahoney -Date: Mon, 4 Aug 2014 19:51:47 -0400 -Subject: [1/2] reiserfs: fix corruption introduced by balance_leaf refactor -Origin: https://git.kernel.org/linus/27d0e5bc85f3341b9ba66f0c23627cf9d7538c9d - -Commits f1f007c308e (reiserfs: balance_leaf refactor, pull out -balance_leaf_insert_left) and cf22df182bf (reiserfs: balance_leaf -refactor, pull out balance_leaf_paste_left) missed that the `body' -pointer was getting repositioned. Subsequent users of the pointer -would expect it to be repositioned, and as a result, parts of the -tree would get overwritten. The most common observed corruption -is indirect block pointers being overwritten. - -Since the body value isn't actually used anymore in the called routines, -we can pass back the offset it should be shifted. We constify the body -and ih pointers in the balance_leaf as a mostly-free preventative measure. - -Cc: # 3.16 -Reported-and-tested-by: Jeff Chua -Signed-off-by: Jeff Mahoney -Signed-off-by: Jan Kara ---- - fs/reiserfs/do_balan.c | 111 ++++++++++++++++++++++++++++--------------------- - fs/reiserfs/lbalance.c | 5 ++- - fs/reiserfs/reiserfs.h | 9 ++-- - 3 files changed, 71 insertions(+), 54 deletions(-) - -diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c -index 54fdf19..4d5e529 100644 ---- a/fs/reiserfs/do_balan.c -+++ b/fs/reiserfs/do_balan.c -@@ -286,12 +286,14 @@ static int balance_leaf_when_delete(struct tree_balance *tb, int flag) - return 0; - } - --static void balance_leaf_insert_left(struct tree_balance *tb, -- struct item_head *ih, const char *body) -+static unsigned int balance_leaf_insert_left(struct tree_balance *tb, -+ struct item_head *const ih, -+ const char * const body) - { - int ret; - struct buffer_info bi; - int n = B_NR_ITEMS(tb->L[0]); -+ unsigned body_shift_bytes = 0; - - if (tb->item_pos == tb->lnum[0] - 1 && tb->lbytes != -1) { - /* part of new item falls into L[0] */ -@@ -329,7 +331,7 @@ static void balance_leaf_insert_left(struct tree_balance *tb, - - put_ih_item_len(ih, new_item_len); - if (tb->lbytes > tb->zeroes_num) { -- body += (tb->lbytes - tb->zeroes_num); -+ body_shift_bytes = tb->lbytes - tb->zeroes_num; - tb->zeroes_num = 0; - } else - tb->zeroes_num -= tb->lbytes; -@@ -349,11 +351,12 @@ static void balance_leaf_insert_left(struct tree_balance *tb, - tb->insert_size[0] = 0; - tb->zeroes_num = 0; - } -+ return body_shift_bytes; - } - - static void balance_leaf_paste_left_shift_dirent(struct tree_balance *tb, -- struct item_head *ih, -- const char *body) -+ struct item_head * const ih, -+ const char * const body) - { - int n = B_NR_ITEMS(tb->L[0]); - struct buffer_info bi; -@@ -413,17 +416,18 @@ static void balance_leaf_paste_left_shift_dirent(struct tree_balance *tb, - tb->pos_in_item -= tb->lbytes; - } - --static void balance_leaf_paste_left_shift(struct tree_balance *tb, -- struct item_head *ih, -- const char *body) -+static unsigned int balance_leaf_paste_left_shift(struct tree_balance *tb, -+ struct item_head * const ih, -+ const char * const body) - { - struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); - int n = B_NR_ITEMS(tb->L[0]); - struct buffer_info bi; -+ int body_shift_bytes = 0; - - if (is_direntry_le_ih(item_head(tbS0, tb->item_pos))) { - balance_leaf_paste_left_shift_dirent(tb, ih, body); -- return; -+ return 0; - } - - RFALSE(tb->lbytes <= 0, -@@ -497,7 +501,7 @@ static void balance_leaf_paste_left_shift(struct tree_balance *tb, - * insert_size[0] - */ - if (l_n > tb->zeroes_num) { -- body += (l_n - tb->zeroes_num); -+ body_shift_bytes = l_n - tb->zeroes_num; - tb->zeroes_num = 0; - } else - tb->zeroes_num -= l_n; -@@ -526,13 +530,14 @@ static void balance_leaf_paste_left_shift(struct tree_balance *tb, - */ - leaf_shift_left(tb, tb->lnum[0], tb->lbytes); - } -+ return body_shift_bytes; - } - - - /* appended item will be in L[0] in whole */ - static void balance_leaf_paste_left_whole(struct tree_balance *tb, -- struct item_head *ih, -- const char *body) -+ struct item_head * const ih, -+ const char * const body) - { - struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); - int n = B_NR_ITEMS(tb->L[0]); -@@ -584,39 +589,44 @@ static void balance_leaf_paste_left_whole(struct tree_balance *tb, - tb->zeroes_num = 0; - } - --static void balance_leaf_paste_left(struct tree_balance *tb, -- struct item_head *ih, const char *body) -+static unsigned int balance_leaf_paste_left(struct tree_balance *tb, -+ struct item_head * const ih, -+ const char * const body) - { - /* we must shift the part of the appended item */ - if (tb->item_pos == tb->lnum[0] - 1 && tb->lbytes != -1) -- balance_leaf_paste_left_shift(tb, ih, body); -+ return balance_leaf_paste_left_shift(tb, ih, body); - else - balance_leaf_paste_left_whole(tb, ih, body); -+ return 0; - } - - /* Shift lnum[0] items from S[0] to the left neighbor L[0] */ --static void balance_leaf_left(struct tree_balance *tb, struct item_head *ih, -- const char *body, int flag) -+static unsigned int balance_leaf_left(struct tree_balance *tb, -+ struct item_head * const ih, -+ const char * const body, int flag) - { - if (tb->lnum[0] <= 0) -- return; -+ return 0; - - /* new item or it part falls to L[0], shift it too */ - if (tb->item_pos < tb->lnum[0]) { - BUG_ON(flag != M_INSERT && flag != M_PASTE); - - if (flag == M_INSERT) -- balance_leaf_insert_left(tb, ih, body); -+ return balance_leaf_insert_left(tb, ih, body); - else /* M_PASTE */ -- balance_leaf_paste_left(tb, ih, body); -+ return balance_leaf_paste_left(tb, ih, body); - } else - /* new item doesn't fall into L[0] */ - leaf_shift_left(tb, tb->lnum[0], tb->lbytes); -+ return 0; - } - - - static void balance_leaf_insert_right(struct tree_balance *tb, -- struct item_head *ih, const char *body) -+ struct item_head * const ih, -+ const char * const body) - { - - struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); -@@ -704,7 +714,8 @@ static void balance_leaf_insert_right(struct tree_balance *tb, - - - static void balance_leaf_paste_right_shift_dirent(struct tree_balance *tb, -- struct item_head *ih, const char *body) -+ struct item_head * const ih, -+ const char * const body) - { - struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); - struct buffer_info bi; -@@ -754,7 +765,8 @@ static void balance_leaf_paste_right_shift_dirent(struct tree_balance *tb, - } - - static void balance_leaf_paste_right_shift(struct tree_balance *tb, -- struct item_head *ih, const char *body) -+ struct item_head * const ih, -+ const char * const body) - { - struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); - int n_shift, n_rem, r_zeroes_number, version; -@@ -831,7 +843,8 @@ static void balance_leaf_paste_right_shift(struct tree_balance *tb, - } - - static void balance_leaf_paste_right_whole(struct tree_balance *tb, -- struct item_head *ih, const char *body) -+ struct item_head * const ih, -+ const char * const body) - { - struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); - int n = B_NR_ITEMS(tbS0); -@@ -874,7 +887,8 @@ static void balance_leaf_paste_right_whole(struct tree_balance *tb, - } - - static void balance_leaf_paste_right(struct tree_balance *tb, -- struct item_head *ih, const char *body) -+ struct item_head * const ih, -+ const char * const body) - { - struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); - int n = B_NR_ITEMS(tbS0); -@@ -896,8 +910,9 @@ static void balance_leaf_paste_right(struct tree_balance *tb, - } - - /* shift rnum[0] items from S[0] to the right neighbor R[0] */ --static void balance_leaf_right(struct tree_balance *tb, struct item_head *ih, -- const char *body, int flag) -+static void balance_leaf_right(struct tree_balance *tb, -+ struct item_head * const ih, -+ const char * const body, int flag) - { - if (tb->rnum[0] <= 0) - return; -@@ -911,8 +926,8 @@ static void balance_leaf_right(struct tree_balance *tb, struct item_head *ih, - } - - static void balance_leaf_new_nodes_insert(struct tree_balance *tb, -- struct item_head *ih, -- const char *body, -+ struct item_head * const ih, -+ const char * const body, - struct item_head *insert_key, - struct buffer_head **insert_ptr, - int i) -@@ -1003,8 +1018,8 @@ static void balance_leaf_new_nodes_insert(struct tree_balance *tb, - - /* we append to directory item */ - static void balance_leaf_new_nodes_paste_dirent(struct tree_balance *tb, -- struct item_head *ih, -- const char *body, -+ struct item_head * const ih, -+ const char * const body, - struct item_head *insert_key, - struct buffer_head **insert_ptr, - int i) -@@ -1058,8 +1073,8 @@ static void balance_leaf_new_nodes_paste_dirent(struct tree_balance *tb, - } - - static void balance_leaf_new_nodes_paste_shift(struct tree_balance *tb, -- struct item_head *ih, -- const char *body, -+ struct item_head * const ih, -+ const char * const body, - struct item_head *insert_key, - struct buffer_head **insert_ptr, - int i) -@@ -1131,8 +1146,8 @@ static void balance_leaf_new_nodes_paste_shift(struct tree_balance *tb, - } - - static void balance_leaf_new_nodes_paste_whole(struct tree_balance *tb, -- struct item_head *ih, -- const char *body, -+ struct item_head * const ih, -+ const char * const body, - struct item_head *insert_key, - struct buffer_head **insert_ptr, - int i) -@@ -1184,8 +1199,8 @@ static void balance_leaf_new_nodes_paste_whole(struct tree_balance *tb, - - } - static void balance_leaf_new_nodes_paste(struct tree_balance *tb, -- struct item_head *ih, -- const char *body, -+ struct item_head * const ih, -+ const char * const body, - struct item_head *insert_key, - struct buffer_head **insert_ptr, - int i) -@@ -1214,8 +1229,8 @@ static void balance_leaf_new_nodes_paste(struct tree_balance *tb, - - /* Fill new nodes that appear in place of S[0] */ - static void balance_leaf_new_nodes(struct tree_balance *tb, -- struct item_head *ih, -- const char *body, -+ struct item_head * const ih, -+ const char * const body, - struct item_head *insert_key, - struct buffer_head **insert_ptr, - int flag) -@@ -1254,8 +1269,8 @@ static void balance_leaf_new_nodes(struct tree_balance *tb, - } - - static void balance_leaf_finish_node_insert(struct tree_balance *tb, -- struct item_head *ih, -- const char *body) -+ struct item_head * const ih, -+ const char * const body) - { - struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); - struct buffer_info bi; -@@ -1271,8 +1286,8 @@ static void balance_leaf_finish_node_insert(struct tree_balance *tb, - } - - static void balance_leaf_finish_node_paste_dirent(struct tree_balance *tb, -- struct item_head *ih, -- const char *body) -+ struct item_head * const ih, -+ const char * const body) - { - struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); - struct item_head *pasted = item_head(tbS0, tb->item_pos); -@@ -1305,8 +1320,8 @@ static void balance_leaf_finish_node_paste_dirent(struct tree_balance *tb, - } - - static void balance_leaf_finish_node_paste(struct tree_balance *tb, -- struct item_head *ih, -- const char *body) -+ struct item_head * const ih, -+ const char * const body) - { - struct buffer_head *tbS0 = PATH_PLAST_BUFFER(tb->tb_path); - struct buffer_info bi; -@@ -1349,8 +1364,8 @@ static void balance_leaf_finish_node_paste(struct tree_balance *tb, - * of the affected item which remains in S - */ - static void balance_leaf_finish_node(struct tree_balance *tb, -- struct item_head *ih, -- const char *body, int flag) -+ struct item_head * const ih, -+ const char * const body, int flag) - { - /* if we must insert or append into buffer S[0] */ - if (0 <= tb->item_pos && tb->item_pos < tb->s0num) { -@@ -1402,7 +1417,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih, - && is_indirect_le_ih(item_head(tbS0, tb->item_pos))) - tb->pos_in_item *= UNFM_P_SIZE; - -- balance_leaf_left(tb, ih, body, flag); -+ body += balance_leaf_left(tb, ih, body, flag); - - /* tb->lnum[0] > 0 */ - /* Calculate new item position */ -diff --git a/fs/reiserfs/lbalance.c b/fs/reiserfs/lbalance.c -index d6744c8..3a74d15 100644 ---- a/fs/reiserfs/lbalance.c -+++ b/fs/reiserfs/lbalance.c -@@ -899,8 +899,9 @@ void leaf_delete_items(struct buffer_info *cur_bi, int last_first, - - /* insert item into the leaf node in position before */ - void leaf_insert_into_buf(struct buffer_info *bi, int before, -- struct item_head *inserted_item_ih, -- const char *inserted_item_body, int zeros_number) -+ struct item_head * const inserted_item_ih, -+ const char * const inserted_item_body, -+ int zeros_number) - { - struct buffer_head *bh = bi->bi_bh; - int nr, free_space; -diff --git a/fs/reiserfs/reiserfs.h b/fs/reiserfs/reiserfs.h -index bf53888..735c2c2 100644 ---- a/fs/reiserfs/reiserfs.h -+++ b/fs/reiserfs/reiserfs.h -@@ -3216,11 +3216,12 @@ int leaf_shift_right(struct tree_balance *tb, int shift_num, int shift_bytes); - void leaf_delete_items(struct buffer_info *cur_bi, int last_first, int first, - int del_num, int del_bytes); - void leaf_insert_into_buf(struct buffer_info *bi, int before, -- struct item_head *inserted_item_ih, -- const char *inserted_item_body, int zeros_number); --void leaf_paste_in_buffer(struct buffer_info *bi, int pasted_item_num, -- int pos_in_item, int paste_size, const char *body, -+ struct item_head * const inserted_item_ih, -+ const char * const inserted_item_body, - int zeros_number); -+void leaf_paste_in_buffer(struct buffer_info *bi, int pasted_item_num, -+ int pos_in_item, int paste_size, -+ const char * const body, int zeros_number); - void leaf_cut_from_buffer(struct buffer_info *bi, int cut_item_num, - int pos_in_item, int cut_size); - void leaf_paste_entries(struct buffer_info *bi, int item_num, int before, diff --git a/debian/patches/bugfix/mips/MIPS-O32-32-bit-Fix-bug-which-can-cause-incorrect-sy.patch b/debian/patches/bugfix/mips/MIPS-O32-32-bit-Fix-bug-which-can-cause-incorrect-sy.patch deleted file mode 100644 index 330613f1b..000000000 --- a/debian/patches/bugfix/mips/MIPS-O32-32-bit-Fix-bug-which-can-cause-incorrect-sy.patch +++ /dev/null @@ -1,61 +0,0 @@ -From: Alex Smith -Date: Wed, 23 Jul 2014 14:40:11 +0100 -Subject: MIPS: O32/32-bit: Fix bug which can cause incorrect system - call restarts -Origin: https://git.kernel.org/linus/e90e6fddc57055c4c6b57f92787fea1c065d440b - -On 32-bit/O32, pt_regs has a padding area at the beginning into which the -syscall arguments passed via the user stack are copied. 4 arguments -totalling 16 bytes are copied to offset 16 bytes into this area, however -the area is only 24 bytes long. This means the last 2 arguments overwrite -pt_regs->regs[{0,1}]. - -If a syscall function returns an error, handle_sys stores the original -syscall number in pt_regs->regs[0] for syscall restart. signal.c checks -whether regs[0] is non-zero, if it is it will check whether the syscall -return value is one of the ERESTART* codes to see if it must be -restarted. - -Should a syscall be made that results in a non-zero value being copied -off the user stack into regs[0], and then returns a positive (non-error) -value that matches one of the ERESTART* error codes, this can be mistaken -for requiring a syscall restart. - -While the possibility for this to occur has always existed, it is made -much more likely to occur by commit 46e12c07b3b9 ("MIPS: O32 / 32-bit: -Always copy 4 stack arguments."), since now every syscall will copy 4 -arguments and overwrite regs[0], rather than just those with 7 or 8 -arguments. - -Since that commit, booting Debian under a 32-bit MIPS kernel almost -always results in a hang early in boot, due to a wait4 syscall returning -a PID that matches one of the ERESTART* codes, which then causes an -incorrect restart of the syscall. - -The problem is fixed by increasing the size of the padding area so that -arguments copied off the stack will not overwrite pt_regs->regs[{0,1}]. - -Signed-off-by: Alex Smith -Cc: # v3.13+ -Tested-by: Aurelien Jarno -Reviewed-by: Aurelien Jarno ---- - arch/mips/include/asm/ptrace.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h -index 7e6e682..c301fa9 100644 ---- a/arch/mips/include/asm/ptrace.h -+++ b/arch/mips/include/asm/ptrace.h -@@ -23,7 +23,7 @@ - struct pt_regs { - #ifdef CONFIG_32BIT - /* Pad bytes for argument save space on the stack. */ -- unsigned long pad0[6]; -+ unsigned long pad0[8]; - #endif - - /* Saved main processor registers. */ --- -1.7.10.4 - diff --git a/debian/patches/bugfix/mips/MIPS-OCTEON-make-get_system_type-thread-safe.patch b/debian/patches/bugfix/mips/MIPS-OCTEON-make-get_system_type-thread-safe.patch deleted file mode 100644 index ae6514660..000000000 --- a/debian/patches/bugfix/mips/MIPS-OCTEON-make-get_system_type-thread-safe.patch +++ /dev/null @@ -1,66 +0,0 @@ -From: Aaro Koskinen -Date: Tue, 22 Jul 2014 14:51:08 +0300 -Subject: MIPS: OCTEON: make get_system_type() thread-safe -Origin: https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/commit/?id=726d129dfdc9622197a8c3f5947ce09c1a4c935e - -get_system_type() is not thread-safe on OCTEON. It uses static data, -also more dangerous issue is that it's calling cvmx_fuse_read_byte() -every time without any synchronization. Currently it's possible to get -processes stuck looping forever in kernel simply by launching multiple -readers of /proc/cpuinfo: - - (while true; do cat /proc/cpuinfo > /dev/null; done) & - (while true; do cat /proc/cpuinfo > /dev/null; done) & - ... - -Fix by initializing the system type string only once during the early -boot. - -Signed-off-by: Aaro Koskinen -Cc: stable@vger.kernel.org -Reviewed-by: Markos Chandras -Patchwork: http://patchwork.linux-mips.org/patch/7437/ -Signed-off-by: James Hogan ---- - arch/mips/cavium-octeon/setup.c | 18 +++++++++++++----- - 1 file changed, 13 insertions(+), 5 deletions(-) - -diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c -index 008e9c8..c9d9c62 100644 ---- a/arch/mips/cavium-octeon/setup.c -+++ b/arch/mips/cavium-octeon/setup.c -@@ -458,6 +458,18 @@ static void octeon_halt(void) - octeon_kill_core(NULL); - } - -+static char __read_mostly octeon_system_type[80]; -+ -+static int __init init_octeon_system_type(void) -+{ -+ snprintf(octeon_system_type, sizeof(octeon_system_type), "%s (%s)", -+ cvmx_board_type_to_string(octeon_bootinfo->board_type), -+ octeon_model_get_string(read_c0_prid())); -+ -+ return 0; -+} -+early_initcall(init_octeon_system_type); -+ - /** - * Return a string representing the system type - * -@@ -465,11 +477,7 @@ static void octeon_halt(void) - */ - const char *octeon_board_type_string(void) - { -- static char name[80]; -- sprintf(name, "%s (%s)", -- cvmx_board_type_to_string(octeon_bootinfo->board_type), -- octeon_model_get_string(read_c0_prid())); -- return name; -+ return octeon_system_type; - } - - const char *get_system_type(void) --- -1.7.10.4 - diff --git a/debian/patches/bugfix/mips/MIPS-Remove-BUG_ON-is_fpu_owner-in-do_ade.patch b/debian/patches/bugfix/mips/MIPS-Remove-BUG_ON-is_fpu_owner-in-do_ade.patch deleted file mode 100644 index fbb0a3e0b..000000000 --- a/debian/patches/bugfix/mips/MIPS-Remove-BUG_ON-is_fpu_owner-in-do_ade.patch +++ /dev/null @@ -1,63 +0,0 @@ -From: Huacai Chen -Date: Wed, 16 Jul 2014 09:19:16 +0800 -Subject: MIPS: Remove BUG_ON(!is_fpu_owner()) in do_ade() -Origin: https://git.kernel.org/linus/2e5767a27337812f6850b3fa362419e2f085e5c3 - -In do_ade(), is_fpu_owner() isn't preempt-safe. For example, when an -unaligned ldc1 is executed, do_cpu() is called and then FPU will be -enabled (and TIF_USEDFPU will be set for the current process). Then, -do_ade() is called because the access is unaligned. If the current -process is preempted at this time, TIF_USEDFPU will be cleard. So when -the process is scheduled again, BUG_ON(!is_fpu_owner()) is triggered. - -This small program can trigger this BUG in a preemptible kernel: - -int main (int argc, char *argv[]) -{ - double u64[2]; - - while (1) { - asm volatile ( - ".set push \n\t" - ".set noreorder \n\t" - "ldc1 $f3, 4(%0) \n\t" - ".set pop \n\t" - ::"r"(u64): - ); - } - - return 0; -} - -V2: Remove the BUG_ON() unconditionally due to Paul's suggestion. - -Signed-off-by: Huacai Chen -Signed-off-by: Jie Chen -Signed-off-by: Rui Wang -Cc: -Cc: John Crispin -Cc: Steven J. Hill -Cc: linux-mips@linux-mips.org -Cc: Fuxin Zhang -Cc: Zhangjin Wu -Cc: stable@vger.kernel.org -Signed-off-by: Ralf Baechle ---- - arch/mips/kernel/unaligned.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c -index 2b35172..e11906d 100644 ---- a/arch/mips/kernel/unaligned.c -+++ b/arch/mips/kernel/unaligned.c -@@ -690,7 +690,6 @@ static void emulate_load_store_insn(struct pt_regs *regs, - case sdc1_op: - die_if_kernel("Unaligned FP access in kernel code", regs); - BUG_ON(!used_math()); -- BUG_ON(!is_fpu_owner()); - - lose_fpu(1); /* Save FPU state for the emulator. */ - res = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1, --- -1.7.10.4 - diff --git a/debian/patches/bugfix/mips/MIPS-prevent-user-from-setting-FCSR-cause-bits.patch b/debian/patches/bugfix/mips/MIPS-prevent-user-from-setting-FCSR-cause-bits.patch deleted file mode 100644 index bcff7aaa3..000000000 --- a/debian/patches/bugfix/mips/MIPS-prevent-user-from-setting-FCSR-cause-bits.patch +++ /dev/null @@ -1,50 +0,0 @@ -From: Paul Burton -Date: Tue, 22 Jul 2014 14:21:21 +0100 -Subject: MIPS: prevent user from setting FCSR cause bits -Origin: https://git.kernel.org/linus/b1442d39fac2fcfbe6a4814979020e993ca59c9e - -If one or more matching FCSR cause & enable bits are set in saved thread -context then when that context is restored the kernel will take an FP -exception. This is of course undesirable and considered an oops, leading -to the kernel writing a backtrace to the console and potentially -rebooting depending upon the configuration. Thus the kernel avoids this -situation by clearing the cause bits of the FCSR register when handling -FP exceptions and after emulating FP instructions. - -However the kernel does not prevent userland from setting arbitrary FCSR -cause & enable bits via ptrace, using either the PTRACE_POKEUSR or -PTRACE_SETFPREGS requests. This means userland can trivially cause the -kernel to oops on any system with an FPU. Prevent this from happening -by clearing the cause bits when writing to the saved FCSR context via -ptrace. - -This problem appears to exist at least back to the beginning of the git -era in the PTRACE_POKEUSR case. - -Signed-off-by: Paul Burton -Cc: stable@vger.kernel.org -Patchwork: http://patchwork.linux-mips.org/patch/7438/ -Signed-off-by: James Hogan ---- - arch/mips/kernel/ptrace.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/arch/mips/kernel/ptrace.c -+++ b/arch/mips/kernel/ptrace.c -@@ -151,6 +151,7 @@ int ptrace_setfpregs(struct task_struct - } - - __get_user(child->thread.fpu.fcr31, data + 64); -+ child->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X; - - /* FIR may not be written. */ - -@@ -565,7 +566,7 @@ long arch_ptrace(struct task_struct *chi - break; - #endif - case FPC_CSR: -- child->thread.fpu.fcr31 = data; -+ child->thread.fpu.fcr31 = data & ~FPU_CSR_ALL_X; - break; - case DSP_BASE ... DSP_BASE + 5: { - dspreg_t *dregs; diff --git a/debian/patches/bugfix/mips/MIPS-tlbex-fix-a-missing-statement-for-HUGETLB.patch b/debian/patches/bugfix/mips/MIPS-tlbex-fix-a-missing-statement-for-HUGETLB.patch deleted file mode 100644 index c9225b6c1..000000000 --- a/debian/patches/bugfix/mips/MIPS-tlbex-fix-a-missing-statement-for-HUGETLB.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: Huacai Chen -Date: Tue, 29 Jul 2014 14:54:40 +0800 -Subject: MIPS: tlbex: fix a missing statement for HUGETLB -Origin: https://git.kernel.org/linus/8393c524a25609a30129e4a8975cf3b91f6c16a5 - -In commit 2c8c53e28f1 (MIPS: Optimize TLB handlers for Octeon CPUs) -build_r4000_tlb_refill_handler() is modified. But it doesn't compatible -with the original code in HUGETLB case. Because there is a copy & paste -error and one line of code is missing. It is very easy to produce a bug -with LTP's hugemmap05 test. - -Signed-off-by: Huacai Chen -Signed-off-by: Binbin Zhou -Cc: -Tested-by: Aurelien Jarno -Reviewed-by: Aurelien Jarno ---- - arch/mips/mm/tlbex.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c -index e80e10b..343fe0f 100644 ---- a/arch/mips/mm/tlbex.c -+++ b/arch/mips/mm/tlbex.c -@@ -1299,6 +1299,7 @@ static void build_r4000_tlb_refill_handler(void) - } - #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT - uasm_l_tlb_huge_update(&l, p); -+ UASM_i_LW(&p, K0, 0, K1); - build_huge_update_entries(&p, htlb_info.huge_pte, K1); - build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random, - htlb_info.restore_scratch); --- -1.7.10.4 - diff --git a/debian/patches/series b/debian/patches/series index b09855200..a17d4ae36 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -52,11 +52,6 @@ bugfix/mips/disable-advansys.patch bugfix/arm/ixp4xx_iobe.patch bugfix/m68k/ethernat-kconfig.patch bugfix/mips/MIPS-ZBOOT-add-missing-linux-string.h-include.patch -bugfix/mips/MIPS-OCTEON-make-get_system_type-thread-safe.patch -bugfix/mips/MIPS-O32-32-bit-Fix-bug-which-can-cause-incorrect-sy.patch -bugfix/mips/MIPS-tlbex-fix-a-missing-statement-for-HUGETLB.patch -bugfix/mips/MIPS-prevent-user-from-setting-FCSR-cause-bits.patch -bugfix/mips/MIPS-Remove-BUG_ON-is_fpu_owner-in-do_ade.patch bugfix/x86/x86-reject-x32-executables-if-x32-abi-not-supported.patch bugfix/s390/s390-3215-fix-hanging-console-issue.patch bugfix/arm64/arm64-crypto-fix-makefile-rule-for-aes-glue-.o.patch @@ -110,21 +105,9 @@ bugfix/all/misc-bmp085-Enable-building-as-a-module.patch bugfix/all/kbuild-use-nostdinc-in-compile-tests.patch bugfix/all/disable-some-marvell-phys.patch bugfix/all/aio-fix-reqs_available-handling.patch -bugfix/all/mnt-Only-change-user-settable-mount-flags-in-remount.patch -bugfix/all/mnt-Move-the-test-for-MNT_LOCK_READONLY-from-change_.patch -bugfix/all/mnt-Correct-permission-checks-in-do_remount.patch -bugfix/all/mnt-Change-the-default-remount-atime-from-relatime-t.patch -bugfix/all/mnt-Add-tests-for-unprivileged-remount-cases-that-ha.patch debian/i2o-disable-i2o_ext_adaptec-on-64bit.patch bugfix/all/aic94xx-remove-broken-fallback-for-missing-ctrl-a.patch bugfix/all/builddeb-put-the-dbg-files-into-the-correct-director.patch -bugfix/all/libceph-set-last_piece-in-ceph_msg_data_pages_cursor.patch -bugfix/all/libceph-gracefully-handle-large-reply-messages-from-.patch -bugfix/all/libceph-add-process_one_ticket-helper.patch -bugfix/all/libceph-do-not-hard-code-max-auth-ticket-len.patch -bugfix/all/drivers-mfd-rtsx_usb.c-export-device-table.patch -bugfix/all/reiserfs-fix-corruption-introduced-by-balance_leaf-r.patch -bugfix/all/reiserfs-Fix-use-after-free-in-journal-teardown.patch # memfd_create() & kdbus backport features/all/kdbus/mm-allow-drivers-to-prevent-new-writable-mappings.patch