setrlimitシステムコール(オープンファイル数)


Rev.1を表示中。最新版はこちら

プロセスの取得できるファイルIDはtsk->signal->rlim[RLIMIT_NOFILE]->rlim_curまでで、setrlimitシステムコールで最大tsk->signal->rlim[RLIMIT_NOFILE]->rlim_maxまでの範囲で設定できます。、CAP_SYS_RESOURCEを有してないならtsk->signal->rlim[RLIMIT_NOFILE]->rlim_max超えるrlim_maxを設定できません。子プロセスは親のtsk->signal->rlimを継承しrootプロセスのrlim_maxがシステムとしてデフォルト値となります。

sysctl_nr_openは全プロセスに反映され、rlim_max<sysctl_nr_openとされ、全プロセスに対しての取得ファイルID制限値となります。
#define RLIMIT_CPU              0       /* CPU time in sec */
#define RLIMIT_FSIZE            1       /* Maximum filesize */
#define RLIMIT_DATA             2       /* max data size */
#define RLIMIT_STACK            3       /* max stack size */
#define RLIMIT_CORE             4       /* max core file size */

#ifndef RLIMIT_RSS
# define RLIMIT_RSS             5       /* max resident set size */
#endif

#ifndef RLIMIT_NPROC
# define RLIMIT_NPROC           6       /* max number of processes */
#endif

#ifndef RLIMIT_NOFILE
# define RLIMIT_NOFILE          7       /* max number of open files */
#endif

#ifndef RLIMIT_MEMLOCK
# define RLIMIT_MEMLOCK         8       /* max locked-in-memory address space */
#endif

#ifndef RLIMIT_AS
# define RLIMIT_AS              9       /* address space limit */
#endif

#define RLIMIT_LOCKS            10      /* maximum file locks held */
#define RLIMIT_SIGPENDING       11      /* max number of pending signals */
#define RLIMIT_MSGQUEUE         12      /* maximum bytes in POSIX mqueues */
#define RLIMIT_NICE             13      /* max nice prio allowed to raise to
                                           0-39 for nice level 19 .. -20 */
#define RLIMIT_RTPRIO           14      /* maximum realtime priority */
#define RLIMIT_RTTIME           15      /* timeout for RT tasks in us */
#define RLIM_NLIMITS            16

struct rlimit {
       unsigned long   rlim_cur;
       unsigned long   rlim_max;
};

SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
{
       struct rlimit new_rlim;

       if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
               return -EFAULT;
       return do_prlimit(current, resource, &new_rlim, NULL);
}

int do_prlimit(struct task_struct *tsk, unsigned int resource,
               struct rlimit *new_rlim, struct rlimit *old_rlim)
{
       struct rlimit *rlim;
       int retval = 0;

       if (resource >= RLIM_NLIMITS)
               return -EINVAL;
       if (new_rlim) {
               if (new_rlim->rlim_cur > new_rlim->rlim_max)
                       return -EINVAL;
               if (resource == RLIMIT_NOFILE &&
                               new_rlim->rlim_max > sysctl_nr_open)
                       return -EPERM;
       }

       read_lock(&tasklist_lock);
       if (!tsk->sighand) {
               retval = -ESRCH;
               goto out;
       }

       rlim = tsk->signal->rlim + resource;
       task_lock(tsk->group_leader);
       if (new_rlim) {
               if (new_rlim->rlim_max > rlim->rlim_max &&
                               !capable(CAP_SYS_RESOURCE))
                       retval = -EPERM;
               if (!retval)
                       retval = security_task_setrlimit(tsk->group_leader,
                                       resource, new_rlim);
               if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
                       new_rlim->rlim_cur = 1;
               }
       }
       if (!retval) {
               if (old_rlim)
                       *old_rlim = *rlim;
               if (new_rlim)
                       *rlim = *new_rlim;
       }
       task_unlock(tsk->group_leader);

        if (!retval && new_rlim && resource == RLIMIT_CPU &&
                        new_rlim->rlim_cur != RLIM_INFINITY)
               update_rlimit_cpu(tsk, new_rlim->rlim_cur);
out:
       read_unlock(&tasklist_lock);
       return retval;
}

補足

[root@localhost ~]# cat /proc/self/limits | grep files
Max open files            1024                 4096                 files

#define INR_OPEN_CUR 1024       /* Initial setting for nfile rlimits */
#define INR_OPEN_MAX 4096       /* Hard limit for nfile rlimits */

init_task.signal->rlim[RLIMIT_NOFILE]->rlim_cur=1024/init_task.signal->rlim[RLIMIT_NOFILE]->rlim_cur=4096 

[root@localhost ~]# cat /proc/sys/fs/nr_open
1048576

int sysctl_nr_open __read_mostly = 1024*1024;
int sysctl_nr_open_min = BITS_PER_LONG;
int sysctl_nr_open_max = 1024 * 1024;

static struct ctl_table fs_table[] = {
 :

      {
              .procname       = "nr_open",
              .data           = &sysctl_nr_open,
              .maxlen         = sizeof(int),
              .mode           = 0644,
              .proc_handler   = proc_dointvec_minmax,
              .extra1         = &sysctl_nr_open_min,
              .extra2         = &sysctl_nr_open_max,
      },
 :
}

追記

sysctl_nr_openはBITS_PER_LONGから1024 * 1024でrlim_curのsysctl_nr_open制約のように、sysctl_nr_openのrlim_cur制約がなく、rlim_cur以下のsysctl_nr_open設定が可能で、ファイルID取得チェックはsysctl_nr_openが優先されます。この実装によりsysctl_nr_open=224とする事で、ファイルIDが224を超る必要のない起動済みプロセス(サーバ等)に影響はなく、実はシェルによるコマンド実行を禁止することができます。

最終更新 2016/08/14 15:23:14 - north
(2016/08/14 15:23:14 作成)


検索

アクセス数
3575499
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。