*
* Returns the &file bound with @sock, implicitly storing it
* in sock->file. If dname is %NULL, sets to "".
- * On failure the return is a ERR pointer (see linux/err.h).
+ *
+ * On failure @sock is released, and an ERR pointer is returned.
+ *
* This function uses GFP_KERNEL internally.
*/
static void sock_recv_mark(struct msghdr *msg, struct sock *sk,
struct sk_buff *skb)
{
- if (sock_flag(sk, SOCK_RCVMARK) && skb)
- put_cmsg(msg, SOL_SOCKET, SO_MARK, sizeof(__u32),
- &skb->mark);
+ if (sock_flag(sk, SOCK_RCVMARK) && skb) {
+ /* We must use a bounce buffer for CONFIG_HARDENED_USERCOPY=y */
+ __u32 mark = skb->mark;
+
+ put_cmsg(msg, SOL_SOCKET, SO_MARK, sizeof(__u32), &mark);
+ }
}
void __sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,
struct file *__sys_socket_file(int family, int type, int protocol)
{
struct socket *sock;
- struct file *file;
int flags;
sock = __sys_socket_create(family, type, protocol);
if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
- file = sock_alloc_file(sock, flags, NULL);
- if (IS_ERR(file))
- sock_release(sock);
-
- return file;
+ return sock_alloc_file(sock, flags, NULL);
}
int __sys_socket(int family, int type, int protocol)
* error to return on the next call or if the
* app asks about it using getsockopt(SO_ERROR).
*/
- sock->sk->sk_err = -err;
+ WRITE_ONCE(sock->sk->sk_err, -err);
}
out_put:
fput_light(sock->file, fput_needed);