Skip to contentSkip to conversation

serial/sunsu: add missing of_node_put()

PATCH In review Yangtao Li 2 participants 2 messages Nov 21, 2018 – Dec 3, 2018

Subsystems (2)
lore
Share & tools
lore

Yangtao Li

author
#0 lore raw

PATCH 1/1 serial/sunsu: add missing of_node_put()

of_find_node_by_path() acquires a reference to the node returned by it and that reference needs to be dropped by its caller. This place is not doing this, so fix it.

---
 drivers/tty/serial/sunsu.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)
drivers/tty/serial/sunsu.c +15 -5
index 6cf3e9b0728f..4a27c0114d50 100644
@@ -1394,22 +1394,32 @@ static inline struct console *SUNSU_CONSOLE(void)
 static enum su_type su_get_type(struct device_node *dp)
 {
 	struct device_node *ap = of_find_node_by_path("/aliases");
+	enum su_type rc = SU_PORT_PORT;
 
 	if (ap) {
+		struct device_node *tmp;
 		const char *keyb = of_get_property(ap, "keyboard", NULL);
 		const char *ms = of_get_property(ap, "mouse", NULL);
 
 		if (keyb) {
-			if (dp == of_find_node_by_path(keyb))
-				return SU_PORT_KBD;
+			tmp = of_find_node_by_path(keyb);
+			if (tmp && dp == tmp){
+				rc = SU_PORT_KBD;
+				goto out;
+			}
 		}
 		if (ms) {
-			if (dp == of_find_node_by_path(ms))
-				return SU_PORT_MS;
+			tmp = of_find_node_by_path(ms);
+			if (tmp && dp == tmp){
+				rc = SU_PORT_MS;
+				goto out;
+			}
 		}
 	}
 
-	return SU_PORT_PORT;
+out:
+	of_node_put(ap);
+	return rc;
 }
 
 static int su_probe(struct platform_device *op)
Signature · 1 line
2.17.0
maintainer
#1 lore raw

From: Yangtao Li <[email protected]>
Date: Wed, 21 Nov 2018 11:06:15 -0500

Quoted 5 lines

of_find_node_by_path() acquires a reference to the node returned by it and that reference needs to be dropped by its caller. This place is not doing this, so fix it.

Several coding style problems and you are adding two new leaks.

drivers/tty/serial/sunsu.c static inline struct console *SUNSU_CONSOLE(void) · line 1402

Quoted 3 lines
drivers/tty/serial/sunsu.c +1 -0
+		struct device_node *tmp;
 		const char *keyb = of_get_property(ap, "keyboard", NULL);
 		const char *ms = of_get_property(ap, "mouse", NULL);

Always order local variable declarations from longest to shortest line.

drivers/tty/serial/sunsu.c static inline struct console *SUNSU_CONSOLE(void) · line 1406

Quoted 6 lines
drivers/tty/serial/sunsu.c +2 -2
 		if (keyb) {
-			if (dp == of_find_node_by_path(keyb))
-				return SU_PORT_KBD;
+			tmp = of_find_node_by_path(keyb);
+			if (tmp && dp == tmp){

Always put a space between ")" and the "{" openning a new basic block.

Quoted 9 lines
drivers/tty/serial/sunsu.c +5 -2
+				rc = SU_PORT_KBD;
+				goto out;
+			}
 		}
 		if (ms) {
-			if (dp == of_find_node_by_path(ms))
-				return SU_PORT_MS;
+			tmp = of_find_node_by_path(ms);
+			if (tmp && dp == tmp){

drivers/tty/serial/sunsu.c static inline struct console *SUNSU_CONSOLE(void) · line 1422

Quoted 10 lines
drivers/tty/serial/sunsu.c +6 -1
+				rc = SU_PORT_MS;
+				goto out;
+			}
 		}
 	}
 
-	return SU_PORT_PORT;
+out:
+	of_node_put(ap);
+	return rc;

Now you have two references, one held by 'ap' and one held by 'tmp'.

You are not releasing the one held by 'tmp', and you must release 'tmp' even if it equals 'dp'.

It's pretty obvious you have no way by which to test these changes and therefore are not doing so.