From 81d4f7a253193ebfe559f675d3c0975c0899d592 Mon Sep 17 00:00:00 2001 From: Amir Shehata Date: Thu, 24 Aug 2017 18:06:57 -0700 Subject: [PATCH] LU-9909 lnet: fix memory leak and lnet_interfaces_max Free buffer allocated for discover command. Set lnet_interfaces_max to LNET_INTERFACES_MAX_DEFAULT if it's not defined or if it's being set to something below LNET_INTERFACES_MIN. For lnet_ping() and lnet_discover() if the provided space can fit more NIDs than lnet_interfaces_max then ensure only lnet_interfaces_max is copied into the buffer. Test-Parameters: trivial Signed-off-by: Amir Shehata Change-Id: I19aed712f40a8bf44d2fb112588e9ae07257469f Reviewed-on: https://review.whamcloud.com/28702 Tested-by: Jenkins Reviewed-by: Sonia Sharma Tested-by: Maloo Reviewed-by: Olaf Weber Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin --- lnet/lnet/api-ni.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/lnet/lnet/api-ni.c b/lnet/lnet/api-ni.c index a9b1839..db67866 100644 --- a/lnet/lnet/api-ni.c +++ b/lnet/lnet/api-ni.c @@ -167,8 +167,8 @@ intf_max_set(const char *val, struct kernel_param *kp) if (value < LNET_INTERFACES_MIN) { CWARN("max interfaces provided are too small, setting to %d\n", - LNET_INTERFACES_MIN); - value = LNET_INTERFACES_MIN; + LNET_INTERFACES_MAX_DEFAULT); + value = LNET_INTERFACES_MAX_DEFAULT; } *(int *)kp->arg = value; @@ -3465,9 +3465,16 @@ static int lnet_ping(struct lnet_process_id id, signed long timeout, sigset_t blocked; /* n_ids limit is arbitrary */ - if (n_ids <= 0 || n_ids > lnet_interfaces_max || id.nid == LNET_NID_ANY) + if (n_ids <= 0 || id.nid == LNET_NID_ANY) return -EINVAL; + /* + * if the user buffer has more space than the lnet_interfaces_max + * then only fill it up to lnet_interfaces_max + */ + if (n_ids > lnet_interfaces_max) + n_ids = lnet_interfaces_max; + if (id.pid == LNET_PID_ANY) id.pid = LNET_PID_LUSTRE; @@ -3636,16 +3643,25 @@ lnet_discover(lnet_process_id_t id, __u32 force, lnet_process_id_t __user *ids, int i; int rc; int max_intf = lnet_interfaces_max; + size_t buf_size; if (n_ids <= 0 || - id.nid == LNET_NID_ANY || - n_ids > max_intf) + id.nid == LNET_NID_ANY) return -EINVAL; if (id.pid == LNET_PID_ANY) id.pid = LNET_PID_LUSTRE; - LIBCFS_ALLOC(buf, n_ids * sizeof(*buf)); + /* + * if the user buffer has more space than the max_intf + * then only fill it up to max_intf + */ + if (n_ids > max_intf) + n_ids = max_intf; + + buf_size = n_ids * sizeof(*buf); + + LIBCFS_ALLOC(buf, buf_size); if (!buf) return -ENOMEM; @@ -3698,5 +3714,7 @@ out_decref: out: lnet_net_unlock(cpt); + LIBCFS_FREE(buf, buf_size); + return rc; } -- 1.8.3.1