@@ -23,6 +23,7 @@
#include <linux/nfsd/debug.h>
#include <linux/nfsd/nfs4pnfsdlm.h>
+#include <linux/sunrpc/addr.h>
#define NFSDDBG_FACILITY NFSDDBG_FILELAYOUT
@@ -56,6 +57,25 @@ struct dlm_device_entry {
return NULL;
}
+bool nfsd4_validate_pnfs_dlm_device(char *ds_list, int *num_ds)
+{
+ char *start = ds_list;
+
+ *num_ds = 0;
+
+ while (*start) {
+ struct sockaddr_storage tempAddr;
+ int ipLen = strcspn(start, ",");
+
+ if (!rpc_pton(&init_net, start, ipLen,
+ (struct sockaddr *)&tempAddr, sizeof(tempAddr)))
+ return false;
+ (*num_ds)++;
+ start += ipLen + 1;
+ }
+ return true;
+}
+
/*
* pnfs_dlm_device string format:
* block-device-path:<ds1 ipv4 address>,<ds2 ipv4 address>
@@ -109,12 +129,10 @@ struct dlm_device_entry {
goto out_free;
memcpy(new->ds_list, bufp, len);
- /* count the number of comma-delimited DS IPs */
- new->num_ds = 1;
- while ((bufp = strchr(bufp, ',')) != NULL) {
- new->num_ds++;
- bufp++;
- }
+
+ /* validate the ips */
+ if (!nfsd4_validate_pnfs_dlm_device(new->ds_list, &(new->num_ds)))
+ goto out_free;
dprintk("%s disk_name %s num_ds %d ds_list %s\n", __func__,
new->disk_name, new->num_ds, new->ds_list);