Serge/Rishi,
Can you let me know whether this is through in Mainline kernel? If yes,
then i can include the same in LTP. Also, please do provide me the test
run results for this feature on all architecture/kernel versions you
have run .

--Subrata--

On Wed, 2007-05-23 at 15:38 -0500, Serge E. Hallyn wrote:
> Hi,
> 
> the following patch adds some tests for file capabilities on linux.  The
> feature is only in -mm right now, so I don't know whether that means you
> don't yet want to include it.  It also requires -lcap.
> 
> thanks,
> -serge
> 
> diff -Nrup ltp-full-20070430/runltp ltp-full-20070430-filecaps/runltp
> --- ltp-full-20070430/runltp  2007-04-26 13:02:48.000000000 +0200
> +++ ltp-full-20070430-filecaps/runltp 2007-05-23 00:32:02.000000000 +0200
> @@ -284,7 +284,8 @@ main()
>                       ${LTPROOT}/runtest/mm ${LTPROOT}/runtest/ipc \
>                       ${LTPROOT}/runtest/sched ${LTPROOT}/runtest/math \
>                       ${LTPROOT}/runtest/nptl ${LTPROOT}/runtest/pty \
> -                     ${LTPROOT}/runtest/containers
> +                     ${LTPROOT}/runtest/containers \
> +                     ${LTPROOT}/runtest/filecaps
>          do
>              [ -a "$SCENFILES" ] || \
>              {
> diff -Nrup ltp-full-20070430/runtest/filecaps 
> ltp-full-20070430-filecaps/runtest/filecaps
> --- ltp-full-20070430/runtest/filecaps        1970-01-01 01:00:00.000000000 
> +0100
> +++ ltp-full-20070430-filecaps/runtest/filecaps       2007-05-23 
> 00:04:33.000000000 +0200
> @@ -0,0 +1,2 @@
> +#DESCRIPTION:file capabilities
> +Filecaps     filecapstest.sh
> diff -Nrup ltp-full-20070430/testcases/kernel/security/Makefile 
> ltp-full-20070430-filecaps/testcases/kernel/security/Makefile
> --- ltp-full-20070430/testcases/kernel/security/Makefile      2006-02-01 
> 23:37:54.000000000 +0100
> +++ ltp-full-20070430-filecaps/testcases/kernel/security/Makefile     
> 2007-05-22 21:48:07.000000000 +0200
> @@ -1,4 +1,4 @@
> -SUBDIRS = mmc_security
> +SUBDIRS = mmc_security filecaps
> 
>  all:
>       @set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i ; done
> diff -Nrup ltp-full-20070430/testcases/kernel/security/filecaps/Makefile 
> ltp-full-20070430-filecaps/testcases/kernel/security/filecaps/Makefile
> --- ltp-full-20070430/testcases/kernel/security/filecaps/Makefile     
> 1970-01-01 01:00:00.000000000 +0100
> +++ ltp-full-20070430-filecaps/testcases/kernel/security/filecaps/Makefile    
> 2007-05-23 00:03:26.000000000 +0200
> @@ -0,0 +1,24 @@
> +CC=gcc
> +
> +CFLAGS += -I../../../../include -Wall
> +LDLIBS += -L../../../../lib -lltp -lcap
> +
> +SRCS    = $(wildcard *.c)
> +TARGETS = $(patsubst %.c,%,$(SRCS))
> +NOLTP_TARGETS = $(patsubst %.c,%_noltp,$(SRCS))
> +
> +%_noltp : %.c
> +     $(CC) -g -DNO_LTP -o $@ $< -lcap
> +
> +all: $(TARGETS)
> +
> +noltp:  $(NOLTP_TARGETS)
> +
> +clean:
> +     rm -f $(TARGETS) *.o $(NOLTP_TARGETS) caps_fifo
> +
> +install:
> +     @set -e; for i in $(TARGETS) filecapstest.sh; do ln -f $$i 
> ../../../bin/$$i ; chmod +x ../../../bin/$$i; done
> +
> +noltp_check: noltp
> +     ./runtests_noltp.sh
> diff -Nrup 
> ltp-full-20070430/testcases/kernel/security/filecaps/filecapstest.sh 
> ltp-full-20070430-filecaps/testcases/kernel/security/filecaps/filecapstest.sh
> --- ltp-full-20070430/testcases/kernel/security/filecaps/filecapstest.sh      
> 1970-01-01 01:00:00.000000000 +0100
> +++ 
> ltp-full-20070430-filecaps/testcases/kernel/security/filecaps/filecapstest.sh 
>     2007-05-23 21:38:31.000000000 +0200
> @@ -0,0 +1,21 @@
> +#!/bin/sh
> +
> +echo "Running in:"
> +cp $LTPROOT/testcases/bin/print_caps .
> +mkfifo caps_fifo
> +chmod 777 caps_fifo
> +exit_code=0
> +echo "cap_sys_admin tests"
> +testfilecaps 0
> +tmp=$?
> +if [ $tmp -ne 0 ]; then
> +     exit_code=$tmp
> +fi
> +echo "testing for correct caps"
> +testfilecaps 1
> +tmp=$?
> +if [ $tmp -ne 0 ]; then
> +     exit_code=$tmp
> +fi
> +
> +exit $exit_code
> diff -Nrup ltp-full-20070430/testcases/kernel/security/filecaps/print_caps.c 
> ltp-full-20070430-filecaps/testcases/kernel/security/filecaps/print_caps.c
> --- ltp-full-20070430/testcases/kernel/security/filecaps/print_caps.c 
> 1970-01-01 01:00:00.000000000 +0100
> +++ 
> ltp-full-20070430-filecaps/testcases/kernel/security/filecaps/print_caps.c    
>     2007-05-23 22:14:33.000000000 +0200
> @@ -0,0 +1,46 @@
> +/*
> + * File: print_caps.c
> + * Author: Serge Hallyn
> + * Copyright 2007 IBM Corp
> + * Purpose: print out the POSIX capabilities with which it runs
> + */
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/capability.h>
> +#include <unistd.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
> +
> +#define FIFOFILE "caps_fifo"
> +//#define DEBUG 1
> +
> +int main(int argc, char *argv[])
> +{
> +     cap_t cap = cap_get_proc();
> +     int fd;
> +     char *txt;
> +
> +     if (!cap) {
> +             perror("print_caps - cap_get_proc");
> +             exit(1);
> +     }
> +
> +     fd = open(FIFOFILE, O_WRONLY);
> +     if (!fd) {
> +             perror("print_caps: open fifo");
> +             exit(2);
> +     }
> +
> +     txt = cap_to_text(cap, NULL);
> +     write(fd, txt, strlen(txt)+1);
> +     close(fd);
> +#ifdef DEBUG
> +     printf("%s: running with caps %s\n", argv[0], cap_to_text(cap, NULL));
> +#endif
> +
> +     cap_free(cap);
> +
> +     return 0;
> +}
> diff -Nrup 
> ltp-full-20070430/testcases/kernel/security/filecaps/runtests_noltp.sh 
> ltp-full-20070430-filecaps/testcases/kernel/security/filecaps/runtests_noltp.sh
> --- ltp-full-20070430/testcases/kernel/security/filecaps/runtests_noltp.sh    
> 1970-01-01 01:00:00.000000000 +0100
> +++ 
> ltp-full-20070430-filecaps/testcases/kernel/security/filecaps/runtests_noltp.sh
>    2007-05-23 21:28:27.000000000 +0200
> @@ -0,0 +1,20 @@
> +#!/bin/sh
> +
> +mkfifo caps_fifo
> +chmod 777 caps_fifo
> +exit_code=0
> +echo "cap_sys_admin tests"
> +./testfilecaps_noltp 0
> +tmp=$?
> +if [ $tmp -ne 0 ]; then
> +     exit_code=$tmp
> +fi
> +echo "testing for correct caps"
> +./testfilecaps_noltp 1
> +tmp=$?
> +if [ $tmp -ne 0 ]; then
> +     exit_code=$tmp
> +fi
> +
> +rm caps_fifo
> +exit $exit_code
> diff -Nrup 
> ltp-full-20070430/testcases/kernel/security/filecaps/testfilecaps.c 
> ltp-full-20070430-filecaps/testcases/kernel/security/filecaps/testfilecaps.c
> --- ltp-full-20070430/testcases/kernel/security/filecaps/testfilecaps.c       
> 1970-01-01 01:00:00.000000000 +0100
> +++ 
> ltp-full-20070430-filecaps/testcases/kernel/security/filecaps/testfilecaps.c  
>     2007-05-23 21:55:40.000000000 +0200
> @@ -0,0 +1,276 @@
> +/*
> + * File: testfscaps.c
> + * Author: Serge Hallyn
> + * Copyright 2007 IBM Corp
> + * Purpose: perform several tests of file capabilities:
> + *  1. try setting caps without CAP_SYS_ADMIN
> + *  2. try setting valid caps, drop rights, and run the executable,
> + *     make sure we get the rights
> + */
> +#define _GNU_SOURCE
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <endian.h>
> +#include <byteswap.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <sys/wait.h>
> +#include <attr/xattr.h>
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <sys/capability.h>
> +
> +#ifdef NO_LTP
> +#define TFAIL "FAILURE: "
> +#define TPASS "PASS: "
> +#define TINFO "INFO: "
> +#define tst_resm(x, format, arg...) printf("%s:" format, x, ## arg)
> +#define tst_exit(x) exit(x)
> +#define TSTPATH "./print_caps_noltp"
> +#else
> +#define TSTPATH "./print_caps"
> +#include <test.h>
> +char *TCID = "filecaps";
> +int TST_TOTAL=1;
> +#endif
> +
> +int errno;
> +
> +void usage(char *me)
> +{
> +     tst_resm(TFAIL, "Usage: %s <0|1|2> [arg]\n", me);
> +     tst_resm(TINFO, "  0: set file caps without CAP_SYS_ADMIN\n");
> +     tst_resm(TINFO, "  1: test that file caps are set correctly on exec\n");
> +     tst_exit(1);
> +}
> +
> +int drop_root()
> +{
> +     int ret;
> +     ret = setresuid(1000, 1000, 1000);
> +     if (ret) {
> +             perror("setresuid");
> +             tst_resm(TFAIL, "Error dropping root privs\n");
> +             tst_exit(4);
> +     }
> +     return 1;
> +}
> +
> +#if BYTE_ORDER == LITTLE_ENDIAN
> +#define cpu_to_le32(x)  x
> +#else
> +#define cpu_to_le32(x)  bswap_32(x)
> +#endif
> +
> +#define CAPNAME "security.capability"
> +#ifndef __CAP_BITS
> +#define __CAP_BITS 31
> +#endif
> +
> +int perms_test(void)
> +{
> +     int ret;
> +     unsigned int value[4];
> +
> +     drop_root();
> +     value[0] = cpu_to_le32(_LINUX_CAPABILITY_VERSION);
> +     value[1] = 1;
> +     value[2] = 1;
> +     value[3] = 1;
> +     ret = setxattr(TSTPATH, CAPNAME, value, 4*sizeof(unsigned int), 0);
> +     if (ret) {
> +             perror("setxattr");
> +             tst_resm(TPASS, "could not set capabilities as non-root\n");
> +             ret = 0;
> +     } else {
> +             tst_resm(TFAIL, "could set capabilities as non-root\n");
> +             ret = 1;
> +     }
> +
> +     tst_exit(ret);
> +}
> +
> +#define FIFOFILE "caps_fifo"
> +void create_fifo(void)
> +{
> +     int ret;
> +
> +     ret = mkfifo(FIFOFILE, S_IRWXU | S_IRWXG | S_IRWXO);
> +     if (ret == -1 && errno != EEXIST) {
> +             perror("mkfifo");
> +             tst_resm(TFAIL, "failed creating %s\n", FIFOFILE);
> +             tst_exit(1);
> +     }
> +}
> +
> +static inline int getcapflag(int w)
> +{
> +     switch (w) {
> +             case 0: return CAP_EFFECTIVE;
> +             case 1: return CAP_PERMITTED;
> +             case 2: return CAP_INHERITABLE;
> +             default:
> +                     tst_resm(TFAIL, "%s: bad value %d (not 0-2)\n",
> +                             __FUNCTION__, w);
> +                     tst_exit(10);
> +     }
> +}
> +
> +void write_to_fifo(char *buf)
> +{
> +     int fd;
> +
> +     fd = open(FIFOFILE, O_WRONLY);
> +     write(fd, buf, strlen(buf));
> +     close(fd);
> +}
> +
> +void read_from_fifo(char *buf)
> +{
> +     int fd;
> +
> +     memset(buf, 0, 200);
> +     fd = open(FIFOFILE, O_RDONLY);
> +     if (fd < 0) {
> +             perror("open");
> +             tst_resm(TFAIL, "Failed opening fifo\n");
> +             tst_exit(1);
> +     }
> +     read(fd, buf, 199);
> +     close(fd);
> +}
> +
> +int compare_caps(int expect_success, char *buf1, char *buf2)
> +{
> +     int res;
> +
> +     res = strcmp(buf1, buf2) == 0;
> +     if (expect_success)
> +             return res;
> +     return !res;
> +}
> +
> +int fork_drop_and_exec(int expect_success, char *capstxt)
> +{
> +     int pid;
> +     int ret;
> +     char buf[200];
> +
> +     if (ret == -1) {
> +             perror("pipe");
> +             tst_resm(TFAIL, "%s: could not create pipe\n", __FUNCTION__);
> +             tst_exit(1);
> +     }
> +
> +     //printf("execing with %s\n", capstxt);
> +     pid = fork();
> +     if (pid < 0) {
> +             perror("fork");
> +             tst_resm(TFAIL, "%s: failed fork\n", __FUNCTION__);
> +             tst_exit(1);
> +     }
> +     if (pid == 0) {
> +             drop_root();
> +             ret = execlp(TSTPATH, TSTPATH);
> +             perror("execl");
> +             tst_resm(TFAIL, "%s: exec failed\n", __FUNCTION__);
> +             snprintf(buf, 200, "failed to run as %s\n", capstxt);
> +             write_to_fifo(buf);
> +             tst_exit(1);
> +     } else {
> +             ret = 0;
> +             read_from_fifo(buf);
> +             if (!compare_caps(expect_success, buf, capstxt)) {
> +                     tst_resm(TINFO, "Set caps to %s, ran as %s.\n",
> +                             capstxt, buf);
> +                     ret = -1;
> +             }
> +     }
> +     return ret;
> +}
> +
> +int caps_actually_set_test(void)
> +{
> +     int whichset, whichcap, finalret = 0, ret;
> +     cap_t cap;
> +     char *capstxt;
> +     unsigned int value[4];
> +     cap_flag_t capflag;
> +     cap_value_t capvalue[1];
> +     int expect_success;
> +
> +     value[0] = cpu_to_le32(_LINUX_CAPABILITY_VERSION);
> +
> +     cap = cap_init();
> +     if (!cap) {
> +             perror("cap_init");
> +             exit(2);
> +     }
> +
> +     create_fifo();
> +
> +     for (whichset=0; whichset<3; whichset++) {
> +             capflag = getcapflag(whichset);
> +             value[1] = value[2] = value[3] = cpu_to_le32(0);
> +             for (whichcap=0; whichcap < __CAP_BITS; whichcap++) {
> +                     if (whichset == 1 && whichcap != 8)
> +                             expect_success = 1;
> +                     else
> +                             expect_success = 0;
> +                     cap_clear(cap);
> +                     capvalue[0] = whichcap;
> +                     cap_set_flag(cap, capflag, 1, capvalue, CAP_SET);
> +                     value[whichset+1] = cpu_to_le32(1 << whichcap);
> +                     ret = setxattr(TSTPATH, CAPNAME, value, 
> 4*sizeof(unsigned int), 0);
> +                     if (ret) {
> +                             tst_resm(TINFO, "%d %d\n", whichset, whichcap);
> +                             perror("setxattr");
> +                             continue;
> +                     }
> +                     /* do a sanity check */
> +                     capstxt = cap_to_text(cap, NULL);
> +                     if (strcmp(capstxt, "=")==0) {
> +                             tst_resm(TINFO, "%s: libcap doesn't know about 
> cap %d, not running\n",
> +                                     __FUNCTION__, whichcap);
> +                             ret = 0;
> +                     } else
> +                             ret = fork_drop_and_exec(expect_success, 
> capstxt);
> +                     if (ret) {
> +                             tst_resm(TINFO, "Error execing at %d %d\n",
> +                                     whichset, whichcap);
> +                             if (!finalret)
> +                                     finalret = ret;
> +                     } else {
> +                             tst_resm(TINFO, "Success at %d %d\n",
> +                                     whichset, whichcap);
> +                     }
> +             }
> +     }
> +
> +     cap_free(cap);
> +     return finalret;
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +     int ret = 0;
> +
> +     if (argc < 2)
> +             usage(argv[0]);
> +
> +     switch(atoi(argv[1])) {
> +             case 0:
> +                     ret = perms_test();
> +                     break;
> +             case 1:
> +                     ret = caps_actually_set_test();
> +                     if (ret)
> +                             tst_resm(TFAIL, "Some tests failed\n");
> +                     else
> +                             tst_resm(TPASS, "All tests passed\n");
> +                     break;
> +             default: usage(argv[0]);
> +     }
> +
> +     tst_exit(ret);
> +}
> diff -Nrup ltp-full-20070430/testscripts/test_filecaps.sh 
> ltp-full-20070430-filecaps/testscripts/test_filecaps.sh
> --- ltp-full-20070430/testscripts/test_filecaps.sh    1970-01-01 
> 01:00:00.000000000 +0100
> +++ ltp-full-20070430-filecaps/testscripts/test_filecaps.sh   2007-05-23 
> 00:00:10.000000000 +0200
> @@ -0,0 +1,47 @@
> +#!/bin/bash
> +#
> +# Copyright 2007 IBM
> +#
> +# This program is free software; you can redistribute it and/or modify it
> +# under the terms of the GNU General Public License as published by the Free
> +# Software Foundation; either version 2 of the License, or (at your option)
> +# any later version.
> +#
> +# test_filecaps.sh - Run the file capabilities test suite.
> +
> +# Must be root to run the containers testsuite
> +if [ $UID != 0 ]
> +then
> +        echo "FAILED: Must be root to execute this script"
> +        exit 1
> +fi
> +
> +# set the LTPROOT directory
> +cd `dirname $0`
> +LTPROOT=${PWD}
> +echo $LTPROOT | grep testscripts > /dev/null 2>&1
> +if [ $? -eq 0 ]
> +then
> +     cd ..
> +     LTPROOT=${PWD}
> +fi
> +
> +# set the PATH to include testcase/bin
> +
> +export PATH=$PATH:/usr/sbin:$LTPROOT/testcases/bin
> +export LTPBIN=$LTPROOT/testcases/bin
> +
> +# We will store the logfiles in $LTPROOT/results, so make sure
> +# it exists.
> +if [ ! -d $LTPROOT/results ]
> +then
> +     mkdir $LTPROOT/results
> +fi
> +
> +# Check the role and mode testsuite is being executed under.
> +echo "Running the file capabilities testsuite..."
> +
> +$LTPROOT/pan/pan -S -a $LTPROOT/results/filecaps -n ltp-filecaps -l 
> $LTPROOT/results/filecaps.logfile -o $LTPROOT/results/filecaps.outfile -p -f 
> $LTPROOT/runtest/filecaps
> +
> +echo "Done."
> +exit 0
> 
> -------------------------------------------------------------------------
> This SF.net email is sponsored by DB2 Express
> Download DB2 Express C - the FREE version of DB2 express and take
> control of your XML. No limits. Just data. Click to get it now.
> http://sourceforge.net/powerbar/db2/
> _______________________________________________
> Ltp-list mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/ltp-list


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to