diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 10:06:00 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 10:06:00 +0000 |
commit | b15a952c52a6825376d3e7f6c1bf5c886c6d8b74 (patch) | |
tree | 1500f2f8f276908a36d8126cb632c0d6b1276764 /debian/patches/features/all | |
parent | Adding upstream version 5.10.209. (diff) | |
download | linux-b15a952c52a6825376d3e7f6c1bf5c886c6d8b74.tar.xz linux-b15a952c52a6825376d3e7f6c1bf5c886c6d8b74.zip |
Adding debian version 5.10.209-2.debian/5.10.209-2debian
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
14 files changed, 2116 insertions, 0 deletions
diff --git a/debian/patches/features/all/aufs5/aufs5-base.patch b/debian/patches/features/all/aufs5/aufs5-base.patch new file mode 100644 index 000000000..60f24b56b --- /dev/null +++ b/debian/patches/features/all/aufs5/aufs5-base.patch @@ -0,0 +1,332 @@ +From: J. R. Okajima <hooanon05@yahoo.co.jp> +Date: Tue Apr 7 22:14:47 2020 +0900 +Subject: aufs5.6 base patch +Origin: https://github.com/sfjro/aufs5-standalone/tree/7c07d9737e9de058981f020d66ac0d4407a80899 +Bug-Debian: https://bugs.debian.org/541828 + +Patch headers added by debian/bin/genpatch-aufs + +SPDX-License-Identifier: GPL-2.0 +aufs5.6 base patch + +diff --git a/MAINTAINERS b/MAINTAINERS +index b4a43a9e7fbc..32f7c8c48001 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -2984,6 +2984,19 @@ F: include/linux/audit.h + F: include/uapi/linux/audit.h + F: kernel/audit* + ++AUFS (advanced multi layered unification filesystem) FILESYSTEM ++M: "J. R. Okajima" <hooanon05g@gmail.com> ++L: aufs-users@lists.sourceforge.net (members only) ++L: linux-unionfs@vger.kernel.org ++W: http://aufs.sourceforge.net ++T: git://github.com/sfjro/aufs4-linux.git ++S: Supported ++F: Documentation/filesystems/aufs/ ++F: Documentation/ABI/testing/debugfs-aufs ++F: Documentation/ABI/testing/sysfs-aufs ++F: fs/aufs/ ++F: include/uapi/linux/aufs_type.h ++ + AUXILIARY DISPLAY DRIVERS + M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com> + S: Maintained +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index 475e1a738560..8d77e68aa52b 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -763,6 +763,24 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, + return error; + } + ++/* ++ * for AUFS ++ * no get/put for file. ++ */ ++struct file *loop_backing_file(struct super_block *sb) ++{ ++ struct file *ret; ++ struct loop_device *l; ++ ++ ret = NULL; ++ if (MAJOR(sb->s_dev) == LOOP_MAJOR) { ++ l = sb->s_bdev->bd_disk->private_data; ++ ret = l->lo_backing_file; ++ } ++ return ret; ++} ++EXPORT_SYMBOL_GPL(loop_backing_file); ++ + /* loop sysfs attributes */ + + static ssize_t loop_attr_show(struct device *dev, char *page, +diff --git a/fs/dcache.c b/fs/dcache.c +index 361ea7ab30ea..3cd36474f302 100644 +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -1285,7 +1285,7 @@ enum d_walk_ret { + * + * The @enter() callbacks are called with d_lock held. + */ +-static void d_walk(struct dentry *parent, void *data, ++void d_walk(struct dentry *parent, void *data, + enum d_walk_ret (*enter)(void *, struct dentry *)) + { + struct dentry *this_parent; +diff --git a/fs/fcntl.c b/fs/fcntl.c +index 2e4c0fa2074b..0b28a37f7e50 100644 +--- a/fs/fcntl.c ++++ b/fs/fcntl.c +@@ -32,7 +32,7 @@ + + #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME) + +-static int setfl(int fd, struct file * filp, unsigned long arg) ++int setfl(int fd, struct file *filp, unsigned long arg) + { + struct inode * inode = file_inode(filp); + int error = 0; +@@ -63,6 +63,8 @@ static int setfl(int fd, struct file * filp, unsigned long arg) + + if (filp->f_op->check_flags) + error = filp->f_op->check_flags(arg); ++ if (!error && filp->f_op->setfl) ++ error = filp->f_op->setfl(filp, arg); + if (error) + return error; + +diff --git a/fs/inode.c b/fs/inode.c +index 72c4c347afb7..a7ff2099c2ef 100644 +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -1768,7 +1768,7 @@ EXPORT_SYMBOL(generic_update_time); + * This does the actual work of updating an inodes time or version. Must have + * had called mnt_want_write() before calling this. + */ +-static int update_time(struct inode *inode, struct timespec64 *time, int flags) ++int update_time(struct inode *inode, struct timespec64 *time, int flags) + { + if (inode->i_op->update_time) + return inode->i_op->update_time(inode, time, flags); +diff --git a/fs/namespace.c b/fs/namespace.c +index f30ed401cc6d..8ddebaf7ad57 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -792,6 +792,12 @@ static inline int check_mnt(struct mount *mnt) + return mnt->mnt_ns == current->nsproxy->mnt_ns; + } + ++/* for aufs, CONFIG_AUFS_BR_FUSE */ ++int is_current_mnt_ns(struct vfsmount *mnt) ++{ ++ return check_mnt(real_mount(mnt)); ++} ++ + /* + * vfsmount lock must be held for write + */ +diff --git a/fs/read_write.c b/fs/read_write.c +index 4fb797822567..744831cd0094 100644 +--- a/fs/read_write.c ++++ b/fs/read_write.c +@@ -507,6 +507,28 @@ static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t + return ret; + } + ++vfs_readf_t vfs_readf(struct file *file) ++{ ++ const struct file_operations *fop = file->f_op; ++ ++ if (fop->read) ++ return fop->read; ++ if (fop->read_iter) ++ return new_sync_read; ++ return ERR_PTR(-ENOSYS); /* doesn't have ->read(|_iter)() op */ ++} ++ ++vfs_writef_t vfs_writef(struct file *file) ++{ ++ const struct file_operations *fop = file->f_op; ++ ++ if (fop->write) ++ return fop->write; ++ if (fop->write_iter) ++ return new_sync_write; ++ return ERR_PTR(-ENOSYS); /* doesn't have ->write(|_iter)() op */ ++} ++ + /* caller is responsible for file_start_write/file_end_write */ + ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) + { +diff --git a/fs/splice.c b/fs/splice.c +index d7c8a7c4db07..f0b625e27554 100644 +--- a/fs/splice.c ++++ b/fs/splice.c +@@ -839,8 +839,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); + /* + * Attempt to initiate a splice from pipe to file. + */ +-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +- loff_t *ppos, size_t len, unsigned int flags) ++long do_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags) + { + if (out->f_op->splice_write) + return out->f_op->splice_write(pipe, out, ppos, len, flags); +@@ -850,9 +850,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, + /* + * Attempt to initiate a splice from a file to a pipe. + */ +-static long do_splice_to(struct file *in, loff_t *ppos, +- struct pipe_inode_info *pipe, size_t len, +- unsigned int flags) ++long do_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags) + { + int ret; + +diff --git a/fs/sync.c b/fs/sync.c +index 1373a610dc78..b7b5a0a0df6f 100644 +--- a/fs/sync.c ++++ b/fs/sync.c +@@ -28,7 +28,7 @@ + * wait == 1 case since in that case write_inode() functions do + * sync_dirty_buffer() and thus effectively write one block at a time. + */ +-static int __sync_filesystem(struct super_block *sb, int wait) ++int __sync_filesystem(struct super_block *sb, int wait) + { + if (wait) + sync_inodes_sb(sb); +diff --git a/include/linux/fs.h b/include/linux/fs.h +index f5abba86107d..0b008da5678d 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1360,6 +1360,7 @@ extern void fasync_free(struct fasync_struct *); + /* can be called from interrupts */ + extern void kill_fasync(struct fasync_struct **, int, int); + ++extern int setfl(int fd, struct file *filp, unsigned long arg); + extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force); + extern int f_setown(struct file *filp, unsigned long arg, int force); + extern void f_delown(struct file *filp); +@@ -1848,6 +1849,7 @@ struct file_operations { + ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); + unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); + int (*check_flags)(int); ++ int (*setfl)(struct file *, unsigned long); + int (*flock) (struct file *, int, struct file_lock *); + ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); + ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); +@@ -1918,6 +1920,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, + struct iovec *fast_pointer, + struct iovec **ret_pointer); + ++typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *); ++typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t, ++ loff_t *); ++vfs_readf_t vfs_readf(struct file *file); ++vfs_writef_t vfs_writef(struct file *file); ++ + extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); + extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); + extern ssize_t vfs_readv(struct file *, const struct iovec __user *, +@@ -2352,6 +2360,7 @@ extern int current_umask(void); + extern void ihold(struct inode * inode); + extern void iput(struct inode *); + extern int generic_update_time(struct inode *, struct timespec64 *, int); ++extern int update_time(struct inode *, struct timespec64 *, int); + + /* /sys/fs */ + extern struct kobject *fs_kobj; +@@ -2633,6 +2642,7 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb) + return false; + } + #endif ++extern int __sync_filesystem(struct super_block *, int); + extern int sync_filesystem(struct super_block *); + extern const struct file_operations def_blk_fops; + extern const struct file_operations def_chr_fops; +diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h +index 8fce5c98a4b0..c1a3f172e97a 100644 +--- a/include/linux/lockdep.h ++++ b/include/linux/lockdep.h +@@ -395,6 +395,8 @@ static inline int lockdep_match_key(struct lockdep_map *lock, + return lock->key == key; + } + ++struct lock_class *lockdep_hlock_class(struct held_lock *hlock); ++ + /* + * Acquire a lock. + * +@@ -540,6 +542,7 @@ struct lockdep_map { }; + + #define lockdep_depth(tsk) (0) + ++#define lockdep_is_held(lock) (1) + #define lockdep_is_held_type(l, r) (1) + + #define lockdep_assert_held(l) do { (void)(l); } while (0) +diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h +index 8f882f5881e8..6b9808f09843 100644 +--- a/include/linux/mnt_namespace.h ++++ b/include/linux/mnt_namespace.h +@@ -7,12 +7,15 @@ struct mnt_namespace; + struct fs_struct; + struct user_namespace; + struct ns_common; ++struct vfsmount; + + extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *, + struct user_namespace *, struct fs_struct *); + extern void put_mnt_ns(struct mnt_namespace *ns); + extern struct ns_common *from_mnt_ns(struct mnt_namespace *); + ++extern int is_current_mnt_ns(struct vfsmount *mnt); ++ + extern const struct file_operations proc_mounts_operations; + extern const struct file_operations proc_mountinfo_operations; + extern const struct file_operations proc_mountstats_operations; +diff --git a/include/linux/splice.h b/include/linux/splice.h +index 5c47013f708e..fef6c59ed92a 100644 +--- a/include/linux/splice.h ++++ b/include/linux/splice.h +@@ -93,4 +93,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *); + + extern const struct pipe_buf_operations page_cache_pipe_buf_ops; + extern const struct pipe_buf_operations default_pipe_buf_ops; ++ ++extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags); ++extern long do_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags); + #endif +diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c +index 29a8de4c50b9..6cfff5e18c84 100644 +--- a/kernel/locking/lockdep.c ++++ b/kernel/locking/lockdep.c +@@ -169,7 +169,7 @@ static + struct lock_class lock_classes[MAX_LOCKDEP_KEYS]; + static DECLARE_BITMAP(lock_classes_in_use, MAX_LOCKDEP_KEYS); + +-static inline struct lock_class *hlock_class(struct held_lock *hlock) ++inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock) + { + unsigned int class_idx = hlock->class_idx; + +@@ -190,6 +190,7 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock) + */ + return lock_classes + class_idx; + } ++#define hlock_class(hlock) lockdep_hlock_class(hlock) + + #ifdef CONFIG_LOCK_STAT + static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats); +-- +2.27.0 + diff --git a/debian/patches/features/all/aufs5/aufs5-mmap.patch b/debian/patches/features/all/aufs5/aufs5-mmap.patch new file mode 100644 index 000000000..4cf1e0b2b --- /dev/null +++ b/debian/patches/features/all/aufs5/aufs5-mmap.patch @@ -0,0 +1,405 @@ +From: J. R. Okajima <hooanon05@yahoo.co.jp> +Date: Tue Apr 7 22:14:47 2020 +0900 +Subject: aufs5.6 mmap patch +Origin: https://github.com/sfjro/aufs5-standalone/tree/7c07d9737e9de058981f020d66ac0d4407a80899 +Bug-Debian: https://bugs.debian.org/541828 + +Patch headers added by debian/bin/genpatch-aufs + +SPDX-License-Identifier: GPL-2.0 +aufs5.6 mmap patch + +Index: debian-kernel/fs/proc/base.c +=================================================================== +--- debian-kernel.orig/fs/proc/base.c ++++ debian-kernel/fs/proc/base.c +@@ -2170,7 +2170,7 @@ static int map_files_get_link(struct den + rc = -ENOENT; + vma = find_exact_vma(mm, vm_start, vm_end); + if (vma && vma->vm_file) { +- *path = vma->vm_file->f_path; ++ *path = vma_pr_or_file(vma)->f_path; + path_get(path); + rc = 0; + } +Index: debian-kernel/fs/proc/nommu.c +=================================================================== +--- debian-kernel.orig/fs/proc/nommu.c ++++ debian-kernel/fs/proc/nommu.c +@@ -40,7 +40,10 @@ static int nommu_region_show(struct seq_ + file = region->vm_file; + + if (file) { +- struct inode *inode = file_inode(region->vm_file); ++ struct inode *inode; ++ ++ file = vmr_pr_or_file(region); ++ inode = file_inode(file); + dev = inode->i_sb->s_dev; + ino = inode->i_ino; + } +Index: debian-kernel/fs/proc/task_mmu.c +=================================================================== +--- debian-kernel.orig/fs/proc/task_mmu.c ++++ debian-kernel/fs/proc/task_mmu.c +@@ -280,7 +280,10 @@ show_map_vma(struct seq_file *m, struct + const char *name = NULL; + + if (file) { +- struct inode *inode = file_inode(vma->vm_file); ++ struct inode *inode; ++ ++ file = vma_pr_or_file(vma); ++ inode = file_inode(file); + dev = inode->i_sb->s_dev; + ino = inode->i_ino; + pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT; +@@ -1793,7 +1796,7 @@ static int show_numa_map(struct seq_file + struct proc_maps_private *proc_priv = &numa_priv->proc_maps; + struct vm_area_struct *vma = v; + struct numa_maps *md = &numa_priv->md; +- struct file *file = vma->vm_file; ++ struct file *file = vma_pr_or_file(vma); + struct mm_struct *mm = vma->vm_mm; + struct mempolicy *pol; + char buffer[64]; +Index: debian-kernel/fs/proc/task_nommu.c +=================================================================== +--- debian-kernel.orig/fs/proc/task_nommu.c ++++ debian-kernel/fs/proc/task_nommu.c +@@ -155,7 +155,10 @@ static int nommu_vma_show(struct seq_fil + file = vma->vm_file; + + if (file) { +- struct inode *inode = file_inode(vma->vm_file); ++ struct inode *inode; ++ ++ file = vma_pr_or_file(vma); ++ inode = file_inode(file); + dev = inode->i_sb->s_dev; + ino = inode->i_ino; + pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT; +Index: debian-kernel/include/linux/mm.h +=================================================================== +--- debian-kernel.orig/include/linux/mm.h ++++ debian-kernel/include/linux/mm.h +@@ -1684,6 +1684,28 @@ static inline void unmap_shared_mapping_ + unmap_mapping_range(mapping, holebegin, holelen, 0); + } + ++extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int); ++extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[], ++ int); ++extern void vma_do_get_file(struct vm_area_struct *, const char[], int); ++extern void vma_do_fput(struct vm_area_struct *, const char[], int); ++ ++#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \ ++ __LINE__) ++#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \ ++ __LINE__) ++#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__) ++#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__) ++ ++#ifndef CONFIG_MMU ++extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int); ++extern void vmr_do_fput(struct vm_region *, const char[], int); ++ ++#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \ ++ __LINE__) ++#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__) ++#endif /* !CONFIG_MMU */ ++ + extern int access_process_vm(struct task_struct *tsk, unsigned long addr, + void *buf, int len, unsigned int gup_flags); + extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, +Index: debian-kernel/include/linux/mm_types.h +=================================================================== +--- debian-kernel.orig/include/linux/mm_types.h ++++ debian-kernel/include/linux/mm_types.h +@@ -276,6 +276,7 @@ struct vm_region { + unsigned long vm_top; /* region allocated to here */ + unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */ + struct file *vm_file; /* the backing file or NULL */ ++ struct file *vm_prfile; /* the virtual backing file or NULL */ + + int vm_usage; /* region usage count (access under nommu_region_sem) */ + bool vm_icache_flushed : 1; /* true if the icache has been flushed for +@@ -355,6 +356,7 @@ struct vm_area_struct { + unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE + units */ + struct file * vm_file; /* File we map to (can be NULL). */ ++ struct file *vm_prfile; /* shadow of vm_file */ + void * vm_private_data; /* was vm_pte (shared mem) */ + + #ifdef CONFIG_SWAP +Index: debian-kernel/kernel/fork.c +=================================================================== +--- debian-kernel.orig/kernel/fork.c ++++ debian-kernel/kernel/fork.c +@@ -570,7 +570,7 @@ static __latent_entropy int dup_mmap(str + struct inode *inode = file_inode(file); + struct address_space *mapping = file->f_mapping; + +- get_file(file); ++ vma_get_file(tmp); + if (tmp->vm_flags & VM_DENYWRITE) + atomic_dec(&inode->i_writecount); + i_mmap_lock_write(mapping); +Index: debian-kernel/mm/Makefile +=================================================================== +--- debian-kernel.orig/mm/Makefile ++++ debian-kernel/mm/Makefile +@@ -52,7 +52,7 @@ obj-y := filemap.o mempool.o oom_kill. + mm_init.o percpu.o slab_common.o \ + compaction.o vmacache.o \ + interval_tree.o list_lru.o workingset.o \ +- debug.o gup.o $(mmu-y) ++ prfile.o debug.o gup.o $(mmu-y) + + # Give 'page_alloc' its own module-parameter namespace + page-alloc-y := page_alloc.o +Index: debian-kernel/mm/filemap.c +=================================================================== +--- debian-kernel.orig/mm/filemap.c ++++ debian-kernel/mm/filemap.c +@@ -2676,7 +2676,7 @@ vm_fault_t filemap_page_mkwrite(struct v + vm_fault_t ret = VM_FAULT_LOCKED; + + sb_start_pagefault(inode->i_sb); +- file_update_time(vmf->vma->vm_file); ++ vma_file_update_time(vmf->vma); + lock_page(page); + if (page->mapping != inode->i_mapping) { + unlock_page(page); +Index: debian-kernel/mm/mmap.c +=================================================================== +--- debian-kernel.orig/mm/mmap.c ++++ debian-kernel/mm/mmap.c +@@ -179,7 +179,7 @@ static struct vm_area_struct *remove_vma + if (vma->vm_ops && vma->vm_ops->close) + vma->vm_ops->close(vma); + if (vma->vm_file) +- fput(vma->vm_file); ++ vma_fput(vma); + mpol_put(vma_policy(vma)); + vm_area_free(vma); + return next; +@@ -910,7 +910,7 @@ again: + if (remove_next) { + if (file) { + uprobe_munmap(next, next->vm_start, next->vm_end); +- fput(file); ++ vma_fput(vma); + } + if (next->anon_vma) + anon_vma_merge(vma, next); +@@ -1831,8 +1831,8 @@ out: + return addr; + + unmap_and_free_vma: ++ vma_fput(vma); + vma->vm_file = NULL; +- fput(file); + + /* Undo any partial mapping done by a device driver. */ + unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); +@@ -2683,7 +2683,7 @@ int __split_vma(struct mm_struct *mm, st + goto out_free_mpol; + + if (new->vm_file) +- get_file(new->vm_file); ++ vma_get_file(new); + + if (new->vm_ops && new->vm_ops->open) + new->vm_ops->open(new); +@@ -2702,7 +2702,7 @@ int __split_vma(struct mm_struct *mm, st + if (new->vm_ops && new->vm_ops->close) + new->vm_ops->close(new); + if (new->vm_file) +- fput(new->vm_file); ++ vma_fput(new); + unlink_anon_vmas(new); + out_free_mpol: + mpol_put(vma_policy(new)); +@@ -2894,7 +2894,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsign + struct vm_area_struct *vma; + unsigned long populate = 0; + unsigned long ret = -EINVAL; +- struct file *file; ++ struct file *file, *prfile; + + pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.rst.\n", + current->comm, current->pid); +@@ -2969,10 +2969,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsign + } + } + +- file = get_file(vma->vm_file); ++ vma_get_file(vma); ++ file = vma->vm_file; ++ prfile = vma->vm_prfile; + ret = do_mmap_pgoff(vma->vm_file, start, size, + prot, flags, pgoff, &populate, NULL); ++ if (!IS_ERR_VALUE(ret) && file && prfile) { ++ struct vm_area_struct *new_vma; ++ ++ new_vma = find_vma(mm, ret); ++ if (!new_vma->vm_prfile) ++ new_vma->vm_prfile = prfile; ++ if (new_vma != vma) ++ get_file(prfile); ++ } ++ /* ++ * two fput()s instead of vma_fput(vma), ++ * coz vma may not be available anymore. ++ */ + fput(file); ++ if (prfile) ++ fput(prfile); + out: + mmap_write_unlock(mm); + if (populate) +@@ -3263,7 +3280,7 @@ struct vm_area_struct *copy_vma(struct v + if (anon_vma_clone(new_vma, vma)) + goto out_free_mempol; + if (new_vma->vm_file) +- get_file(new_vma->vm_file); ++ vma_get_file(new_vma); + if (new_vma->vm_ops && new_vma->vm_ops->open) + new_vma->vm_ops->open(new_vma); + vma_link(mm, new_vma, prev, rb_link, rb_parent); +Index: debian-kernel/mm/nommu.c +=================================================================== +--- debian-kernel.orig/mm/nommu.c ++++ debian-kernel/mm/nommu.c +@@ -540,7 +540,7 @@ static void __put_nommu_region(struct vm + up_write(&nommu_region_sem); + + if (region->vm_file) +- fput(region->vm_file); ++ vmr_fput(region); + + /* IO memory and memory shared directly out of the pagecache + * from ramfs/tmpfs mustn't be released here */ +@@ -672,7 +672,7 @@ static void delete_vma(struct mm_struct + if (vma->vm_ops && vma->vm_ops->close) + vma->vm_ops->close(vma); + if (vma->vm_file) +- fput(vma->vm_file); ++ vma_fput(vma); + put_nommu_region(vma->vm_region); + vm_area_free(vma); + } +@@ -1195,7 +1195,7 @@ unsigned long do_mmap(struct file *file, + goto error_just_free; + } + } +- fput(region->vm_file); ++ vmr_fput(region); + kmem_cache_free(vm_region_jar, region); + region = pregion; + result = start; +@@ -1272,10 +1272,10 @@ error_just_free: + up_write(&nommu_region_sem); + error: + if (region->vm_file) +- fput(region->vm_file); ++ vmr_fput(region); + kmem_cache_free(vm_region_jar, region); + if (vma->vm_file) +- fput(vma->vm_file); ++ vma_fput(vma); + vm_area_free(vma); + return ret; + +Index: debian-kernel/mm/prfile.c +=================================================================== +--- /dev/null ++++ debian-kernel/mm/prfile.c +@@ -0,0 +1,86 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Mainly for aufs which mmap(2) different file and wants to print different ++ * path in /proc/PID/maps. ++ * Call these functions via macros defined in linux/mm.h. ++ * ++ * See Documentation/filesystems/aufs/design/06mmap.txt ++ * ++ * Copyright (c) 2014-2020 Junjro R. Okajima ++ * Copyright (c) 2014 Ian Campbell ++ */ ++ ++#include <linux/mm.h> ++#include <linux/file.h> ++#include <linux/fs.h> ++ ++/* #define PRFILE_TRACE */ ++static inline void prfile_trace(struct file *f, struct file *pr, ++ const char func[], int line, const char func2[]) ++{ ++#ifdef PRFILE_TRACE ++ if (pr) ++ pr_info("%s:%d: %s, %pD2\n", func, line, func2, f); ++#endif ++} ++ ++void vma_do_file_update_time(struct vm_area_struct *vma, const char func[], ++ int line) ++{ ++ struct file *f = vma->vm_file, *pr = vma->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ file_update_time(f); ++ if (f && pr) ++ file_update_time(pr); ++} ++ ++struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[], ++ int line) ++{ ++ struct file *f = vma->vm_file, *pr = vma->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ return (f && pr) ? pr : f; ++} ++ ++void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line) ++{ ++ struct file *f = vma->vm_file, *pr = vma->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ get_file(f); ++ if (f && pr) ++ get_file(pr); ++} ++ ++void vma_do_fput(struct vm_area_struct *vma, const char func[], int line) ++{ ++ struct file *f = vma->vm_file, *pr = vma->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ fput(f); ++ if (f && pr) ++ fput(pr); ++} ++ ++#ifndef CONFIG_MMU ++struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[], ++ int line) ++{ ++ struct file *f = region->vm_file, *pr = region->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ return (f && pr) ? pr : f; ++} ++ ++void vmr_do_fput(struct vm_region *region, const char func[], int line) ++{ ++ struct file *f = region->vm_file, *pr = region->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ fput(f); ++ if (f && pr) ++ fput(pr); ++} ++#endif /* !CONFIG_MMU */ diff --git a/debian/patches/features/all/aufs5/aufs5-standalone.patch b/debian/patches/features/all/aufs5/aufs5-standalone.patch new file mode 100644 index 000000000..ffd06c8ce --- /dev/null +++ b/debian/patches/features/all/aufs5/aufs5-standalone.patch @@ -0,0 +1,308 @@ +From: J. R. Okajima <hooanon05@yahoo.co.jp> +Date: Tue Apr 7 22:14:47 2020 +0900 +Subject: aufs5.6 standalone patch +Origin: https://github.com/sfjro/aufs5-standalone/tree/7c07d9737e9de058981f020d66ac0d4407a80899 +Bug-Debian: https://bugs.debian.org/541828 + +Patch headers added by debian/bin/genpatch-aufs + +SPDX-License-Identifier: GPL-2.0 +aufs5.6 standalone patch + +Index: debian-kernel/fs/dcache.c +=================================================================== +--- debian-kernel.orig/fs/dcache.c ++++ debian-kernel/fs/dcache.c +@@ -1390,6 +1390,7 @@ rename_retry: + seq = 1; + goto again; + } ++EXPORT_SYMBOL_GPL(d_walk); + + struct check_mount { + struct vfsmount *mnt; +@@ -2935,6 +2936,7 @@ void d_exchange(struct dentry *dentry1, + + write_sequnlock(&rename_lock); + } ++EXPORT_SYMBOL_GPL(d_exchange); + + /** + * d_ancestor - search for an ancestor +Index: debian-kernel/fs/exec.c +=================================================================== +--- debian-kernel.orig/fs/exec.c ++++ debian-kernel/fs/exec.c +@@ -111,6 +111,7 @@ bool path_noexec(const struct path *path + return (path->mnt->mnt_flags & MNT_NOEXEC) || + (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC); + } ++EXPORT_SYMBOL_GPL(path_noexec); + + #ifdef CONFIG_USELIB + /* +Index: debian-kernel/fs/fcntl.c +=================================================================== +--- debian-kernel.orig/fs/fcntl.c ++++ debian-kernel/fs/fcntl.c +@@ -85,6 +85,7 @@ int setfl(int fd, struct file *filp, uns + out: + return error; + } ++EXPORT_SYMBOL_GPL(setfl); + + static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, + int force) +Index: debian-kernel/fs/file_table.c +=================================================================== +--- debian-kernel.orig/fs/file_table.c ++++ debian-kernel/fs/file_table.c +@@ -162,6 +162,7 @@ over: + } + return ERR_PTR(-ENFILE); + } ++EXPORT_SYMBOL_GPL(alloc_empty_file); + + /* + * Variant of alloc_empty_file() that doesn't check and modify nr_files. +@@ -376,6 +377,7 @@ void __fput_sync(struct file *file) + } + + EXPORT_SYMBOL(fput); ++EXPORT_SYMBOL_GPL(__fput_sync); + + void __init files_init(void) + { +Index: debian-kernel/fs/inode.c +=================================================================== +--- debian-kernel.orig/fs/inode.c ++++ debian-kernel/fs/inode.c +@@ -1774,6 +1774,7 @@ int update_time(struct inode *inode, str + return inode->i_op->update_time(inode, time, flags); + return generic_update_time(inode, time, flags); + } ++EXPORT_SYMBOL_GPL(update_time); + + /** + * touch_atime - update the access time +Index: debian-kernel/fs/namespace.c +=================================================================== +--- debian-kernel.orig/fs/namespace.c ++++ debian-kernel/fs/namespace.c +@@ -431,6 +431,7 @@ void __mnt_drop_write(struct vfsmount *m + mnt_dec_writers(real_mount(mnt)); + preempt_enable(); + } ++EXPORT_SYMBOL_GPL(__mnt_drop_write); + + /** + * mnt_drop_write - give up write access to a mount +@@ -797,6 +798,7 @@ int is_current_mnt_ns(struct vfsmount *m + { + return check_mnt(real_mount(mnt)); + } ++EXPORT_SYMBOL_GPL(is_current_mnt_ns); + + /* + * vfsmount lock must be held for write +@@ -1961,6 +1963,7 @@ int iterate_mounts(int (*f)(struct vfsmo + } + return 0; + } ++EXPORT_SYMBOL_GPL(iterate_mounts); + + static void lock_mnt_tree(struct mount *mnt) + { +Index: debian-kernel/fs/notify/group.c +=================================================================== +--- debian-kernel.orig/fs/notify/group.c ++++ debian-kernel/fs/notify/group.c +@@ -100,6 +100,7 @@ void fsnotify_get_group(struct fsnotify_ + { + refcount_inc(&group->refcnt); + } ++EXPORT_SYMBOL_GPL(fsnotify_get_group); + + /* + * Drop a reference to a group. Free it if it's through. +Index: debian-kernel/fs/open.c +=================================================================== +--- debian-kernel.orig/fs/open.c ++++ debian-kernel/fs/open.c +@@ -65,6 +65,7 @@ int do_truncate(struct dentry *dentry, l + inode_unlock(dentry->d_inode); + return ret; + } ++EXPORT_SYMBOL_GPL(do_truncate); + + long vfs_truncate(const struct path *path, loff_t length) + { +Index: debian-kernel/fs/read_write.c +=================================================================== +--- debian-kernel.orig/fs/read_write.c ++++ debian-kernel/fs/read_write.c +@@ -488,6 +488,7 @@ ssize_t vfs_read(struct file *file, char + inc_syscr(current); + return ret; + } ++EXPORT_SYMBOL_GPL(vfs_read); + + static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) + { +@@ -517,6 +518,7 @@ vfs_readf_t vfs_readf(struct file *file) + return new_sync_read; + return ERR_PTR(-ENOSYS); /* doesn't have ->read(|_iter)() op */ + } ++EXPORT_SYMBOL_GPL(vfs_readf); + + vfs_writef_t vfs_writef(struct file *file) + { +@@ -528,6 +530,7 @@ vfs_writef_t vfs_writef(struct file *fil + return new_sync_write; + return ERR_PTR(-ENOSYS); /* doesn't have ->write(|_iter)() op */ + } ++EXPORT_SYMBOL_GPL(vfs_writef); + + /* caller is responsible for file_start_write/file_end_write */ + ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) +@@ -608,6 +611,7 @@ ssize_t vfs_write(struct file *file, con + file_end_write(file); + return ret; + } ++EXPORT_SYMBOL_GPL(vfs_write); + + /* file_ppos returns &file->f_pos or NULL if file is stream */ + static inline loff_t *file_ppos(struct file *file) +Index: debian-kernel/fs/splice.c +=================================================================== +--- debian-kernel.orig/fs/splice.c ++++ debian-kernel/fs/splice.c +@@ -870,6 +870,7 @@ long do_splice_to(struct file *in, loff_ + return in->f_op->splice_read(in, ppos, pipe, len, flags); + return default_file_splice_read(in, ppos, pipe, len, flags); + } ++EXPORT_SYMBOL_GPL(do_splice_from); + + /** + * splice_direct_to_actor - splices data directly between two non-pipes +@@ -1016,6 +1017,7 @@ static int direct_splice_actor(struct pi + return do_splice_from(pipe, file, sd->opos, sd->total_len, + sd->flags); + } ++EXPORT_SYMBOL_GPL(do_splice_to); + + /** + * do_splice_direct - splices data directly between two files +Index: debian-kernel/fs/sync.c +=================================================================== +--- debian-kernel.orig/fs/sync.c ++++ debian-kernel/fs/sync.c +@@ -39,6 +39,7 @@ int __sync_filesystem(struct super_block + sb->s_op->sync_fs(sb, wait); + return __sync_blockdev(sb->s_bdev, wait); + } ++EXPORT_SYMBOL_GPL(__sync_filesystem); + + /* + * Write out and wait upon all dirty data associated with this +Index: debian-kernel/fs/xattr.c +=================================================================== +--- debian-kernel.orig/fs/xattr.c ++++ debian-kernel/fs/xattr.c +@@ -296,6 +296,7 @@ vfs_getxattr_alloc(struct dentry *dentry + *xattr_value = value; + return error; + } ++EXPORT_SYMBOL_GPL(vfs_getxattr_alloc); + + ssize_t + __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name, +Index: debian-kernel/kernel/locking/lockdep.c +=================================================================== +--- debian-kernel.orig/kernel/locking/lockdep.c ++++ debian-kernel/kernel/locking/lockdep.c +@@ -190,6 +190,7 @@ inline struct lock_class *lockdep_hlock_ + */ + return lock_classes + class_idx; + } ++EXPORT_SYMBOL_GPL(lockdep_hlock_class); + #define hlock_class(hlock) lockdep_hlock_class(hlock) + + #ifdef CONFIG_LOCK_STAT +Index: debian-kernel/kernel/task_work.c +=================================================================== +--- debian-kernel.orig/kernel/task_work.c ++++ debian-kernel/kernel/task_work.c +@@ -139,3 +139,4 @@ void task_work_run(void) + } while (work); + } + } ++EXPORT_SYMBOL_GPL(task_work_run); +Index: debian-kernel/security/security.c +=================================================================== +--- debian-kernel.orig/security/security.c ++++ debian-kernel/security/security.c +@@ -1096,6 +1096,7 @@ int security_path_rmdir(const struct pat + return 0; + return call_int_hook(path_rmdir, 0, dir, dentry); + } ++EXPORT_SYMBOL_GPL(security_path_rmdir); + + int security_path_unlink(const struct path *dir, struct dentry *dentry) + { +@@ -1112,6 +1113,7 @@ int security_path_symlink(const struct p + return 0; + return call_int_hook(path_symlink, 0, dir, dentry, old_name); + } ++EXPORT_SYMBOL_GPL(security_path_symlink); + + int security_path_link(struct dentry *old_dentry, const struct path *new_dir, + struct dentry *new_dentry) +@@ -1120,6 +1122,7 @@ int security_path_link(struct dentry *ol + return 0; + return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry); + } ++EXPORT_SYMBOL_GPL(security_path_link); + + int security_path_rename(const struct path *old_dir, struct dentry *old_dentry, + const struct path *new_dir, struct dentry *new_dentry, +@@ -1147,6 +1150,7 @@ int security_path_truncate(const struct + return 0; + return call_int_hook(path_truncate, 0, path); + } ++EXPORT_SYMBOL_GPL(security_path_truncate); + + int security_path_chmod(const struct path *path, umode_t mode) + { +@@ -1154,6 +1158,7 @@ int security_path_chmod(const struct pat + return 0; + return call_int_hook(path_chmod, 0, path, mode); + } ++EXPORT_SYMBOL_GPL(security_path_chmod); + + int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) + { +@@ -1161,6 +1166,7 @@ int security_path_chown(const struct pat + return 0; + return call_int_hook(path_chown, 0, path, uid, gid); + } ++EXPORT_SYMBOL_GPL(security_path_chown); + + int security_path_chroot(const struct path *path) + { +@@ -1261,6 +1267,7 @@ int security_inode_permission(struct ino + return 0; + return call_int_hook(inode_permission, 0, inode, mask); + } ++EXPORT_SYMBOL_GPL(security_inode_permission); + + int security_inode_setattr(struct dentry *dentry, struct iattr *attr) + { +@@ -1453,6 +1460,7 @@ int security_file_permission(struct file + + return fsnotify_perm(file, mask); + } ++EXPORT_SYMBOL_GPL(security_file_permission); + + int security_file_alloc(struct file *file) + { diff --git a/debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch b/debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch new file mode 100644 index 000000000..5d4ec82f0 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch @@ -0,0 +1,40 @@ +From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com> +Date: Tue, 13 Mar 2018 18:37:59 +0800 +Subject: [PATCH 1/5] MODSIGN: do not load mok when secure boot disabled +Origin: https://lore.kernel.org/patchwork/patch/933173/ + +The mok can not be trusted when the secure boot is disabled. Which +means that the kernel embedded certificate is the only trusted key. + +Due to db/dbx are authenticated variables, they needs manufacturer's +KEK for update. So db/dbx are secure when secureboot disabled. + +Cc: David Howells <dhowells@redhat.com> +Cc: Josh Boyer <jwboyer@fedoraproject.org> +Cc: James Bottomley <James.Bottomley@HansenPartnership.com> +Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> +[Rebased by Luca Boccassi] +[bwh: Forward-ported to 5.5.9: + - get_cert_list() takes a pointer to status and returns the cert list + - Adjust filename] +[Salvatore Bonaccorso: Forward-ported to 5.10: Refresh for changes in +38a1f03aa240 ("integrity: Move import of MokListRT certs to a separate +routine"). Refresh in context for change in ebd9c2ae369a ("integrity: Load mokx +variables into the blacklist keyring")] +--- + security/integrity/platform_certs/load_uefi.c | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +--- a/security/integrity/platform_certs/load_uefi.c ++++ b/security/integrity/platform_certs/load_uefi.c +@@ -176,6 +176,10 @@ static int __init load_uefi_certs(void) + kfree(dbx); + } + ++ /* the MOK can not be trusted when secure boot is disabled */ ++ if (!efi_enabled(EFI_SECURE_BOOT)) ++ return 0; ++ + mokx = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &status); + if (!mokx) { + if (status == EFI_NOT_FOUND) diff --git a/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch b/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch new file mode 100644 index 000000000..a7ec5ccb5 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch @@ -0,0 +1,117 @@ +From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com> +Date: Tue, 13 Mar 2018 18:38:02 +0800 +Subject: [PATCH 3/4] MODSIGN: checking the blacklisted hash before loading a + kernel module +Origin: https://lore.kernel.org/patchwork/patch/933175/ + +This patch adds the logic for checking the kernel module's hash +base on blacklist. The hash must be generated by sha256 and enrolled +to dbx/mokx. + +For example: + sha256sum sample.ko + mokutil --mokx --import-hash $HASH_RESULT + +Whether the signature on ko file is stripped or not, the hash can be +compared by kernel. + +Cc: David Howells <dhowells@redhat.com> +Cc: Josh Boyer <jwboyer@fedoraproject.org> +Cc: James Bottomley <James.Bottomley@HansenPartnership.com> +Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> +[Rebased by Luca Boccassi] +--- + kernel/module_signing.c | 59 +++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 57 insertions(+), 2 deletions(-) + +--- a/kernel/module_signing.c ++++ b/kernel/module_signing.c +@@ -12,15 +12,62 @@ + #include <linux/string.h> + #include <linux/verification.h> + #include <crypto/public_key.h> ++#include <crypto/hash.h> ++#include <keys/system_keyring.h> + #include "module-internal.h" + ++static int mod_is_hash_blacklisted(const void *mod, size_t verifylen) ++{ ++ struct crypto_shash *tfm; ++ struct shash_desc *desc; ++ size_t digest_size, desc_size; ++ u8 *digest; ++ int ret = 0; ++ ++ tfm = crypto_alloc_shash("sha256", 0, 0); ++ if (IS_ERR(tfm)) ++ goto error_return; ++ ++ desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); ++ digest_size = crypto_shash_digestsize(tfm); ++ digest = kzalloc(digest_size + desc_size, GFP_KERNEL); ++ if (!digest) { ++ pr_err("digest memory buffer allocate fail\n"); ++ ret = -ENOMEM; ++ goto error_digest; ++ } ++ desc = (void *)digest + digest_size; ++ desc->tfm = tfm; ++ ret = crypto_shash_init(desc); ++ if (ret < 0) ++ goto error_shash; ++ ++ ret = crypto_shash_finup(desc, mod, verifylen, digest); ++ if (ret < 0) ++ goto error_shash; ++ ++ pr_debug("%ld digest: %*phN\n", verifylen, (int) digest_size, digest); ++ ++ ret = is_hash_blacklisted(digest, digest_size, "bin"); ++ if (ret == -EKEYREJECTED) ++ pr_err("Module hash %*phN is blacklisted\n", ++ (int) digest_size, digest); ++ ++error_shash: ++ kfree(digest); ++error_digest: ++ crypto_free_shash(tfm); ++error_return: ++ return ret; ++} ++ + /* + * Verify the signature on a module. + */ + int mod_verify_sig(const void *mod, struct load_info *info) + { + struct module_signature ms; +- size_t sig_len, modlen = info->len; ++ size_t sig_len, modlen = info->len, wholelen; + int ret; + + pr_devel("==>%s(,%zu)\n", __func__, modlen); +@@ -28,6 +75,7 @@ int mod_verify_sig(const void *mod, stru + if (modlen <= sizeof(ms)) + return -EBADMSG; + ++ wholelen = modlen + sizeof(MODULE_SIG_STRING) - 1; + memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms)); + + ret = mod_check_sig(&ms, modlen, "module"); +@@ -38,8 +86,15 @@ int mod_verify_sig(const void *mod, stru + modlen -= sig_len + sizeof(ms); + info->len = modlen; + +- return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, ++ ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, + VERIFY_USE_SECONDARY_KEYRING, + VERIFYING_MODULE_SIGNATURE, + NULL, NULL); ++ pr_devel("verify_pkcs7_signature() = %d\n", ret); ++ ++ /* checking hash of module is in blacklist */ ++ if (!ret) ++ ret = mod_is_hash_blacklisted(mod, wholelen); ++ ++ return ret; + } diff --git a/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch new file mode 100644 index 000000000..530885944 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch @@ -0,0 +1,113 @@ +From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com> +Date: Tue, 13 Mar 2018 18:38:03 +0800 +Subject: [PATCH 4/4] MODSIGN: check the attributes of db and mok +Origin: https://lore.kernel.org/patchwork/patch/933176/ + +That's better for checking the attributes of db and mok variables +before loading certificates to kernel keyring. + +For db and dbx, both of them are authenticated variables. Which +means that they can only be modified by manufacturer's key. So +the kernel should checks EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS +attribute before we trust it. + +For mok-rt and mokx-rt, both of them are created by shim boot loader +to forward the mok/mokx content to runtime. They must be runtime-volatile +variables. So kernel should checks that the attributes map did not set +EFI_VARIABLE_NON_VOLATILE bit before we trust it. + +Cc: David Howells <dhowells@redhat.com> +Cc: Josh Boyer <jwboyer@fedoraproject.org> +Cc: James Bottomley <James.Bottomley@HansenPartnership.com> +Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> +[Rebased by Luca Boccassi] +[bwh: Forward-ported to 5.5.9: + - get_cert_list() takes a pointer to status and returns the cert list + - Adjust filename, context] +[bwh: Forward-ported to 5.10: MokListRT and MokListXRT are now both + loaded through a single code path.] +--- + security/integrity/platform_certs/load_uefi.c | 27 ++++++++++++++----- + 1 file changed, 21 insertions(+), 6 deletions(-) + +--- a/security/integrity/platform_certs/load_uefi.c ++++ b/security/integrity/platform_certs/load_uefi.c +@@ -35,11 +35,13 @@ static __init bool uefi_check_ignore_db( + * Get a certificate list blob from the named EFI variable. + */ + static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, +- unsigned long *size, efi_status_t *status) ++ unsigned long *size, efi_status_t *status, ++ u32 pos_attr, u32 neg_attr) + { + unsigned long lsize = 4; + unsigned long tmpdb[4]; + void *db; ++ u32 attr = 0; + + *status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb); + if (*status == EFI_NOT_FOUND) +@@ -54,13 +56,22 @@ static __init void *get_cert_list(efi_ch + if (!db) + return NULL; + +- *status = efi.get_variable(name, guid, NULL, &lsize, db); ++ *status = efi.get_variable(name, guid, &attr, &lsize, db); + if (*status != EFI_SUCCESS) { + kfree(db); + pr_err("Error reading db var: 0x%lx\n", *status); + return NULL; + } + ++ /* must have positive attributes and no negative attributes */ ++ if ((pos_attr && !(attr & pos_attr)) || ++ (neg_attr && (attr & neg_attr))) { ++ kfree(db); ++ pr_err("Error reading db var attributes: 0x%016x\n", attr); ++ *status = EFI_SECURITY_VIOLATION; ++ return NULL; ++ } ++ + *size = lsize; + return db; + } +@@ -106,7 +117,8 @@ static int __init load_moklist_certs(voi + /* Get MokListRT. It might not exist, so it isn't an error + * if we can't get it. + */ +- mok = get_cert_list(L"MokListRT", &mok_var, &moksize, &status); ++ mok = get_cert_list(L"MokListRT", &mok_var, &moksize, &status, ++ 0, EFI_VARIABLE_NON_VOLATILE); + if (mok) { + rc = parse_efi_signature_list("UEFI:MokListRT", + mok, moksize, get_handler_for_db); +@@ -145,7 +157,8 @@ static int __init load_uefi_certs(void) + * if we can't get them. + */ + if (!uefi_check_ignore_db()) { +- db = get_cert_list(L"db", &secure_var, &dbsize, &status); ++ db = get_cert_list(L"db", &secure_var, &dbsize, &status, ++ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, 0); + if (!db) { + if (status == EFI_NOT_FOUND) + pr_debug("MODSIGN: db variable wasn't found\n"); +@@ -161,7 +174,8 @@ static int __init load_uefi_certs(void) + } + } + +- dbx = get_cert_list(L"dbx", &secure_var, &dbxsize, &status); ++ dbx = get_cert_list(L"dbx", &secure_var, &dbxsize, &status, ++ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, 0); + if (!dbx) { + if (status == EFI_NOT_FOUND) + pr_debug("dbx variable wasn't found\n"); +@@ -180,7 +194,8 @@ static int __init load_uefi_certs(void) + if (!efi_enabled(EFI_SECURE_BOOT)) + return 0; + +- mokx = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &status); ++ mokx = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &status, ++ 0, EFI_VARIABLE_NON_VOLATILE); + if (!mokx) { + if (status == EFI_NOT_FOUND) + pr_debug("mokx variable wasn't found\n"); diff --git a/debian/patches/features/all/db-mok-keyring/KEYS-Make-use-of-platform-keyring-for-module-signature.patch b/debian/patches/features/all/db-mok-keyring/KEYS-Make-use-of-platform-keyring-for-module-signature.patch new file mode 100644 index 000000000..f00bf3d24 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/KEYS-Make-use-of-platform-keyring-for-module-signature.patch @@ -0,0 +1,37 @@ +From: Robert Holmes <robeholmes@gmail.com> +Date: Tue, 23 Apr 2019 07:39:29 +0000 +Subject: [PATCH] KEYS: Make use of platform keyring for module signature + verify +Bug-Debian: https://bugs.debian.org/935945 +Origin: https://src.fedoraproject.org/rpms/kernel/raw/master/f/KEYS-Make-use-of-platform-keyring-for-module-signature.patch + +This patch completes commit 278311e417be ("kexec, KEYS: Make use of +platform keyring for signature verify") which, while adding the +platform keyring for bzImage verification, neglected to also add +this keyring for module verification. + +As such, kernel modules signed with keys from the MokList variable +were not successfully verified. + +Signed-off-by: Robert Holmes <robeholmes@gmail.com> +Signed-off-by: Jeremy Cline <jcline@redhat.com> +--- + kernel/module_signing.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +--- a/kernel/module_signing.c ++++ b/kernel/module_signing.c +@@ -135,6 +135,13 @@ int mod_verify_sig(const void *mod, stru + VERIFYING_MODULE_SIGNATURE, + NULL, NULL); + pr_devel("verify_pkcs7_signature() = %d\n", ret); ++ if (ret == -ENOKEY && IS_ENABLED(CONFIG_INTEGRITY_PLATFORM_KEYRING)) { ++ ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, ++ VERIFY_USE_PLATFORM_KEYRING, ++ VERIFYING_MODULE_SIGNATURE, ++ NULL, NULL); ++ pr_devel("verify_pkcs7_signature() = %d\n", ret); ++ } + + /* checking hash of module is in blacklist */ + if (!ret) diff --git a/debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch b/debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch new file mode 100644 index 000000000..2ae3ddde4 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch @@ -0,0 +1,28 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sun, 05 May 2019 13:45:06 +0100 +Subject: MODSIGN: Make shash allocation failure fatal + +mod_is_hash_blacklisted() currently returns 0 (suceess) if +crypto_alloc_shash() fails. This should instead be a fatal error, +so unwrap and pass up the error code. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/kernel/module_signing.c ++++ b/kernel/module_signing.c +@@ -51,11 +51,13 @@ static int mod_is_hash_blacklisted(const + struct shash_desc *desc; + size_t digest_size, desc_size; + u8 *digest; +- int ret = 0; ++ int ret; + + tfm = crypto_alloc_shash("sha256", 0, 0); +- if (IS_ERR(tfm)) ++ if (IS_ERR(tfm)) { ++ ret = PTR_ERR(tfm); + goto error_return; ++ } + + desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); + digest_size = crypto_shash_digestsize(tfm); diff --git a/debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch b/debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch new file mode 100644 index 000000000..a24ba17ef --- /dev/null +++ b/debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch @@ -0,0 +1,149 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Mon, 24 Aug 2009 23:19:58 +0100 +Subject: af9005: Use request_firmware() to load register init script +Forwarded: no + +Read the register init script from the Windows driver. This is sick +but should avoid the potential copyright infringement in distributing +a version of the script which is directly derived from the driver. +--- + drivers/media/dvb/dvb-usb/Kconfig | 2 +- + drivers/media/dvb/dvb-usb/af9005-fe.c | 66 ++++++++++++++++++++++++++------ + 2 files changed, 54 insertions(+), 14 deletions(-) + +Index: debian-kernel/drivers/media/usb/dvb-usb/Kconfig +=================================================================== +--- debian-kernel.orig/drivers/media/usb/dvb-usb/Kconfig ++++ debian-kernel/drivers/media/usb/dvb-usb/Kconfig +@@ -260,10 +260,10 @@ config DVB_USB_OPERA1 + + config DVB_USB_AF9005 + tristate "Afatech AF9005 DVB-T USB1.1 support" +- depends on BROKEN + depends on DVB_USB + select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT ++ select FW_LOADER + help + Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver + and the TerraTec Cinergy T USB XE (Rev.1) +Index: debian-kernel/drivers/media/usb/dvb-usb/af9005-fe.c +=================================================================== +--- debian-kernel.orig/drivers/media/usb/dvb-usb/af9005-fe.c ++++ debian-kernel/drivers/media/usb/dvb-usb/af9005-fe.c +@@ -9,10 +9,26 @@ + * see Documentation/driver-api/media/drivers/dvb-usb.rst for more information + */ + #include "af9005.h" +-#include "af9005-script.h" + #include "mt2060.h" + #include "qt1010.h" + #include <asm/div64.h> ++#include <linux/firmware.h> ++ ++/* Register initialisation script to be extracted from the Windows driver */ ++ ++typedef struct { ++ __le16 reg; ++ u8 pos; ++ u8 len; ++ u8 val; ++ u8 pad; ++} __packed RegDesc; ++ ++#define WIN_DRV_NAME "AF05BDA.sys" ++#define WIN_DRV_VERSION "6.3.2.1" ++#define WIN_DRV_SIZE 133504 ++#define WIN_DRV_SCRIPT_OFFSET 88316 ++#define WIN_DRV_SCRIPT_SIZE 1110 + + struct af9005_fe_state { + struct dvb_usb_device *d; +@@ -804,6 +820,8 @@ static int af9005_fe_init(struct dvb_fro + { + struct af9005_fe_state *state = fe->demodulator_priv; + struct dvb_usb_adapter *adap = fe->dvb->priv; ++ const struct firmware *fw; ++ const RegDesc *script; + int ret, i, scriptlen; + u8 temp, temp0 = 0, temp1 = 0, temp2 = 0; + u8 buf[2]; +@@ -956,37 +974,55 @@ static int af9005_fe_init(struct dvb_fro + if ((ret = af9005_write_ofdm_register(state->d, 0xaefb, 0x01))) + return ret; + +- /* load init script */ +- deb_info("load init script\n"); +- scriptlen = sizeof(script) / sizeof(RegDesc); ++ /* load and validate init script */ ++ deb_info("load init script from Windows driver\n"); ++ ret = request_firmware(&fw, WIN_DRV_NAME, &state->d->udev->dev); ++ if (ret) ++ return ret; ++ BUILD_BUG_ON(sizeof(RegDesc) != 6); ++ if (fw->size != WIN_DRV_SIZE || ++ memcmp(fw->data + WIN_DRV_SCRIPT_OFFSET, ++ "\x80\xa1\x00\x08\x0a\x00", 6) || ++ memcmp(fw->data + WIN_DRV_SCRIPT_OFFSET + WIN_DRV_SCRIPT_SIZE - 6, ++ "\x49\xa3\x00\x06\x02\x00", 6)) { ++ err("%s is invalid - should be version %s, size %u bytes\n", ++ WIN_DRV_NAME, WIN_DRV_VERSION, WIN_DRV_SIZE); ++ ret = -EINVAL; ++ goto fail_release; ++ } ++ ++ script = (const RegDesc *)(fw->data + WIN_DRV_SCRIPT_OFFSET); ++ scriptlen = WIN_DRV_SCRIPT_SIZE / sizeof(RegDesc); + for (i = 0; i < scriptlen; i++) { ++ u16 reg = le16_to_cpu(script[i].reg); + if ((ret = +- af9005_write_register_bits(state->d, script[i].reg, ++ af9005_write_register_bits(state->d, reg, + script[i].pos, + script[i].len, script[i].val))) +- return ret; ++ goto fail_release; + /* save 3 bytes of original fcw */ +- if (script[i].reg == 0xae18) ++ if (reg == 0xae18) + temp2 = script[i].val; +- if (script[i].reg == 0xae19) ++ if (reg == 0xae19) + temp1 = script[i].val; +- if (script[i].reg == 0xae1a) ++ if (reg == 0xae1a) + temp0 = script[i].val; + + /* save original unplug threshold */ +- if (script[i].reg == xd_p_reg_unplug_th) ++ if (reg == xd_p_reg_unplug_th) + state->original_if_unplug_th = script[i].val; +- if (script[i].reg == xd_p_reg_unplug_rf_gain_th) ++ if (reg == xd_p_reg_unplug_rf_gain_th) + state->original_rf_unplug_th = script[i].val; +- if (script[i].reg == xd_p_reg_unplug_dtop_if_gain_th) ++ if (reg == xd_p_reg_unplug_dtop_if_gain_th) + state->original_dtop_if_unplug_th = script[i].val; +- if (script[i].reg == xd_p_reg_unplug_dtop_rf_gain_th) ++ if (reg == xd_p_reg_unplug_dtop_rf_gain_th) + state->original_dtop_rf_unplug_th = script[i].val; + + } + state->original_fcw = + ((u32) temp2 << 16) + ((u32) temp1 << 8) + (u32) temp0; + ++ release_firmware(fw); + + /* save original TOPs */ + deb_info("save original TOPs\n"); +@@ -1066,6 +1102,10 @@ static int af9005_fe_init(struct dvb_fro + + deb_info("profit!\n"); + return 0; ++ ++fail_release: ++ release_firmware(fw); ++ return ret; + } + + static int af9005_fe_sleep(struct dvb_frontend *fe) diff --git a/debian/patches/features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch b/debian/patches/features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch new file mode 100644 index 000000000..7f9ee1cf9 --- /dev/null +++ b/debian/patches/features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch @@ -0,0 +1,153 @@ +From: Linn Crosetto <linn@hpe.com> +Date: Tue, 30 Aug 2016 11:54:38 -0600 +Subject: arm64: add kernel config option to lock down when in Secure Boot mode +Bug-Debian: https://bugs.debian.org/831827 +Forwarded: no + +Add a kernel configuration option to lock down the kernel, to restrict +userspace's ability to modify the running kernel when UEFI Secure Boot is +enabled. Based on the x86 patch by Matthew Garrett. + +Determine the state of Secure Boot in the EFI stub and pass this to the +kernel using the FDT. + +Signed-off-by: Linn Crosetto <linn@hpe.com> +[bwh: Forward-ported to 4.10: adjust context] +[Lukas Wunner: Forward-ported to 4.11: drop parts applied upstream] +[bwh: Forward-ported to 4.15 and lockdown patch set: + - Pass result of efi_get_secureboot() in stub through to + efi_set_secure_boot() in main kernel + - Use lockdown API and naming] +[bwh: Forward-ported to 4.19.3: adjust context in update_fdt()] +[dannf: Moved init_lockdown() call after uefi_init(), fixing SB detection] +[bwh: Drop call to init_lockdown(), as efi_set_secure_boot() now calls this] +[bwh: Forward-ported to 5.6: efi_get_secureboot() no longer takes a + sys_table parameter] +[bwh: Forward-ported to 5.7: EFI initialisation from FDT was rewritten, so: + - Add Secure Boot mode to the parameter enumeration in fdtparams.c + - Add a parameter to efi_get_fdt_params() to return the Secure Boot mode + - Since Xen does not have a property name defined for Secure Boot mode, + change efi_get_fdt_prop() to handle a missing property name by clearing + the output variable] +[Salvatore Bonaccorso: Forward-ported to 5.10: f30f242fb131 ("efi: Rename +arm-init to efi-init common for all arch") renamed arm-init.c to efi-init.c] +--- + drivers/firmware/efi/efi-init.c | 5 ++++- + drivers/firmware/efi/fdtparams.c | 12 +++++++++++- + drivers/firmware/efi/libstub/fdt.c | 6 ++++++ + include/linux/efi.h | 3 ++- + 4 files changed, 23 insertions(+), 3 deletions(-) + +--- a/drivers/firmware/efi/efi-init.c ++++ b/drivers/firmware/efi/efi-init.c +@@ -210,9 +210,10 @@ void __init efi_init(void) + { + struct efi_memory_map_data data; + u64 efi_system_table; ++ u32 secure_boot; + + /* Grab UEFI information placed in FDT by stub */ +- efi_system_table = efi_get_fdt_params(&data); ++ efi_system_table = efi_get_fdt_params(&data, &secure_boot); + if (!efi_system_table) + return; + +@@ -234,6 +235,8 @@ void __init efi_init(void) + return; + } + ++ efi_set_secure_boot(secure_boot); ++ + reserve_regions(); + efi_esrt_init(); + efi_mokvar_table_init(); +--- a/drivers/firmware/efi/fdtparams.c ++++ b/drivers/firmware/efi/fdtparams.c +@@ -16,6 +16,7 @@ enum { + MMSIZE, + DCSIZE, + DCVERS, ++ SBMODE, + + PARAMCOUNT + }; +@@ -26,6 +27,7 @@ static __initconst const char name[][22] + [MMSIZE] = "MemMap Size ", + [DCSIZE] = "MemMap Desc. Size ", + [DCVERS] = "MemMap Desc. Version ", ++ [SBMODE] = "Secure Boot Enabled ", + }; + + static __initconst const struct { +@@ -41,6 +43,7 @@ static __initconst const struct { + [MMSIZE] = "xen,uefi-mmap-size", + [DCSIZE] = "xen,uefi-mmap-desc-size", + [DCVERS] = "xen,uefi-mmap-desc-ver", ++ [SBMODE] = "", + } + }, { + #endif +@@ -51,6 +54,7 @@ static __initconst const struct { + [MMSIZE] = "linux,uefi-mmap-size", + [DCSIZE] = "linux,uefi-mmap-desc-size", + [DCVERS] = "linux,uefi-mmap-desc-ver", ++ [SBMODE] = "linux,uefi-secure-boot", + } + } + }; +@@ -62,6 +66,11 @@ static int __init efi_get_fdt_prop(const + int len; + u64 val; + ++ if (!pname[0]) { ++ memset(var, 0, size); ++ return 0; ++ } ++ + prop = fdt_getprop(fdt, node, pname, &len); + if (!prop) + return 1; +@@ -79,7 +88,7 @@ static int __init efi_get_fdt_prop(const + return 0; + } + +-u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) ++u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm, u32 *secure_boot) + { + const void *fdt = initial_boot_params; + unsigned long systab; +@@ -93,6 +102,7 @@ u64 __init efi_get_fdt_params(struct efi + [MMSIZE] = { &mm->size, sizeof(mm->size) }, + [DCSIZE] = { &mm->desc_size, sizeof(mm->desc_size) }, + [DCVERS] = { &mm->desc_version, sizeof(mm->desc_version) }, ++ [SBMODE] = { secure_boot, sizeof(*secure_boot) }, + }; + + BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(name)); +--- a/drivers/firmware/efi/libstub/fdt.c ++++ b/drivers/firmware/efi/libstub/fdt.c +@@ -148,6 +148,12 @@ static efi_status_t update_fdt(void *ori + } + } + ++ fdt_val32 = cpu_to_fdt32(efi_get_secureboot()); ++ status = fdt_setprop(fdt, node, "linux,uefi-secure-boot", ++ &fdt_val32, sizeof(fdt_val32)); ++ if (status) ++ goto fdt_set_fail; ++ + /* Shrink the FDT back to its minimum size: */ + fdt_pack(fdt); + +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -665,7 +665,8 @@ extern void efi_mem_reserve(phys_addr_t + extern int efi_mem_reserve_persistent(phys_addr_t addr, u64 size); + extern void efi_initialize_iomem_resources(struct resource *code_resource, + struct resource *data_resource, struct resource *bss_resource); +-extern u64 efi_get_fdt_params(struct efi_memory_map_data *data); ++extern u64 efi_get_fdt_params(struct efi_memory_map_data *data, ++ u32 *secure_boot); + extern struct kobject *efi_kobj; + + extern int efi_reboot_quirk_mode; diff --git a/debian/patches/features/all/lockdown/efi-add-an-efi_secure_boot-flag-to-indicate-secure-b.patch b/debian/patches/features/all/lockdown/efi-add-an-efi_secure_boot-flag-to-indicate-secure-b.patch new file mode 100644 index 000000000..431281249 --- /dev/null +++ b/debian/patches/features/all/lockdown/efi-add-an-efi_secure_boot-flag-to-indicate-secure-b.patch @@ -0,0 +1,152 @@ +From: David Howells <dhowells@redhat.com> +Date: Mon, 18 Feb 2019 12:45:03 +0000 +Subject: [28/30] efi: Add an EFI_SECURE_BOOT flag to indicate secure boot mode +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=a5d70c55c603233c192b375f72116a395909da28 + +UEFI machines can be booted in Secure Boot mode. Add an EFI_SECURE_BOOT +flag that can be passed to efi_enabled() to find out whether secure boot is +enabled. + +Move the switch-statement in x86's setup_arch() that inteprets the +secure_boot boot parameter to generic code and set the bit there. + +Suggested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> +cc: linux-efi@vger.kernel.org +[rperier: Forward-ported to 5.5: + - Use pr_warn() + - Adjust context] +[bwh: Forward-ported to 5.6: adjust context] +[bwh: Forward-ported to 5.7: + - Use the next available bit in efi.flags + - Adjust context] +--- + arch/x86/kernel/setup.c | 14 +---------- + drivers/firmware/efi/Makefile | 1 + + drivers/firmware/efi/secureboot.c | 39 +++++++++++++++++++++++++++++++ + include/linux/efi.h | 16 ++++++++----- + 4 files changed, 51 insertions(+), 19 deletions(-) + create mode 100644 drivers/firmware/efi/secureboot.c + +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -1124,19 +1124,7 @@ void __init setup_arch(char **cmdline_p) + /* Allocate bigger log buffer */ + setup_log_buf(1); + +- if (efi_enabled(EFI_BOOT)) { +- switch (boot_params.secure_boot) { +- case efi_secureboot_mode_disabled: +- pr_info("Secure boot disabled\n"); +- break; +- case efi_secureboot_mode_enabled: +- pr_info("Secure boot enabled\n"); +- break; +- default: +- pr_info("Secure boot could not be determined\n"); +- break; +- } +- } ++ efi_set_secure_boot(boot_params.secure_boot); + + reserve_initrd(); + +--- a/drivers/firmware/efi/Makefile ++++ b/drivers/firmware/efi/Makefile +@@ -25,6 +25,7 @@ obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_m + obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o + obj-$(CONFIG_EFI_TEST) += test/ + obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o ++obj-$(CONFIG_EFI) += secureboot.o + obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o + obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o + obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o +--- /dev/null ++++ b/drivers/firmware/efi/secureboot.c +@@ -0,0 +1,39 @@ ++ ++/* Core kernel secure boot support. ++ * ++ * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved. ++ * Written by David Howells (dhowells@redhat.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public Licence ++ * as published by the Free Software Foundation; either version ++ * 2 of the Licence, or (at your option) any later version. ++ */ ++ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include <linux/efi.h> ++#include <linux/kernel.h> ++#include <linux/printk.h> ++ ++/* ++ * Decide what to do when UEFI secure boot mode is enabled. ++ */ ++void __init efi_set_secure_boot(enum efi_secureboot_mode mode) ++{ ++ if (efi_enabled(EFI_BOOT)) { ++ switch (mode) { ++ case efi_secureboot_mode_disabled: ++ pr_info("Secure boot disabled\n"); ++ break; ++ case efi_secureboot_mode_enabled: ++ set_bit(EFI_SECURE_BOOT, &efi.flags); ++ pr_info("Secure boot enabled\n"); ++ break; ++ default: ++ pr_warn("Secure boot could not be determined (mode %u)\n", ++ mode); ++ break; ++ } ++ } ++} +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -776,6 +776,14 @@ extern int __init efi_setup_pcdp_console + #define EFI_MEM_ATTR 10 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */ + #define EFI_MEM_NO_SOFT_RESERVE 11 /* Is the kernel configured to ignore soft reservations? */ + #define EFI_PRESERVE_BS_REGIONS 12 /* Are EFI boot-services memory segments available? */ ++#define EFI_SECURE_BOOT 13 /* Are we in Secure Boot mode? */ ++ ++enum efi_secureboot_mode { ++ efi_secureboot_mode_unset, ++ efi_secureboot_mode_unknown, ++ efi_secureboot_mode_disabled, ++ efi_secureboot_mode_enabled, ++}; + + #ifdef CONFIG_EFI + /* +@@ -799,6 +807,7 @@ static inline bool efi_rt_services_suppo + { + return (efi.runtime_supported_mask & mask) == mask; + } ++extern void __init efi_set_secure_boot(enum efi_secureboot_mode mode); + #else + static inline bool efi_enabled(int feature) + { +@@ -822,6 +831,7 @@ static inline bool efi_rt_services_suppo + { + return false; + } ++static inline void efi_set_secure_boot(enum efi_secureboot_mode mode) {} + #endif + + extern int efi_status_to_err(efi_status_t status); +@@ -1083,12 +1093,6 @@ static inline bool efi_runtime_disabled( + extern void efi_call_virt_check_flags(unsigned long flags, const char *call); + extern unsigned long efi_call_virt_save_flags(void); + +-enum efi_secureboot_mode { +- efi_secureboot_mode_unset, +- efi_secureboot_mode_unknown, +- efi_secureboot_mode_disabled, +- efi_secureboot_mode_enabled, +-}; + enum efi_secureboot_mode efi_get_secureboot(void); + + #ifdef CONFIG_RESET_ATTACK_MITIGATION diff --git a/debian/patches/features/all/lockdown/efi-lock-down-the-kernel-if-booted-in-secure-boot-mo.patch b/debian/patches/features/all/lockdown/efi-lock-down-the-kernel-if-booted-in-secure-boot-mo.patch new file mode 100644 index 000000000..627e37154 --- /dev/null +++ b/debian/patches/features/all/lockdown/efi-lock-down-the-kernel-if-booted-in-secure-boot-mo.patch @@ -0,0 +1,127 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Tue, 10 Sep 2019 11:54:28 +0100 +Subject: efi: Lock down the kernel if booted in secure boot mode + +Based on an earlier patch by David Howells, who wrote the following +description: + +> UEFI Secure Boot provides a mechanism for ensuring that the firmware will +> only load signed bootloaders and kernels. Certain use cases may also +> require that all kernel modules also be signed. Add a configuration option +> that to lock down the kernel - which includes requiring validly signed +> modules - if the kernel is secure-booted. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/x86/kernel/setup.c | 4 ++-- + drivers/firmware/efi/secureboot.c | 3 +++ + include/linux/security.h | 6 ++++++ + security/lockdown/Kconfig | 15 +++++++++++++++ + security/lockdown/lockdown.c | 2 +- + 5 files changed, 27 insertions(+), 3 deletions(-) + +Index: debian-kernel/arch/x86/kernel/setup.c +=================================================================== +--- debian-kernel.orig/arch/x86/kernel/setup.c ++++ debian-kernel/arch/x86/kernel/setup.c +@@ -979,6 +979,8 @@ void __init setup_arch(char **cmdline_p) + if (efi_enabled(EFI_BOOT)) + efi_init(); + ++ efi_set_secure_boot(boot_params.secure_boot); ++ + dmi_setup(); + + /* +@@ -1130,8 +1132,6 @@ void __init setup_arch(char **cmdline_p) + /* Allocate bigger log buffer */ + setup_log_buf(1); + +- efi_set_secure_boot(boot_params.secure_boot); +- + reserve_initrd(); + + acpi_table_upgrade(); +Index: debian-kernel/drivers/firmware/efi/secureboot.c +=================================================================== +--- debian-kernel.orig/drivers/firmware/efi/secureboot.c ++++ debian-kernel/drivers/firmware/efi/secureboot.c +@@ -15,6 +15,7 @@ + #include <linux/efi.h> + #include <linux/kernel.h> + #include <linux/printk.h> ++#include <linux/security.h> + + /* + * Decide what to do when UEFI secure boot mode is enabled. +@@ -28,6 +29,10 @@ void __init efi_set_secure_boot(enum efi + break; + case efi_secureboot_mode_enabled: + set_bit(EFI_SECURE_BOOT, &efi.flags); ++#ifdef CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT ++ lock_kernel_down("EFI Secure Boot", ++ LOCKDOWN_INTEGRITY_MAX); ++#endif + pr_info("Secure boot enabled\n"); + break; + default: +Index: debian-kernel/include/linux/security.h +=================================================================== +--- debian-kernel.orig/include/linux/security.h ++++ debian-kernel/include/linux/security.h +@@ -451,6 +451,7 @@ int security_inode_notifysecctx(struct i + int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); + int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen); + int security_locked_down(enum lockdown_reason what); ++int lock_kernel_down(const char *where, enum lockdown_reason level); + #else /* CONFIG_SECURITY */ + + static inline int call_blocking_lsm_notifier(enum lsm_event event, void *data) +@@ -1291,6 +1292,11 @@ static inline int security_locked_down(e + { + return 0; + } ++static inline int ++lock_kernel_down(const char *where, enum lockdown_reason level) ++{ ++ return -EOPNOTSUPP; ++} + #endif /* CONFIG_SECURITY */ + + #if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE) +Index: debian-kernel/security/lockdown/Kconfig +=================================================================== +--- debian-kernel.orig/security/lockdown/Kconfig ++++ debian-kernel/security/lockdown/Kconfig +@@ -45,3 +45,18 @@ config LOCK_DOWN_KERNEL_FORCE_CONFIDENTI + disabled. + + endchoice ++ ++config LOCK_DOWN_IN_EFI_SECURE_BOOT ++ bool "Lock down the kernel in EFI Secure Boot mode" ++ default n ++ depends on SECURITY_LOCKDOWN_LSM ++ depends on EFI ++ select SECURITY_LOCKDOWN_LSM_EARLY ++ help ++ UEFI Secure Boot provides a mechanism for ensuring that the firmware ++ will only load signed bootloaders and kernels. Secure boot mode may ++ be determined from EFI variables provided by the system firmware if ++ not indicated by the boot parameters. ++ ++ Enabling this option results in kernel lockdown being ++ triggered in confidentiality mode if EFI Secure Boot is set. +Index: debian-kernel/security/lockdown/lockdown.c +=================================================================== +--- debian-kernel.orig/security/lockdown/lockdown.c ++++ debian-kernel/security/lockdown/lockdown.c +@@ -23,7 +23,7 @@ static const enum lockdown_reason lockdo + /* + * Put the kernel into lock-down mode. + */ +-static int lock_kernel_down(const char *where, enum lockdown_reason level) ++int lock_kernel_down(const char *where, enum lockdown_reason level) + { + if (kernel_locked_down >= level) + return -EPERM; diff --git a/debian/patches/features/all/lockdown/mtd-disable-slram-and-phram-when-locked-down.patch b/debian/patches/features/all/lockdown/mtd-disable-slram-and-phram-when-locked-down.patch new file mode 100644 index 000000000..5004e5dca --- /dev/null +++ b/debian/patches/features/all/lockdown/mtd-disable-slram-and-phram-when-locked-down.patch @@ -0,0 +1,75 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 30 Aug 2019 15:54:24 +0100 +Subject: mtd: phram,slram: Disable when the kernel is locked down +Forwarded: https://lore.kernel.org/linux-security-module/20190830154720.eekfjt6c4jzvlbfz@decadent.org.uk/ + +These drivers allow mapping arbitrary memory ranges as MTD devices. +This should be disabled to preserve the kernel's integrity when it is +locked down. + +* Add the HWPARAM flag to the module parameters +* When slram is built-in, it uses __setup() to read kernel parameters, + so add an explicit check security_locked_down() check + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +Cc: Matthew Garrett <mjg59@google.com> +Cc: David Howells <dhowells@redhat.com> +Cc: Joern Engel <joern@lazybastard.org> +Cc: linux-mtd@lists.infradead.org +--- + drivers/mtd/devices/phram.c | 6 +++++- + drivers/mtd/devices/slram.c | 9 ++++++++- + 2 files changed, 13 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/devices/phram.c ++++ b/drivers/mtd/devices/phram.c +@@ -294,7 +294,11 @@ static int phram_param_call(const char * + #endif + } + +-module_param_call(phram, phram_param_call, NULL, NULL, 0200); ++static const struct kernel_param_ops phram_param_ops = { ++ .set = phram_param_call ++}; ++__module_param_call(MODULE_PARAM_PREFIX, phram, &phram_param_ops, NULL, ++ 0200, -1, KERNEL_PARAM_FL_HWPARAM | hwparam_iomem); + MODULE_PARM_DESC(phram, "Memory region to map. \"phram=<name>,<start>,<length>\""); + + +--- a/drivers/mtd/devices/slram.c ++++ b/drivers/mtd/devices/slram.c +@@ -43,6 +43,7 @@ + #include <linux/ioctl.h> + #include <linux/init.h> + #include <linux/io.h> ++#include <linux/security.h> + + #include <linux/mtd/mtd.h> + +@@ -65,7 +66,7 @@ typedef struct slram_mtd_list { + #ifdef MODULE + static char *map[SLRAM_MAX_DEVICES_PARAMS]; + +-module_param_array(map, charp, NULL, 0); ++module_param_hw_array(map, charp, iomem, NULL, 0); + MODULE_PARM_DESC(map, "List of memory regions to map. \"map=<name>, <start>, <length / end>\""); + #else + static char *map; +@@ -281,11 +282,17 @@ static int __init init_slram(void) + #ifndef MODULE + char *devstart; + char *devlength; ++ int ret; + + if (!map) { + E("slram: not enough parameters.\n"); + return(-EINVAL); + } ++ ++ ret = security_locked_down(LOCKDOWN_MODULE_PARAMETERS); ++ if (ret) ++ return ret; ++ + while (map) { + devname = devstart = devlength = NULL; + diff --git a/debian/patches/features/all/security-perf-allow-further-restriction-of-perf_event_open.patch b/debian/patches/features/all/security-perf-allow-further-restriction-of-perf_event_open.patch new file mode 100644 index 000000000..33db1f765 --- /dev/null +++ b/debian/patches/features/all/security-perf-allow-further-restriction-of-perf_event_open.patch @@ -0,0 +1,80 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Mon, 11 Jan 2016 15:23:55 +0000 +Subject: security,perf: Allow further restriction of perf_event_open +Forwarded: https://lkml.org/lkml/2016/1/11/587 + +When kernel.perf_event_open is set to 3 (or greater), disallow all +access to performance events by users without CAP_SYS_ADMIN. +Add a Kconfig symbol CONFIG_SECURITY_PERF_EVENTS_RESTRICT that +makes this value the default. + +This is based on a similar feature in grsecurity +(CONFIG_GRKERNSEC_PERF_HARDEN). This version doesn't include making +the variable read-only. It also allows enabling further restriction +at run-time regardless of whether the default is changed. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + include/linux/perf_event.h | 5 +++++ + kernel/events/core.c | 8 ++++++++ + security/Kconfig | 9 +++++++++ + 3 files changed, 22 insertions(+) + +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -1305,6 +1305,11 @@ int perf_cpu_time_max_percent_handler(st + int perf_event_max_stack_handler(struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos); + ++static inline bool perf_paranoid_any(void) ++{ ++ return sysctl_perf_event_paranoid > 2; ++} ++ + /* Access to perf_event_open(2) syscall. */ + #define PERF_SECURITY_OPEN 0 + +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -408,8 +408,13 @@ static cpumask_var_t perf_online_mask; + * 0 - disallow raw tracepoint access for unpriv + * 1 - disallow cpu events for unpriv + * 2 - disallow kernel profiling for unpriv ++ * 3 - disallow all unpriv perf event use + */ ++#ifdef CONFIG_SECURITY_PERF_EVENTS_RESTRICT ++int sysctl_perf_event_paranoid __read_mostly = 3; ++#else + int sysctl_perf_event_paranoid __read_mostly = 2; ++#endif + + /* Minimum for 512 kiB + 1 user control page */ + int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */ +@@ -11785,6 +11790,9 @@ SYSCALL_DEFINE5(perf_event_open, + if (err) + return err; + ++ if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN)) ++ return -EACCES; ++ + /* Do we allow access to perf_event_open(2) ? */ + err = security_perf_event_open(&attr, PERF_SECURITY_OPEN); + if (err) +--- a/security/Kconfig ++++ b/security/Kconfig +@@ -19,6 +19,15 @@ config SECURITY_DMESG_RESTRICT + + If you are unsure how to answer this question, answer N. + ++config SECURITY_PERF_EVENTS_RESTRICT ++ bool "Restrict unprivileged use of performance events" ++ depends on PERF_EVENTS ++ help ++ If you say Y here, the kernel.perf_event_paranoid sysctl ++ will be set to 3 by default, and no unprivileged use of the ++ perf_event_open syscall will be permitted unless it is ++ changed. ++ + config SECURITY + bool "Enable different security models" + depends on SYSFS |