Skip to content

Commit

Permalink
Merge branch 'net-remove-compat-alloc-user-space'
Browse files Browse the repository at this point in the history
Arnd Bergmann says:

====================
remove compat_alloc_user_space()

This is the fifth version of my series, now spanning four patches
instead of two, with a new approach for handling struct ifreq
compatibility after I realized that my earlier approach introduces
additional problems.

The idea here is to always push down the compat conversion
deeper into the call stack: rather than pretending to be
native mode with a modified copy of the original data on
the user space stack, have the code that actually works on
the data understand the difference between native and compat
versions.

I have spent a long time looking at all drivers that implement
an ndo_do_ioctl callback to verify that my assumptions are
correct. This has led to a series of ~30 additional patches
that I am not including here but will post separately, fixing
a number of bugs in SIOCDEVPRIVATE ioctls, removing dead
code, and splitting ndo_do_ioctl into multiple new ndo callbacks
for private and ethernet specific commands.

      Arnd

Link: https://lore.kernel.org/netdev/20201124151828.169152-1-arnd@kernel.org/

Changes in v6:
 - Split out and expand linux/compat.h rework
 - Split ifconf change into two patches
 - Rebase on latest net-next/master

Changes in v5:
 - Rebase to v5.14-rc2
 - Fix a few build issues

Changes in v4:
 - build fix without CONFIG_INET
 - build fix without CONFIG_COMPAT
 - style fixes pointed out by hch

Changes in v3:
 - complete rewrite of the series
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jul 23, 2021
2 parents 4431531 + 29c4964 commit 090597b
Show file tree
Hide file tree
Showing 21 changed files with 352 additions and 431 deletions.
14 changes: 3 additions & 11 deletions arch/arm64/include/asm/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#ifndef __ASM_COMPAT_H
#define __ASM_COMPAT_H

#define compat_mode_t compat_mode_t
typedef u16 compat_mode_t;

#include <asm-generic/compat.h>

#ifdef CONFIG_COMPAT
Expand All @@ -27,13 +30,9 @@ typedef u16 __compat_uid_t;
typedef u16 __compat_gid_t;
typedef u16 __compat_uid16_t;
typedef u16 __compat_gid16_t;
typedef u32 __compat_uid32_t;
typedef u32 __compat_gid32_t;
typedef u16 compat_mode_t;
typedef u32 compat_dev_t;
typedef s32 compat_nlink_t;
typedef u16 compat_ipc_pid_t;
typedef u32 compat_caddr_t;
typedef __kernel_fsid_t compat_fsid_t;

struct compat_stat {
Expand Down Expand Up @@ -103,13 +102,6 @@ struct compat_statfs {

#define COMPAT_RLIM_INFINITY 0xffffffff

typedef u32 compat_old_sigset_t;

#define _COMPAT_NSIG 64
#define _COMPAT_NSIG_BPW 32

typedef u32 compat_sigset_word;

#define COMPAT_OFF_T_MAX 0x7fffffff

#define compat_user_stack_pointer() (user_stack_pointer(task_pt_regs(current)))
Expand Down
24 changes: 11 additions & 13 deletions arch/mips/include/asm/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,25 @@
#include <asm/page.h>
#include <asm/ptrace.h>

typedef s32 __compat_uid_t;
typedef s32 __compat_gid_t;
typedef __compat_uid_t __compat_uid32_t;
typedef __compat_gid_t __compat_gid32_t;
#define __compat_uid32_t __compat_uid32_t
#define __compat_gid32_t __compat_gid32_t

#define _COMPAT_NSIG 128 /* Don't ask !$@#% ... */
#define _COMPAT_NSIG_BPW 32
typedef u32 compat_sigset_word;

#include <asm-generic/compat.h>

#define COMPAT_USER_HZ 100
#define COMPAT_UTS_MACHINE "mips\0\0\0"

typedef s32 __compat_uid_t;
typedef s32 __compat_gid_t;
typedef __compat_uid_t __compat_uid32_t;
typedef __compat_gid_t __compat_gid32_t;
typedef u32 compat_mode_t;
typedef u32 compat_dev_t;
typedef u32 compat_nlink_t;
typedef s32 compat_ipc_pid_t;
typedef s32 compat_caddr_t;
typedef struct {
s32 val[2];
} compat_fsid_t;
Expand Down Expand Up @@ -89,13 +94,6 @@ struct compat_statfs {

#define COMPAT_RLIM_INFINITY 0x7fffffffUL

typedef u32 compat_old_sigset_t; /* at least 32 bits */

#define _COMPAT_NSIG 128 /* Don't ask !$@#% ... */
#define _COMPAT_NSIG_BPW 32

typedef u32 compat_sigset_word;

#define COMPAT_OFF_T_MAX 0x7fffffff

static inline void __user *arch_compat_alloc_user_space(long len)
Expand Down
14 changes: 3 additions & 11 deletions arch/parisc/include/asm/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,19 @@
#include <linux/sched.h>
#include <linux/thread_info.h>

#define compat_mode_t compat_mode_t
typedef u16 compat_mode_t;

#include <asm-generic/compat.h>

#define COMPAT_USER_HZ 100
#define COMPAT_UTS_MACHINE "parisc\0\0"

typedef u32 __compat_uid_t;
typedef u32 __compat_gid_t;
typedef u32 __compat_uid32_t;
typedef u32 __compat_gid32_t;
typedef u16 compat_mode_t;
typedef u32 compat_dev_t;
typedef u16 compat_nlink_t;
typedef u16 compat_ipc_pid_t;
typedef u32 compat_caddr_t;

struct compat_stat {
compat_dev_t st_dev; /* dev_t is 32 bits on parisc */
Expand Down Expand Up @@ -96,13 +95,6 @@ struct compat_sigcontext {

#define COMPAT_RLIM_INFINITY 0xffffffff

typedef u32 compat_old_sigset_t; /* at least 32 bits */

#define _COMPAT_NSIG 64
#define _COMPAT_NSIG_BPW 32

typedef u32 compat_sigset_word;

#define COMPAT_OFF_T_MAX 0x7fffffff

struct compat_ipc64_perm {
Expand Down
11 changes: 0 additions & 11 deletions arch/powerpc/include/asm/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,9 @@

typedef u32 __compat_uid_t;
typedef u32 __compat_gid_t;
typedef u32 __compat_uid32_t;
typedef u32 __compat_gid32_t;
typedef u32 compat_mode_t;
typedef u32 compat_dev_t;
typedef s16 compat_nlink_t;
typedef u16 compat_ipc_pid_t;
typedef u32 compat_caddr_t;
typedef __kernel_fsid_t compat_fsid_t;

struct compat_stat {
Expand Down Expand Up @@ -85,13 +81,6 @@ struct compat_statfs {

#define COMPAT_RLIM_INFINITY 0xffffffff

typedef u32 compat_old_sigset_t;

#define _COMPAT_NSIG 64
#define _COMPAT_NSIG_BPW 32

typedef u32 compat_sigset_word;

#define COMPAT_OFF_T_MAX 0x7fffffff

static inline void __user *arch_compat_alloc_user_space(long len)
Expand Down
14 changes: 3 additions & 11 deletions arch/s390/include/asm/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#include <linux/sched/task_stack.h>
#include <linux/thread_info.h>

#define compat_mode_t compat_mode_t
typedef u16 compat_mode_t;

#include <asm-generic/compat.h>

#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p( \
Expand Down Expand Up @@ -55,13 +58,9 @@

typedef u16 __compat_uid_t;
typedef u16 __compat_gid_t;
typedef u32 __compat_uid32_t;
typedef u32 __compat_gid32_t;
typedef u16 compat_mode_t;
typedef u16 compat_dev_t;
typedef u16 compat_nlink_t;
typedef u16 compat_ipc_pid_t;
typedef u32 compat_caddr_t;
typedef __kernel_fsid_t compat_fsid_t;

typedef struct {
Expand Down Expand Up @@ -155,13 +154,6 @@ struct compat_statfs64 {

#define COMPAT_RLIM_INFINITY 0xffffffff

typedef u32 compat_old_sigset_t; /* at least 32 bits */

#define _COMPAT_NSIG 64
#define _COMPAT_NSIG_BPW 32

typedef u32 compat_sigset_word;

#define COMPAT_OFF_T_MAX 0x7fffffff

/*
Expand Down
14 changes: 3 additions & 11 deletions arch/sparc/include/asm/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,19 @@
*/
#include <linux/types.h>

#define compat_mode_t compat_mode_t
typedef u16 compat_mode_t;

#include <asm-generic/compat.h>

#define COMPAT_USER_HZ 100
#define COMPAT_UTS_MACHINE "sparc\0\0"

typedef u16 __compat_uid_t;
typedef u16 __compat_gid_t;
typedef u32 __compat_uid32_t;
typedef u32 __compat_gid32_t;
typedef u16 compat_mode_t;
typedef u16 compat_dev_t;
typedef s16 compat_nlink_t;
typedef u16 compat_ipc_pid_t;
typedef u32 compat_caddr_t;
typedef __kernel_fsid_t compat_fsid_t;

struct compat_stat {
Expand Down Expand Up @@ -115,13 +114,6 @@ struct compat_statfs {

#define COMPAT_RLIM_INFINITY 0x7fffffff

typedef u32 compat_old_sigset_t;

#define _COMPAT_NSIG 64
#define _COMPAT_NSIG_BPW 32

typedef u32 compat_sigset_word;

#define COMPAT_OFF_T_MAX 0x7fffffff

#ifdef CONFIG_COMPAT
Expand Down
14 changes: 3 additions & 11 deletions arch/x86/include/asm/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,19 @@
#include <asm/user32.h>
#include <asm/unistd.h>

#define compat_mode_t compat_mode_t
typedef u16 compat_mode_t;

#include <asm-generic/compat.h>

#define COMPAT_USER_HZ 100
#define COMPAT_UTS_MACHINE "i686\0\0"

typedef u16 __compat_uid_t;
typedef u16 __compat_gid_t;
typedef u32 __compat_uid32_t;
typedef u32 __compat_gid32_t;
typedef u16 compat_mode_t;
typedef u16 compat_dev_t;
typedef u16 compat_nlink_t;
typedef u16 compat_ipc_pid_t;
typedef u32 compat_caddr_t;
typedef __kernel_fsid_t compat_fsid_t;

struct compat_stat {
Expand Down Expand Up @@ -92,13 +91,6 @@ struct compat_statfs {

#define COMPAT_RLIM_INFINITY 0xffffffff

typedef u32 compat_old_sigset_t; /* at least 32 bits */

#define _COMPAT_NSIG 64
#define _COMPAT_NSIG_BPW 32

typedef u32 compat_sigset_word;

#define COMPAT_OFF_T_MAX 0x7fffffff

struct compat_ipc64_perm {
Expand Down
1 change: 1 addition & 0 deletions arch/x86/include/asm/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ typedef struct {
#define SA_X32_ABI 0x01000000u

#ifndef CONFIG_COMPAT
#define compat_sigset_t compat_sigset_t
typedef sigset_t compat_sigset_t;
#endif

Expand Down
17 changes: 17 additions & 0 deletions include/asm-generic/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,18 @@ typedef u16 compat_ushort_t;
typedef u32 compat_uint_t;
typedef u32 compat_ulong_t;
typedef u32 compat_uptr_t;
typedef u32 compat_caddr_t;
typedef u32 compat_aio_context_t;
typedef u32 compat_old_sigset_t;

#ifndef __compat_uid32_t
typedef u32 __compat_uid32_t;
typedef u32 __compat_gid32_t;
#endif

#ifndef compat_mode_t
typedef u32 compat_mode_t;
#endif

#ifdef CONFIG_COMPAT_FOR_U64_ALIGNMENT
typedef s64 __attribute__((aligned(4))) compat_s64;
Expand All @@ -30,4 +41,10 @@ typedef s64 compat_s64;
typedef u64 compat_u64;
#endif

#ifndef _COMPAT_NSIG
typedef u32 compat_sigset_word;
#define _COMPAT_NSIG _NSIG
#define _COMPAT_NSIG_BPW 32
#endif

#endif
32 changes: 15 additions & 17 deletions include/linux/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,8 @@
#include <linux/unistd.h>

#include <asm/compat.h>

#ifdef CONFIG_COMPAT
#include <asm/siginfo.h>
#include <asm/signal.h>
#endif

#ifdef CONFIG_ARCH_HAS_SYSCALL_WRAPPER
/*
Expand Down Expand Up @@ -95,8 +92,6 @@ struct compat_iovec {
compat_size_t iov_len;
};

#ifdef CONFIG_COMPAT

#ifndef compat_user_stack_pointer
#define compat_user_stack_pointer() current_user_stack_pointer()
#endif
Expand Down Expand Up @@ -131,9 +126,11 @@ struct compat_tms {

#define _COMPAT_NSIG_WORDS (_COMPAT_NSIG / _COMPAT_NSIG_BPW)

#ifndef compat_sigset_t
typedef struct {
compat_sigset_word sig[_COMPAT_NSIG_WORDS];
} compat_sigset_t;
#endif

int set_compat_user_sigmask(const compat_sigset_t __user *umask,
size_t sigsetsize);
Expand Down Expand Up @@ -384,6 +381,7 @@ struct compat_keyctl_kdf_params {
__u32 __spare[8];
};

struct compat_stat;
struct compat_statfs;
struct compat_statfs64;
struct compat_old_linux_dirent;
Expand Down Expand Up @@ -428,7 +426,7 @@ put_compat_sigset(compat_sigset_t __user *compat, const sigset_t *set,
unsigned int size)
{
/* size <= sizeof(compat_sigset_t) <= sizeof(sigset_t) */
#ifdef __BIG_ENDIAN
#if defined(__BIG_ENDIAN) && defined(CONFIG_64BIT)
compat_sigset_t v;
switch (_NSIG_WORDS) {
case 4: v.sig[7] = (set->sig[3] >> 32); v.sig[6] = set->sig[3];
Expand Down Expand Up @@ -929,17 +927,6 @@ asmlinkage long compat_sys_socketcall(int call, u32 __user *args);

#endif /* CONFIG_ARCH_HAS_SYSCALL_WRAPPER */


/*
* For most but not all architectures, "am I in a compat syscall?" and
* "am I a compat task?" are the same question. For architectures on which
* they aren't the same question, arch code can override in_compat_syscall.
*/

#ifndef in_compat_syscall
static inline bool in_compat_syscall(void) { return is_compat_task(); }
#endif

/**
* ns_to_old_timeval32 - Compat version of ns_to_timeval
* @nsec: the nanoseconds value to be converted
Expand Down Expand Up @@ -969,6 +956,17 @@ int kcompat_sys_statfs64(const char __user * pathname, compat_size_t sz,
int kcompat_sys_fstatfs64(unsigned int fd, compat_size_t sz,
struct compat_statfs64 __user * buf);

#ifdef CONFIG_COMPAT

/*
* For most but not all architectures, "am I in a compat syscall?" and
* "am I a compat task?" are the same question. For architectures on which
* they aren't the same question, arch code can override in_compat_syscall.
*/
#ifndef in_compat_syscall
static inline bool in_compat_syscall(void) { return is_compat_task(); }
#endif

#else /* !CONFIG_COMPAT */

#define is_compat_task() (0)
Expand Down
Loading

0 comments on commit 090597b

Please sign in to comment.