Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc73fee0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull ipc compat cleanup and 64-bit time_t from Al Viro:
 "IPC copyin/copyout sanitizing, including 64bit time_t work from Deepa
  Dinamani"

* 'work.ipc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  utimes: Make utimes y2038 safe
  ipc: shm: Make shmid_kernel timestamps y2038 safe
  ipc: sem: Make sem_array timestamps y2038 safe
  ipc: msg: Make msg_queue timestamps y2038 safe
  ipc: mqueue: Replace timespec with timespec64
  ipc: Make sys_semtimedop() y2038 safe
  get rid of SYSVIPC_COMPAT on ia64
  semtimedop(): move compat to native
  shmat(2): move compat to native
  msgrcv(2), msgsnd(2): move compat to native
  ipc(2): move compat to native
  ipc: make use of compat ipc_perm helpers
  semctl(): move compat to native
  semctl(): separate all layout-dependent copyin/copyout
  msgctl(): move compat to native
  msgctl(): split the actual work from copyin/copyout
  ipc: move compat shmctl to native
  shmctl: split the work from copyin/copyout
parents e7cdb60f aaed2dd8
Loading
Loading
Loading
Loading
+0 −5
Original line number Original line Diff line number Diff line
@@ -56,9 +56,4 @@ config IA64_DEBUG_IRQ
	  and restore instructions.  It's useful for tracking down spinlock
	  and restore instructions.  It's useful for tracking down spinlock
	  problems, but slow!  If you're unsure, select N.
	  problems, but slow!  If you're unsure, select N.


config SYSVIPC_COMPAT
	bool
	depends on COMPAT && SYSVIPC
	default y

endmenu
endmenu
+12 −11
Original line number Original line Diff line number Diff line
@@ -22,7 +22,7 @@
 */
 */
SYSCALL_DEFINE2(utime, char __user *, filename, struct utimbuf __user *, times)
SYSCALL_DEFINE2(utime, char __user *, filename, struct utimbuf __user *, times)
{
{
	struct timespec tv[2];
	struct timespec64 tv[2];


	if (times) {
	if (times) {
		if (get_user(tv[0].tv_sec, &times->actime) ||
		if (get_user(tv[0].tv_sec, &times->actime) ||
@@ -44,7 +44,7 @@ static bool nsec_valid(long nsec)
	return nsec >= 0 && nsec <= 999999999;
	return nsec >= 0 && nsec <= 999999999;
}
}


static int utimes_common(const struct path *path, struct timespec *times)
static int utimes_common(const struct path *path, struct timespec64 *times)
{
{
	int error;
	int error;
	struct iattr newattrs;
	struct iattr newattrs;
@@ -115,7 +115,7 @@ static int utimes_common(const struct path *path, struct timespec *times)
 * must be owner or have write permission.
 * must be owner or have write permission.
 * Else, update from *times, must be owner or super user.
 * Else, update from *times, must be owner or super user.
 */
 */
long do_utimes(int dfd, const char __user *filename, struct timespec *times,
long do_utimes(int dfd, const char __user *filename, struct timespec64 *times,
	       int flags)
	       int flags)
{
{
	int error = -EINVAL;
	int error = -EINVAL;
@@ -167,10 +167,11 @@ long do_utimes(int dfd, const char __user *filename, struct timespec *times,
SYSCALL_DEFINE4(utimensat, int, dfd, const char __user *, filename,
SYSCALL_DEFINE4(utimensat, int, dfd, const char __user *, filename,
		struct timespec __user *, utimes, int, flags)
		struct timespec __user *, utimes, int, flags)
{
{
	struct timespec tstimes[2];
	struct timespec64 tstimes[2];


	if (utimes) {
	if (utimes) {
		if (copy_from_user(&tstimes, utimes, sizeof(tstimes)))
		if ((get_timespec64(&tstimes[0], &utimes[0]) ||
			get_timespec64(&tstimes[1], &utimes[1])))
			return -EFAULT;
			return -EFAULT;


		/* Nothing to do, we must not even check the path.  */
		/* Nothing to do, we must not even check the path.  */
@@ -186,7 +187,7 @@ SYSCALL_DEFINE3(futimesat, int, dfd, const char __user *, filename,
		struct timeval __user *, utimes)
		struct timeval __user *, utimes)
{
{
	struct timeval times[2];
	struct timeval times[2];
	struct timespec tstimes[2];
	struct timespec64 tstimes[2];


	if (utimes) {
	if (utimes) {
		if (copy_from_user(&times, utimes, sizeof(times)))
		if (copy_from_user(&times, utimes, sizeof(times)))
@@ -224,7 +225,7 @@ SYSCALL_DEFINE2(utimes, char __user *, filename,
COMPAT_SYSCALL_DEFINE2(utime, const char __user *, filename,
COMPAT_SYSCALL_DEFINE2(utime, const char __user *, filename,
		       struct compat_utimbuf __user *, t)
		       struct compat_utimbuf __user *, t)
{
{
	struct timespec tv[2];
	struct timespec64 tv[2];


	if (t) {
	if (t) {
		if (get_user(tv[0].tv_sec, &t->actime) ||
		if (get_user(tv[0].tv_sec, &t->actime) ||
@@ -238,11 +239,11 @@ COMPAT_SYSCALL_DEFINE2(utime, const char __user *, filename,


COMPAT_SYSCALL_DEFINE4(utimensat, unsigned int, dfd, const char __user *, filename, struct compat_timespec __user *, t, int, flags)
COMPAT_SYSCALL_DEFINE4(utimensat, unsigned int, dfd, const char __user *, filename, struct compat_timespec __user *, t, int, flags)
{
{
	struct timespec tv[2];
	struct timespec64 tv[2];


	if  (t) {
	if  (t) {
		if (compat_get_timespec(&tv[0], &t[0]) ||
		if (compat_get_timespec64(&tv[0], &t[0]) ||
		    compat_get_timespec(&tv[1], &t[1]))
		    compat_get_timespec64(&tv[1], &t[1]))
			return -EFAULT;
			return -EFAULT;


		if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT)
		if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT)
@@ -253,7 +254,7 @@ COMPAT_SYSCALL_DEFINE4(utimensat, unsigned int, dfd, const char __user *, filena


COMPAT_SYSCALL_DEFINE3(futimesat, unsigned int, dfd, const char __user *, filename, struct compat_timeval __user *, t)
COMPAT_SYSCALL_DEFINE3(futimesat, unsigned int, dfd, const char __user *, filename, struct compat_timeval __user *, t)
{
{
	struct timespec tv[2];
	struct timespec64 tv[2];


	if (t) {
	if (t) {
		if (get_user(tv[0].tv_sec, &t[0].tv_sec) ||
		if (get_user(tv[0].tv_sec, &t[0].tv_sec) ||
+3 −3
Original line number Original line Diff line number Diff line
@@ -351,7 +351,7 @@ extern int __audit_socketcall(int nargs, unsigned long *args);
extern int __audit_sockaddr(int len, void *addr);
extern int __audit_sockaddr(int len, void *addr);
extern void __audit_fd_pair(int fd1, int fd2);
extern void __audit_fd_pair(int fd1, int fd2);
extern void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr);
extern void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr);
extern void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout);
extern void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec64 *abs_timeout);
extern void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification);
extern void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification);
extern void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
extern void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
@@ -412,7 +412,7 @@ static inline void audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
	if (unlikely(!audit_dummy_context()))
	if (unlikely(!audit_dummy_context()))
		__audit_mq_open(oflag, mode, attr);
		__audit_mq_open(oflag, mode, attr);
}
}
static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout)
static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec64 *abs_timeout)
{
{
	if (unlikely(!audit_dummy_context()))
	if (unlikely(!audit_dummy_context()))
		__audit_mq_sendrecv(mqdes, msg_len, msg_prio, abs_timeout);
		__audit_mq_sendrecv(mqdes, msg_len, msg_prio, abs_timeout);
@@ -549,7 +549,7 @@ static inline void audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
{ }
{ }
static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len,
static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len,
				     unsigned int msg_prio,
				     unsigned int msg_prio,
				     const struct timespec *abs_timeout)
				     const struct timespec64 *abs_timeout)
{ }
{ }
static inline void audit_mq_notify(mqd_t mqdes,
static inline void audit_mq_notify(mqd_t mqdes,
				   const struct sigevent *notification)
				   const struct sigevent *notification)
+0 −9
Original line number Original line Diff line number Diff line
@@ -171,15 +171,6 @@ extern int get_compat_itimerspec64(struct itimerspec64 *its,
extern int put_compat_itimerspec64(const struct itimerspec64 *its,
extern int put_compat_itimerspec64(const struct itimerspec64 *its,
			struct compat_itimerspec __user *uits);
			struct compat_itimerspec __user *uits);


/*
 * This function convert a timespec if necessary and returns a *user
 * space* pointer.  If no conversion is necessary, it returns the
 * initial pointer.  NULL is a legitimate argument and will always
 * output NULL.
 */
extern int compat_convert_timespec(struct timespec __user **,
				   const void __user *);

struct compat_iovec {
struct compat_iovec {
	compat_uptr_t	iov_base;
	compat_uptr_t	iov_base;
	compat_size_t	iov_len;
	compat_size_t	iov_len;
+4 −11
Original line number Original line Diff line number Diff line
@@ -2,6 +2,7 @@
#define _LINUX_MSG_H
#define _LINUX_MSG_H


#include <linux/list.h>
#include <linux/list.h>
#include <linux/time64.h>
#include <uapi/linux/msg.h>
#include <uapi/linux/msg.h>


/* one msg_msg structure for each message */
/* one msg_msg structure for each message */
@@ -17,9 +18,9 @@ struct msg_msg {
/* one msq_queue structure for each present queue on the system */
/* one msq_queue structure for each present queue on the system */
struct msg_queue {
struct msg_queue {
	struct kern_ipc_perm q_perm;
	struct kern_ipc_perm q_perm;
	time_t q_stime;			/* last msgsnd time */
	time64_t q_stime;		/* last msgsnd time */
	time_t q_rtime;			/* last msgrcv time */
	time64_t q_rtime;		/* last msgrcv time */
	time_t q_ctime;			/* last change time */
	time64_t q_ctime;		/* last change time */
	unsigned long q_cbytes;		/* current number of bytes on queue */
	unsigned long q_cbytes;		/* current number of bytes on queue */
	unsigned long q_qnum;		/* number of messages in queue */
	unsigned long q_qnum;		/* number of messages in queue */
	unsigned long q_qbytes;		/* max number of bytes on queue */
	unsigned long q_qbytes;		/* max number of bytes on queue */
@@ -31,12 +32,4 @@ struct msg_queue {
	struct list_head q_senders;
	struct list_head q_senders;
} __randomize_layout;
} __randomize_layout;


/* Helper routines for sys_msgsnd and sys_msgrcv */
extern long do_msgsnd(int msqid, long mtype, void __user *mtext,
			size_t msgsz, int msgflg);
extern long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp,
		      int msgflg,
		      long (*msg_fill)(void __user *, struct msg_msg *,
				       size_t));

#endif /* _LINUX_MSG_H */
#endif /* _LINUX_MSG_H */
Loading