Two nfsd bugfixes, neither 4.13 regressions, but both potentially
serious. -----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJZoFxzAAoJECebzXlCjuG+T+4QAJhvEAPfoqxAJcjpy5Wgal96 1QmHR1owRyA85MMVHhnVUClzzezECc8uXOxRvRFx+4pCW4PRwY3CRa6H0Acrte0l npxWi6CiOkuLTCA+NNVnJAty7zBp2Ag0hYJc2NFwhZJ1cVOcIab6Pc7U6jyoB7Nh d10rmB7eYsevZgKaCwxxlieFIkIDrPhIJzku5Zy7PXneITzDKX8kEaIs+JkuJ3xt H2w3ERpeeDVDlRd6ffo2OwXKaQkCmMNb64c2YA6yZptOHikuR5ARuvZxbOGveHrM uCrxAFgETBIusmBC45W9MmTw4c3GgDcW8/yx09pLWD7UDwsbOLMspXl9usX5sgaq Py3HpyPpZjovmfJUCI4UW/RWyo4El5T3IlknHjjg5AfnA3fe15xZVKcmKetVe4k9 QxWKenwv+0hnOztF5Xotiysw+08aF6rIe3QQ/n6ZMathZAqvaaKsHa5TICL78anO F1WqwEKx7c7wg1ZnvV2uAeVsGobHi6Y5LAsyKx3dZMfZmVjqZe4wxGSD5eFAore5 t4QWDWnLY0t/iPrYpLB1vINXvgD1T6b3rvnMiwm2B+ITMNzNOgLK0vYsNjzsk0uL gIOGma2LN7HwtKlsZHZewsR2rsIPcQ4D9FfPZBo1+jSYLzL4ktHWTalFCngwylhe y7iV/D+jvrHzrMr9T6rl =L3ES -----END PGP SIGNATURE----- Merge tag 'nfsd-4.13-2' of git://linux-nfs.org/~bfields/linux Pull nfsd fixes from Bruce Fields: "Two nfsd bugfixes, neither 4.13 regressions, but both potentially serious" * tag 'nfsd-4.13-2' of git://linux-nfs.org/~bfields/linux: net: sunrpc: svcsock: fix NULL-pointer exception nfsd: Limit end of page list when decoding NFSv4 WRITE
This commit is contained in:
commit
105065c3f7
2 changed files with 22 additions and 6 deletions
|
@ -144,7 +144,7 @@ static void next_decode_page(struct nfsd4_compoundargs *argp)
|
|||
argp->p = page_address(argp->pagelist[0]);
|
||||
argp->pagelist++;
|
||||
if (argp->pagelen < PAGE_SIZE) {
|
||||
argp->end = argp->p + (argp->pagelen>>2);
|
||||
argp->end = argp->p + XDR_QUADLEN(argp->pagelen);
|
||||
argp->pagelen = 0;
|
||||
} else {
|
||||
argp->end = argp->p + (PAGE_SIZE>>2);
|
||||
|
@ -1279,9 +1279,7 @@ nfsd4_decode_write(struct nfsd4_compoundargs *argp, struct nfsd4_write *write)
|
|||
argp->pagelen -= pages * PAGE_SIZE;
|
||||
len -= pages * PAGE_SIZE;
|
||||
|
||||
argp->p = (__be32 *)page_address(argp->pagelist[0]);
|
||||
argp->pagelist++;
|
||||
argp->end = argp->p + XDR_QUADLEN(PAGE_SIZE);
|
||||
next_decode_page(argp);
|
||||
}
|
||||
argp->p += XDR_QUADLEN(len);
|
||||
|
||||
|
|
|
@ -421,6 +421,9 @@ static void svc_data_ready(struct sock *sk)
|
|||
dprintk("svc: socket %p(inet %p), busy=%d\n",
|
||||
svsk, sk,
|
||||
test_bit(XPT_BUSY, &svsk->sk_xprt.xpt_flags));
|
||||
|
||||
/* Refer to svc_setup_socket() for details. */
|
||||
rmb();
|
||||
svsk->sk_odata(sk);
|
||||
if (!test_and_set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags))
|
||||
svc_xprt_enqueue(&svsk->sk_xprt);
|
||||
|
@ -437,6 +440,9 @@ static void svc_write_space(struct sock *sk)
|
|||
if (svsk) {
|
||||
dprintk("svc: socket %p(inet %p), write_space busy=%d\n",
|
||||
svsk, sk, test_bit(XPT_BUSY, &svsk->sk_xprt.xpt_flags));
|
||||
|
||||
/* Refer to svc_setup_socket() for details. */
|
||||
rmb();
|
||||
svsk->sk_owspace(sk);
|
||||
svc_xprt_enqueue(&svsk->sk_xprt);
|
||||
}
|
||||
|
@ -760,8 +766,12 @@ static void svc_tcp_listen_data_ready(struct sock *sk)
|
|||
dprintk("svc: socket %p TCP (listen) state change %d\n",
|
||||
sk, sk->sk_state);
|
||||
|
||||
if (svsk)
|
||||
if (svsk) {
|
||||
/* Refer to svc_setup_socket() for details. */
|
||||
rmb();
|
||||
svsk->sk_odata(sk);
|
||||
}
|
||||
|
||||
/*
|
||||
* This callback may called twice when a new connection
|
||||
* is established as a child socket inherits everything
|
||||
|
@ -794,6 +804,8 @@ static void svc_tcp_state_change(struct sock *sk)
|
|||
if (!svsk)
|
||||
printk("svc: socket %p: no user data\n", sk);
|
||||
else {
|
||||
/* Refer to svc_setup_socket() for details. */
|
||||
rmb();
|
||||
svsk->sk_ostate(sk);
|
||||
if (sk->sk_state != TCP_ESTABLISHED) {
|
||||
set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags);
|
||||
|
@ -1381,12 +1393,18 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
|
|||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
inet->sk_user_data = svsk;
|
||||
svsk->sk_sock = sock;
|
||||
svsk->sk_sk = inet;
|
||||
svsk->sk_ostate = inet->sk_state_change;
|
||||
svsk->sk_odata = inet->sk_data_ready;
|
||||
svsk->sk_owspace = inet->sk_write_space;
|
||||
/*
|
||||
* This barrier is necessary in order to prevent race condition
|
||||
* with svc_data_ready(), svc_listen_data_ready() and others
|
||||
* when calling callbacks above.
|
||||
*/
|
||||
wmb();
|
||||
inet->sk_user_data = svsk;
|
||||
|
||||
/* Initialize the socket */
|
||||
if (sock->type == SOCK_DGRAM)
|
||||
|
|
Loading…
Reference in a new issue