12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122 |
- diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
- index 51f845419b9c..be23caf4af4d 100644
- --- a/Documentation/admin-guide/kernel-parameters.txt
- +++ b/Documentation/admin-guide/kernel-parameters.txt
- @@ -509,16 +509,6 @@
- nosocket -- Disable socket memory accounting.
- nokmem -- Disable kernel memory accounting.
-
- - checkreqprot [SELINUX] Set initial checkreqprot flag value.
- - Format: { "0" | "1" }
- - See security/selinux/Kconfig help text.
- - 0 -- check protection applied by kernel (includes
- - any implied execute protection).
- - 1 -- check protection requested by application.
- - Default value is set via a kernel config option.
- - Value can be changed at runtime via
- - /selinux/checkreqprot.
- -
- cio_ignore= [S390]
- See Documentation/s390/common_io.rst for details.
- clk_ignore_unused
- @@ -3454,6 +3444,11 @@
- the specified number of seconds. This is to be used if
- your oopses keep scrolling off the screen.
-
- + extra_latent_entropy
- + Enable a very simple form of latent entropy extraction
- + from the first 4GB of memory as the bootmem allocator
- + passes the memory pages to the buddy allocator.
- +
- pcbit= [HW,ISDN]
-
- pcd. [PARIDE]
- diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst
- index 568c24ff00a7..5e3e2749d842 100644
- --- a/Documentation/admin-guide/sysctl/kernel.rst
- +++ b/Documentation/admin-guide/sysctl/kernel.rst
- @@ -102,6 +102,7 @@ show up in /proc/sys/kernel:
- - sysctl_writes_strict
- - tainted ==> Documentation/admin-guide/tainted-kernels.rst
- - threads-max
- +- tiocsti_restrict
- - unknown_nmi_panic
- - watchdog
- - watchdog_thresh
- @@ -743,6 +744,8 @@ users (without CAP_SYS_ADMIN). The default value is 2.
- >=1 Disallow CPU event access by users without CAP_SYS_ADMIN
-
- >=2 Disallow kernel profiling by users without CAP_SYS_ADMIN
- +
- +>=3 Disallow use of any event by users without CAP_SYS_ADMIN
- === ==================================================================
-
-
- @@ -1154,6 +1157,25 @@ thread structures would occupy too much (more than 1/8th) of the
- available RAM pages threads-max is reduced accordingly.
-
-
- +tiocsti_restrict:
- +=================
- +
- +This toggle indicates whether unprivileged users are prevented from using the
- +TIOCSTI ioctl to inject commands into other processes which share a tty
- +session.
- +
- +When tiocsti_restrict is set to (0) there are no restrictions(accept the
- +default restriction of only being able to injection commands into one's own
- +tty). When tiocsti_restrict is set to (1), users must have CAP_SYS_ADMIN to
- +use the TIOCSTI ioctl.
- +
- +When user namespaces are in use, the check for the capability CAP_SYS_ADMIN is
- +done against the user namespace that originally opened the tty.
- +
- +The kernel config option CONFIG_SECURITY_TIOCSTI_RESTRICT sets the default
- +value of tiocsti_restrict.
- +
- +
- unknown_nmi_panic:
- ==================
-
- diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
- index 5cf601c94e35..1fd8046af9f3 100644
- --- a/Documentation/networking/ip-sysctl.txt
- +++ b/Documentation/networking/ip-sysctl.txt
- @@ -583,6 +583,23 @@ tcp_comp_sack_nr - INTEGER
-
- Default : 44
-
- +tcp_simult_connect - BOOLEAN
- + Enable TCP simultaneous connect that adds a weakness in Linux's strict
- + implementation of TCP that allows two clients to connect to each other
- + without either entering a listening state. The weakness allows an attacker
- + to easily prevent a client from connecting to a known server provided the
- + source port for the connection is guessed correctly.
- +
- + As the weakness could be used to prevent an antivirus or IPS from fetching
- + updates, or prevent an SSL gateway from fetching a CRL, it should be
- + eliminated by disabling this option. Though Linux is one of few operating
- + systems supporting simultaneous connect, it has no legitimate use in
- + practice and is rarely supported by firewalls.
- +
- + Disabling this may break TCP STUNT which is used by some applications for
- + NAT traversal.
- + Default: Value of CONFIG_TCP_SIMULT_CONNECT_DEFAULT_ON
- +
- tcp_slow_start_after_idle - BOOLEAN
- If set, provide RFC2861 behavior and time out the congestion
- window after an idle period. An idle period is defined at
- diff --git a/arch/Kconfig b/arch/Kconfig
- index 4d03616bf597..138d1925abf6 100644
- --- a/arch/Kconfig
- +++ b/arch/Kconfig
- @@ -679,7 +679,7 @@ config ARCH_MMAP_RND_BITS
- int "Number of bits to use for ASLR of mmap base address" if EXPERT
- range ARCH_MMAP_RND_BITS_MIN ARCH_MMAP_RND_BITS_MAX
- default ARCH_MMAP_RND_BITS_DEFAULT if ARCH_MMAP_RND_BITS_DEFAULT
- - default ARCH_MMAP_RND_BITS_MIN
- + default ARCH_MMAP_RND_BITS_MAX
- depends on HAVE_ARCH_MMAP_RND_BITS
- help
- This value can be used to select the number of bits to use to
- @@ -713,7 +713,7 @@ config ARCH_MMAP_RND_COMPAT_BITS
- int "Number of bits to use for ASLR of mmap base address for compatible applications" if EXPERT
- range ARCH_MMAP_RND_COMPAT_BITS_MIN ARCH_MMAP_RND_COMPAT_BITS_MAX
- default ARCH_MMAP_RND_COMPAT_BITS_DEFAULT if ARCH_MMAP_RND_COMPAT_BITS_DEFAULT
- - default ARCH_MMAP_RND_COMPAT_BITS_MIN
- + default ARCH_MMAP_RND_COMPAT_BITS_MAX
- depends on HAVE_ARCH_MMAP_RND_COMPAT_BITS
- help
- This value can be used to select the number of bits to use to
- diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
- index 384b1bf56667..ccb53d76c68c 100644
- --- a/arch/arm64/Kconfig
- +++ b/arch/arm64/Kconfig
- @@ -1179,6 +1179,7 @@ config RODATA_FULL_DEFAULT_ENABLED
-
- config ARM64_SW_TTBR0_PAN
- bool "Emulate Privileged Access Never using TTBR0_EL1 switching"
- + default y
- help
- Enabling this option prevents the kernel from accessing
- user-space memory directly by pointing TTBR0_EL1 to a reserved
- @@ -1578,6 +1579,7 @@ config RANDOMIZE_BASE
- bool "Randomize the address of the kernel image"
- select ARM64_MODULE_PLTS if MODULES
- select RELOCATABLE
- + default y
- help
- Randomizes the virtual address at which the kernel image is
- loaded, as a security feature that deters exploit attempts
- diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug
- index cf09010d825f..dc4083ceff57 100644
- --- a/arch/arm64/Kconfig.debug
- +++ b/arch/arm64/Kconfig.debug
- @@ -43,6 +43,7 @@ config ARM64_RANDOMIZE_TEXT_OFFSET
- config DEBUG_WX
- bool "Warn on W+X mappings at boot"
- select ARM64_PTDUMP_CORE
- + default y
- ---help---
- Generate a warning if any W+X mappings are found at boot.
-
- diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
- index c9a867ac32d4..5c4d264f6a6e 100644
- --- a/arch/arm64/configs/defconfig
- +++ b/arch/arm64/configs/defconfig
- @@ -1,4 +1,3 @@
- -CONFIG_SYSVIPC=y
- CONFIG_POSIX_MQUEUE=y
- CONFIG_AUDIT=y
- CONFIG_NO_HZ_IDLE=y
- diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
- index b618017205a3..0a228dbcad65 100644
- --- a/arch/arm64/include/asm/elf.h
- +++ b/arch/arm64/include/asm/elf.h
- @@ -103,14 +103,10 @@
-
- /*
- * This is the base location for PIE (ET_DYN with INTERP) loads. On
- - * 64-bit, this is above 4GB to leave the entire 32-bit address
- + * 64-bit, this is raised to 4GB to leave the entire 32-bit address
- * space open for things that want to use the area for 32-bit pointers.
- */
- -#ifdef CONFIG_ARM64_FORCE_52BIT
- -#define ELF_ET_DYN_BASE (2 * TASK_SIZE_64 / 3)
- -#else
- -#define ELF_ET_DYN_BASE (2 * DEFAULT_MAP_WINDOW_64 / 3)
- -#endif /* CONFIG_ARM64_FORCE_52BIT */
- +#define ELF_ET_DYN_BASE 0x100000000UL
-
- #ifndef __ASSEMBLY__
-
- @@ -164,10 +160,10 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
- /* 1GB of VA */
- #ifdef CONFIG_COMPAT
- #define STACK_RND_MASK (test_thread_flag(TIF_32BIT) ? \
- - 0x7ff >> (PAGE_SHIFT - 12) : \
- - 0x3ffff >> (PAGE_SHIFT - 12))
- + ((1UL << mmap_rnd_compat_bits) - 1) >> (PAGE_SHIFT - 12) : \
- + ((1UL << mmap_rnd_bits) - 1) >> (PAGE_SHIFT - 12))
- #else
- -#define STACK_RND_MASK (0x3ffff >> (PAGE_SHIFT - 12))
- +#define STACK_RND_MASK (((1UL << mmap_rnd_bits) - 1) >> (PAGE_SHIFT - 12))
- #endif
-
- #ifdef __AARCH64EB__
- diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
- index df0a3a1b08ae..8c4d25460460 100644
- --- a/arch/x86/Kconfig
- +++ b/arch/x86/Kconfig
- @@ -1220,8 +1220,7 @@ config VM86
- default X86_LEGACY_VM86
-
- config X86_16BIT
- - bool "Enable support for 16-bit segments" if EXPERT
- - default y
- + bool "Enable support for 16-bit segments"
- depends on MODIFY_LDT_SYSCALL
- ---help---
- This option is required by programs like Wine to run 16-bit
- @@ -2366,7 +2365,7 @@ config COMPAT_VDSO
- choice
- prompt "vsyscall table for legacy applications"
- depends on X86_64
- - default LEGACY_VSYSCALL_XONLY
- + default LEGACY_VSYSCALL_NONE
- help
- Legacy user code that does not know how to find the vDSO expects
- to be able to issue three syscalls by calling fixed addresses in
- @@ -2462,8 +2461,7 @@ config CMDLINE_OVERRIDE
- be set to 'N' under normal conditions.
-
- config MODIFY_LDT_SYSCALL
- - bool "Enable the LDT (local descriptor table)" if EXPERT
- - default y
- + bool "Enable the LDT (local descriptor table)"
- ---help---
- Linux can allow user programs to install a per-process x86
- Local Descriptor Table (LDT) using the modify_ldt(2) system
- diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
- index bf9cd83de777..13ef90f3de52 100644
- --- a/arch/x86/Kconfig.debug
- +++ b/arch/x86/Kconfig.debug
- @@ -91,6 +91,7 @@ config EFI_PGT_DUMP
- config DEBUG_WX
- bool "Warn on W+X mappings at boot"
- select X86_PTDUMP_CORE
- + default y
- ---help---
- Generate a warning if any W+X mappings are found at boot.
-
- diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig
- index 8092d7baf8b5..6cdf055c7a79 100644
- --- a/arch/x86/configs/x86_64_defconfig
- +++ b/arch/x86/configs/x86_64_defconfig
- @@ -1,5 +1,4 @@
- # CONFIG_LOCALVERSION_AUTO is not set
- -CONFIG_SYSVIPC=y
- CONFIG_POSIX_MQUEUE=y
- CONFIG_BSD_PROCESS_ACCT=y
- CONFIG_TASKSTATS=y
- diff --git a/arch/x86/entry/vdso/vma.c b/arch/x86/entry/vdso/vma.c
- index 8d7a4a2caf55..ca6e37881893 100644
- --- a/arch/x86/entry/vdso/vma.c
- +++ b/arch/x86/entry/vdso/vma.c
- @@ -198,55 +198,9 @@ static int map_vdso(const struct vdso_image *image, unsigned long addr)
- }
-
- #ifdef CONFIG_X86_64
- -/*
- - * Put the vdso above the (randomized) stack with another randomized
- - * offset. This way there is no hole in the middle of address space.
- - * To save memory make sure it is still in the same PTE as the stack
- - * top. This doesn't give that many random bits.
- - *
- - * Note that this algorithm is imperfect: the distribution of the vdso
- - * start address within a PMD is biased toward the end.
- - *
- - * Only used for the 64-bit and x32 vdsos.
- - */
- -static unsigned long vdso_addr(unsigned long start, unsigned len)
- -{
- - unsigned long addr, end;
- - unsigned offset;
- -
- - /*
- - * Round up the start address. It can start out unaligned as a result
- - * of stack start randomization.
- - */
- - start = PAGE_ALIGN(start);
- -
- - /* Round the lowest possible end address up to a PMD boundary. */
- - end = (start + len + PMD_SIZE - 1) & PMD_MASK;
- - if (end >= DEFAULT_MAP_WINDOW)
- - end = DEFAULT_MAP_WINDOW;
- - end -= len;
- -
- - if (end > start) {
- - offset = get_random_int() % (((end - start) >> PAGE_SHIFT) + 1);
- - addr = start + (offset << PAGE_SHIFT);
- - } else {
- - addr = start;
- - }
- -
- - /*
- - * Forcibly align the final address in case we have a hardware
- - * issue that requires alignment for performance reasons.
- - */
- - addr = align_vdso_addr(addr);
- -
- - return addr;
- -}
- -
- static int map_vdso_randomized(const struct vdso_image *image)
- {
- - unsigned long addr = vdso_addr(current->mm->start_stack, image->size-image->sym_vvar_start);
- -
- - return map_vdso(image, addr);
- + return map_vdso(image, 0);
- }
- #endif
-
- diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
- index 69c0f892e310..f9f7a85bb71e 100644
- --- a/arch/x86/include/asm/elf.h
- +++ b/arch/x86/include/asm/elf.h
- @@ -248,11 +248,11 @@ extern int force_personality32;
-
- /*
- * This is the base location for PIE (ET_DYN with INTERP) loads. On
- - * 64-bit, this is above 4GB to leave the entire 32-bit address
- + * 64-bit, this is raised to 4GB to leave the entire 32-bit address
- * space open for things that want to use the area for 32-bit pointers.
- */
- #define ELF_ET_DYN_BASE (mmap_is_ia32() ? 0x000400000UL : \
- - (DEFAULT_MAP_WINDOW / 3 * 2))
- + 0x100000000UL)
-
- /* This yields a mask that user programs can use to figure out what
- instruction set this CPU supports. This could be done in user space,
- @@ -312,8 +312,8 @@ extern bool mmap_address_hint_valid(unsigned long addr, unsigned long len);
-
- #ifdef CONFIG_X86_32
-
- -#define __STACK_RND_MASK(is32bit) (0x7ff)
- -#define STACK_RND_MASK (0x7ff)
- +#define __STACK_RND_MASK(is32bit) ((1UL << mmap_rnd_bits) - 1)
- +#define STACK_RND_MASK ((1UL << mmap_rnd_bits) - 1)
-
- #define ARCH_DLINFO ARCH_DLINFO_IA32
-
- @@ -322,7 +322,11 @@ extern bool mmap_address_hint_valid(unsigned long addr, unsigned long len);
- #else /* CONFIG_X86_32 */
-
- /* 1GB for 64bit, 8MB for 32bit */
- -#define __STACK_RND_MASK(is32bit) ((is32bit) ? 0x7ff : 0x3fffff)
- +#ifdef CONFIG_COMPAT
- +#define __STACK_RND_MASK(is32bit) ((is32bit) ? (1UL << mmap_rnd_compat_bits) - 1 : (1UL << mmap_rnd_bits) - 1)
- +#else
- +#define __STACK_RND_MASK(is32bit) ((1UL << mmap_rnd_bits) - 1)
- +#endif
- #define STACK_RND_MASK __STACK_RND_MASK(mmap_is_ia32())
-
- #define ARCH_DLINFO \
- @@ -380,5 +384,4 @@ struct va_alignment {
- } ____cacheline_aligned;
-
- extern struct va_alignment va_align;
- -extern unsigned long align_vdso_addr(unsigned long);
- #endif /* _ASM_X86_ELF_H */
- diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
- index 6f66d841262d..6914640316dc 100644
- --- a/arch/x86/include/asm/tlbflush.h
- +++ b/arch/x86/include/asm/tlbflush.h
- @@ -295,6 +295,7 @@ static inline void cr4_set_bits_irqsoff(unsigned long mask)
- unsigned long cr4;
-
- cr4 = this_cpu_read(cpu_tlbstate.cr4);
- + BUG_ON(cr4 != __read_cr4());
- if ((cr4 | mask) != cr4)
- __cr4_set(cr4 | mask);
- }
- @@ -305,6 +306,7 @@ static inline void cr4_clear_bits_irqsoff(unsigned long mask)
- unsigned long cr4;
-
- cr4 = this_cpu_read(cpu_tlbstate.cr4);
- + BUG_ON(cr4 != __read_cr4());
- if ((cr4 & ~mask) != cr4)
- __cr4_set(cr4 & ~mask);
- }
- @@ -334,6 +336,7 @@ static inline void cr4_toggle_bits_irqsoff(unsigned long mask)
- unsigned long cr4;
-
- cr4 = this_cpu_read(cpu_tlbstate.cr4);
- + BUG_ON(cr4 != __read_cr4());
- __cr4_set(cr4 ^ mask);
- }
-
- @@ -440,6 +443,7 @@ static inline void __native_flush_tlb_global(void)
- raw_local_irq_save(flags);
-
- cr4 = this_cpu_read(cpu_tlbstate.cr4);
- + BUG_ON(cr4 != __read_cr4());
- /* toggle PGE */
- native_write_cr4(cr4 ^ X86_CR4_PGE);
- /* write old PGE again and flush TLBs */
- diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
- index 1592f309c3c1..136a272ceb09 100644
- --- a/arch/x86/kernel/cpu/common.c
- +++ b/arch/x86/kernel/cpu/common.c
- @@ -2033,7 +2033,6 @@ void cpu_init(void)
- wrmsrl(MSR_KERNEL_GS_BASE, 0);
- barrier();
-
- - x86_configure_nx();
- x2apic_setup();
-
- /*
- diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
- index b8de27bb6e09..4149f330076f 100644
- --- a/arch/x86/kernel/process.c
- +++ b/arch/x86/kernel/process.c
- @@ -42,6 +42,8 @@
- #include <asm/prctl.h>
- #include <asm/spec-ctrl.h>
- #include <asm/proto.h>
- +#include <asm/elf.h>
- +#include <linux/sizes.h>
-
- #include "process.h"
-
- @@ -793,7 +795,10 @@ unsigned long arch_align_stack(unsigned long sp)
-
- unsigned long arch_randomize_brk(struct mm_struct *mm)
- {
- - return randomize_page(mm->brk, 0x02000000);
- + if (mmap_is_ia32())
- + return mm->brk + get_random_long() % SZ_32M + PAGE_SIZE;
- + else
- + return mm->brk + get_random_long() % SZ_1G + PAGE_SIZE;
- }
-
- /*
- diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
- index 42e31358a9d3..e13f2166f922 100644
- --- a/arch/x86/kernel/sys_x86_64.c
- +++ b/arch/x86/kernel/sys_x86_64.c
- @@ -54,13 +54,6 @@ static unsigned long get_align_bits(void)
- return va_align.bits & get_align_mask();
- }
-
- -unsigned long align_vdso_addr(unsigned long addr)
- -{
- - unsigned long align_mask = get_align_mask();
- - addr = (addr + align_mask) & ~align_mask;
- - return addr | get_align_bits();
- -}
- -
- static int __init control_va_addr_alignment(char *str)
- {
- /* guard against enabling this on other CPU families */
- diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
- index 0a74407ef92e..5ceff405c81c 100644
- --- a/arch/x86/mm/init_32.c
- +++ b/arch/x86/mm/init_32.c
- @@ -560,9 +560,9 @@ static void __init pagetable_init(void)
-
- #define DEFAULT_PTE_MASK ~(_PAGE_NX | _PAGE_GLOBAL)
- /* Bits supported by the hardware: */
- -pteval_t __supported_pte_mask __read_mostly = DEFAULT_PTE_MASK;
- +pteval_t __supported_pte_mask __ro_after_init = DEFAULT_PTE_MASK;
- /* Bits allowed in normal kernel mappings: */
- -pteval_t __default_kernel_pte_mask __read_mostly = DEFAULT_PTE_MASK;
- +pteval_t __default_kernel_pte_mask __ro_after_init = DEFAULT_PTE_MASK;
- EXPORT_SYMBOL_GPL(__supported_pte_mask);
- /* Used in PAGE_KERNEL_* macros which are reasonably used out-of-tree: */
- EXPORT_SYMBOL(__default_kernel_pte_mask);
- diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
- index a37ccafe065b..64df9614e105 100644
- --- a/arch/x86/mm/init_64.c
- +++ b/arch/x86/mm/init_64.c
- @@ -97,9 +97,9 @@ DEFINE_ENTRY(pte, pte, init)
- */
-
- /* Bits supported by the hardware: */
- -pteval_t __supported_pte_mask __read_mostly = ~0;
- +pteval_t __supported_pte_mask __ro_after_init = ~0;
- /* Bits allowed in normal kernel mappings: */
- -pteval_t __default_kernel_pte_mask __read_mostly = ~0;
- +pteval_t __default_kernel_pte_mask __ro_after_init = ~0;
- EXPORT_SYMBOL_GPL(__supported_pte_mask);
- /* Used in PAGE_KERNEL_* macros which are reasonably used out-of-tree: */
- EXPORT_SYMBOL(__default_kernel_pte_mask);
- diff --git a/block/blk-softirq.c b/block/blk-softirq.c
- index 457d9ba3eb20..5f987fc1c0a0 100644
- --- a/block/blk-softirq.c
- +++ b/block/blk-softirq.c
- @@ -20,7 +20,7 @@ static DEFINE_PER_CPU(struct list_head, blk_cpu_done);
- * Softirq action handler - move entries to local list and loop over them
- * while passing them to the queue registered handler.
- */
- -static __latent_entropy void blk_done_softirq(struct softirq_action *h)
- +static __latent_entropy void blk_done_softirq(void)
- {
- struct list_head *cpu_list, local_list;
-
- diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
- index e2cf9859c67b..9b7ec4e053bd 100644
- --- a/drivers/ata/libata-core.c
- +++ b/drivers/ata/libata-core.c
- @@ -5199,7 +5199,7 @@ void ata_qc_free(struct ata_queued_cmd *qc)
- struct ata_port *ap;
- unsigned int tag;
-
- - WARN_ON_ONCE(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
- + BUG_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
- ap = qc->ap;
-
- qc->flags = 0;
- @@ -5216,7 +5216,7 @@ void __ata_qc_complete(struct ata_queued_cmd *qc)
- struct ata_port *ap;
- struct ata_link *link;
-
- - WARN_ON_ONCE(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
- + BUG_ON(qc == NULL); /* ata_qc_from_tag _might_ return NULL */
- WARN_ON_ONCE(!(qc->flags & ATA_QCFLAG_ACTIVE));
- ap = qc->ap;
- link = qc->dev->link;
- diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
- index 85e97550a9a6..1cfd2c7bd1bf 100644
- --- a/drivers/char/Kconfig
- +++ b/drivers/char/Kconfig
- @@ -9,7 +9,6 @@ source "drivers/tty/Kconfig"
-
- config DEVMEM
- bool "/dev/mem virtual device support"
- - default y
- help
- Say Y here if you want to support the /dev/mem device.
- The /dev/mem device is used to access areas of physical
- @@ -514,7 +513,6 @@ config TELCLOCK
- config DEVPORT
- bool "/dev/port character device"
- depends on ISA || PCI
- - default y
- help
- Say Y here if you want to support the /dev/port device. The /dev/port
- device is similar to /dev/mem, but for I/O ports.
- diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig
- index c7623f99ac0f..859c2782c8e2 100644
- --- a/drivers/tty/Kconfig
- +++ b/drivers/tty/Kconfig
- @@ -122,7 +122,6 @@ config UNIX98_PTYS
-
- config LEGACY_PTYS
- bool "Legacy (BSD) PTY support"
- - default y
- ---help---
- A pseudo terminal (PTY) is a software device consisting of two
- halves: a master and a slave. The slave device behaves identical to
- diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
- index bb14bd4f6e55..340deb0029e2 100644
- --- a/drivers/tty/tty_io.c
- +++ b/drivers/tty/tty_io.c
- @@ -173,6 +173,7 @@ static void free_tty_struct(struct tty_struct *tty)
- put_device(tty->dev);
- kfree(tty->write_buf);
- tty->magic = 0xDEADDEAD;
- + put_user_ns(tty->owner_user_ns);
- kfree(tty);
- }
-
- @@ -2180,11 +2181,19 @@ static int tty_fasync(int fd, struct file *filp, int on)
- * current->signal->tty check is safe without locks
- */
-
- +int tiocsti_restrict = IS_ENABLED(CONFIG_SECURITY_TIOCSTI_RESTRICT);
- +
- static int tiocsti(struct tty_struct *tty, char __user *p)
- {
- char ch, mbz = 0;
- struct tty_ldisc *ld;
-
- + if (tiocsti_restrict &&
- + !ns_capable(tty->owner_user_ns, CAP_SYS_ADMIN)) {
- + dev_warn_ratelimited(tty->dev,
- + "Denied TIOCSTI ioctl for non-privileged process\n");
- + return -EPERM;
- + }
- if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (get_user(ch, p))
- @@ -3013,6 +3022,7 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx)
- tty->index = idx;
- tty_line_name(driver, idx, tty->name);
- tty->dev = tty_get_device(tty);
- + tty->owner_user_ns = get_user_ns(current_user_ns());
-
- return tty;
- }
- diff --git a/drivers/usb/core/Makefile b/drivers/usb/core/Makefile
- index 18e874b0441e..a010a4a5830e 100644
- --- a/drivers/usb/core/Makefile
- +++ b/drivers/usb/core/Makefile
- @@ -11,6 +11,7 @@ usbcore-y += phy.o port.o
- usbcore-$(CONFIG_OF) += of.o
- usbcore-$(CONFIG_USB_PCI) += hcd-pci.o
- usbcore-$(CONFIG_ACPI) += usb-acpi.o
- +usbcore-$(CONFIG_SYSCTL) += sysctl.o
-
- obj-$(CONFIG_USB) += usbcore.o
-
- diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
- index 238674fab7ce..289edfcd7f42 100644
- --- a/drivers/usb/core/hub.c
- +++ b/drivers/usb/core/hub.c
- @@ -5095,6 +5095,12 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
- goto done;
- return;
- }
- +
- + if (deny_new_usb) {
- + dev_err(&port_dev->dev, "denied insert of USB device on port %d\n", port1);
- + goto done;
- + }
- +
- if (hub_is_superspeed(hub->hdev))
- unit_load = 150;
- else
- diff --git a/drivers/usb/core/sysctl.c b/drivers/usb/core/sysctl.c
- new file mode 100644
- index 000000000000..2b7b9d778dd2
- --- /dev/null
- +++ b/drivers/usb/core/sysctl.c
- @@ -0,0 +1,46 @@
- +#include <linux/errno.h>
- +#include <linux/printk.h>
- +#include <linux/init.h>
- +#include <linux/sysctl.h>
- +#include <linux/usb.h>
- +
- +static int zero = 0;
- +static int one = 1;
- +
- +static struct ctl_table usb_table[] = {
- + {
- + .procname = "deny_new_usb",
- + .data = &deny_new_usb,
- + .maxlen = sizeof(int),
- + .mode = 0644,
- + .proc_handler = proc_dointvec_minmax_sysadmin,
- + .extra1 = &zero,
- + .extra2 = &one,
- + },
- + { }
- +};
- +
- +static struct ctl_table usb_root_table[] = {
- + { .procname = "kernel",
- + .mode = 0555,
- + .child = usb_table },
- + { }
- +};
- +
- +static struct ctl_table_header *usb_table_header;
- +
- +int __init usb_init_sysctl(void)
- +{
- + usb_table_header = register_sysctl_table(usb_root_table);
- + if (!usb_table_header) {
- + pr_warn("usb: sysctl registration failed\n");
- + return -ENOMEM;
- + }
- +
- + return 0;
- +}
- +
- +void usb_exit_sysctl(void)
- +{
- + unregister_sysctl_table(usb_table_header);
- +}
- diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
- index 502d911f71fa..61f3174cc3d8 100644
- --- a/drivers/usb/core/usb.c
- +++ b/drivers/usb/core/usb.c
- @@ -73,6 +73,9 @@ MODULE_PARM_DESC(autosuspend, "default autosuspend delay");
- #define usb_autosuspend_delay 0
- #endif
-
- +int deny_new_usb __read_mostly = 0;
- +EXPORT_SYMBOL(deny_new_usb);
- +
- static bool match_endpoint(struct usb_endpoint_descriptor *epd,
- struct usb_endpoint_descriptor **bulk_in,
- struct usb_endpoint_descriptor **bulk_out,
- @@ -1067,6 +1070,9 @@ static int __init usb_init(void)
- usb_debugfs_init();
-
- usb_acpi_register();
- + retval = usb_init_sysctl();
- + if (retval)
- + goto sysctl_init_failed;
- retval = bus_register(&usb_bus_type);
- if (retval)
- goto bus_register_failed;
- @@ -1101,6 +1107,8 @@ static int __init usb_init(void)
- bus_notifier_failed:
- bus_unregister(&usb_bus_type);
- bus_register_failed:
- + usb_exit_sysctl();
- +sysctl_init_failed:
- usb_acpi_unregister();
- usb_debugfs_cleanup();
- out:
- @@ -1124,6 +1132,7 @@ static void __exit usb_exit(void)
- usb_hub_cleanup();
- bus_unregister_notifier(&usb_bus_type, &usb_bus_nb);
- bus_unregister(&usb_bus_type);
- + usb_exit_sysctl();
- usb_acpi_unregister();
- usb_debugfs_cleanup();
- idr_destroy(&usb_bus_idr);
- diff --git a/fs/exec.c b/fs/exec.c
- index a7d78241082a..58901ced219e 100644
- --- a/fs/exec.c
- +++ b/fs/exec.c
- @@ -63,6 +63,7 @@
- #include <linux/oom.h>
- #include <linux/compat.h>
- #include <linux/vmalloc.h>
- +#include <linux/random.h>
-
- #include <linux/uaccess.h>
- #include <asm/mmu_context.h>
- @@ -276,6 +277,8 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
- arch_bprm_mm_init(mm, vma);
- up_write(&mm->mmap_sem);
- bprm->p = vma->vm_end - sizeof(void *);
- + if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
- + bprm->p ^= get_random_int() & ~PAGE_MASK;
- return 0;
- err:
- up_write(&mm->mmap_sem);
- diff --git a/fs/namei.c b/fs/namei.c
- index a4cba6991a4d..ad71a8abbd82 100644
- --- a/fs/namei.c
- +++ b/fs/namei.c
- @@ -877,10 +877,10 @@ static inline void put_link(struct nameidata *nd)
- path_put(&last->link);
- }
-
- -int sysctl_protected_symlinks __read_mostly = 0;
- -int sysctl_protected_hardlinks __read_mostly = 0;
- -int sysctl_protected_fifos __read_mostly;
- -int sysctl_protected_regular __read_mostly;
- +int sysctl_protected_symlinks __read_mostly = 1;
- +int sysctl_protected_hardlinks __read_mostly = 1;
- +int sysctl_protected_fifos __read_mostly = 2;
- +int sysctl_protected_regular __read_mostly = 2;
-
- /**
- * may_follow_link - Check symlink following for unsafe situations
- diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
- index e84c187d942e..fdac5ca7f677 100644
- --- a/fs/nfs/Kconfig
- +++ b/fs/nfs/Kconfig
- @@ -195,4 +195,3 @@ config NFS_DEBUG
- bool
- depends on NFS_FS && SUNRPC_DEBUG
- select CRC32
- - default y
- diff --git a/fs/proc/Kconfig b/fs/proc/Kconfig
- index cb5629bd5fff..bc44606fcc48 100644
- --- a/fs/proc/Kconfig
- +++ b/fs/proc/Kconfig
- @@ -41,7 +41,6 @@ config PROC_KCORE
- config PROC_VMCORE
- bool "/proc/vmcore support"
- depends on PROC_FS && CRASH_DUMP
- - default y
- help
- Exports the dump image of crashed kernel in ELF format.
-
- diff --git a/fs/stat.c b/fs/stat.c
- index 268c9eb89656..b6ef85222932 100644
- --- a/fs/stat.c
- +++ b/fs/stat.c
- @@ -40,8 +40,13 @@ void generic_fillattr(struct inode *inode, struct kstat *stat)
- stat->gid = inode->i_gid;
- stat->rdev = inode->i_rdev;
- stat->size = i_size_read(inode);
- - stat->atime = inode->i_atime;
- - stat->mtime = inode->i_mtime;
- + if (is_sidechannel_device(inode) && !capable_noaudit(CAP_MKNOD)) {
- + stat->atime = inode->i_ctime;
- + stat->mtime = inode->i_ctime;
- + } else {
- + stat->atime = inode->i_atime;
- + stat->mtime = inode->i_mtime;
- + }
- stat->ctime = inode->i_ctime;
- stat->blksize = i_blocksize(inode);
- stat->blocks = inode->i_blocks;
- @@ -77,9 +82,14 @@ int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
- if (IS_AUTOMOUNT(inode))
- stat->attributes |= STATX_ATTR_AUTOMOUNT;
-
- - if (inode->i_op->getattr)
- - return inode->i_op->getattr(path, stat, request_mask,
- - query_flags);
- + if (inode->i_op->getattr) {
- + int retval = inode->i_op->getattr(path, stat, request_mask, query_flags);
- + if (!retval && is_sidechannel_device(inode) && !capable_noaudit(CAP_MKNOD)) {
- + stat->atime = stat->ctime;
- + stat->mtime = stat->ctime;
- + }
- + return retval;
- + }
-
- generic_fillattr(inode, stat);
- return 0;
- diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
- index 740853465356..56d2e6966980 100644
- --- a/fs/userfaultfd.c
- +++ b/fs/userfaultfd.c
- @@ -28,7 +28,11 @@
- #include <linux/security.h>
- #include <linux/hugetlb.h>
-
- +#ifdef CONFIG_USERFAULTFD_UNPRIVILEGED
- int sysctl_unprivileged_userfaultfd __read_mostly = 1;
- +#else
- +int sysctl_unprivileged_userfaultfd __read_mostly;
- +#endif
-
- static struct kmem_cache *userfaultfd_ctx_cachep __read_mostly;
-
- diff --git a/include/linux/cache.h b/include/linux/cache.h
- index 750621e41d1c..e7157c18c62c 100644
- --- a/include/linux/cache.h
- +++ b/include/linux/cache.h
- @@ -31,6 +31,8 @@
- #define __ro_after_init __attribute__((__section__(".data..ro_after_init")))
- #endif
-
- +#define __read_only __ro_after_init
- +
- #ifndef ____cacheline_aligned
- #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
- #endif
- diff --git a/include/linux/capability.h b/include/linux/capability.h
- index ecce0f43c73a..e46306dd4401 100644
- --- a/include/linux/capability.h
- +++ b/include/linux/capability.h
- @@ -208,6 +208,7 @@ extern bool has_capability_noaudit(struct task_struct *t, int cap);
- extern bool has_ns_capability_noaudit(struct task_struct *t,
- struct user_namespace *ns, int cap);
- extern bool capable(int cap);
- +extern bool capable_noaudit(int cap);
- extern bool ns_capable(struct user_namespace *ns, int cap);
- extern bool ns_capable_noaudit(struct user_namespace *ns, int cap);
- extern bool ns_capable_setid(struct user_namespace *ns, int cap);
- @@ -234,6 +235,10 @@ static inline bool capable(int cap)
- {
- return true;
- }
- +static inline bool capable_noaudit(int cap)
- +{
- + return true;
- +}
- static inline bool ns_capable(struct user_namespace *ns, int cap)
- {
- return true;
- diff --git a/include/linux/fs.h b/include/linux/fs.h
- index e009b52ab6b0..71e374c77338 100644
- --- a/include/linux/fs.h
- +++ b/include/linux/fs.h
- @@ -3645,4 +3645,15 @@ static inline int inode_drain_writes(struct inode *inode)
- return filemap_write_and_wait(inode->i_mapping);
- }
-
- +extern int device_sidechannel_restrict;
- +
- +static inline bool is_sidechannel_device(const struct inode *inode)
- +{
- + umode_t mode;
- + if (!device_sidechannel_restrict)
- + return false;
- + mode = inode->i_mode;
- + return ((S_ISCHR(mode) || S_ISBLK(mode)) && (mode & (S_IROTH | S_IWOTH)));
- +}
- +
- #endif /* _LINUX_FS_H */
- diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
- index e9d2024473b0..e75cfbcfda56 100644
- --- a/include/linux/fsnotify.h
- +++ b/include/linux/fsnotify.h
- @@ -269,6 +269,9 @@ static inline void fsnotify_access(struct file *file)
- struct inode *inode = file_inode(file);
- __u32 mask = FS_ACCESS;
-
- + if (is_sidechannel_device(inode))
- + return;
- +
- if (S_ISDIR(inode->i_mode))
- mask |= FS_ISDIR;
-
- @@ -285,6 +288,9 @@ static inline void fsnotify_modify(struct file *file)
- struct inode *inode = file_inode(file);
- __u32 mask = FS_MODIFY;
-
- + if (is_sidechannel_device(inode))
- + return;
- +
- if (S_ISDIR(inode->i_mode))
- mask |= FS_ISDIR;
-
- diff --git a/include/linux/gfp.h b/include/linux/gfp.h
- index c89f8456f18d..c85e898c2a37 100644
- --- a/include/linux/gfp.h
- +++ b/include/linux/gfp.h
- @@ -553,9 +553,9 @@ extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order,
- extern unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order);
- extern unsigned long get_zeroed_page(gfp_t gfp_mask);
-
- -void *alloc_pages_exact(size_t size, gfp_t gfp_mask);
- +void *alloc_pages_exact(size_t size, gfp_t gfp_mask) __attribute__((alloc_size(1)));
- void free_pages_exact(void *virt, size_t size);
- -void * __meminit alloc_pages_exact_nid(int nid, size_t size, gfp_t gfp_mask);
- +void * __meminit alloc_pages_exact_nid(int nid, size_t size, gfp_t gfp_mask) __attribute__((alloc_size(2)));
-
- #define __get_free_page(gfp_mask) \
- __get_free_pages((gfp_mask), 0)
- diff --git a/include/linux/highmem.h b/include/linux/highmem.h
- index 900f224bb640..97e0135c8268 100644
- --- a/include/linux/highmem.h
- +++ b/include/linux/highmem.h
- @@ -215,6 +215,13 @@ static inline void clear_highpage(struct page *page)
- kunmap_atomic(kaddr);
- }
-
- +static inline void verify_zero_highpage(struct page *page)
- +{
- + void *kaddr = kmap_atomic(page);
- + BUG_ON(memchr_inv(kaddr, 0, PAGE_SIZE));
- + kunmap_atomic(kaddr);
- +}
- +
- static inline void zero_user_segments(struct page *page,
- unsigned start1, unsigned end1,
- unsigned start2, unsigned end2)
- diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
- index 01517747214a..8b712abac03f 100644
- --- a/include/linux/interrupt.h
- +++ b/include/linux/interrupt.h
- @@ -544,7 +544,7 @@ extern const char * const softirq_to_name[NR_SOFTIRQS];
-
- struct softirq_action
- {
- - void (*action)(struct softirq_action *);
- + void (*action)(void);
- };
-
- asmlinkage void do_softirq(void);
- @@ -559,7 +559,7 @@ static inline void do_softirq_own_stack(void)
- }
- #endif
-
- -extern void open_softirq(int nr, void (*action)(struct softirq_action *));
- +extern void __init open_softirq(int nr, void (*action)(void));
- extern void softirq_init(void);
- extern void __raise_softirq_irqoff(unsigned int nr);
-
- diff --git a/include/linux/kobject_ns.h b/include/linux/kobject_ns.h
- index 069aa2ebef90..cb9e3637a620 100644
- --- a/include/linux/kobject_ns.h
- +++ b/include/linux/kobject_ns.h
- @@ -45,7 +45,7 @@ struct kobj_ns_type_operations {
- void (*drop_ns)(void *);
- };
-
- -int kobj_ns_type_register(const struct kobj_ns_type_operations *ops);
- +int __init kobj_ns_type_register(const struct kobj_ns_type_operations *ops);
- int kobj_ns_type_registered(enum kobj_ns_type type);
- const struct kobj_ns_type_operations *kobj_child_ns_ops(struct kobject *parent);
- const struct kobj_ns_type_operations *kobj_ns_ops(struct kobject *kobj);
- diff --git a/include/linux/mm.h b/include/linux/mm.h
- index d14aba548ff4..2b665745900e 100644
- --- a/include/linux/mm.h
- +++ b/include/linux/mm.h
- @@ -667,7 +667,7 @@ static inline int is_vmalloc_or_module_addr(const void *x)
- }
- #endif
-
- -extern void *kvmalloc_node(size_t size, gfp_t flags, int node);
- +extern void *kvmalloc_node(size_t size, gfp_t flags, int node) __attribute__((alloc_size(1)));
- static inline void *kvmalloc(size_t size, gfp_t flags)
- {
- return kvmalloc_node(size, flags, NUMA_NO_NODE);
- diff --git a/include/linux/percpu.h b/include/linux/percpu.h
- index 5e76af742c80..9a6c682ec127 100644
- --- a/include/linux/percpu.h
- +++ b/include/linux/percpu.h
- @@ -123,7 +123,7 @@ extern int __init pcpu_page_first_chunk(size_t reserved_size,
- pcpu_fc_populate_pte_fn_t populate_pte_fn);
- #endif
-
- -extern void __percpu *__alloc_reserved_percpu(size_t size, size_t align);
- +extern void __percpu *__alloc_reserved_percpu(size_t size, size_t align) __attribute__((alloc_size(1)));
- extern bool __is_kernel_percpu_address(unsigned long addr, unsigned long *can_addr);
- extern bool is_kernel_percpu_address(unsigned long addr);
-
- @@ -131,8 +131,8 @@ extern bool is_kernel_percpu_address(unsigned long addr);
- extern void __init setup_per_cpu_areas(void);
- #endif
-
- -extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp);
- -extern void __percpu *__alloc_percpu(size_t size, size_t align);
- +extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp) __attribute__((alloc_size(1)));
- +extern void __percpu *__alloc_percpu(size_t size, size_t align) __attribute__((alloc_size(1)));
- extern void free_percpu(void __percpu *__pdata);
- extern phys_addr_t per_cpu_ptr_to_phys(void *addr);
-
- diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
- index 9e0e20c11aa3..6830f1831dea 100644
- --- a/include/linux/perf_event.h
- +++ b/include/linux/perf_event.h
- @@ -1271,6 +1271,11 @@ extern int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write,
- int perf_event_max_stack_handler(struct ctl_table *table, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos);
-
- +static inline bool perf_paranoid_any(void)
- +{
- + return sysctl_perf_event_paranoid > 2;
- +}
- +
- static inline bool perf_paranoid_tracepoint_raw(void)
- {
- return sysctl_perf_event_paranoid > -1;
- diff --git a/include/linux/slab.h b/include/linux/slab.h
- index 4d2a2fa55ed5..be3a8234edde 100644
- --- a/include/linux/slab.h
- +++ b/include/linux/slab.h
- @@ -184,8 +184,8 @@ void memcg_deactivate_kmem_caches(struct mem_cgroup *, struct mem_cgroup *);
- /*
- * Common kmalloc functions provided by all allocators
- */
- -void * __must_check __krealloc(const void *, size_t, gfp_t);
- -void * __must_check krealloc(const void *, size_t, gfp_t);
- +void * __must_check __krealloc(const void *, size_t, gfp_t) __attribute__((alloc_size(2)));
- +void * __must_check krealloc(const void *, size_t, gfp_t) __attribute((alloc_size(2)));
- void kfree(const void *);
- void kzfree(const void *);
- size_t __ksize(const void *);
- @@ -390,7 +390,7 @@ static __always_inline unsigned int kmalloc_index(size_t size)
- }
- #endif /* !CONFIG_SLOB */
-
- -void *__kmalloc(size_t size, gfp_t flags) __assume_kmalloc_alignment __malloc;
- +void *__kmalloc(size_t size, gfp_t flags) __assume_kmalloc_alignment __malloc __attribute__((alloc_size(1)));
- void *kmem_cache_alloc(struct kmem_cache *, gfp_t flags) __assume_slab_alignment __malloc;
- void kmem_cache_free(struct kmem_cache *, void *);
-
- @@ -414,7 +414,7 @@ static __always_inline void kfree_bulk(size_t size, void **p)
- }
-
- #ifdef CONFIG_NUMA
- -void *__kmalloc_node(size_t size, gfp_t flags, int node) __assume_kmalloc_alignment __malloc;
- +void *__kmalloc_node(size_t size, gfp_t flags, int node) __assume_kmalloc_alignment __malloc __attribute__((alloc_size(1)));
- void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node) __assume_slab_alignment __malloc;
- #else
- static __always_inline void *__kmalloc_node(size_t size, gfp_t flags, int node)
- @@ -539,7 +539,7 @@ static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
- * Try really hard to succeed the allocation but fail
- * eventually.
- */
- -static __always_inline void *kmalloc(size_t size, gfp_t flags)
- +static __always_inline __attribute__((alloc_size(1))) void *kmalloc(size_t size, gfp_t flags)
- {
- if (__builtin_constant_p(size)) {
- #ifndef CONFIG_SLOB
- @@ -581,7 +581,7 @@ static __always_inline unsigned int kmalloc_size(unsigned int n)
- return 0;
- }
-
- -static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
- +static __always_inline __attribute__((alloc_size(1))) void *kmalloc_node(size_t size, gfp_t flags, int node)
- {
- #ifndef CONFIG_SLOB
- if (__builtin_constant_p(size) &&
- diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
- index d2153789bd9f..97da977d6060 100644
- --- a/include/linux/slub_def.h
- +++ b/include/linux/slub_def.h
- @@ -121,6 +121,11 @@ struct kmem_cache {
- unsigned long random;
- #endif
-
- +#ifdef CONFIG_SLAB_CANARY
- + unsigned long random_active;
- + unsigned long random_inactive;
- +#endif
- +
- #ifdef CONFIG_NUMA
- /*
- * Defragmentation by allocating from a remote node.
- diff --git a/include/linux/string.h b/include/linux/string.h
- index b2264355272d..2115131ba73f 100644
- --- a/include/linux/string.h
- +++ b/include/linux/string.h
- @@ -268,6 +268,12 @@ void __read_overflow2(void) __compiletime_error("detected read beyond size of ob
- void __read_overflow3(void) __compiletime_error("detected read beyond size of object passed as 3rd parameter");
- void __write_overflow(void) __compiletime_error("detected write beyond size of object passed as 1st parameter");
-
- +#ifdef CONFIG_FORTIFY_SOURCE_STRICT_STRING
- +#define __string_size(p) __builtin_object_size(p, 1)
- +#else
- +#define __string_size(p) __builtin_object_size(p, 0)
- +#endif
- +
- #if !defined(__NO_FORTIFY) && defined(__OPTIMIZE__) && defined(CONFIG_FORTIFY_SOURCE)
-
- #ifdef CONFIG_KASAN
- @@ -296,7 +302,7 @@ extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size)
-
- __FORTIFY_INLINE char *strncpy(char *p, const char *q, __kernel_size_t size)
- {
- - size_t p_size = __builtin_object_size(p, 0);
- + size_t p_size = __string_size(p);
- if (__builtin_constant_p(size) && p_size < size)
- __write_overflow();
- if (p_size < size)
- @@ -306,7 +312,7 @@ __FORTIFY_INLINE char *strncpy(char *p, const char *q, __kernel_size_t size)
-
- __FORTIFY_INLINE char *strcat(char *p, const char *q)
- {
- - size_t p_size = __builtin_object_size(p, 0);
- + size_t p_size = __string_size(p);
- if (p_size == (size_t)-1)
- return __underlying_strcat(p, q);
- if (strlcat(p, q, p_size) >= p_size)
- @@ -317,7 +323,7 @@ __FORTIFY_INLINE char *strcat(char *p, const char *q)
- __FORTIFY_INLINE __kernel_size_t strlen(const char *p)
- {
- __kernel_size_t ret;
- - size_t p_size = __builtin_object_size(p, 0);
- + size_t p_size = __string_size(p);
-
- /* Work around gcc excess stack consumption issue */
- if (p_size == (size_t)-1 ||
- @@ -332,7 +338,7 @@ __FORTIFY_INLINE __kernel_size_t strlen(const char *p)
- extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __RENAME(strnlen);
- __FORTIFY_INLINE __kernel_size_t strnlen(const char *p, __kernel_size_t maxlen)
- {
- - size_t p_size = __builtin_object_size(p, 0);
- + size_t p_size = __string_size(p);
- __kernel_size_t ret = __real_strnlen(p, maxlen < p_size ? maxlen : p_size);
- if (p_size <= ret && maxlen != ret)
- fortify_panic(__func__);
- @@ -344,8 +350,8 @@ extern size_t __real_strlcpy(char *, const char *, size_t) __RENAME(strlcpy);
- __FORTIFY_INLINE size_t strlcpy(char *p, const char *q, size_t size)
- {
- size_t ret;
- - size_t p_size = __builtin_object_size(p, 0);
- - size_t q_size = __builtin_object_size(q, 0);
- + size_t p_size = __string_size(p);
- + size_t q_size = __string_size(q);
- if (p_size == (size_t)-1 && q_size == (size_t)-1)
- return __real_strlcpy(p, q, size);
- ret = strlen(q);
- @@ -365,8 +371,8 @@ __FORTIFY_INLINE size_t strlcpy(char *p, const char *q, size_t size)
- __FORTIFY_INLINE char *strncat(char *p, const char *q, __kernel_size_t count)
- {
- size_t p_len, copy_len;
- - size_t p_size = __builtin_object_size(p, 0);
- - size_t q_size = __builtin_object_size(q, 0);
- + size_t p_size = __string_size(p);
- + size_t q_size = __string_size(q);
- if (p_size == (size_t)-1 && q_size == (size_t)-1)
- return __underlying_strncat(p, q, count);
- p_len = strlen(p);
- @@ -479,8 +485,8 @@ __FORTIFY_INLINE void *kmemdup(const void *p, size_t size, gfp_t gfp)
- /* defined after fortified strlen and memcpy to reuse them */
- __FORTIFY_INLINE char *strcpy(char *p, const char *q)
- {
- - size_t p_size = __builtin_object_size(p, 0);
- - size_t q_size = __builtin_object_size(q, 0);
- + size_t p_size = __string_size(p);
- + size_t q_size = __string_size(q);
- if (p_size == (size_t)-1 && q_size == (size_t)-1)
- return __underlying_strcpy(p, q);
- memcpy(p, q, strlen(q) + 1);
- diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
- index aa615a0863f5..56e46e43b1b0 100644
- --- a/include/linux/sysctl.h
- +++ b/include/linux/sysctl.h
- @@ -58,6 +58,8 @@ extern int proc_dointvec_minmax(struct ctl_table *, int,
- extern int proc_douintvec_minmax(struct ctl_table *table, int write,
- void __user *buffer, size_t *lenp,
- loff_t *ppos);
- +extern int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
- + void *buffer, size_t *lenp, loff_t *ppos);
- extern int proc_dointvec_jiffies(struct ctl_table *, int,
- void __user *, size_t *, loff_t *);
- extern int proc_dointvec_userhz_jiffies(struct ctl_table *, int,
- diff --git a/include/linux/tty.h b/include/linux/tty.h
- index 8be25caa97f6..ca9ea36782a3 100644
- --- a/include/linux/tty.h
- +++ b/include/linux/tty.h
- @@ -14,6 +14,7 @@
- #include <uapi/linux/tty.h>
- #include <linux/rwsem.h>
- #include <linux/llist.h>
- +#include <linux/user_namespace.h>
-
-
- /*
- @@ -342,6 +343,7 @@ struct tty_struct {
- /* If the tty has a pending do_SAK, queue it here - akpm */
- struct work_struct SAK_work;
- struct tty_port *port;
- + struct user_namespace *owner_user_ns;
- } __randomize_layout;
-
- /* Each of a tty's open files has private_data pointing to tty_file_private */
- @@ -351,6 +353,8 @@ struct tty_file_private {
- struct list_head list;
- };
-
- +extern int tiocsti_restrict;
- +
- /* tty magic number */
- #define TTY_MAGIC 0x5401
-
- diff --git a/include/linux/usb.h b/include/linux/usb.h
- index abcf1ce9bb06..25dfdd22bc7d 100644
- --- a/include/linux/usb.h
- +++ b/include/linux/usb.h
- @@ -2025,6 +2025,16 @@ extern void usb_led_activity(enum usb_led_event ev);
- static inline void usb_led_activity(enum usb_led_event ev) {}
- #endif
-
- +/* sysctl.c */
- +extern int deny_new_usb;
- +#ifdef CONFIG_SYSCTL
- +extern int usb_init_sysctl(void);
- +extern void usb_exit_sysctl(void);
- +#else
- +static inline int usb_init_sysctl(void) { return 0; }
- +static inline void usb_exit_sysctl(void) { }
- +#endif /* CONFIG_SYSCTL */
- +
- #endif /* __KERNEL__ */
-
- #endif
- diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
- index 01a1334c5fc5..576e00382884 100644
- --- a/include/linux/vmalloc.h
- +++ b/include/linux/vmalloc.h
- @@ -88,19 +88,19 @@ static inline void vmalloc_init(void)
- static inline unsigned long vmalloc_nr_pages(void) { return 0; }
- #endif
-
- -extern void *vmalloc(unsigned long size);
- -extern void *vzalloc(unsigned long size);
- -extern void *vmalloc_user(unsigned long size);
- -extern void *vmalloc_node(unsigned long size, int node);
- -extern void *vzalloc_node(unsigned long size, int node);
- -extern void *vmalloc_exec(unsigned long size);
- -extern void *vmalloc_32(unsigned long size);
- -extern void *vmalloc_32_user(unsigned long size);
- -extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot);
- +extern void *vmalloc(unsigned long size) __attribute__((alloc_size(1)));
- +extern void *vzalloc(unsigned long size) __attribute__((alloc_size(1)));
- +extern void *vmalloc_user(unsigned long size) __attribute__((alloc_size(1)));
- +extern void *vmalloc_node(unsigned long size, int node) __attribute__((alloc_size(1)));
- +extern void *vzalloc_node(unsigned long size, int node) __attribute__((alloc_size(1)));
- +extern void *vmalloc_exec(unsigned long size) __attribute__((alloc_size(1)));
- +extern void *vmalloc_32(unsigned long size) __attribute__((alloc_size(1)));
- +extern void *vmalloc_32_user(unsigned long size) __attribute__((alloc_size(1)));
- +extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot) __attribute__((alloc_size(1)));
- extern void *__vmalloc_node_range(unsigned long size, unsigned long align,
- unsigned long start, unsigned long end, gfp_t gfp_mask,
- pgprot_t prot, unsigned long vm_flags, int node,
- - const void *caller);
- + const void *caller) __attribute__((alloc_size(1)));
- #ifndef CONFIG_MMU
- extern void *__vmalloc_node_flags(unsigned long size, int node, gfp_t flags);
- static inline void *__vmalloc_node_flags_caller(unsigned long size, int node,
- diff --git a/include/net/tcp.h b/include/net/tcp.h
- index 164ba7b77bd9..159339f324a4 100644
- --- a/include/net/tcp.h
- +++ b/include/net/tcp.h
- @@ -246,6 +246,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo);
- /* sysctl variables for tcp */
- extern int sysctl_tcp_max_orphans;
- extern long sysctl_tcp_mem[3];
- +extern int sysctl_tcp_simult_connect;
-
- #define TCP_RACK_LOSS_DETECTION 0x1 /* Use RACK to detect losses */
- #define TCP_RACK_STATIC_REO_WND 0x2 /* Use static RACK reo wnd */
- diff --git a/init/Kconfig b/init/Kconfig
- index f641518f4ac5..54786890b3e7 100644
- --- a/init/Kconfig
- +++ b/init/Kconfig
- @@ -357,6 +357,7 @@ config USELIB
- config AUDIT
- bool "Auditing support"
- depends on NET
- + default y
- help
- Enable auditing infrastructure that can be used with another
- kernel subsystem, such as SELinux (which requires this for
- @@ -1095,6 +1096,22 @@ config USER_NS
-
- If unsure, say N.
-
- +config USER_NS_UNPRIVILEGED
- + bool "Allow unprivileged users to create namespaces"
- + depends on USER_NS
- + default n
- + help
- + When disabled, unprivileged users will not be able to create
- + new namespaces. Allowing users to create their own namespaces
- + has been part of several recent local privilege escalation
- + exploits, so if you need user namespaces but are
- + paranoid^Wsecurity-conscious you want to disable this.
- +
- + This setting can be overridden at runtime via the
- + kernel.unprivileged_userns_clone sysctl.
- +
- + If unsure, say N.
- +
- config PID_NS
- bool "PID Namespaces"
- default y
- @@ -1307,9 +1324,8 @@ menuconfig EXPERT
- Only use this if you really know what you are doing.
-
- config UID16
- - bool "Enable 16-bit UID system calls" if EXPERT
- + bool "Enable 16-bit UID system calls"
- depends on HAVE_UID16 && MULTIUSER
- - default y
- help
- This enables the legacy 16-bit UID syscall wrappers.
-
- @@ -1338,14 +1354,13 @@ config SGETMASK_SYSCALL
- If unsure, leave the default option here.
-
- config SYSFS_SYSCALL
- - bool "Sysfs syscall support" if EXPERT
- - default y
- + bool "Sysfs syscall support"
- ---help---
- sys_sysfs is an obsolete system call no longer supported in libc.
- Note that disabling this option is more secure but might break
- compatibility with some systems.
-
- - If unsure say Y here.
- + If unsure say N here.
-
- config SYSCTL_SYSCALL
- bool "Sysctl syscall support" if EXPERT
- @@ -1513,8 +1528,7 @@ config SHMEM
- which may be appropriate on small systems without swap.
-
- config AIO
- - bool "Enable AIO support" if EXPERT
- - default y
- + bool "Enable AIO support"
- help
- This option enables POSIX asynchronous I/O which may by used
- by some high performance threaded applications. Disabling
- @@ -1621,6 +1635,7 @@ config BPF_JIT_ALWAYS_ON
- config BPF_UNPRIV_DEFAULT_OFF
- bool "Disable unprivileged BPF by default"
- depends on BPF_SYSCALL
- + default y
- help
- Disables unprivileged BPF by default by setting the corresponding
- /proc/sys/kernel/unprivileged_bpf_disabled knob to 2. An admin can
- @@ -1635,6 +1650,23 @@ config USERFAULTFD
- Enable the userfaultfd() system call that allows to intercept and
- handle page faults in userland.
-
- +config USERFAULTFD_UNPRIVILEGED
- + bool "Allow unprivileged users to use the userfaultfd syscall"
- + depends on USERFAULTFD
- + default n
- + help
- + When disabled, unprivileged users will not be able to use the userfaultfd
- + syscall. Userfaultfd provide attackers with a way to stall a kernel
- + thread in the middle of memory accesses from userspace by initiating an
- + access on an unmapped page. To avoid various heap grooming and heap
- + spraying techniques for exploiting use-after-free flaws this should be
- + disabled by default.
- +
- + This setting can be overridden at runtime via the
- + vm.unprivileged_userfaultfd sysctl.
- +
- + If unsure, say N.
- +
- config ARCH_HAS_MEMBARRIER_CALLBACKS
- bool
-
- @@ -1747,7 +1779,7 @@ config VM_EVENT_COUNTERS
-
- config SLUB_DEBUG
- default y
- - bool "Enable SLUB debugging support" if EXPERT
- + bool "Enable SLUB debugging support"
- depends on SLUB && SYSFS
- help
- SLUB has extensive debug support features. Disabling these can
- @@ -1771,7 +1803,6 @@ config SLUB_MEMCG_SYSFS_ON
-
- config COMPAT_BRK
- bool "Disable heap randomization"
- - default y
- help
- Randomizing heap placement makes heap exploits harder, but it
- also breaks ancient binaries (including anything libc5 based).
- @@ -1818,7 +1849,6 @@ endchoice
-
- config SLAB_MERGE_DEFAULT
- bool "Allow slab caches to be merged"
- - default y
- help
- For reduced kernel memory fragmentation, slab caches can be
- merged when they share the same size and other characteristics.
- @@ -1831,9 +1861,9 @@ config SLAB_MERGE_DEFAULT
- command line.
-
- config SLAB_FREELIST_RANDOM
- - default n
- depends on SLAB || SLUB
- bool "SLAB freelist randomization"
- + default y
- help
- Randomizes the freelist order used on creating new pages. This
- security feature reduces the predictability of the kernel slab
- @@ -1842,12 +1872,30 @@ config SLAB_FREELIST_RANDOM
- config SLAB_FREELIST_HARDENED
- bool "Harden slab freelist metadata"
- depends on SLUB
- + default y
- help
- Many kernel heap attacks try to target slab cache metadata and
- other infrastructure. This options makes minor performance
- sacrifices to harden the kernel slab allocator against common
- freelist exploit methods.
-
- +config SLAB_CANARY
- + depends on SLUB
- + depends on !SLAB_MERGE_DEFAULT
- + bool "SLAB canaries"
- + default y
- + help
- + Place canaries at the end of kernel slab allocations, sacrificing
- + some performance and memory usage for security.
- +
- + Canaries can detect some forms of heap corruption when allocations
- + are freed and as part of the HARDENED_USERCOPY feature. It provides
- + basic use-after-free detection for HARDENED_USERCOPY.
- +
- + Canaries absorb small overflows (rendering them harmless), mitigate
- + non-NUL terminated C string overflows on 64-bit via a guaranteed zero
- + byte and provide basic double-free detection.
- +
- config SHUFFLE_PAGE_ALLOCATOR
- bool "Page allocator randomization"
- default SLAB_FREELIST_RANDOM && ACPI_NUMA
- diff --git a/kernel/audit.c b/kernel/audit.c
- index 39e84d65d253..12b4b3b478c0 100644
- --- a/kernel/audit.c
- +++ b/kernel/audit.c
- @@ -1695,6 +1695,9 @@ static int __init audit_enable(char *str)
-
- if (audit_default == AUDIT_OFF)
- audit_initialized = AUDIT_DISABLED;
- + else if (!audit_ever_enabled)
- + audit_initialized = AUDIT_UNINITIALIZED;
- +
- if (audit_set_enabled(audit_default))
- pr_err("audit: error setting audit state (%d)\n",
- audit_default);
- diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
- index dde21d23f220..3fce16faf85f 100644
- --- a/kernel/bpf/core.c
- +++ b/kernel/bpf/core.c
- @@ -523,7 +523,7 @@ void bpf_prog_kallsyms_del_all(struct bpf_prog *fp)
- #ifdef CONFIG_BPF_JIT
- /* All BPF JIT sysctl knobs here. */
- int bpf_jit_enable __read_mostly = IS_BUILTIN(CONFIG_BPF_JIT_ALWAYS_ON);
- -int bpf_jit_harden __read_mostly;
- +int bpf_jit_harden __read_mostly = 2;
- int bpf_jit_kallsyms __read_mostly;
- long bpf_jit_limit __read_mostly;
- long bpf_jit_limit_max __read_mostly;
- diff --git a/kernel/capability.c b/kernel/capability.c
- index 1444f3954d75..8cc9dd7992f2 100644
- --- a/kernel/capability.c
- +++ b/kernel/capability.c
- @@ -449,6 +449,12 @@ bool capable(int cap)
- return ns_capable(&init_user_ns, cap);
- }
- EXPORT_SYMBOL(capable);
- +
- +bool capable_noaudit(int cap)
- +{
- + return ns_capable_noaudit(&init_user_ns, cap);
- +}
- +EXPORT_SYMBOL(capable_noaudit);
- #endif /* CONFIG_MULTIUSER */
-
- /**
- diff --git a/kernel/events/core.c b/kernel/events/core.c
- index f18a5bbc66ef..1ad470ef3fd0 100644
- --- a/kernel/events/core.c
- +++ b/kernel/events/core.c
- @@ -404,8 +404,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 */
- @@ -11041,6 +11046,9 @@ SYSCALL_DEFINE5(perf_event_open,
- if (flags & ~PERF_FLAG_ALL)
- return -EINVAL;
-
- + if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN))
- + return -EACCES;
- +
- err = perf_copy_attr(attr_uptr, &attr);
- if (err)
- return err;
- diff --git a/kernel/fork.c b/kernel/fork.c
- index 1728aa77861c..9868846c1412 100644
- --- a/kernel/fork.c
- +++ b/kernel/fork.c
- @@ -106,6 +106,11 @@
-
- #define CREATE_TRACE_POINTS
- #include <trace/events/task.h>
- +#ifdef CONFIG_USER_NS
- +extern int unprivileged_userns_clone;
- +#else
- +#define unprivileged_userns_clone 0
- +#endif
-
- /*
- * Minimum number of threads to boot the kernel
- @@ -1808,6 +1813,10 @@ static __latent_entropy struct task_struct *copy_process(
- if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
- return ERR_PTR(-EINVAL);
-
- + if ((clone_flags & CLONE_NEWUSER) && !unprivileged_userns_clone)
- + if (!capable(CAP_SYS_ADMIN))
- + return ERR_PTR(-EPERM);
- +
- /*
- * Thread groups must share signals as well, and detached threads
- * can only be started up within the thread group.
- @@ -2866,6 +2875,12 @@ int ksys_unshare(unsigned long unshare_flags)
- if (unshare_flags & CLONE_NEWNS)
- unshare_flags |= CLONE_FS;
-
- + if ((unshare_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) {
- + err = -EPERM;
- + if (!capable(CAP_SYS_ADMIN))
- + goto bad_unshare_out;
- + }
- +
- err = check_unshare_flags(unshare_flags);
- if (err)
- goto bad_unshare_out;
- diff --git a/kernel/rcu/tiny.c b/kernel/rcu/tiny.c
- index 477b4eb44af5..db28cc3fd301 100644
- --- a/kernel/rcu/tiny.c
- +++ b/kernel/rcu/tiny.c
- @@ -74,7 +74,7 @@ void rcu_sched_clock_irq(int user)
- }
-
- /* Invoke the RCU callbacks whose grace period has elapsed. */
- -static __latent_entropy void rcu_process_callbacks(struct softirq_action *unused)
- +static __latent_entropy void rcu_process_callbacks(void)
- {
- struct rcu_head *next, *list;
- unsigned long flags;
- diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c
- index 615283404d9d..0daa6877ea09 100644
- --- a/kernel/rcu/tree.c
- +++ b/kernel/rcu/tree.c
- @@ -2389,7 +2389,7 @@ static __latent_entropy void rcu_core(void)
- trace_rcu_utilization(TPS("End RCU core"));
- }
-
- -static void rcu_core_si(struct softirq_action *h)
- +static void rcu_core_si(void)
- {
- rcu_core();
- }
- diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
- index 2680216234ff..564c13c727de 100644
- --- a/kernel/sched/fair.c
- +++ b/kernel/sched/fair.c
- @@ -10016,7 +10016,7 @@ int newidle_balance(struct rq *this_rq, struct rq_flags *rf)
- * run_rebalance_domains is triggered when needed from the scheduler tick.
- * Also triggered for nohz idle balancing (with nohz_balancing_kick set).
- */
- -static __latent_entropy void run_rebalance_domains(struct softirq_action *h)
- +static __latent_entropy void run_rebalance_domains(void)
- {
- struct rq *this_rq = this_rq();
- enum cpu_idle_type idle = this_rq->idle_balance ?
- diff --git a/kernel/softirq.c b/kernel/softirq.c
- index 0427a86743a4..5e6a9b4ccb41 100644
- --- a/kernel/softirq.c
- +++ b/kernel/softirq.c
- @@ -52,7 +52,7 @@ DEFINE_PER_CPU_ALIGNED(irq_cpustat_t, irq_stat);
- EXPORT_PER_CPU_SYMBOL(irq_stat);
- #endif
-
- -static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;
- +static struct softirq_action softirq_vec[NR_SOFTIRQS] __ro_after_init __aligned(PAGE_SIZE);
-
- DEFINE_PER_CPU(struct task_struct *, ksoftirqd);
-
- @@ -289,7 +289,7 @@ asmlinkage __visible void __softirq_entry __do_softirq(void)
- kstat_incr_softirqs_this_cpu(vec_nr);
-
- trace_softirq_entry(vec_nr);
- - h->action(h);
- + h->action();
- trace_softirq_exit(vec_nr);
- if (unlikely(prev_count != preempt_count())) {
- pr_err("huh, entered softirq %u %s %p with preempt_count %08x, exited with %08x?\n",
- @@ -452,7 +452,7 @@ void __raise_softirq_irqoff(unsigned int nr)
- or_softirq_pending(1UL << nr);
- }
-
- -void open_softirq(int nr, void (*action)(struct softirq_action *))
- +void __init open_softirq(int nr, void (*action)(void))
- {
- softirq_vec[nr].action = action;
- }
- @@ -498,8 +498,7 @@ void __tasklet_hi_schedule(struct tasklet_struct *t)
- }
- EXPORT_SYMBOL(__tasklet_hi_schedule);
-
- -static void tasklet_action_common(struct softirq_action *a,
- - struct tasklet_head *tl_head,
- +static void tasklet_action_common(struct tasklet_head *tl_head,
- unsigned int softirq_nr)
- {
- struct tasklet_struct *list;
- @@ -536,14 +535,14 @@ static void tasklet_action_common(struct softirq_action *a,
- }
- }
-
- -static __latent_entropy void tasklet_action(struct softirq_action *a)
- +static __latent_entropy void tasklet_action(void)
- {
- - tasklet_action_common(a, this_cpu_ptr(&tasklet_vec), TASKLET_SOFTIRQ);
- + tasklet_action_common(this_cpu_ptr(&tasklet_vec), TASKLET_SOFTIRQ);
- }
-
- -static __latent_entropy void tasklet_hi_action(struct softirq_action *a)
- +static __latent_entropy void tasklet_hi_action(void)
- {
- - tasklet_action_common(a, this_cpu_ptr(&tasklet_hi_vec), HI_SOFTIRQ);
- + tasklet_action_common(this_cpu_ptr(&tasklet_hi_vec), HI_SOFTIRQ);
- }
-
- void tasklet_init(struct tasklet_struct *t,
- diff --git a/kernel/sysctl.c b/kernel/sysctl.c
- index 865e539c7354..6a3032679601 100644
- --- a/kernel/sysctl.c
- +++ b/kernel/sysctl.c
- @@ -100,6 +100,9 @@
- #ifdef CONFIG_LOCKUP_DETECTOR
- #include <linux/nmi.h>
- #endif
- +#if defined CONFIG_TTY
- +#include <linux/tty.h>
- +#endif
-
- #if defined(CONFIG_SYSCTL)
-
- @@ -110,6 +113,9 @@ extern int core_uses_pid;
- extern char core_pattern[];
- extern unsigned int core_pipe_limit;
- #endif
- +#ifdef CONFIG_USER_NS
- +extern int unprivileged_userns_clone;
- +#endif
- extern int pid_max;
- extern int pid_max_min, pid_max_max;
- extern int percpu_pagelist_fraction;
- @@ -121,32 +127,32 @@ extern int sysctl_nr_trim_pages;
-
- /* Constants used for minimum and maximum */
- #ifdef CONFIG_LOCKUP_DETECTOR
- -static int sixty = 60;
- +static int sixty __read_only = 60;
- #endif
-
- -static int __maybe_unused neg_one = -1;
- -static int __maybe_unused two = 2;
- -static int __maybe_unused four = 4;
- -static unsigned long zero_ul;
- -static unsigned long one_ul = 1;
- -static unsigned long long_max = LONG_MAX;
- -static int one_hundred = 100;
- -static int one_thousand = 1000;
- +static int __maybe_unused neg_one __read_only = -1;
- +static int __maybe_unused two __read_only = 2;
- +static int __maybe_unused four __read_only = 4;
- +static unsigned long zero_ul __read_only;
- +static unsigned long one_ul __read_only = 1;
- +static unsigned long long_max __read_only = LONG_MAX;
- +static int one_hundred __read_only = 100;
- +static int one_thousand __read_only = 1000;
- #ifdef CONFIG_PRINTK
- -static int ten_thousand = 10000;
- +static int ten_thousand __read_only = 10000;
- #endif
- #ifdef CONFIG_PERF_EVENTS
- -static int six_hundred_forty_kb = 640 * 1024;
- +static int six_hundred_forty_kb __read_only = 640 * 1024;
- #endif
-
- /* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */
- -static unsigned long dirty_bytes_min = 2 * PAGE_SIZE;
- +static unsigned long dirty_bytes_min __read_only = 2 * PAGE_SIZE;
-
- /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
- -static int maxolduid = 65535;
- -static int minolduid;
- +static int maxolduid __read_only = 65535;
- +static int minolduid __read_only;
-
- -static int ngroups_max = NGROUPS_MAX;
- +static int ngroups_max __read_only = NGROUPS_MAX;
- static const int cap_last_cap = CAP_LAST_CAP;
-
- /*
- @@ -154,9 +160,12 @@ static const int cap_last_cap = CAP_LAST_CAP;
- * and hung_task_check_interval_secs
- */
- #ifdef CONFIG_DETECT_HUNG_TASK
- -static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
- +static unsigned long hung_task_timeout_max __read_only = (LONG_MAX/HZ);
- #endif
-
- +int device_sidechannel_restrict __read_mostly = 1;
- +EXPORT_SYMBOL(device_sidechannel_restrict);
- +
- #ifdef CONFIG_INOTIFY_USER
- #include <linux/inotify.h>
- #endif
- @@ -214,11 +223,6 @@ static int proc_taint(struct ctl_table *table, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos);
- #endif
-
- -#ifdef CONFIG_PRINTK
- -static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
- - void __user *buffer, size_t *lenp, loff_t *ppos);
- -#endif
- -
- static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos);
- #ifdef CONFIG_COREDUMP
- @@ -331,19 +335,19 @@ static struct ctl_table sysctl_base_table[] = {
- };
-
- #ifdef CONFIG_SCHED_DEBUG
- -static int min_sched_granularity_ns = 100000; /* 100 usecs */
- -static int max_sched_granularity_ns = NSEC_PER_SEC; /* 1 second */
- -static int min_wakeup_granularity_ns; /* 0 usecs */
- -static int max_wakeup_granularity_ns = NSEC_PER_SEC; /* 1 second */
- +static int min_sched_granularity_ns __read_only = 100000; /* 100 usecs */
- +static int max_sched_granularity_ns __read_only = NSEC_PER_SEC; /* 1 second */
- +static int min_wakeup_granularity_ns __read_only; /* 0 usecs */
- +static int max_wakeup_granularity_ns __read_only = NSEC_PER_SEC; /* 1 second */
- #ifdef CONFIG_SMP
- -static int min_sched_tunable_scaling = SCHED_TUNABLESCALING_NONE;
- -static int max_sched_tunable_scaling = SCHED_TUNABLESCALING_END-1;
- +static int min_sched_tunable_scaling __read_only = SCHED_TUNABLESCALING_NONE;
- +static int max_sched_tunable_scaling __read_only = SCHED_TUNABLESCALING_END-1;
- #endif /* CONFIG_SMP */
- #endif /* CONFIG_SCHED_DEBUG */
-
- #ifdef CONFIG_COMPACTION
- -static int min_extfrag_threshold;
- -static int max_extfrag_threshold = 1000;
- +static int min_extfrag_threshold __read_only;
- +static int max_extfrag_threshold __read_only = 1000;
- #endif
-
- static struct ctl_table kern_table[] = {
- @@ -580,6 +584,15 @@ static struct ctl_table kern_table[] = {
- .proc_handler = proc_dointvec,
- },
- #endif
- +#ifdef CONFIG_USER_NS
- + {
- + .procname = "unprivileged_userns_clone",
- + .data = &unprivileged_userns_clone,
- + .maxlen = sizeof(int),
- + .mode = 0644,
- + .proc_handler = proc_dointvec,
- + },
- +#endif
- #ifdef CONFIG_PROC_SYSCTL
- {
- .procname = "tainted",
- @@ -936,6 +949,26 @@ static struct ctl_table kern_table[] = {
- .extra2 = &two,
- },
- #endif
- +#if defined CONFIG_TTY
- + {
- + .procname = "tiocsti_restrict",
- + .data = &tiocsti_restrict,
- + .maxlen = sizeof(int),
- + .mode = 0644,
- + .proc_handler = proc_dointvec_minmax_sysadmin,
- + .extra1 = SYSCTL_ZERO,
- + .extra2 = SYSCTL_ONE,
- + },
- +#endif
- + {
- + .procname = "device_sidechannel_restrict",
- + .data = &device_sidechannel_restrict,
- + .maxlen = sizeof(int),
- + .mode = 0644,
- + .proc_handler = proc_dointvec_minmax_sysadmin,
- + .extra1 = SYSCTL_ZERO,
- + .extra2 = SYSCTL_ONE,
- + },
- {
- .procname = "ngroups_max",
- .data = &ngroups_max,
- @@ -2679,16 +2712,34 @@ static int proc_taint(struct ctl_table *table, int write,
- return err;
- }
-
- -#ifdef CONFIG_PRINTK
- -static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
- - void __user *buffer, size_t *lenp, loff_t *ppos)
- +/**
- + * proc_dointvec_minmax_sysadmin - read a vector of integers with min/max values
- + * checking CAP_SYS_ADMIN on write
- + * @table: the sysctl table
- + * @write: %TRUE if this is a write to the sysctl file
- + * @buffer: the user buffer
- + * @lenp: the size of the user buffer
- + * @ppos: file position
- + *
- + * Reads/writes up to table->maxlen/sizeof(unsigned int) integer
- + * values from/to the user buffer, treated as an ASCII string.
- + *
- + * This routine will ensure the values are within the range specified by
- + * table->extra1 (min) and table->extra2 (max).
- + *
- + * Writing is only allowed when the current task has CAP_SYS_ADMIN.
- + *
- + * Returns 0 on success, -EPERM on permission failure or -EINVAL on write
- + * when the range check fails.
- + */
- +int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
- + void __user *buffer, size_t *lenp, loff_t *ppos)
- {
- if (write && !capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
- }
- -#endif
-
- /**
- * struct do_proc_dointvec_minmax_conv_param - proc_dointvec_minmax() range checking structure
- @@ -3386,6 +3437,12 @@ int proc_douintvec_minmax(struct ctl_table *table, int write,
- return -ENOSYS;
- }
-
- +int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write,
- + void *buffer, size_t *lenp, loff_t *ppos)
- +{
- + return -ENOSYS;
- +}
- +
- int proc_dointvec_jiffies(struct ctl_table *table, int write,
- void __user *buffer, size_t *lenp, loff_t *ppos)
- {
- @@ -3466,6 +3523,7 @@ EXPORT_SYMBOL(proc_douintvec);
- EXPORT_SYMBOL(proc_dointvec_jiffies);
- EXPORT_SYMBOL(proc_dointvec_minmax);
- EXPORT_SYMBOL_GPL(proc_douintvec_minmax);
- +EXPORT_SYMBOL(proc_dointvec_minmax_sysadmin);
- EXPORT_SYMBOL(proc_dointvec_userhz_jiffies);
- EXPORT_SYMBOL(proc_dointvec_ms_jiffies);
- EXPORT_SYMBOL(proc_dostring);
- diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c
- index 1b301dd1692b..73af067fefd5 100644
- --- a/kernel/time/hrtimer.c
- +++ b/kernel/time/hrtimer.c
- @@ -1648,7 +1648,7 @@ static void __hrtimer_run_queues(struct hrtimer_cpu_base *cpu_base, ktime_t now,
- }
- }
-
- -static __latent_entropy void hrtimer_run_softirq(struct softirq_action *h)
- +static __latent_entropy void hrtimer_run_softirq(void)
- {
- struct hrtimer_cpu_base *cpu_base = this_cpu_ptr(&hrtimer_bases);
- unsigned long flags;
- diff --git a/kernel/time/timer.c b/kernel/time/timer.c
- index 16a2b62f5f74..66df020d607b 100644
- --- a/kernel/time/timer.c
- +++ b/kernel/time/timer.c
- @@ -1793,7 +1793,7 @@ static inline void __run_timers(struct timer_base *base)
- /*
- * This function runs timers and the timer-tq in bottom half context.
- */
- -static __latent_entropy void run_timer_softirq(struct softirq_action *h)
- +static __latent_entropy void run_timer_softirq(void)
- {
- struct timer_base *base = this_cpu_ptr(&timer_bases[BASE_STD]);
-
- diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
- index 8eadadc478f9..c36ecd19562c 100644
- --- a/kernel/user_namespace.c
- +++ b/kernel/user_namespace.c
- @@ -21,6 +21,13 @@
- #include <linux/bsearch.h>
- #include <linux/sort.h>
-
- +/* sysctl */
- +#ifdef CONFIG_USER_NS_UNPRIVILEGED
- +int unprivileged_userns_clone = 1;
- +#else
- +int unprivileged_userns_clone;
- +#endif
- +
- static struct kmem_cache *user_ns_cachep __read_mostly;
- static DEFINE_MUTEX(userns_state_mutex);
-
- diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
- index 6d79e7c3219c..d3c1986465e5 100644
- --- a/lib/Kconfig.debug
- +++ b/lib/Kconfig.debug
- @@ -345,6 +345,9 @@ config SECTION_MISMATCH_WARN_ONLY
-
- If unsure, say Y.
-
- +config DEBUG_WRITABLE_FUNCTION_POINTERS_VERBOSE
- + bool "Enable verbose reporting of writable function pointers"
- +
- #
- # Select this config option from the architecture Kconfig, if it
- # is preferred to always offer frame pointers as a config
- @@ -966,6 +969,7 @@ endmenu # "Debug lockups and hangs"
-
- config PANIC_ON_OOPS
- bool "Panic on Oops"
- + default y
- help
- Say Y here to enable the kernel to panic when it oopses. This
- has the same effect as setting oops=panic on the kernel command
- @@ -975,7 +979,7 @@ config PANIC_ON_OOPS
- anything erroneous after an oops which could result in data
- corruption or other issues.
-
- - Say N if unsure.
- + Say Y if unsure.
-
- config PANIC_ON_OOPS_VALUE
- int
- @@ -1343,6 +1347,7 @@ config DEBUG_BUGVERBOSE
- config DEBUG_LIST
- bool "Debug linked list manipulation"
- depends on DEBUG_KERNEL || BUG_ON_DATA_CORRUPTION
- + default y
- help
- Enable this to turn on extended checks in the linked-list
- walking routines.
- @@ -2081,6 +2086,7 @@ config MEMTEST
- config BUG_ON_DATA_CORRUPTION
- bool "Trigger a BUG when data corruption is detected"
- select DEBUG_LIST
- + default y
- help
- Select this option if the kernel should BUG when it encounters
- data corruption in kernel memory structures when they get checked
- @@ -2120,6 +2126,7 @@ config STRICT_DEVMEM
- config IO_STRICT_DEVMEM
- bool "Filter I/O access to /dev/mem"
- depends on STRICT_DEVMEM
- + default y
- ---help---
- If this option is disabled, you allow userspace (root) access to all
- io-memory regardless of whether a driver is actively using that
- diff --git a/lib/irq_poll.c b/lib/irq_poll.c
- index 2f17b488d58e..b6e7996a0058 100644
- --- a/lib/irq_poll.c
- +++ b/lib/irq_poll.c
- @@ -75,7 +75,7 @@ void irq_poll_complete(struct irq_poll *iop)
- }
- EXPORT_SYMBOL(irq_poll_complete);
-
- -static void __latent_entropy irq_poll_softirq(struct softirq_action *h)
- +static void __latent_entropy irq_poll_softirq(void)
- {
- struct list_head *list = this_cpu_ptr(&blk_cpu_iopoll);
- int rearm = 0, budget = irq_poll_budget;
- diff --git a/lib/kobject.c b/lib/kobject.c
- index 6666c48f125c..7f602ba1059f 100644
- --- a/lib/kobject.c
- +++ b/lib/kobject.c
- @@ -1039,9 +1039,9 @@ EXPORT_SYMBOL_GPL(kset_create_and_add);
-
-
- static DEFINE_SPINLOCK(kobj_ns_type_lock);
- -static const struct kobj_ns_type_operations *kobj_ns_ops_tbl[KOBJ_NS_TYPES];
- +static const struct kobj_ns_type_operations *kobj_ns_ops_tbl[KOBJ_NS_TYPES] __ro_after_init;
-
- -int kobj_ns_type_register(const struct kobj_ns_type_operations *ops)
- +int __init kobj_ns_type_register(const struct kobj_ns_type_operations *ops)
- {
- enum kobj_ns_type type = ops->type;
- int error;
- diff --git a/lib/nlattr.c b/lib/nlattr.c
- index b5ce5e46c06e..96e5069110df 100644
- --- a/lib/nlattr.c
- +++ b/lib/nlattr.c
- @@ -574,6 +574,8 @@ int nla_memcpy(void *dest, const struct nlattr *src, int count)
- {
- int minlen = min_t(int, count, nla_len(src));
-
- + BUG_ON(minlen < 0);
- +
- memcpy(dest, nla_data(src), minlen);
- if (count > minlen)
- memset(dest + minlen, 0, count - minlen);
- diff --git a/lib/vsprintf.c b/lib/vsprintf.c
- index 393623bf3258..35a632a4aa65 100644
- --- a/lib/vsprintf.c
- +++ b/lib/vsprintf.c
- @@ -806,7 +806,7 @@ static char *ptr_to_id(char *buf, char *end, const void *ptr,
- return pointer_string(buf, end, (const void *)hashval, spec);
- }
-
- -int kptr_restrict __read_mostly;
- +int kptr_restrict __read_mostly = 2;
-
- static noinline_for_stack
- char *restricted_pointer(char *buf, char *end, const void *ptr,
- diff --git a/mm/Kconfig b/mm/Kconfig
- index fbdc5c70e487..a1a0d547fc64 100644
- --- a/mm/Kconfig
- +++ b/mm/Kconfig
- @@ -303,7 +303,8 @@ config KSM
- config DEFAULT_MMAP_MIN_ADDR
- int "Low address space to protect from user allocation"
- depends on MMU
- - default 4096
- + default 32768 if ARM || (ARM64 && COMPAT)
- + default 65536
- help
- This is the portion of low virtual memory which should be protected
- from userspace allocation. Keeping a user from writing to low pages
- diff --git a/mm/mmap.c b/mm/mmap.c
- index eeebbb20accf..032724415adc 100644
- --- a/mm/mmap.c
- +++ b/mm/mmap.c
- @@ -228,6 +228,13 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
-
- newbrk = PAGE_ALIGN(brk);
- oldbrk = PAGE_ALIGN(mm->brk);
- + /* properly handle unaligned min_brk as an empty heap */
- + if (min_brk & ~PAGE_MASK) {
- + if (brk == min_brk)
- + newbrk -= PAGE_SIZE;
- + if (mm->brk == min_brk)
- + oldbrk -= PAGE_SIZE;
- + }
- if (oldbrk == newbrk) {
- mm->brk = brk;
- goto success;
- diff --git a/mm/page_alloc.c b/mm/page_alloc.c
- index a3fca320e35a..9d54d66767ea 100644
- --- a/mm/page_alloc.c
- +++ b/mm/page_alloc.c
- @@ -69,6 +69,7 @@
- #include <linux/nmi.h>
- #include <linux/psi.h>
- #include <linux/khugepaged.h>
- +#include <linux/random.h>
-
- #include <asm/sections.h>
- #include <asm/tlbflush.h>
- @@ -107,6 +108,15 @@ struct pcpu_drain {
- DEFINE_MUTEX(pcpu_drain_mutex);
- DEFINE_PER_CPU(struct pcpu_drain, pcpu_drain);
-
- +bool __meminitdata extra_latent_entropy;
- +
- +static int __init setup_extra_latent_entropy(char *str)
- +{
- + extra_latent_entropy = true;
- + return 0;
- +}
- +early_param("extra_latent_entropy", setup_extra_latent_entropy);
- +
- #ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
- volatile unsigned long latent_entropy __latent_entropy;
- EXPORT_SYMBOL(latent_entropy);
- @@ -1433,6 +1443,25 @@ static void __free_pages_ok(struct page *page, unsigned int order)
- local_irq_restore(flags);
- }
-
- +static void __init __gather_extra_latent_entropy(struct page *page,
- + unsigned int nr_pages)
- +{
- + if (extra_latent_entropy && !PageHighMem(page) && page_to_pfn(page) < 0x100000) {
- + unsigned long hash = 0;
- + size_t index, end = PAGE_SIZE * nr_pages / sizeof hash;
- + const unsigned long *data = lowmem_page_address(page);
- +
- + for (index = 0; index < end; index++)
- + hash ^= hash + data[index];
- +#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
- + latent_entropy ^= hash;
- + add_device_randomness((const void *)&latent_entropy, sizeof(latent_entropy));
- +#else
- + add_device_randomness((const void *)&hash, sizeof(hash));
- +#endif
- + }
- +}
- +
- void __free_pages_core(struct page *page, unsigned int order)
- {
- unsigned int nr_pages = 1 << order;
- @@ -1447,7 +1476,6 @@ void __free_pages_core(struct page *page, unsigned int order)
- }
- __ClearPageReserved(p);
- set_page_count(p, 0);
- -
- atomic_long_add(nr_pages, &page_zone(page)->managed_pages);
- set_page_refcounted(page);
- __free_pages(page, order);
- @@ -1498,6 +1526,7 @@ void __init memblock_free_pages(struct page *page, unsigned long pfn,
- {
- if (early_page_uninitialised(pfn))
- return;
- + __gather_extra_latent_entropy(page, 1 << order);
- __free_pages_core(page, order);
- }
-
- @@ -1589,6 +1618,7 @@ static void __init deferred_free_range(unsigned long pfn,
- if (nr_pages == pageblock_nr_pages &&
- (pfn & (pageblock_nr_pages - 1)) == 0) {
- set_pageblock_migratetype(page, MIGRATE_MOVABLE);
- + __gather_extra_latent_entropy(page, 1 << pageblock_order);
- __free_pages_core(page, pageblock_order);
- return;
- }
- @@ -1596,6 +1626,7 @@ static void __init deferred_free_range(unsigned long pfn,
- for (i = 0; i < nr_pages; i++, page++, pfn++) {
- if ((pfn & (pageblock_nr_pages - 1)) == 0)
- set_pageblock_migratetype(page, MIGRATE_MOVABLE);
- + __gather_extra_latent_entropy(page, 1);
- __free_pages_core(page, 0);
- }
- }
- @@ -2158,6 +2189,12 @@ static void prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags
- {
- post_alloc_hook(page, order, gfp_flags);
-
- + if (IS_ENABLED(CONFIG_PAGE_SANITIZE_VERIFY) && want_init_on_free()) {
- + int i;
- + for (i = 0; i < (1 << order); i++)
- + verify_zero_highpage(page + i);
- + }
- +
- if (!free_pages_prezeroed() && want_init_on_alloc(gfp_flags))
- kernel_init_free_pages(page, 1 << order);
-
- diff --git a/mm/slab.h b/mm/slab.h
- index 61feda3d7e00..08f63bf92f53 100644
- --- a/mm/slab.h
- +++ b/mm/slab.h
- @@ -470,9 +470,13 @@ static inline struct kmem_cache *virt_to_cache(const void *obj)
- struct page *page;
-
- page = virt_to_head_page(obj);
- +#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
- + BUG_ON(!PageSlab(page));
- +#else
- if (WARN_ONCE(!PageSlab(page), "%s: Object is not a Slab page!\n",
- __func__))
- return NULL;
- +#endif
- return page->slab_cache;
- }
-
- @@ -518,9 +522,14 @@ static inline struct kmem_cache *cache_from_obj(struct kmem_cache *s, void *x)
- return s;
-
- cachep = virt_to_cache(x);
- - WARN_ONCE(cachep && !slab_equal_or_root(cachep, s),
- - "%s: Wrong slab cache. %s but object is from %s\n",
- - __func__, s->name, cachep->name);
- + if (cachep && !slab_equal_or_root(cachep, s)) {
- +#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
- + BUG();
- +#else
- + WARN_ONCE(1, "%s: Wrong slab cache. %s but object is from %s\n",
- + __func__, s->name, cachep->name);
- +#endif
- + }
- return cachep;
- }
-
- @@ -545,7 +554,7 @@ static inline size_t slab_ksize(const struct kmem_cache *s)
- * back there or track user information then we can
- * only use the space before that information.
- */
- - if (s->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_STORE_USER))
- + if ((s->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_STORE_USER)) || IS_ENABLED(CONFIG_SLAB_CANARY))
- return s->inuse;
- /*
- * Else we can use all the padding etc for the allocation
- @@ -674,8 +683,10 @@ static inline void cache_random_seq_destroy(struct kmem_cache *cachep) { }
- static inline bool slab_want_init_on_alloc(gfp_t flags, struct kmem_cache *c)
- {
- if (static_branch_unlikely(&init_on_alloc)) {
- +#ifndef CONFIG_SLUB
- if (c->ctor)
- return false;
- +#endif
- if (c->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_POISON))
- return flags & __GFP_ZERO;
- return true;
- @@ -685,9 +696,15 @@ static inline bool slab_want_init_on_alloc(gfp_t flags, struct kmem_cache *c)
-
- static inline bool slab_want_init_on_free(struct kmem_cache *c)
- {
- - if (static_branch_unlikely(&init_on_free))
- - return !(c->ctor ||
- - (c->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_POISON)));
- + if (static_branch_unlikely(&init_on_free)) {
- +#ifndef CONFIG_SLUB
- + if (c->ctor)
- + return false;
- +#endif
- + if (c->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_POISON))
- + return false;
- + return true;
- + }
- return false;
- }
-
- diff --git a/mm/slab_common.c b/mm/slab_common.c
- index 8f128245b300..5e3b270aeb22 100644
- --- a/mm/slab_common.c
- +++ b/mm/slab_common.c
- @@ -28,10 +28,10 @@
-
- #include "slab.h"
-
- -enum slab_state slab_state;
- +enum slab_state slab_state __ro_after_init;
- LIST_HEAD(slab_caches);
- DEFINE_MUTEX(slab_mutex);
- -struct kmem_cache *kmem_cache;
- +struct kmem_cache *kmem_cache __ro_after_init;
-
- #ifdef CONFIG_HARDENED_USERCOPY
- bool usercopy_fallback __ro_after_init =
- @@ -59,7 +59,7 @@ static DECLARE_WORK(slab_caches_to_rcu_destroy_work,
- /*
- * Merge control. If this is set then no merging of slab caches will occur.
- */
- -static bool slab_nomerge = !IS_ENABLED(CONFIG_SLAB_MERGE_DEFAULT);
- +static bool slab_nomerge __ro_after_init = !IS_ENABLED(CONFIG_SLAB_MERGE_DEFAULT);
-
- static int __init setup_slab_nomerge(char *str)
- {
- diff --git a/mm/slub.c b/mm/slub.c
- index e978f647e92a..9a65c872e869 100644
- --- a/mm/slub.c
- +++ b/mm/slub.c
- @@ -126,6 +126,12 @@ static inline int kmem_cache_debug(struct kmem_cache *s)
- #endif
- }
-
- +static inline bool has_sanitize_verify(struct kmem_cache *s)
- +{
- + return IS_ENABLED(CONFIG_SLAB_SANITIZE_VERIFY) &&
- + slab_want_init_on_free(s);
- +}
- +
- void *fixup_red_left(struct kmem_cache *s, void *p)
- {
- if (kmem_cache_debug(s) && s->flags & SLAB_RED_ZONE)
- @@ -310,6 +316,35 @@ static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp)
- *(void **)freeptr_addr = freelist_ptr(s, fp, freeptr_addr);
- }
-
- +#ifdef CONFIG_SLAB_CANARY
- +static inline unsigned long *get_canary(struct kmem_cache *s, void *object)
- +{
- + if (s->offset)
- + return object + s->offset + sizeof(void *);
- + return object + s->inuse;
- +}
- +
- +static inline unsigned long get_canary_value(const void *canary, unsigned long value)
- +{
- + return (value ^ (unsigned long)canary) & CANARY_MASK;
- +}
- +
- +static inline void set_canary(struct kmem_cache *s, void *object, unsigned long value)
- +{
- + unsigned long *canary = get_canary(s, object);
- + *canary = get_canary_value(canary, value);
- +}
- +
- +static inline void check_canary(struct kmem_cache *s, void *object, unsigned long value)
- +{
- + unsigned long *canary = get_canary(s, object);
- + BUG_ON(*canary != get_canary_value(canary, value));
- +}
- +#else
- +#define set_canary(s, object, value)
- +#define check_canary(s, object, value)
- +#endif
- +
- /* Loop over all objects in a slab */
- #define for_each_object(__p, __s, __addr, __objects) \
- for (__p = fixup_red_left(__s, __addr); \
- @@ -477,13 +512,13 @@ static inline void *restore_red_left(struct kmem_cache *s, void *p)
- * Debug settings:
- */
- #if defined(CONFIG_SLUB_DEBUG_ON)
- -static slab_flags_t slub_debug = DEBUG_DEFAULT_FLAGS;
- +static slab_flags_t slub_debug __ro_after_init = DEBUG_DEFAULT_FLAGS;
- #else
- -static slab_flags_t slub_debug;
- +static slab_flags_t slub_debug __ro_after_init;
- #endif
-
- -static char *slub_debug_slabs;
- -static int disable_higher_order_debug;
- +static char *slub_debug_slabs __ro_after_init;
- +static int disable_higher_order_debug __ro_after_init;
-
- /*
- * slub is about to manipulate internal object metadata. This memory lies
- @@ -561,6 +596,9 @@ static struct track *get_track(struct kmem_cache *s, void *object,
-
- p = object + get_info_end(s);
-
- + if (IS_ENABLED(CONFIG_SLAB_CANARY))
- + p = (void *)p + sizeof(void *);
- +
- return p + alloc;
- }
-
- @@ -702,6 +740,9 @@ static void print_trailer(struct kmem_cache *s, struct page *page, u8 *p)
-
- off = get_info_end(s);
-
- + if (IS_ENABLED(CONFIG_SLAB_CANARY))
- + off += sizeof(void *);
- +
- if (s->flags & SLAB_STORE_USER)
- off += 2 * sizeof(struct track);
-
- @@ -827,6 +868,9 @@ static int check_pad_bytes(struct kmem_cache *s, struct page *page, u8 *p)
- {
- unsigned long off = get_info_end(s); /* The end of info */
-
- + if (IS_ENABLED(CONFIG_SLAB_CANARY))
- + off += sizeof(void *);
- +
- if (s->flags & SLAB_STORE_USER)
- /* We also have user information there */
- off += 2 * sizeof(struct track);
- @@ -1472,6 +1516,8 @@ static inline bool slab_free_freelist_hook(struct kmem_cache *s,
- object = next;
- next = get_freepointer(s, object);
-
- + check_canary(s, object, s->random_active);
- +
- if (slab_want_init_on_free(s)) {
- /*
- * Clear the object and the metadata, but don't touch
- @@ -1482,8 +1528,12 @@ static inline bool slab_free_freelist_hook(struct kmem_cache *s,
- : 0;
- memset((char *)object + s->inuse, 0,
- s->size - s->inuse - rsize);
- -
- + if (!IS_ENABLED(CONFIG_SLAB_SANITIZE_VERIFY) && s->ctor)
- + s->ctor(object);
- }
- +
- + set_canary(s, object, s->random_inactive);
- +
- /* If object's reuse doesn't have to be delayed */
- if (!slab_free_hook(s, object)) {
- /* Move object to the new freelist */
- @@ -1497,6 +1547,22 @@ static inline bool slab_free_freelist_hook(struct kmem_cache *s,
- * accordingly if object's reuse is delayed.
- */
- --(*cnt);
- +
- + /* Objects that are put into quarantine by KASAN will
- + * still undergo free_consistency_checks(), which
- + * checks whether the freelist pointer is valid if it
- + * is located after the object (see check_object()).
- + * Since this is the case for slab caches with
- + * constructors, we need to fix the freelist pointer
- + * after init_on_free has overwritten it.
- + *
- + * Note that doing this for all caches (not just ctor
- + * ones) would cause a GPF due to KASAN poisoning and
- + * the way set_freepointer() eventually dereferences
- + * the freepointer.
- + */
- + if (slab_want_init_on_free(s) && s->ctor)
- + set_freepointer(s, object, NULL);
- }
- } while (object != old_tail);
-
- @@ -1510,8 +1576,9 @@ static void *setup_object(struct kmem_cache *s, struct page *page,
- void *object)
- {
- setup_object_debug(s, page, object);
- + set_canary(s, object, s->random_inactive);
- object = kasan_init_slab_obj(s, object);
- - if (unlikely(s->ctor)) {
- + if (unlikely(s->ctor) && !has_sanitize_verify(s)) {
- kasan_unpoison_object_data(s, object);
- s->ctor(object);
- kasan_poison_object_data(s, object);
- @@ -2805,8 +2872,28 @@ static __always_inline void *slab_alloc_node(struct kmem_cache *s,
-
- maybe_wipe_obj_freeptr(s, object);
-
- - if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object)
- + if (has_sanitize_verify(s) && object) {
- + /* KASAN hasn't unpoisoned the object yet (this is done in the
- + * post-alloc hook), so let's do it temporarily.
- + */
- + kasan_unpoison_object_data(s, object);
- + BUG_ON(memchr_inv(object, 0, s->object_size));
- + if (s->ctor)
- + s->ctor(object);
- + kasan_poison_object_data(s, object);
- + } else if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object) {
- memset(object, 0, s->object_size);
- + if (s->ctor) {
- + kasan_unpoison_object_data(s, object);
- + s->ctor(object);
- + kasan_poison_object_data(s, object);
- + }
- + }
- +
- + if (object) {
- + check_canary(s, object, s->random_inactive);
- + set_canary(s, object, s->random_active);
- + }
-
- slab_post_alloc_hook(s, gfpflags, 1, &object);
-
- @@ -3191,7 +3278,7 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
- void **p)
- {
- struct kmem_cache_cpu *c;
- - int i;
- + int i, k;
-
- /* memcg and kmem_cache debug support */
- s = slab_pre_alloc_hook(s, flags);
- @@ -3240,11 +3327,35 @@ int kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags, size_t size,
- local_irq_enable();
-
- /* Clear memory outside IRQ disabled fastpath loop */
- - if (unlikely(slab_want_init_on_alloc(flags, s))) {
- + if (has_sanitize_verify(s)) {
- int j;
-
- - for (j = 0; j < i; j++)
- + for (j = 0; j < i; j++) {
- + /* KASAN hasn't unpoisoned the object yet (this is done
- + * in the post-alloc hook), so let's do it temporarily.
- + */
- + kasan_unpoison_object_data(s, p[j]);
- + BUG_ON(memchr_inv(p[j], 0, s->object_size));
- + if (s->ctor)
- + s->ctor(p[j]);
- + kasan_poison_object_data(s, p[j]);
- + }
- + } else if (unlikely(slab_want_init_on_alloc(flags, s))) {
- + int j;
- +
- + for (j = 0; j < i; j++) {
- memset(p[j], 0, s->object_size);
- + if (s->ctor) {
- + kasan_unpoison_object_data(s, p[j]);
- + s->ctor(p[j]);
- + kasan_poison_object_data(s, p[j]);
- + }
- + }
- + }
- +
- + for (k = 0; k < i; k++) {
- + check_canary(s, p[k], s->random_inactive);
- + set_canary(s, p[k], s->random_active);
- }
-
- /* memcg and kmem_cache debug support */
- @@ -3278,9 +3389,9 @@ EXPORT_SYMBOL(kmem_cache_alloc_bulk);
- * and increases the number of allocations possible without having to
- * take the list_lock.
- */
- -static unsigned int slub_min_order;
- -static unsigned int slub_max_order = PAGE_ALLOC_COSTLY_ORDER;
- -static unsigned int slub_min_objects;
- +static unsigned int slub_min_order __ro_after_init;
- +static unsigned int slub_max_order __ro_after_init = PAGE_ALLOC_COSTLY_ORDER;
- +static unsigned int slub_min_objects __ro_after_init;
-
- /*
- * Calculate the order of allocation given an slab object size.
- @@ -3448,6 +3559,7 @@ static void early_kmem_cache_node_alloc(int node)
- init_object(kmem_cache_node, n, SLUB_RED_ACTIVE);
- init_tracking(kmem_cache_node, n);
- #endif
- + set_canary(kmem_cache_node, n, kmem_cache_node->random_active);
- n = kasan_kmalloc(kmem_cache_node, n, sizeof(struct kmem_cache_node),
- GFP_KERNEL);
- page->freelist = get_freepointer(kmem_cache_node, n);
- @@ -3615,6 +3727,9 @@ static int calculate_sizes(struct kmem_cache *s, int forced_order)
- size += sizeof(void *);
- }
-
- + if (IS_ENABLED(CONFIG_SLAB_CANARY))
- + size += sizeof(void *);
- +
- #ifdef CONFIG_SLUB_DEBUG
- if (flags & SLAB_STORE_USER)
- /*
- @@ -3687,6 +3802,10 @@ static int kmem_cache_open(struct kmem_cache *s, slab_flags_t flags)
- #ifdef CONFIG_SLAB_FREELIST_HARDENED
- s->random = get_random_long();
- #endif
- +#ifdef CONFIG_SLAB_CANARY
- + s->random_active = get_random_long();
- + s->random_inactive = get_random_long();
- +#endif
-
- if (!calculate_sizes(s, -1))
- goto error;
- @@ -3962,6 +4081,8 @@ void __check_heap_object(const void *ptr, unsigned long n, struct page *page,
- offset -= s->red_left_pad;
- }
-
- + check_canary(s, (void *)ptr - offset, s->random_active);
- +
- /* Allow address range falling entirely within usercopy region. */
- if (offset >= s->useroffset &&
- offset - s->useroffset <= s->usersize &&
- @@ -3995,7 +4116,11 @@ size_t __ksize(const void *object)
- page = virt_to_head_page(object);
-
- if (unlikely(!PageSlab(page))) {
- +#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
- + BUG_ON(!PageCompound(page));
- +#else
- WARN_ON(!PageCompound(page));
- +#endif
- return page_size(page);
- }
-
- @@ -4840,7 +4965,7 @@ enum slab_stat_type {
- #define SO_TOTAL (1 << SL_TOTAL)
-
- #ifdef CONFIG_MEMCG
- -static bool memcg_sysfs_enabled = IS_ENABLED(CONFIG_SLUB_MEMCG_SYSFS_ON);
- +static bool memcg_sysfs_enabled __ro_after_init = IS_ENABLED(CONFIG_SLUB_MEMCG_SYSFS_ON);
-
- static int __init setup_slub_memcg_sysfs(char *str)
- {
- diff --git a/mm/swap.c b/mm/swap.c
- index 1c5021b57e2c..79d5a429eb49 100644
- --- a/mm/swap.c
- +++ b/mm/swap.c
- @@ -94,6 +94,13 @@ static void __put_compound_page(struct page *page)
- if (!PageHuge(page))
- __page_cache_release(page);
- dtor = get_compound_page_dtor(page);
- + if (!PageHuge(page))
- + BUG_ON(dtor != free_compound_page
- +#ifdef CONFIG_TRANSPARENT_HUGEPAGE
- + && dtor != free_transhuge_page
- +#endif
- + );
- +
- (*dtor)(page);
- }
-
- diff --git a/mm/util.c b/mm/util.c
- index 04ebc76588aa..0a4a4198c0eb 100644
- --- a/mm/util.c
- +++ b/mm/util.c
- @@ -357,9 +357,9 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
- {
- /* Is the current task 32bit ? */
- if (!IS_ENABLED(CONFIG_64BIT) || is_compat_task())
- - return randomize_page(mm->brk, SZ_32M);
- + return mm->brk + get_random_long() % SZ_32M + PAGE_SIZE;
-
- - return randomize_page(mm->brk, SZ_1G);
- + return mm->brk + get_random_long() % SZ_1G + PAGE_SIZE;
- }
-
- unsigned long arch_mmap_rnd(void)
- diff --git a/net/core/dev.c b/net/core/dev.c
- index 5e043e6f0947..401da1f69fb1 100644
- --- a/net/core/dev.c
- +++ b/net/core/dev.c
- @@ -4502,7 +4502,7 @@ int netif_rx_ni(struct sk_buff *skb)
- }
- EXPORT_SYMBOL(netif_rx_ni);
-
- -static __latent_entropy void net_tx_action(struct softirq_action *h)
- +static __latent_entropy void net_tx_action(void)
- {
- struct softnet_data *sd = this_cpu_ptr(&softnet_data);
-
- @@ -6404,7 +6404,7 @@ static int napi_poll(struct napi_struct *n, struct list_head *repoll)
- return work;
- }
-
- -static __latent_entropy void net_rx_action(struct softirq_action *h)
- +static __latent_entropy void net_rx_action(void)
- {
- struct softnet_data *sd = this_cpu_ptr(&softnet_data);
- unsigned long time_limit = jiffies +
- diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
- index f5af8c6b2f87..842267c99dc4 100644
- --- a/net/ipv4/Kconfig
- +++ b/net/ipv4/Kconfig
- @@ -267,6 +267,7 @@ config IP_PIMSM_V2
-
- config SYN_COOKIES
- bool "IP: TCP syncookie support"
- + default y
- ---help---
- Normal TCP/IP networking is open to an attack known as "SYN
- flooding". This denial-of-service attack prevents legitimate remote
- @@ -738,3 +739,26 @@ config TCP_MD5SIG
- on the Internet.
-
- If unsure, say N.
- +
- +config TCP_SIMULT_CONNECT_DEFAULT_ON
- + bool "Enable TCP simultaneous connect"
- + help
- + Enable TCP simultaneous connect that adds a weakness in Linux's strict
- + implementation of TCP that allows two clients to connect to each other
- + without either entering a listening state. The weakness allows an
- + attacker to easily prevent a client from connecting to a known server
- + provided the source port for the connection is guessed correctly.
- +
- + As the weakness could be used to prevent an antivirus or IPS from
- + fetching updates, or prevent an SSL gateway from fetching a CRL, it
- + should be eliminated by disabling this option. Though Linux is one of
- + few operating systems supporting simultaneous connect, it has no
- + legitimate use in practice and is rarely supported by firewalls.
- +
- + Disabling this may break TCP STUNT which is used by some applications
- + for NAT traversal.
- +
- + This setting can be overridden at runtime via the
- + net.ipv4.tcp_simult_connect sysctl.
- +
- + If unsure, say N.
- diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
- index 4d4dba1d42ae..89fe646c79dd 100644
- --- a/net/ipv4/sysctl_net_ipv4.c
- +++ b/net/ipv4/sysctl_net_ipv4.c
- @@ -549,6 +549,15 @@ static struct ctl_table ipv4_table[] = {
- .mode = 0644,
- .proc_handler = proc_do_static_key,
- },
- + {
- + .procname = "tcp_simult_connect",
- + .data = &sysctl_tcp_simult_connect,
- + .maxlen = sizeof(int),
- + .mode = 0644,
- + .proc_handler = proc_dointvec_minmax,
- + .extra1 = SYSCTL_ZERO,
- + .extra2 = SYSCTL_ONE,
- + },
- { }
- };
-
- diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
- index 61243531a7f4..8559658cbaa2 100644
- --- a/net/ipv4/tcp_input.c
- +++ b/net/ipv4/tcp_input.c
- @@ -81,6 +81,7 @@
- #include <net/busy_poll.h>
-
- int sysctl_tcp_max_orphans __read_mostly = NR_FILE;
- +int sysctl_tcp_simult_connect __read_mostly = IS_ENABLED(CONFIG_TCP_SIMULT_CONNECT_DEFAULT_ON);
-
- #define FLAG_DATA 0x01 /* Incoming frame contained data. */
- #define FLAG_WIN_UPDATE 0x02 /* Incoming ACK was a window update. */
- @@ -6112,7 +6113,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
- tcp_paws_reject(&tp->rx_opt, 0))
- goto discard_and_undo;
-
- - if (th->syn) {
- + if (th->syn && sysctl_tcp_simult_connect) {
- /* We see SYN without ACK. It is attempt of
- * simultaneous connect with crossed SYNs.
- * Particularly, it can be connect to self.
- diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
- index 2dde6e5e9e69..e91ec2607abd 100644
- --- a/scripts/Makefile.modpost
- +++ b/scripts/Makefile.modpost
- @@ -54,6 +54,7 @@ MODPOST = scripts/mod/modpost \
- $(if $(KBUILD_EXTMOD),$(addprefix -e ,$(KBUILD_EXTRA_SYMBOLS))) \
- $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
- $(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \
- + $(if $(CONFIG_DEBUG_WRITABLE_FUNCTION_POINTERS_VERBOSE),-f) \
- $(if $(KBUILD_MODPOST_WARN),-w) \
- $(if $(filter nsdeps,$(MAKECMDGOALS)),-d)
-
- diff --git a/scripts/gcc-plugins/Kconfig b/scripts/gcc-plugins/Kconfig
- index e3569543bdac..55cc439b3bc6 100644
- --- a/scripts/gcc-plugins/Kconfig
- +++ b/scripts/gcc-plugins/Kconfig
- @@ -61,6 +61,11 @@ config GCC_PLUGIN_LATENT_ENTROPY
- is some slowdown of the boot process (about 0.5%) and fork and
- irq processing.
-
- + When extra_latent_entropy is passed on the kernel command line,
- + entropy will be extracted from up to the first 4GB of RAM while the
- + runtime memory allocator is being initialized. This costs even more
- + slowdown of the boot process.
- +
- Note that entropy extracted this way is not cryptographically
- secure!
-
- diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
- index 53e276bb24ac..dbb33e420915 100644
- --- a/scripts/mod/modpost.c
- +++ b/scripts/mod/modpost.c
- @@ -36,6 +36,8 @@ static int warn_unresolved = 0;
- /* How a symbol is exported */
- static int sec_mismatch_count = 0;
- static int sec_mismatch_fatal = 0;
- +static int writable_fptr_count = 0;
- +static int writable_fptr_verbose = false;
- /* ignore missing files */
- static int ignore_missing_files;
- /* write namespace dependencies */
- @@ -1019,6 +1021,7 @@ enum mismatch {
- ANY_EXIT_TO_ANY_INIT,
- EXPORT_TO_INIT_EXIT,
- EXTABLE_TO_NON_TEXT,
- + DATA_TO_TEXT
- };
-
- /**
- @@ -1145,6 +1148,12 @@ static const struct sectioncheck sectioncheck[] = {
- .good_tosec = {ALL_TEXT_SECTIONS , NULL},
- .mismatch = EXTABLE_TO_NON_TEXT,
- .handler = extable_mismatch_handler,
- +},
- +/* Do not reference code from writable data */
- +{
- + .fromsec = { DATA_SECTIONS, NULL },
- + .bad_tosec = { ALL_TEXT_SECTIONS, NULL },
- + .mismatch = DATA_TO_TEXT
- }
- };
-
- @@ -1337,10 +1346,10 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
- continue;
- if (!is_valid_name(elf, sym))
- continue;
- - if (sym->st_value == addr)
- - return sym;
- /* Find a symbol nearby - addr are maybe negative */
- d = sym->st_value - addr;
- + if (d == 0)
- + return sym;
- if (d < 0)
- d = addr - sym->st_value;
- if (d < distance) {
- @@ -1475,7 +1484,13 @@ static void report_sec_mismatch(const char *modname,
- char *prl_from;
- char *prl_to;
-
- - sec_mismatch_count++;
- + if (mismatch->mismatch == DATA_TO_TEXT) {
- + writable_fptr_count++;
- + if (!writable_fptr_verbose)
- + return;
- + } else {
- + sec_mismatch_count++;
- + }
-
- get_pretty_name(from_is_func, &from, &from_p);
- get_pretty_name(to_is_func, &to, &to_p);
- @@ -1597,6 +1612,12 @@ static void report_sec_mismatch(const char *modname,
- fatal("There's a special handler for this mismatch type, "
- "we should never get here.");
- break;
- + case DATA_TO_TEXT:
- + fprintf(stderr,
- + "The %s %s:%s references\n"
- + "the %s %s:%s%s\n",
- + from, fromsec, fromsym, to, tosec, tosym, to_p);
- + break;
- }
- fprintf(stderr, "\n");
- }
- @@ -2588,7 +2609,7 @@ int main(int argc, char **argv)
- struct ext_sym_list *extsym_iter;
- struct ext_sym_list *extsym_start = NULL;
-
- - while ((opt = getopt(argc, argv, "i:I:e:mnsT:o:awEd")) != -1) {
- + while ((opt = getopt(argc, argv, "i:I:e:fmnsT:o:awEd")) != -1) {
- switch (opt) {
- case 'i':
- kernel_read = optarg;
- @@ -2605,6 +2626,9 @@ int main(int argc, char **argv)
- extsym_iter->file = optarg;
- extsym_start = extsym_iter;
- break;
- + case 'f':
- + writable_fptr_verbose = true;
- + break;
- case 'm':
- modversions = 1;
- break;
- @@ -2711,6 +2735,11 @@ int main(int argc, char **argv)
- }
-
- free(buf.p);
- + if (writable_fptr_count && !writable_fptr_verbose)
- + warn("modpost: Found %d writable function pointer%s.\n"
- + "To see full details build your kernel with:\n"
- + "'make CONFIG_DEBUG_WRITABLE_FUNCTION_POINTERS_VERBOSE=y'\n",
- + writable_fptr_count, (writable_fptr_count == 1 ? "" : "s"));
-
- return err;
- }
- diff --git a/security/Kconfig b/security/Kconfig
- index 52e5109f2c1b..d9664a242f20 100644
- --- a/security/Kconfig
- +++ b/security/Kconfig
- @@ -9,7 +9,7 @@ source "security/keys/Kconfig"
-
- config SECURITY_DMESG_RESTRICT
- bool "Restrict unprivileged access to the kernel syslog"
- - default n
- + default y
- help
- This enforces restrictions on unprivileged users reading the kernel
- syslog via dmesg(8).
- @@ -19,10 +19,34 @@ 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
- + default y
- + 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_TIOCSTI_RESTRICT
- + bool "Restrict unprivileged use of tiocsti command injection"
- + default y
- + help
- + This enforces restrictions on unprivileged users injecting commands
- + into other processes which share a tty session using the TIOCSTI
- + ioctl. This option makes TIOCSTI use require CAP_SYS_ADMIN.
- +
- + If this option is not selected, no restrictions will be enforced
- + unless the tiocsti_restrict sysctl is explicitly set to (1).
- +
- + If you are unsure how to answer this question, answer N.
- +
- config SECURITY
- bool "Enable different security models"
- depends on SYSFS
- depends on MULTIUSER
- + default y
- help
- This allows you to choose different security modules to be
- configured into your kernel.
- @@ -48,6 +72,7 @@ config SECURITYFS
- config SECURITY_NETWORK
- bool "Socket and Networking Security Hooks"
- depends on SECURITY
- + default y
- help
- This enables the socket and networking security hooks.
- If enabled, a security module can use these hooks to
- @@ -154,6 +179,7 @@ config HARDENED_USERCOPY
- bool "Harden memory copies between kernel and userspace"
- depends on HAVE_HARDENED_USERCOPY_ALLOCATOR
- imply STRICT_DEVMEM
- + default y
- help
- This option checks for obviously wrong memory regions when
- copying memory to/from the kernel (via copy_to_user() and
- @@ -166,7 +192,6 @@ config HARDENED_USERCOPY
- config HARDENED_USERCOPY_FALLBACK
- bool "Allow usercopy whitelist violations to fallback to object size"
- depends on HARDENED_USERCOPY
- - default y
- help
- This is a temporary option that allows missing usercopy whitelists
- to be discovered via a WARN() to the kernel log, instead of
- @@ -194,10 +219,21 @@ config FORTIFY_SOURCE
- # https://bugs.llvm.org/show_bug.cgi?id=50322
- # https://bugs.llvm.org/show_bug.cgi?id=41459
- depends on !CC_IS_CLANG
- + default y
- help
- Detect overflows of buffers in common string and memory functions
- where the compiler can determine and validate the buffer sizes.
-
- +config FORTIFY_SOURCE_STRICT_STRING
- + bool "Harden common functions against buffer overflows"
- + depends on FORTIFY_SOURCE
- + depends on EXPERT
- + help
- + Perform stricter overflow checks catching overflows within objects
- + for common C string functions rather than only between objects.
- +
- + This is not yet intended for production use, only bug finding.
- +
- config STATIC_USERMODEHELPER
- bool "Force all usermode helper calls through a single binary"
- help
- diff --git a/security/Kconfig.hardening b/security/Kconfig.hardening
- index af4c979b38ee..473e40bb8537 100644
- --- a/security/Kconfig.hardening
- +++ b/security/Kconfig.hardening
- @@ -169,6 +169,7 @@ config STACKLEAK_RUNTIME_DISABLE
-
- config INIT_ON_ALLOC_DEFAULT_ON
- bool "Enable heap memory zeroing on allocation by default"
- + default yes
- help
- This has the effect of setting "init_on_alloc=1" on the kernel
- command line. This can be disabled with "init_on_alloc=0".
- @@ -181,6 +182,7 @@ config INIT_ON_ALLOC_DEFAULT_ON
-
- config INIT_ON_FREE_DEFAULT_ON
- bool "Enable heap memory zeroing on free by default"
- + default yes
- help
- This has the effect of setting "init_on_free=1" on the kernel
- command line. This can be disabled with "init_on_free=0".
- @@ -196,6 +198,20 @@ config INIT_ON_FREE_DEFAULT_ON
- touching "cold" memory areas. Most cases see 3-5% impact. Some
- synthetic workloads have measured as high as 8%.
-
- +config PAGE_SANITIZE_VERIFY
- + bool "Verify sanitized pages"
- + default y
- + help
- + When init_on_free is enabled, verify that newly allocated pages
- + are zeroed to detect write-after-free bugs.
- +
- +config SLAB_SANITIZE_VERIFY
- + default y
- + bool "Verify sanitized SLAB allocations"
- + help
- + When init_on_free is enabled, verify that newly allocated slab
- + objects are zeroed to detect write-after-free bugs.
- +
- endmenu
-
- endmenu
- diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
- index 5711689deb6a..fab0cb896907 100644
- --- a/security/selinux/Kconfig
- +++ b/security/selinux/Kconfig
- @@ -3,7 +3,7 @@ config SECURITY_SELINUX
- bool "NSA SELinux Support"
- depends on SECURITY_NETWORK && AUDIT && NET && INET
- select NETWORK_SECMARK
- - default n
- + default y
- help
- This selects NSA Security-Enhanced Linux (SELinux).
- You will also need a policy configuration and a labeled filesystem.
- @@ -65,23 +65,3 @@ config SECURITY_SELINUX_AVC_STATS
- This option collects access vector cache statistics to
- /selinux/avc/cache_stats, which may be monitored via
- tools such as avcstat.
- -
- -config SECURITY_SELINUX_CHECKREQPROT_VALUE
- - int "NSA SELinux checkreqprot default value"
- - depends on SECURITY_SELINUX
- - range 0 1
- - default 0
- - help
- - This option sets the default value for the 'checkreqprot' flag
- - that determines whether SELinux checks the protection requested
- - by the application or the protection that will be applied by the
- - kernel (including any implied execute for read-implies-exec) for
- - mmap and mprotect calls. If this option is set to 0 (zero),
- - SELinux will default to checking the protection that will be applied
- - by the kernel. If this option is set to 1 (one), SELinux will
- - default to checking the protection requested by the application.
- - The checkreqprot flag may be changed from the default via the
- - 'checkreqprot=' boot parameter. It may also be changed at runtime
- - via /selinux/checkreqprot if authorized by policy.
- -
- - If you are unsure how to answer this question, answer 0.
- diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
- index 6fec9fba41a8..b3da856a6482 100644
- --- a/security/selinux/hooks.c
- +++ b/security/selinux/hooks.c
- @@ -135,18 +135,7 @@ static int __init selinux_enabled_setup(char *str)
- __setup("selinux=", selinux_enabled_setup);
- #endif
-
- -static unsigned int selinux_checkreqprot_boot =
- - CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
- -
- -static int __init checkreqprot_setup(char *str)
- -{
- - unsigned long checkreqprot;
- -
- - if (!kstrtoul(str, 0, &checkreqprot))
- - selinux_checkreqprot_boot = checkreqprot ? 1 : 0;
- - return 1;
- -}
- -__setup("checkreqprot=", checkreqprot_setup);
- +static const unsigned int selinux_checkreqprot_boot;
-
- /**
- * selinux_secmark_enabled - Check to see if SECMARK is currently enabled
- diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
- index e9eaff90cbcc..239592d155a5 100644
- --- a/security/selinux/selinuxfs.c
- +++ b/security/selinux/selinuxfs.c
- @@ -639,7 +639,6 @@ static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf,
- static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
- {
- - struct selinux_fs_info *fsi = file_inode(file)->i_sb->s_fs_info;
- char *page;
- ssize_t length;
- unsigned int new_value;
- @@ -663,10 +662,9 @@ static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
- return PTR_ERR(page);
-
- length = -EINVAL;
- - if (sscanf(page, "%u", &new_value) != 1)
- + if (sscanf(page, "%u", &new_value) != 1 || new_value)
- goto out;
-
- - fsi->state->checkreqprot = new_value ? 1 : 0;
- length = count;
- out:
- kfree(page);
- diff --git a/security/yama/Kconfig b/security/yama/Kconfig
- index a810304123ca..b809050b25d2 100644
- --- a/security/yama/Kconfig
- +++ b/security/yama/Kconfig
- @@ -2,7 +2,7 @@
- config SECURITY_YAMA
- bool "Yama support"
- depends on SECURITY
- - default n
- + default y
- help
- This selects Yama, which extends DAC support with additional
- system-wide security settings beyond regular Linux discretionary
- diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
- index 9dd9e3f4ef59..9b25eefbdcf4 100644
- --- a/tools/perf/util/evsel.c
- +++ b/tools/perf/util/evsel.c
- @@ -2449,6 +2449,7 @@ int perf_evsel__open_strerror(struct evsel *evsel, struct target *target,
- " Disallow raw tracepoint access by users without CAP_SYS_ADMIN\n"
- ">= 1: Disallow CPU event access by users without CAP_SYS_ADMIN\n"
- ">= 2: Disallow kernel profiling by users without CAP_SYS_ADMIN\n\n"
- + ">= 3: Disallow use of any event by users without CAP_SYS_ADMIN\n\n"
- "To make this setting permanent, edit /etc/sysctl.conf too, e.g.:\n\n"
- " kernel.perf_event_paranoid = -1\n" ,
- target->system_wide ? "system-wide " : "",
|