Last active
August 29, 2015 14:06
-
-
Save hxy9243/6c030cc3ec2b6cd7b8d6 to your computer and use it in GitHub Desktop.
capability wrapper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
a.out | |
out | |
*.txt | |
\#*# | |
~ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* descript: | |
* This is is a capability library wrapper for linux, | |
* see more details, please refer to libcap and | |
* <sys/capability.h> for more details. | |
* | |
* dependency: libcap | |
* link flag: -lcap | |
* | |
* author: Hu Xiaoyu | |
* created: Sep. 20 2014 | |
*/ | |
#include "priv.h" | |
/* | |
* Raise the capability in the current list | |
* for the current thread. | |
* param: const int count - total number of capabilities for operation; | |
* const cap_value_t cap - capability values defined in | |
* <linux/capability.h> | |
* | |
* return: 0 on success | |
* -1 on any error | |
*/ | |
int priv_raise (const int count, ...) { | |
int i; | |
cap_t cap; | |
cap_value_t cap_v; | |
cap_value_t *cap_v_list; | |
va_list arglist; | |
// alloca mem for cap_v_list, return error if count is oversized | |
if (count > CAP_LAST_CAP){ | |
return -1; | |
} | |
cap_v_list = (cap_value_t *)alloca (sizeof (cap_value_t) * count); | |
// get the capability of the current process | |
if ( (cap = cap_get_proc ()) == NULL ){ | |
return -1; | |
} | |
// set cap_v_list to effective flag of capability variable | |
va_start (arglist, count); | |
for (i = 0; i < count; i ++){ | |
cap_v = va_arg (arglist, int); | |
cap_v_list[i] = cap_v; | |
} | |
va_end (arglist); | |
// set the flag of cap to value in cap_v_list | |
if ( cap_set_flag (cap, | |
CAP_EFFECTIVE, | |
count, | |
cap_v_list, | |
CAP_SET) != 0){ | |
cap_free (cap); | |
return -1; | |
} | |
// set the capability to current proc | |
if ( cap_set_proc (cap) < 0){ | |
cap_free (cap); | |
return -1; | |
} | |
cap_free (cap); | |
return 0; | |
} | |
/* | |
* Raise the capability in the current list | |
* for the current thread. | |
* param: const int count - total number of capabilities for operation; | |
* const cap_value_t cap - capability values defined in | |
* <linux/capability.h> | |
* | |
* return: 0 on success | |
* -1 on any error | |
*/ | |
int priv_lower (const int count, ...) { | |
int i; | |
cap_t cap; | |
cap_value_t cap_v; | |
cap_value_t *cap_v_list; | |
va_list arglist; | |
// alloca mem for cap_v_list, return error if count is oversized | |
if (count > CAP_LAST_CAP){ | |
return -1; | |
} | |
cap_v_list = (cap_value_t *)alloca (sizeof (cap_value_t) * count); | |
// get the capability of the current process | |
if ( (cap = cap_get_proc ()) == NULL ){ | |
return -1; | |
} | |
// set cap_v_list to effective flag of capability variable | |
va_start (arglist, count); | |
for (i = 0; i < count; i ++){ | |
cap_v = va_arg (arglist, int); | |
cap_v_list[i] = cap_v; | |
} | |
va_end (arglist); | |
// set the flag of cap to value in cap_v_list | |
if ( cap_set_flag (cap, | |
CAP_EFFECTIVE, | |
count, | |
cap_v_list, | |
CAP_CLEAR) != 0){ | |
cap_free (cap); | |
return -1; | |
} | |
// set the capability to current proc | |
if ( cap_set_proc (cap) < 0){ | |
cap_free (cap); | |
return -1; | |
} | |
cap_free (cap); | |
return 0; | |
} | |
/* | |
* Drop the capability in the current list | |
* for the current thread. | |
* param: const int count - total number of capabilities for operation; | |
* const cap_value_t cap - capability values defined in | |
* <linux/capability.h> | |
* | |
* return: 0 on success | |
* -1 on any error | |
*/ | |
int priv_drop (const int count, ...) { | |
int i; | |
cap_t cap; | |
cap_value_t cap_v; | |
cap_value_t *cap_v_list; | |
va_list arglist; | |
// alloca mem for cap_v_list, return error if count is oversized | |
if (count > CAP_LAST_CAP){ | |
return -1; | |
} | |
cap_v_list = (cap_value_t *)alloca (sizeof (cap_value_t) * count); | |
// get the capability of the current process | |
if ( (cap = cap_get_proc ()) == NULL ){ | |
return -1; | |
} | |
// set cap_v_list to effective flag of capability variable | |
va_start (arglist, count); | |
for (i = 0; i < count; i ++){ | |
cap_v = va_arg (arglist, int); | |
cap_v_list[i] = cap_v; | |
} | |
va_end (arglist); | |
// set the flag of cap to value in cap_v_list | |
if ( cap_set_flag (cap, | |
CAP_EFFECTIVE, | |
count, | |
cap_v_list, | |
CAP_CLEAR) != 0){ | |
cap_free (cap); | |
return -1; | |
} | |
if ( cap_set_flag (cap, | |
CAP_PERMITTED, | |
count, | |
cap_v_list, | |
CAP_CLEAR) != 0){ | |
cap_free (cap); | |
return -1; | |
} | |
// set the capability to current proc | |
if ( cap_set_proc (cap) < 0){ | |
cap_free (cap); | |
return -1; | |
} | |
cap_free (cap); | |
return 0; | |
} | |
/* | |
* Drop all the capabilities in the current list | |
* for the current thread. | |
* return: 0 on success | |
* -1 on any error | |
*/ | |
int priv_lowerall () { | |
int i; | |
cap_t cap; | |
cap_value_t cap_v; | |
cap_value_t *cap_v_list; | |
va_list arglist; | |
// get the capability of the current process | |
if ( (cap = cap_get_proc ()) == NULL ){ | |
return -1; | |
} | |
cap_v_list = (cap_value_t *)alloca (sizeof (cap_value_t) * CAP_NUM); | |
// set cap_v_list to effective flag of capability variable | |
for (i = 0; i < CAP_NUM; i ++){ | |
cap_v_list[i] = i; | |
} | |
// set the flag of cap to value in cap_v_list | |
if ( cap_set_flag (cap, | |
CAP_EFFECTIVE, | |
CAP_NUM, | |
cap_v_list, | |
CAP_CLEAR) != 0){ | |
cap_free (cap); | |
return -1; | |
} | |
// set the capability to current proc | |
if ( cap_set_proc (cap) < 0){ | |
cap_free (cap); | |
return -1; | |
} | |
cap_free (cap); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* descript: | |
* This is is a capability library wrapper for linux, | |
* see more details, please refer to libcap and | |
* <sys/capability.h> for more details. | |
* Link with: -lcap | |
* | |
* author: Hu Xiaoyu | |
* created: Sep. 20 2014 | |
*/ | |
#ifndef __CAP_H__ | |
#define __CAP_H__ | |
#define CAP_NUM (CAP_LAST_CAP + 1) | |
#include <sys/capability.h> | |
#include <sys/types.h> | |
#include <stdarg.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
/* | |
* Raise the capability in the current list | |
* for the current thread. | |
* param: const int count - total number of capabilities for operation; | |
* const cap_value_t cap - capability values defined in | |
* <linux/capability.h> | |
* | |
* return: 0 on success | |
* -1 on any error | |
*/ | |
int priv_raise (const int count, ...); | |
/* | |
* Raise the capability in the current list | |
* for the current thread. | |
* param: const int count - total number of capabilities for operation; | |
* const cap_value_t cap - capability values defined in | |
* <linux/capability.h> | |
* | |
* return: 0 on success | |
* -1 on any error | |
*/ | |
int priv_lower (const int count, ...); | |
/* | |
* Raise the capability in the current list | |
* for the current thread. | |
* param: const int count - total number of capabilities for operation; | |
* const cap_value_t cap - capability values defined in | |
* <linux/capability.h> | |
* | |
* return: 0 on success | |
* -1 on any error | |
*/ | |
int priv_drop (const int count, ...); | |
/* | |
* Drop all the capabilities in the current list | |
* for the current thread. | |
* return: 0 on success | |
* -1 on any error | |
*/ | |
int priv_lowerall (); | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* A small test case for cap wrapper library | |
* Compile with gcc test.c priv.c -lcap -o test | |
*/ | |
#include <stdio.h> | |
#include "priv.h" | |
#include <unistd.h> | |
int main (int argc, char** argv){ | |
int i; | |
cap_t cap; | |
cap_value_t cap_v; | |
cap_flag_value_t value; | |
if ( priv_lower (9, | |
CAP_AUDIT_CONTROL, | |
CAP_SYSLOG, | |
CAP_FOWNER, | |
CAP_FSETID, | |
CAP_SYS_BOOT, | |
CAP_SYS_CHROOT, | |
CAP_CHOWN, | |
CAP_DAC_OVERRIDE, | |
CAP_DAC_READ_SEARCH | |
) != 0 ){ | |
fprintf (stderr, "Error dropping cap 0\n"); | |
} | |
if ( priv_drop (3, | |
CAP_SYS_ADMIN, | |
CAP_AUDIT_WRITE, | |
CAP_SYS_BOOT) != 0){ | |
fprintf (stderr, "Error raising cap 1\n"); | |
} | |
if ( priv_raise (9, | |
CAP_AUDIT_CONTROL, | |
CAP_SYSLOG, | |
CAP_FOWNER, | |
CAP_FSETID, | |
CAP_SYS_BOOT, | |
CAP_CHOWN, | |
CAP_SYS_CHROOT, | |
CAP_AUDIT_WRITE, | |
CAP_SYS_BOOT) != 0){ | |
fprintf (stderr, "Error raising cap 2\n"); | |
} | |
if ( priv_lowerall() < 0 ){ | |
fprintf (stderr, "Error lowering all privs\n"); | |
} | |
if ( priv_raise (1, CAP_CHOWN) < 0 ){ | |
fprintf (stderr, "Error raising priv again\n"); | |
} | |
cap = cap_get_proc(); | |
printf ("pid %d\n", getpid ()); | |
printf ("\tPERM\tINHERIT\tEFFECT\n"); | |
for (i = 0; i <= CAP_LAST_CAP; i ++){ | |
printf ("%d\t", i); | |
cap_get_flag (cap, i, CAP_PERMITTED, &value); | |
printf ("%d\t", value == CAP_SET); | |
cap_get_flag (cap, i, CAP_INHERITABLE, &value); | |
printf ("%d\t", value == CAP_SET); | |
cap_get_flag (cap, i, CAP_EFFECTIVE, &value); | |
printf ("%d\t", value == CAP_SET); | |
printf ("\n"); | |
} | |
cap_free (cap); | |
return 0; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Yet another test case for priv lib | |
* Testing if you still capable of chmod file after | |
* lowering CAP_FOWNER capability | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <sys/stat.h> | |
#include "priv.h" | |
int main (int argc, char **argv){ | |
int status; | |
status = chmod ("foo.txt", S_IRUSR|S_IRGRP|S_IROTH); | |
printf ("Setting chmod before lowering priv: %s\n", status?"Fail":"Success"); | |
status = priv_lower (1, CAP_FOWNER); | |
printf ("Setting priv %s\n", status?"Fail":"Success"); | |
status = chmod ("foo.txt", S_IWUSR|S_IWGRP|S_IWOTH); | |
printf ("Setting chmod after lowering priv: %s\n", status?"Fail":"Success"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment