git: fd3226dc5769 - stable/13 - loader: net_open() should not replace f->f_devdata

From: Warner Losh <imp_at_FreeBSD.org>
Date: Tue, 24 Jan 2023 22:09:57 UTC
The branch stable/13 has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=fd3226dc576965aeb76d22e77595f339ecca833d

commit fd3226dc576965aeb76d22e77595f339ecca833d
Author:     Toomas Soome <tsoome@FreeBSD.org>
AuthorDate: 2021-09-24 15:04:31 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2023-01-24 21:49:17 +0000

    loader: net_open() should not replace f->f_devdata
    
    net_open() does replace f_devdata with pointer to netdev_sock,
    this will cause memory leak when device is closed, but also does
    alter the devopen() logic.
    
    We should store &netdev_sock to dev->d_opendata instead, this
    would preserve and follow the devopen() logic.
    
    Fixes network boot on aarch64 (tested by bz).
    
    Reviewed-by:    imp
    MFC After:      2 weeks
    Differential Revision: https://reviews.freebsd.org/D32227
    
    (cherry picked from commit 98e805b4a18d6ef4d3c9924166e1217e0430290d)
---
 stand/common/dev_net.c | 8 +++++---
 stand/libsa/nfs.c      | 4 +++-
 stand/libsa/tftp.c     | 7 +++++--
 3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/stand/common/dev_net.c b/stand/common/dev_net.c
index db13e618e822..70b571047d56 100644
--- a/stand/common/dev_net.c
+++ b/stand/common/dev_net.c
@@ -114,7 +114,7 @@ net_init(void)
 
 /*
  * Called by devopen after it sets f->f_dev to our devsw entry.
- * This opens the low-level device and sets f->f_devdata.
+ * This opens the low-level device and sets dev->d_opendata.
  * This is declared with variable arguments...
  */
 static int
@@ -193,20 +193,22 @@ net_open(struct open_file *f, ...)
 
 	}
 	netdev_opens++;
-	f->f_devdata = &netdev_sock;
+	dev->d_opendata = &netdev_sock;
 	return (error);
 }
 
 static int
 net_close(struct open_file *f)
 {
+	struct devdesc *dev;
 
 #ifdef	NETIF_DEBUG
 	if (debug)
 		printf("%s: opens=%d\n", __func__, netdev_opens);
 #endif
 
-	f->f_devdata = NULL;
+	dev = f->f_devdata;
+	dev->d_opendata = NULL;
 
 	return (0);
 }
diff --git a/stand/libsa/nfs.c b/stand/libsa/nfs.c
index 084c7261f054..5757395caba2 100644
--- a/stand/libsa/nfs.c
+++ b/stand/libsa/nfs.c
@@ -464,6 +464,7 @@ nfs_readdata(struct nfs_iodesc *d, off_t off, void *addr, size_t len)
 int
 nfs_open(const char *upath, struct open_file *f)
 {
+	struct devdesc *dev;
 	struct iodesc *desc;
 	struct nfs_iodesc *currfd = NULL;
 	char buf[2 * NFS_V3MAXFHSIZE + 3];
@@ -484,6 +485,7 @@ nfs_open(const char *upath, struct open_file *f)
 	if (netproto != NET_NFS)
 		return (EINVAL);
 
+	dev = f->f_devdata;
 #ifdef NFS_DEBUG
  	if (debug)
 		printf("nfs_open: %s (rootip=%s rootpath=%s)\n", upath,
@@ -497,7 +499,7 @@ nfs_open(const char *upath, struct open_file *f)
 	if (f->f_dev->dv_type != DEVT_NET)
 		return (EINVAL);
 
-	if (!(desc = socktodesc(*(int *)(f->f_devdata))))
+	if (!(desc = socktodesc(*(int *)(dev->d_opendata))))
 		return (EINVAL);
 
 	/* Bind to a reserved port. */
diff --git a/stand/libsa/tftp.c b/stand/libsa/tftp.c
index d3f3048e0257..c520a9e3b3b1 100644
--- a/stand/libsa/tftp.c
+++ b/stand/libsa/tftp.c
@@ -37,7 +37,8 @@ __FBSDID("$FreeBSD$");
 /*
  * Simple TFTP implementation for libsa.
  * Assumes:
- *  - socket descriptor (int) at open_file->f_devdata
+ *  - socket descriptor (int) at dev->d_opendata, dev stored at
+ *	open_file->f_devdata
  *  - server host IP in global rootip
  * Restrictions:
  *  - read only
@@ -443,6 +444,7 @@ tftp_getnextblock(struct tftp_handle *h)
 static int
 tftp_open(const char *path, struct open_file *f)
 {
+	struct devdesc *dev;
 	struct tftp_handle *tftpfile;
 	struct iodesc	*io;
 	int		res;
@@ -463,7 +465,8 @@ tftp_open(const char *path, struct open_file *f)
 		return (ENOMEM);
 
 	tftpfile->tftp_blksize = TFTP_REQUESTED_BLKSIZE;
-	tftpfile->iodesc = io = socktodesc(*(int *)(f->f_devdata));
+	dev = f->f_devdata;
+	tftpfile->iodesc = io = socktodesc(*(int *)(dev->d_opendata));
 	if (io == NULL) {
 		free(tftpfile);
 		return (EINVAL);