hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/net/llc/af_llc.c
....@@ -47,7 +47,7 @@
4747 #if 0
4848 #define dprintk(args...) printk(KERN_DEBUG args)
4949 #else
50
-#define dprintk(args...)
50
+#define dprintk(args...) do {} while (0)
5151 #endif
5252
5353 /* Maybe we'll add some more in the future. */
....@@ -276,6 +276,7 @@
276276 {
277277 struct sock *sk = sock->sk;
278278 struct llc_sock *llc = llc_sk(sk);
279
+ struct net_device *dev = NULL;
279280 struct llc_sap *sap;
280281 int rc = -EINVAL;
281282
....@@ -287,14 +288,14 @@
287288 goto out;
288289 rc = -ENODEV;
289290 if (sk->sk_bound_dev_if) {
290
- llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
291
- if (llc->dev && addr->sllc_arphrd != llc->dev->type) {
292
- dev_put(llc->dev);
293
- llc->dev = NULL;
291
+ dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if);
292
+ if (dev && addr->sllc_arphrd != dev->type) {
293
+ dev_put(dev);
294
+ dev = NULL;
294295 }
295296 } else
296
- llc->dev = dev_getfirstbyhwtype(&init_net, addr->sllc_arphrd);
297
- if (!llc->dev)
297
+ dev = dev_getfirstbyhwtype(&init_net, addr->sllc_arphrd);
298
+ if (!dev)
298299 goto out;
299300 rc = -EUSERS;
300301 llc->laddr.lsap = llc_ui_autoport();
....@@ -304,6 +305,11 @@
304305 sap = llc_sap_open(llc->laddr.lsap, NULL);
305306 if (!sap)
306307 goto out;
308
+
309
+ /* Note: We do not expect errors from this point. */
310
+ llc->dev = dev;
311
+ dev = NULL;
312
+
307313 memcpy(llc->laddr.mac, llc->dev->dev_addr, IFHWADDRLEN);
308314 memcpy(&llc->addr, addr, sizeof(llc->addr));
309315 /* assign new connection to its SAP */
....@@ -311,6 +317,7 @@
311317 sock_reset_flag(sk, SOCK_ZAPPED);
312318 rc = 0;
313319 out:
320
+ dev_put(dev);
314321 return rc;
315322 }
316323
....@@ -333,10 +340,9 @@
333340 struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr;
334341 struct sock *sk = sock->sk;
335342 struct llc_sock *llc = llc_sk(sk);
343
+ struct net_device *dev = NULL;
336344 struct llc_sap *sap;
337345 int rc = -EINVAL;
338
-
339
- dprintk("%s: binding %02X\n", __func__, addr->sllc_sap);
340346
341347 lock_sock(sk);
342348 if (unlikely(!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr)))
....@@ -346,28 +352,30 @@
346352 addr->sllc_arphrd = ARPHRD_ETHER;
347353 if (unlikely(addr->sllc_family != AF_LLC || addr->sllc_arphrd != ARPHRD_ETHER))
348354 goto out;
355
+ dprintk("%s: binding %02X\n", __func__, addr->sllc_sap);
349356 rc = -ENODEV;
350357 rcu_read_lock();
351358 if (sk->sk_bound_dev_if) {
352
- llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if);
353
- if (llc->dev) {
359
+ dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if);
360
+ if (dev) {
354361 if (is_zero_ether_addr(addr->sllc_mac))
355
- memcpy(addr->sllc_mac, llc->dev->dev_addr,
362
+ memcpy(addr->sllc_mac, dev->dev_addr,
356363 IFHWADDRLEN);
357
- if (addr->sllc_arphrd != llc->dev->type ||
364
+ if (addr->sllc_arphrd != dev->type ||
358365 !ether_addr_equal(addr->sllc_mac,
359
- llc->dev->dev_addr)) {
366
+ dev->dev_addr)) {
360367 rc = -EINVAL;
361
- llc->dev = NULL;
368
+ dev = NULL;
362369 }
363370 }
364
- } else
365
- llc->dev = dev_getbyhwaddr_rcu(&init_net, addr->sllc_arphrd,
371
+ } else {
372
+ dev = dev_getbyhwaddr_rcu(&init_net, addr->sllc_arphrd,
366373 addr->sllc_mac);
367
- if (llc->dev)
368
- dev_hold(llc->dev);
374
+ }
375
+ if (dev)
376
+ dev_hold(dev);
369377 rcu_read_unlock();
370
- if (!llc->dev)
378
+ if (!dev)
371379 goto out;
372380 if (!addr->sllc_sap) {
373381 rc = -EUSERS;
....@@ -400,6 +408,11 @@
400408 goto out_put;
401409 }
402410 }
411
+
412
+ /* Note: We do not expect errors from this point. */
413
+ llc->dev = dev;
414
+ dev = NULL;
415
+
403416 llc->laddr.lsap = addr->sllc_sap;
404417 memcpy(llc->laddr.mac, addr->sllc_mac, IFHWADDRLEN);
405418 memcpy(&llc->addr, addr, sizeof(llc->addr));
....@@ -410,6 +423,7 @@
410423 out_put:
411424 llc_sap_put(sap);
412425 out:
426
+ dev_put(dev);
413427 release_sock(sk);
414428 return rc;
415429 }
....@@ -568,7 +582,8 @@
568582
569583 add_wait_queue(sk_sleep(sk), &wait);
570584 while (1) {
571
- if (sk_wait_event(sk, &timeout, sk->sk_state == TCP_CLOSE, &wait))
585
+ if (sk_wait_event(sk, &timeout,
586
+ READ_ONCE(sk->sk_state) == TCP_CLOSE, &wait))
572587 break;
573588 rc = -ERESTARTSYS;
574589 if (signal_pending(current))
....@@ -588,7 +603,8 @@
588603
589604 add_wait_queue(sk_sleep(sk), &wait);
590605 while (1) {
591
- if (sk_wait_event(sk, &timeout, sk->sk_state != TCP_SYN_SENT, &wait))
606
+ if (sk_wait_event(sk, &timeout,
607
+ READ_ONCE(sk->sk_state) != TCP_SYN_SENT, &wait))
592608 break;
593609 if (signal_pending(current) || !timeout)
594610 break;
....@@ -607,7 +623,7 @@
607623 while (1) {
608624 rc = 0;
609625 if (sk_wait_event(sk, &timeout,
610
- (sk->sk_shutdown & RCV_SHUTDOWN) ||
626
+ (READ_ONCE(sk->sk_shutdown) & RCV_SHUTDOWN) ||
611627 (!llc_data_accept_state(llc->state) &&
612628 !llc->remote_busy_flag &&
613629 !llc->p_flag), &wait))
....@@ -718,7 +734,7 @@
718734
719735 /* put original socket back into a clean listen state. */
720736 sk->sk_state = TCP_LISTEN;
721
- sk->sk_ack_backlog--;
737
+ sk_acceptq_removed(sk);
722738 dprintk("%s: ok success on %02X, client on %02X\n", __func__,
723739 llc_sk(sk)->addr.sllc_sap, newllc->daddr.lsap);
724740 frees:
....@@ -993,7 +1009,6 @@
9931009 * llc_ui_getname - return the address info of a socket
9941010 * @sock: Socket to get address of.
9951011 * @uaddr: Address structure to return information.
996
- * @uaddrlen: Length of address structure.
9971012 * @peer: Does user want local or remote address information.
9981013 *
9991014 * Return the address information of a socket.
....@@ -1063,7 +1078,7 @@
10631078 * Set various connection specific parameters.
10641079 */
10651080 static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
1066
- char __user *optval, unsigned int optlen)
1081
+ sockptr_t optval, unsigned int optlen)
10671082 {
10681083 struct sock *sk = sock->sk;
10691084 struct llc_sock *llc = llc_sk(sk);
....@@ -1073,7 +1088,7 @@
10731088 lock_sock(sk);
10741089 if (unlikely(level != SOL_LLC || optlen != sizeof(int)))
10751090 goto out;
1076
- rc = get_user(opt, (int __user *)optval);
1091
+ rc = copy_from_sockptr(&opt, optval, sizeof(opt));
10771092 if (rc)
10781093 goto out;
10791094 rc = -EINVAL;