The getrlimit() and setrlimit() system calls get and set resource limits respectively. Each resource has an associated soft and hard limit, as defined by the rlimit structure:
1 2 3 4
structrlimit { rlim_t rlim_cur; /* Soft limit */ rlim_t rlim_max; /* Hard limit (ceiling for rlim_cur) */ };
The soft limit is the value that the kernel enforces for the corresponding resource. The hard limit acts as a ceiling for the soft limit: an unprivileged process may only set its soft limit to a value in the range from 0 up to the hard limit, and (irreversibly) lower its hard limit. A privileged process (under Linux: one with the CAP_SYS_RESOURCE capability) may make arbitrary changes to either limit value.
The value RLIM_INFINITY denotes no limit on a resource (both in the structure returned by getrlimit() and in the structure passed to setrlimit()).
简单来说,进程可以通过 setrlimit 来限制自身的资源使用上限:
对于普通进程而言,soft limit 只能位于区间 [0, hard limit],而 hard limit 则只能进行下调操作
对于特权进程而言,soft limit 可以随意设置
RLIM_INFINITY 表示没有任何限制
第一个参数 resource 表示资源类型,RLIMIT_DATA 表示内存资源。
RLIMIT_DATA
The maximum size of the process’s data segment (initialized data, uninitialized data, and heap). This limit affects calls to brk(2) and sbrk(2), which fail with the error ENOMEM upon encountering the soft limit of this resource.
/* Environment variable to be removed for SUID programs. The names are all stuffed in a single string which means they have to be terminated with a '\0' explicitly. */ #define UNSECURE_ENVVARS \ "GCONV_PATH\0" \ "GETCONF_DIR\0" \ GLIBC_TUNABLES_ENVVAR \ "HOSTALIASES\0" \ "LD_AUDIT\0" \ "LD_DEBUG\0" \ "LD_DEBUG_OUTPUT\0" \ "LD_DYNAMIC_WEAK\0" \ "LD_HWCAP_MASK\0" \ "LD_LIBRARY_PATH\0" \ "LD_ORIGIN_PATH\0" \ "LD_PRELOAD\0" \ "LD_PROFILE\0" \ "LD_SHOW_AUXV\0" \ "LD_USE_LOAD_BIAS\0" \ "LOCALDOMAIN\0" \ "LOCPATH\0" \ "MALLOC_TRACE\0" \ "NIS_PATH\0" \ "NLSPATH\0" \ "RESOLV_HOST_CONF\0" \ "RES_OPTIONS\0" \ "TMPDIR\0" \ "TZDIR\0"
/* * grab interesting environment variables, zap bad env vars if * issetugid, and set the exported environ and __progname variables */ void _dl_setup_env(constchar *argv0, char **envp) { staticchar progname_storage[NAME_MAX+1] = "";
/* * Get paths to various things we are going to use. */ _dl_debug = _dl_getenv("LD_DEBUG", envp) != NULL; _dl_libpath = _dl_split_path(_dl_getenv("LD_LIBRARY_PATH", envp)); _dl_preload = _dl_getenv("LD_PRELOAD", envp); _dl_bindnow = _dl_getenv("LD_BIND_NOW", envp) != NULL; _dl_traceld = _dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL; _dl_tracefmt1 = _dl_getenv("LD_TRACE_LOADED_OBJECTS_FMT1", envp); _dl_tracefmt2 = _dl_getenv("LD_TRACE_LOADED_OBJECTS_FMT2", envp); _dl_traceprog = _dl_getenv("LD_TRACE_LOADED_OBJECTS_PROGNAME", envp);
/* * Don't allow someone to change the search paths if he runs * a suid program without credentials high enough. */ _dl_trust = !_dl_issetugid(); if (!_dl_trust) { /* Zap paths if s[ug]id... */ if (_dl_libpath) { _dl_free_path(_dl_libpath); _dl_libpath = NULL; _dl_unsetenv("LD_LIBRARY_PATH", envp); } if (_dl_preload) { _dl_preload = NULL; _dl_unsetenv("LD_PRELOAD", envp); } // ...... } // ...... }