O_CLOEXEC for SCM_RIGHTS
Changes
6 files changed · +10 −6
| File | Status | Add | Del | Content |
|---|---|---|---|---|
| fs/open.c | modified | +1 | −1 | View file |
| include/linux/file.h | modified | +1 | −0 | View file |
| include/linux/socket.h | modified | +3 | −0 | View file |
| net/compat.c | modified | +2 | −1 | View file |
| net/core/scm.c | modified | +2 | −1 | View file |
| net/socket.c | modified | +1 | −3 | View file |
fs/open.c
View filediff --git a/fs/open.c b/fs/open.c
index e6991c1..be6a457 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -855,7 +855,7 @@ EXPORT_SYMBOL(dentry_open);
/*
* Find an empty file descriptor entry, and mark it busy.
*/
-static int get_unused_fd_flags(int flags)
+int get_unused_fd_flags(int flags)
{
struct files_struct * files = current->files;
int fd, error;
include/linux/file.h
View filediff --git a/include/linux/file.h b/include/linux/file.h
index a59001e..0114fbc 100644
--- a/include/linux/file.h
+++ b/include/linux/file.h
@@ -73,6 +73,7 @@ extern struct file * FASTCALL(fget_light(unsigned int fd, int *fput_needed));
extern void FASTCALL(set_close_on_exec(unsigned int fd, int flag));
extern void put_filp(struct file *);
extern int get_unused_fd(void);
+extern int get_unused_fd_flags(int flags);
extern void FASTCALL(put_unused_fd(unsigned int fd));
struct kmem_cache;
include/linux/socket.h
View filediff --git a/include/linux/socket.h b/include/linux/socket.h
index fe195c9..f852e1a 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -253,6 +253,9 @@ struct ucred {
#define MSG_EOF MSG_FIN
+#define MSG_CMSG_CLOEXEC 0x40000000 /* Set close_on_exit for file
+ descriptor received through
+ SCM_RIGHTS */
#if defined(CONFIG_COMPAT)
#define MSG_CMSG_COMPAT 0x80000000 /* This message needs 32 bit fixups */
#else
net/compat.c
View filediff --git a/net/compat.c b/net/compat.c
index 9a0f5f2..d74d821 100644
--- a/net/compat.c
+++ b/net/compat.c
@@ -276,7 +276,8 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)
err = security_file_receive(fp[i]);
if (err)
break;
- err = get_unused_fd();
+ err = get_unused_fd_flags(MSG_CMSG_CLOEXEC & kmsg->msg_flags
+ ? O_CLOEXEC : 0);
if (err < 0)
break;
new_fd = err;
net/core/scm.c
View filediff --git a/net/core/scm.c b/net/core/scm.c
index 292ad8d..44c4ec2 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -228,7 +228,8 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
err = security_file_receive(fp[i]);
if (err)
break;
- err = get_unused_fd();
+ err = get_unused_fd_flags(MSG_CMSG_CLOEXEC & msg->msg_flags
+ ? O_CLOEXEC : 0);
if (err < 0)
break;
new_fd = err;
net/socket.c
View filediff --git a/net/socket.c b/net/socket.c
index f453019..b711142 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1939,9 +1939,7 @@ asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg,
total_len = err;
cmsg_ptr = (unsigned long)msg_sys.msg_control;
- msg_sys.msg_flags = 0;
- if (MSG_CMSG_COMPAT & flags)
- msg_sys.msg_flags = MSG_CMSG_COMPAT;
+ msg_sys.msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
if (sock->file->f_flags & O_NONBLOCK)
flags |= MSG_DONTWAIT;