15d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek/*
25d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * Copyright (C) 2012 Linux Test Project, Inc.
35d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek *
45d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * This program is free software; you can redistribute it and/or
55d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * modify it under the terms of version 2 of the GNU General Public
65d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * License as published by the Free Software Foundation.
75d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek *
85d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * This program is distributed in the hope that it would be useful,
95d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * but WITHOUT ANY WARRANTY; without even the implied warranty of
105d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
115d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek *
125d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * Further, this software is distributed without any warranty that it
135d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * is free of the rightful claim of any third person regarding
145d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * infringement or the like.  Any license provided herein, whether
155d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * implied or otherwise, applies only to this software file.  Patent
165d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * licenses, if any, provided herein do not apply to combinations of
175d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * this program with other software, or any other product whatsoever.
185d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek *
195d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * You should have received a copy of the GNU General Public License
205d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * along with this program; if not, write the Free Software
215d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
225d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * 02110-1301, USA.
235d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek */
245d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
255d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek/*
265d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek * errno tests shared by process_vm_readv, process_vm_writev tests.
275d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek */
285d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include <sys/types.h>
295d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include <sys/stat.h>
305d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include <sys/syscall.h>
315d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include <sys/uio.h>
325d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include <sys/wait.h>
335d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include <sys/mman.h>
345d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include <errno.h>
355d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include <signal.h>
365d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include <stdio.h>
375d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include <stdlib.h>
385d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include <string.h>
395d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include <unistd.h>
405d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include <limits.h>
415d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include <pwd.h>
425d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include "config.h"
435d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include "test.h"
445d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include "safe_macros.h"
455d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#include "process_vm.h"
465d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
475d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstruct process_vm_params {
485d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	int len;
495d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	char *ldummy;
505d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	char *rdummy;
515d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	pid_t pid;
525d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	struct iovec *lvec;
535d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	unsigned long liovcnt;
545d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	struct iovec *rvec;
555d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	unsigned long riovcnt;
565d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	unsigned long flags;
575d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek};
585d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
595d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic int rflag;
605d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic int wflag;
615d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
625d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic option_t options[] = {
635d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	{"r", &rflag, NULL},
645d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	{"w", &wflag, NULL},
655d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	{NULL, NULL, NULL}
665d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek};
675d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
685d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic char TCID_readv[] = "process_vm_readv";
695d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic char TCID_writev[] = "process_vm_writev";
705d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekchar *TCID = "cma01";
71354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaoint TST_TOTAL = 1;
72354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gaostatic void (*cma_test_params) (struct process_vm_params * params) = NULL;
735d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
745d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void setup(char *argv[]);
755d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void cleanup(void);
765d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void help(void);
775d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
785d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void cma_test_params_read(struct process_vm_params *params);
795d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void cma_test_params_write(struct process_vm_params *params);
805d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void cma_test_errnos(void);
815d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
825d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekint main(int argc, char *argv[])
835d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
845d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	int lc;
855d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
86d6d11d08678aac1ed2c370ea8e42e5f45aea07beCyril Hrubis	tst_parse_opts(argc, argv, options, &help);
875d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
885d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	setup(argv);
895d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	for (lc = 0; TEST_LOOPING(lc); lc++) {
90d59a659cd639ca2780b00049d102acd2a783d585Caspar Zhang		tst_count = 0;
915d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		cma_test_errnos();
925d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	}
935d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cleanup();
945d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	tst_exit();
955d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
965d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
975d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void setup(char *argv[])
985d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
99d1e794d62b1bf619df8390535e4c2a58899b1145Cyril Hrubis	tst_require_root();
1005d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
1015d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	if (rflag && wflag)
1025d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		tst_brkm(TBROK, NULL, "Parameters -r -w can not be used"
103354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			 " at the same time.");
1045d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	else if (rflag) {
1055d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		TCID = TCID_readv;
1065d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#if defined(__NR_process_vm_readv)
1075d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		cma_test_params = cma_test_params_read;
1085d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#else
1095d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		tst_brkm(TCONF, NULL, "process_vm_readv does not"
110354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			 " exist on your system.");
1115d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#endif
1125d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	} else if (wflag) {
1135d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		TCID = TCID_writev;
1145d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#if defined(__NR_process_vm_writev)
1155d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		cma_test_params = cma_test_params_write;
1165d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#else
1175d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		tst_brkm(TCONF, NULL, "process_vm_writev does not"
118354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			 " exist on your system.");
1195d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek#endif
1205d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	} else
1215d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		tst_brkm(TBROK, NULL, "Parameter missing, required -r or -w.");
1225d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	TEST_PAUSE;
1235d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
1245d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
1255d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void cleanup(void)
1265d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
1275d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
1285d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
1295d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void help(void)
1305d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
1315d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	printf("  -r      Use process_vm_readv\n");
1325d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	printf("  -w      Use process_vm_writev\n");
1335d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
1345d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
1355d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void cma_test_params_read(struct process_vm_params *params)
1365d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
1375d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	TEST(test_process_vm_readv(params->pid,
138354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				   params->lvec, params->liovcnt,
139354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				   params->rvec, params->riovcnt,
140354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				   params->flags));
1415d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
1425d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
1435d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void cma_test_params_write(struct process_vm_params *params)
1445d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
1455d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	TEST(test_process_vm_writev(params->pid,
146354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				    params->lvec, params->liovcnt,
147354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				    params->rvec, params->riovcnt,
148354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao				    params->flags));
1495d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
1505d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
1515d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic int cma_check_ret(long expected_ret, long act_ret)
1525d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
1535d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	if (expected_ret == act_ret) {
1545d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		tst_resm(TPASS, "expected ret success - "
155354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			 "returned value = %ld", act_ret);
1565d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	} else {
1575d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		tst_resm(TFAIL, "unexpected failure - "
158354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			 "returned value = %ld, expected: %ld",
159354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			 act_ret, expected_ret);
1605d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		return 1;
1615d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	}
1625d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	return 0;
1635d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
1645d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
1655d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic int cma_check_errno(long expected_errno)
1665d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
1675d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	if (TEST_ERRNO == expected_errno)
168354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		tst_resm(TPASS | TTERRNO, "expected failure");
1695d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	else if (TEST_ERRNO == 0) {
1705d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		tst_resm(TFAIL, "call succeeded unexpectedly");
1715d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		return 1;
1725d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	} else {
173354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		tst_resm(TFAIL | TTERRNO, "unexpected failure - "
174354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			 "expected = %ld : %s, actual",
175354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			 expected_errno, strerror(expected_errno));
1765d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		return 2;
1775d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	}
1785d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	return 0;
1795d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
1805d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
181c57fba5535abf457e33dd7a986b6c512d95cdef6Mike Frysingerstatic struct process_vm_params *cma_alloc_sane_params(void)
1825d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
1835d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	struct process_vm_params *sane_params;
1845d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	int len;
1855d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
1865d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	len = getpagesize();
1875d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params = SAFE_MALLOC(NULL, sizeof(struct process_vm_params));
1885d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params->len = len;
1895d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params->ldummy = SAFE_MALLOC(NULL, len);
1905d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params->rdummy = SAFE_MALLOC(NULL, len);
1915d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
1925d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params->lvec = SAFE_MALLOC(NULL, sizeof(struct iovec));
1935d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params->lvec->iov_base = sane_params->ldummy;
1945d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params->lvec->iov_len = len;
1955d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params->liovcnt = 1;
1965d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
1975d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params->rvec = SAFE_MALLOC(NULL, sizeof(struct iovec));
1985d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params->rvec->iov_base = sane_params->rdummy;
1995d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params->rvec->iov_len = len;
2005d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params->riovcnt = 1;
2015d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
2025d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params->flags = 0;
2035d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params->pid = getpid();
2045d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
2055d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	return sane_params;
2065d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
2075d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
2085d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void cma_free_params(struct process_vm_params *params)
2095d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
2105d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	if (params) {
2115d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		free(params->ldummy);
2125d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		free(params->rdummy);
2135d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		free(params->lvec);
2145d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		free(params->rvec);
2155d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		free(params);
2165d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	}
2175d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
2185d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
2195d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void cma_test_sane_params(void)
2205d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
2215d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	struct process_vm_params *sane_params;
2225d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
2235d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params = cma_alloc_sane_params();
2245d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	tst_resm(TINFO, "test_sane_params");
2255d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_params(sane_params);
2265d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_ret(sane_params->len, TEST_RETURN);
2275d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_free_params(sane_params);
2285d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
2295d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
2305d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void cma_test_flags(void)
2315d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
2325d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	struct process_vm_params *params;
2335d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	long flags[] = { -INT_MAX, -1, 1, INT_MAX, 0 };
234354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	int flags_size = sizeof(flags) / sizeof(flags[0]);
2355d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	int i;
2365d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
2375d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params = cma_alloc_sane_params();
2385d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	for (i = 0; i < flags_size; i++) {
2395d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		params->flags = flags[i];
2405d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		tst_resm(TINFO, "test_flags, flags=%ld", flags[i]);
2415d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		cma_test_params(params);
2425d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		/* atm. only flags == 0 is allowed, everything else
2435d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		 * should fail with EINVAL */
2445d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		if (flags[i] != 0) {
2455d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek			cma_check_ret(-1, TEST_RETURN);
2465d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek			cma_check_errno(EINVAL);
2475d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		} else {
2485d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek			cma_check_ret(params->len, TEST_RETURN);
2495d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek		}
2505d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	}
2515d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_free_params(params);
2525d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
2535d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
2545d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void cma_test_iov_len_overflow(void)
2555d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
2565d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	struct process_vm_params *params;
2575d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	ssize_t maxlen = -1;
2585d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params = cma_alloc_sane_params();
2595d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
2605d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params->lvec->iov_len = maxlen;
2615d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params->rvec->iov_len = maxlen;
2625d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	tst_resm(TINFO, "test_iov_len_overflow");
2635d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_params(params);
2645d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_ret(-1, TEST_RETURN);
2655d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_errno(EINVAL);
2665d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_free_params(params);
2675d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
2685d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
2695d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void cma_test_iov_invalid(void)
2705d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
2715d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	struct process_vm_params *sane_params;
2725d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	struct process_vm_params params_copy;
2735d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
2745d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params = cma_alloc_sane_params();
2755d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	/* make a shallow copy we can 'damage' */
2765d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
2775d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params_copy = *sane_params;
2785d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	tst_resm(TINFO, "test_iov_invalid - lvec->iov_base");
2795d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params_copy.lvec->iov_base = (void *)-1;
2805d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_params(&params_copy);
2815d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_ret(-1, TEST_RETURN);
2825d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_errno(EFAULT);
2835d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
2845d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params_copy = *sane_params;
2855d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	tst_resm(TINFO, "test_iov_invalid - rvec->iov_base");
2865d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params_copy.rvec->iov_base = (void *)-1;
2875d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_params(&params_copy);
2885d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_ret(-1, TEST_RETURN);
2895d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_errno(EFAULT);
2905d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
2915d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params_copy = *sane_params;
2925d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	tst_resm(TINFO, "test_iov_invalid - lvec");
2935d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params_copy.lvec = (void *)-1;
2945d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_params(&params_copy);
2955d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_ret(-1, TEST_RETURN);
2965d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_errno(EFAULT);
2975d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
2985d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params_copy = *sane_params;
2995d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	tst_resm(TINFO, "test_iov_invalid - rvec");
3005d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params_copy.rvec = (void *)-1;
3015d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_params(&params_copy);
3025d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_ret(-1, TEST_RETURN);
3035d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_errno(EFAULT);
3045d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
3055d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_free_params(sane_params);
3065d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
3075d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
3085d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void cma_test_invalid_pid(void)
3095d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
3105d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	pid_t invalid_pid = -1;
3115d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	struct process_vm_params *params;
3125d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
3135d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params = cma_alloc_sane_params();
3145d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	tst_resm(TINFO, "test_invalid_pid");
3155d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params->pid = invalid_pid;
3165d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_params(params);
3175d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_ret(-1, TEST_RETURN);
3185d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_errno(ESRCH);
3195d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_free_params(params);
3205d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
32123b37f3e039c03ffee10b66f0df637340903577eStanislav Kholmanskikh	invalid_pid = tst_get_unused_pid(cleanup);
3225d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
3235d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params = cma_alloc_sane_params();
3245d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params->pid = invalid_pid;
3255d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_params(params);
3265d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_ret(-1, TEST_RETURN);
3275d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_errno(ESRCH);
3285d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_free_params(params);
3295d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
3305d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
3315d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void cma_test_invalid_perm(void)
3325d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
3335d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	char nobody_uid[] = "nobody";
3345d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	struct passwd *ltpuser;
3355d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	int status;
3365d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	struct process_vm_params *params;
3375d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	pid_t child_pid;
3385d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	pid_t parent_pid;
3395d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	int ret = 0;
3405d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
3415d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	tst_resm(TINFO, "test_invalid_perm");
3425d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	parent_pid = getpid();
3435d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	child_pid = fork();
3445d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	switch (child_pid) {
345354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	case -1:
346354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		tst_brkm(TBROK | TERRNO, cleanup, "fork");
347354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		break;
348354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	case 0:
349354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		ltpuser = getpwnam(nobody_uid);
350354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (ltpuser == NULL)
351354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			tst_brkm(TBROK | TERRNO, NULL, "getpwnam failed");
3524484e1198cd0b44d95cc95296b529a0745e2f791Cyril Hrubis		SAFE_SETUID(NULL, ltpuser->pw_uid);
353354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao
354354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		params = cma_alloc_sane_params();
355354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		params->pid = parent_pid;
356354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		cma_test_params(params);
357354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		ret |= cma_check_ret(-1, TEST_RETURN);
358354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		ret |= cma_check_errno(EPERM);
359354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		cma_free_params(params);
360354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		exit(ret);
361354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao	default:
36266374d503fc48983b3d11369fe31f4aacfe9b57bCyril Hrubis		SAFE_WAITPID(cleanup, child_pid, &status, 0);
363354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
364354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao			tst_resm(TFAIL, "child returns %d", status);
3655d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	}
3665d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
3675d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
3685d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancekstatic void cma_test_invalid_protection(void)
3695d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
3705d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	struct process_vm_params *sane_params;
3715d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	struct process_vm_params params_copy;
3725d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	void *p;
3735d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
3745d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	sane_params = cma_alloc_sane_params();
3755d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	/* make a shallow copy we can 'damage' */
3765d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
3775d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	p = mmap(NULL, getpagesize(), PROT_NONE,
378354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		 MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
3795d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	if (p == MAP_FAILED)
380354ebb48db8e66a853a58379a4808d5dcd1ceac3Wanlong Gao		tst_brkm(TBROK | TERRNO, cleanup, "mmap");
3815d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
3825d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params_copy = *sane_params;
3835d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params_copy.lvec->iov_base = p;
3845d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	tst_resm(TINFO, "test_invalid_protection lvec");
3855d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_params(&params_copy);
3865d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_ret(-1, TEST_RETURN);
3875d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_errno(EFAULT);
3885d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
3895d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params_copy = *sane_params;
3905d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	params_copy.rvec->iov_base = p;
3915d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	tst_resm(TINFO, "test_invalid_protection rvec");
3925d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_params(&params_copy);
3935d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_ret(-1, TEST_RETURN);
3945d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_check_errno(EFAULT);
3955d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
3967bf0cbd87d8981d0a1d034ca4e6a24219e5a77c1Cyril Hrubis	SAFE_MUNMAP(cleanup, p, getpagesize());
3975d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
3985d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_free_params(sane_params);
3995d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
4005d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek
401c57fba5535abf457e33dd7a986b6c512d95cdef6Mike Frysingerstatic void cma_test_errnos(void)
4025d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek{
4035d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_sane_params();
4045d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_flags();
4055d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_iov_len_overflow();
4065d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_iov_invalid();
4075d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_invalid_pid();
4085d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_invalid_perm();
4095d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek	cma_test_invalid_protection();
4105d56dd563dfc88bcdf87406f4f52b1b6abcc96aeJan Stancek}
411