コグノスケ


link 未来から過去へ表示(*)  link 過去から未来へ表示

link もっと前
2025年3月4日 >>> 2025年2月19日
link もっと後

2025年3月3日

健康保険料率

給与明細を見ていて、なんか健康保険料がやたら高くないか……?と気になりました。要因の一つは見た目の問題です。今の会社はこれまで勤めてきた会社と給与制度が違ってボーナスがありません(年俸の12分の1 = 月給)から、同じ年収でもボーナスがある場合に比べて月給が高く見えます。でもこれは見た目だけの問題で気にしなくて良いです。

他の可能性があるとすると、所属する健康保険組合が全国健康保険協会(協会けんぽ)に変わったことです。協会けんぽ(令和6年3月〜、東京)の料率を調べると、

  • 40歳未満: 9.98%
  • 40歳以降: 11.58%

でした。ちなみに大手企業の健保は料率8〜9%くらいが多いらしいので、それと比べたら高いです。私のような40歳以降のおじさんだと、介護保険料1.6%が上乗せされるのでさらに高くなります。辛い。

VC健保は救いの神か?

会社の方針で協会けんぽから「VCスタートアップ健康保険組合」に切り替えるそうで、保険料率が下がるかもと案内がありました。うお〜良いじゃないかと思って調べてみると、

  • 40歳未満: 8.98%
  • 40歳以降: 11.16%(8.98% + 2.18%)

でした。若い人は確かに安くなります。ただ残念ながら40歳以降のおじさんの場合はあまり変わりません。介護保険が協会けんぽの1.6%より割高の2.18%に設定されているためです。スタートアップは若者が圧倒的に多いと思うので、若者が得する設計にするのは当然ですね。仕方ないね……。

編集者:すずき(2025/03/15 00:32)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2025年3月1日

レガシィの半年点検(2025)

目次:

先週、ディーラーに半年点検に持っていったら毎度おなじみのバッテリーがイカレていて、日帰りの予定が1週間の入院と相成りました。バッテリー液の比重が1.2くらいになっていたみたいです(本来の比重は1.28)。今度こそバッテリー交換を提案されるかな?と思いきや「充電してみます!」とのことでした。

今回も何とかバッテリー君は復活してくれたようで良かったです。次はもうダメそうな雰囲気を感じましたけど……これまでのバッテリーに比べたら割と長期間耐えているのでまあ良いでしょう。

バッテリーが早々にイカレてしまう原因は、社外セキュリティの待機電力がでかいことと、あまりにも乗らなさすぎなことで、大阪に住んでいた10年以上前から原因は明確なんですが、ライフスタイルはそんな劇的に変えられないのです。

編集者:すずき(2025/03/12 00:21)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2025年2月19日

LinuxのI/O統計情報が読めないプロセスの謎を追う

目次: Linux

前回はsystemd --userの/proc/[pid]/ioが読めない件を紹介しました。今回はなぜ読めないのか、Linuxカーネルのコードを見て謎を追います。

アクセス違反判定されるまでのLinuxカーネルコード

// fs/proc/base.c

/*
 * Tasks
 */
static const struct pid_entry tid_base_stuff[] = {
	DIR("fd",        S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
	DIR("fdinfo",    S_IRUGO|S_IXUGO, proc_fdinfo_inode_operations, proc_fdinfo_operations),

//...

#ifdef CONFIG_TASK_IO_ACCOUNTING
	ONE("io",	S_IRUSR, proc_tid_io_accounting),    //★★★★
#endif


static int proc_tid_io_accounting(struct seq_file *m, struct pid_namespace *ns,
				  struct pid *pid, struct task_struct *task)
{
	return do_io_accounting(task, m, 0); //★★★★
}


// fs/proc/base.c

#ifdef CONFIG_TASK_IO_ACCOUNTING
static int do_io_accounting(struct task_struct *task, struct seq_file *m, int whole)
{
	struct task_io_accounting acct;
	int result;

	result = down_read_killable(&task->signal->exec_update_lock);
	if (result)
		return result;

	if (!ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS)) {    //★★これ★★
		result = -EACCES;
		goto out_unlock;
	}

	if (whole) {
		struct signal_struct *sig = task->signal;
		struct task_struct *t;
		unsigned int seq = 1;
		unsigned long flags;

		rcu_read_lock();
		do {
			seq++; /* 2 on the 1st/lockless path, otherwise odd */
			flags = read_seqbegin_or_lock_irqsave(&sig->stats_lock, &seq);

			acct = sig->ioac;
			__for_each_thread(sig, t)
				task_io_accounting_add(&acct, &t->ioac);

		} while (need_seqretry(&sig->stats_lock, seq));
		done_seqretry_irqrestore(&sig->stats_lock, seq, flags);
		rcu_read_unlock();
	} else {
		acct = task->ioac;
	}

	seq_printf(m,
		   "rchar: %llu\n"
		   "wchar: %llu\n"
		   "syscr: %llu\n"
		   "syscw: %llu\n"
		   "read_bytes: %llu\n"
		   "write_bytes: %llu\n"
		   "cancelled_write_bytes: %llu\n",
		   (unsigned long long)acct.rchar,
		   (unsigned long long)acct.wchar,
		   (unsigned long long)acct.syscr,
		   (unsigned long long)acct.syscw,
		   (unsigned long long)acct.read_bytes,
		   (unsigned long long)acct.write_bytes,
		   (unsigned long long)acct.cancelled_write_bytes);
	result = 0;

out_unlock:
	up_read(&task->signal->exec_update_lock);
	return result;
}


// kernel/ptrace.c

bool ptrace_may_access(struct task_struct *task, unsigned int mode)
{
	int err;
	task_lock(task);
	err = __ptrace_may_access(task, mode);    //★★これ★★
	task_unlock(task);
	return !err;
}

/* Returns 0 on success, -errno on denial. */
static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
{
	const struct cred *cred = current_cred(), *tcred;
	struct mm_struct *mm;
	kuid_t caller_uid;
	kgid_t caller_gid;

	if (!(mode & PTRACE_MODE_FSCREDS) == !(mode & PTRACE_MODE_REALCREDS)) {
		WARN(1, "denying ptrace access check without PTRACE_MODE_*CREDS\n");
		return -EPERM;
	}

	/* May we inspect the given task?
	 * This check is used both for attaching with ptrace
	 * and for allowing access to sensitive information in /proc.
	 *
	 * ptrace_attach denies several cases that /proc allows
	 * because setting up the necessary parent/child relationship
	 * or halting the specified task is impossible.
	 */

	/* Don't let security modules deny introspection */
	if (same_thread_group(task, current))
		return 0;
	rcu_read_lock();
	if (mode & PTRACE_MODE_FSCREDS) {
		caller_uid = cred->fsuid;
		caller_gid = cred->fsgid;
	} else {
		/*
		 * Using the euid would make more sense here, but something
		 * in userland might rely on the old behavior, and this
		 * shouldn't be a security problem since
		 * PTRACE_MODE_REALCREDS implies that the caller explicitly
		 * used a syscall that requests access to another process
		 * (and not a filesystem syscall to procfs).
		 */
		caller_uid = cred->uid;
		caller_gid = cred->gid;
	}
	tcred = __task_cred(task);
	if (uid_eq(caller_uid, tcred->euid) &&
	    uid_eq(caller_uid, tcred->suid) &&
	    uid_eq(caller_uid, tcred->uid)  &&
	    gid_eq(caller_gid, tcred->egid) &&
	    gid_eq(caller_gid, tcred->sgid) &&
	    gid_eq(caller_gid, tcred->gid))
		goto ok;
	if (ptrace_has_cap(tcred->user_ns, mode))
		goto ok;
	rcu_read_unlock();
	return -EPERM;
ok:
	rcu_read_unlock();
	/*
	 * If a task drops privileges and becomes nondumpable (through a syscall
	 * like setresuid()) while we are trying to access it, we must ensure
	 * that the dumpability is read after the credentials; otherwise,
	 * we may be able to attach to a task that we shouldn't be able to
	 * attach to (as if the task had dropped privileges without becoming
	 * nondumpable).
	 * Pairs with a write barrier in commit_creds().
	 */
	smp_rmb();
	mm = task->mm;
	if (mm &&
	    ((get_dumpable(mm) != SUID_DUMP_USER) &&
	     !ptrace_has_cap(mm->user_ns, mode)))
	    return -EPERM;

	return security_ptrace_access_check(task, mode);    //★★これ★★
}


//security/security.c

int security_ptrace_access_check(struct task_struct *child, unsigned int mode)
{
	return call_int_hook(ptrace_access_check, child, mode);
}

// include/linux/ptrace.h

//★★modeに指定されているPTRACE_MODE_READ_FSCREDS = MODE_READ | MODE_FSCREDSのこと

#define PTRACE_MODE_READ		0x01
#define PTRACE_MODE_ATTACH	0x02
#define PTRACE_MODE_NOAUDIT	0x04
#define PTRACE_MODE_FSCREDS	0x08
#define PTRACE_MODE_REALCREDS	0x10

/* shorthands for READ/ATTACH and FSCREDS/REALCREDS combinations */
#define PTRACE_MODE_READ_FSCREDS (PTRACE_MODE_READ | PTRACE_MODE_FSCREDS)
#define PTRACE_MODE_READ_REALCREDS (PTRACE_MODE_READ | PTRACE_MODE_REALCREDS)
#define PTRACE_MODE_ATTACH_FSCREDS (PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS)
#define PTRACE_MODE_ATTACH_REALCREDS (PTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS)

まずはここまでです。それでも結構長いですね。呼び出しの順序はこんな感じです。

ここまでの呼び出し順序
proc_tid_io_accounting()
  do_io_acconting()
    ptrace_may_access()
      security_ptrace_access_check()
        call_int_hook(ptrace_access_check)

最後のcall_int_hook()の後はセキュリティ機能(SELinuxとか)の有無によって呼び出される関数が変わるようですが、一番大本のコンフィグCONFIG_SECURITYが有効になっていると、ケーパビリティのチェックが実行されます。

ケーパビリティチェック

// include/linux/capability.h

/*
 * Check if "a" is a subset of "set".
 * return true if ALL of the capabilities in "a" are also in "set"
 *	cap_issubset(0101, 1111) will return true
 * return false if ANY of the capabilities in "a" are not in "set"
 *	cap_issubset(1111, 0101) will return false
 */
static inline bool cap_issubset(const kernel_cap_t a, const kernel_cap_t set)
	return !(a.val & ~set.val);



// security/commoncap.c

int cap_ptrace_access_check(struct task_struct *child, unsigned int mode)
{
	int ret = 0;
	const struct cred *cred, *child_cred;
	const kernel_cap_t *caller_caps;

	rcu_read_lock();
	cred = current_cred();
	child_cred = __task_cred(child);
	if (mode & PTRACE_MODE_FSCREDS)
		caller_caps = &cred->cap_effective;    //★こちらを通る★
	else
		caller_caps = &cred->cap_permitted;
	if (cred->user_ns == child_cred->user_ns &&
	    cap_issubset(child_cred->cap_permitted, *caller_caps))    //★★★★この条件を満たさない
		goto out;
	if (ns_capable(child_cred->user_ns, CAP_SYS_PTRACE))
		goto out;
	ret = -EPERM;    //★★★★EPERMエラーが返される
out:
	rcu_read_unlock();
	return ret;
}

相手側(child, systemd --userのプロセス)のeffectiveなケーパビリティが、自分側(child, ユーザーが起動したcatとか)のケーパビリティのサブセットかどうか?を見る部分でエラーになります。

ケーパビリティを確認

プロセスのケーパビリティを確認するには/proc/[pid]/statusを見ます。effectiveなケーパビリティはCapEffに表示されます。通常のプロセスは0ですが、systemd --userはCapEffに0ではない値が入っています。

systemd --userプロセスのケーパビリティ
$ cat /proc/1381/status | grep Cap

CapInh: 0000000800000000
CapPrm: 0000000800000000
CapEff: 0000000800000000
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000

ケーパビリティを見やすく表示してくれるツールgetpcaps(Debianパッケージ名はlibcap2-bin)で見ると、

getpcapsでケーパビリティを表示
$ sudo getpcaps 1381

1381: cap_wake_alarm=eip

相手側のsystemd --userはcap_wake_alarmケーパビリティを持っていて、catなどは持っていません。従ってsystemd --userのケーパビリティはcatのケーパビリティのサブセット「ではない」です。先ほど紹介したコードにあったif文の条件を満たせずにEPERMが返されます。

編集者:すずき(2025/03/01 15:49)

コメント一覧

  • katanaさん(2025/03/21 05:30)
    katana
open/close この記事にコメントする



link もっと前
2025年3月4日 >>> 2025年2月19日
link もっと後

管理用メニュー

link 記事を新規作成

<2025>
<<<03>>>
------1
2345678
9101112131415
16171819202122
23242526272829
3031-----

最近のコメント5件

  • link 24年6月17日
    すずきさん (06/05 23:32)
    「Thnaks for your info...」
  • link 24年6月17日
    Bobさん (06/04 09:25)
    「BindIPv6Only=no does...」
  • link 18年8月12日
    すずきさん (05/29 16:57)
    「コメントありがとうございます。\n\nこ...」
  • link 18年8月12日
    ARM926EJ-Sさん (05/29 14:27)
    「この記事が書かれたのは2018年ですが、...」
  • link 17年9月3日
    すずきさん (05/26 23:59)
    「>ちょさんさん\nご参考になれば幸いです...」

最近の記事3件

  • link 10年4月17日
    すずき (06/13 21:41)
    「[何もしていないのに負荷が高いWindows 7] 目次: WindowsWindows 7は何もしていなくても常時CPU負荷...」
  • link 23年9月11日
    すずき (06/12 02:52)
    「[Windows - まとめリンク] 目次: Windows使いづらいWindows 7のエクスプローラ何もしていないのに負荷...」
  • link 10年4月10日
    すずき (06/12 02:52)
    「[使いづらいWindows 7のエクスプローラ] 目次: Windows週末を利用して旧マシンを葬って、新マシンを立ち上げまし...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 2025年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDFファイル RSS 1.0

最終更新: 06/13 21:41