BPF�v���O�����̍쐬���@�ABPF�̌��؊�AJIT�R���p�C���@�\�FBerkeley Packet Filter�iBPF�j����i3�j�i2/3 �y�[�W�j

» 2018�N12��26�� 05��00�� ���J
[���]���j�COSS�Z�L�����e�B�Z�p�̉�]

���؊�

�@�J�[�l����BPF�̃v���O�������A�^�b�`����O�ɁA����BPF�v���O���������s���Ă����S���ǂ������A���؊��p���Č��؂��܂��B�`�F�b�N���ڂƂ��Ă͈ȉ��̂悤�Ȃ��̂�����܂��B

  • ���[�v���Ȃ�����
  • ���������̃��W�X�^�𗘗p���Ȃ�����
  • �R���e�L�X�g�̋��”͈͂̂݃A�N�Z�X���Ă��邱��
  • ���E�𒴂����������A�N�Z�X�����Ȃ�����
  • �������A�N�Z�X�̃A���C�������g������������

�@�܂��A���؊�͕K�v�ɉ����Ĉꕔ�̖��߂̏����������s���܂��B

�@cBPF�ɂ�cBPF�̌��؊킪�AeBPF�ɂ�eBPF�̌��؊킪���݂��܂��B�܂��AeBPF�ł̓v���O�����^�C�v���ƂɌ��؂�����e�ɍ��ق����݂��܂��B

�@�ȉ��ł͎��eBPF�̌��؊�ɂ‚��ĊȒP�ɐ������܂��B

eBPF�̌��؊�

�@eBPF�̌��؊��kernel/bpf/verifier.c�ɂ���܂��B�܂��Atools/testing/selftests/bpf/test_verifier.c��BPF���؊�̃e�X�g�R�[�h������܂��B

�E��1�i�K

�@���؊�̃G���g���|�C���g�́ubpf_check()�v�ł��B���؊�ł́A���߂Ɂucheck_cfg()�v�Ő[���D��T���ɂ��v���O������T�����A�ȉ����`�F�b�N���܂��B

�@�Ȃ��ABPF�v���O���������T�C�Y�ȉ��ł��邱�Ƃ́A���؊�O��BPF�V�X�e���R�[���̒i�K�Ń`�F�b�N���܂��B

�E��2�i�K

�@���̌�A���؊�́udo_check()�v�Ńv���O�����̊J�n���瓞�B�”\�ȃp�X��S�Ă��ǂ�A�u�s���Ȗ��ߎ��s���Ȃ����v�����؂��܂��B���̂��߂Ɍ��؊�͊e���W�X�^�̏�Ԃ�ǐՂ��Ă��܂��B

�@�e���W�X�^�̏�Ԃ́ustruct bpf_reg_state�v�ŊǗ�����܂��B�ubpf_reg_state�v�͈ȉ��̂悤�ȏ���ێ����܂��B

  • ���W�X�^�̌^�i�uenum bpf_reg_type�v�j
  • ���W�X�^���ێ�������ŏ��l�^�ő�l�ismin_value�Asmax_value�Aumin_value�Aumax_value)
  • ���W�X�^���ێ����Ă���l�i�ustruct tnum�v�Avalue��mask�̃y�A�j
  • �I�t�Z�b�g�i�|�C���^�^�̂݁A�I�t�Z�b�g�͌Œ�i���l�j�̏ꍇ�ƁA�ϐ��̏ꍇ�����݂���j

�@bpf_reg_type�Ƃ��Ĉȉ�����`����Ă��܂��B

bpf_reg_type �Ӗ�
NOT_INIT �����������
SCALAR_VALUE �X�J���l�i�|�C���^�Ƃ��ĕs���Ȓl�j
PTR_TO_CTX �ubpf_context�v�ւ̃|�C���^
CONST_PTR_TO_MAP �ustruct bpf_map�v�ւ̃|�C���^�B�|�C���^���Z�s��
PTR_TO_MAP_VALUEBPF map�v�f�ւ̃|�C���^
PTR_TO_MAP_VALUE_OR_NULL BPF map�v�f���邢��NULL�ւ̃|�C���^�B�|�C���^���Z�s��
PTR_TO_STACK �X�^�b�N�ւ̃|�C���^
PTR_TO_PACKET_META skb->data - meta_len
PTR_TO_PACKET skb->data
PTR_TO_PACKET_END skb->data + headlen�B�|�C���^���Z�s��

�@�v���O�����̏�����Ԃł́AR1�̌^��PTR_TO_CTX�AR10�̌^��PTR_TO_STACK�ł���A����ȊO�̃��W�X�^�̌^��NOT_INIT�ɂȂ�܂��B���߂̎��s�ɂ���āA���W�X�^�̏�Ԃ͕ω����܂��B

�@�ȉ��Ɋ�‚���������܂��B

  • �uR2 = R1�v�Ȃ�R2�̌^��PTR_TO_CTX
  • �uR2 = R1 + R1�v�Ȃ�R2�̌^��SCALAR_VALUE
  • �uif R2 > 8 ; then {} ; else {}�v�̏ꍇ�Atrue block�̒��ł�R2��umin_value��9�ɁAfalse block�̒��ł�R2��umax_value��8
  • �֐��Ăяo����AR1-R5�̃��W�X�^�̌^��NOT_INIT

�@�����̏�Ԃ����ɁA�udo_check()�v�̒��ł͈�ˆ�‚̖��߂ɑ΂��āA���̖��߂����s�”\���m�F���A���s�”\�ł���΃��W�X�^��Ԃ��X�V���܂��B

�@�Ⴆ�΁AALU���߂̏ꍇ�A�ucheck_alu_op()�v�����W�X�^�̃I�y�����h������������A�\��t�B�[���h��0�ł��邩�Ȃǂ��m�F���Ă��܂��B

�@���[�h��X�g�A���߂̏ꍇ�́A�ucheck_mem_access()�v�Ő������������A�N�Z�X���s���邩���`�F�b�N���܂��B

�@���ɁA�A�N�Z�X�悪PTR_TO_CTX�̂Ƃ��A�ucheck_ctx_access()�v�ɂ����āuenv->ops->is_valid_access()�v�R�[���o�b�N�֐����Ă΂�܂��B

�@���̃R�[���o�b�N�֐��́A�R���e�L�X�g���Ƃɐݒ肳���֐��ŁA����ɂ��R���e�L�X�g�ɉ��������؂��s���܂��B

�@�Ⴆ�΁A�p�P�b�g�t�B���^�����O�Ŏg�p�����uBPF_PROG_TYPE_SOCKET_FILTER�v�̏ꍇ�A�Ή�����R���e�L�X�g�̌��؊�́usk_filter_verifier_ops�v�ɂȂ�܂��i�uverifier_ops�v�̃v���g�^�C�v�錾��bpf.h�ɂ���܂��j�B

�@�usk_filter_is_valid_access()�v�ŃI�t�Z�b�g�����������ǂ����i�ǂݏo���֎~�̈�ɃA�N�Z�X���Ȃ����j�A�������݂͋��‚��ꂽ�t�B�[���h�ɑ΂��Ă��ǂ����Ȃǂ𒲂ׂĂ��܂��B

�@�֐��Ăяo���Ɋւ��Ă��A�v���O�����^�C�v���ƂɎg�p�ł���֐��͈قȂ邽�߁A�R�[���o�b�N�֐��𗘗p���܂��B

�@�ucheck_helper_call()�v�ŊO���֐��Ăяo�����߂̃`�F�b�N�����܂��B�����ŁA�uenv->ops->get_func_proto()�v�R�[���o�b�N�֐��Ŋ֐��̃v���g�^�C�v�𓾂邽�߂̊֐����擾���܂��B

�@�uBPF_PROG_TYPE_SOCKET_FILTER�v�̏ꍇ�A���̊֐��́usk_filter_func_proto()�v�ł��B�֐��̃v���g�^�C�v�͖߂�l��������`���Ă���i���j�A���؊�͂���Ɋ�Â��Č��؂��s���܂��B

�E���߂̏�������

�@�udo_check()�v��A���؊�ł͈ꕔ���߂����������܂��B

�@�uconvert_ctx_access()�v�ł́AeBPF�v���O�����̈����Ƃ��ēn�����R���e�L�X�g�����������܂��B

�@�Ⴆ�΁A�l�b�g���[�N�Ɋ֘A����eBPF�v���O�������쐬����ۂ�include/uapi/linux/bpf.h�Œ�`�����ustruct __sk_buff�v���n�������̂Ƃ��ăv���O�������쐬���܂����A�uconvert_ctx_access()�v�ł͂��́u__sk_buff�v�̃A�N�Z�X�����ۂ̃J�[�l�����̃f�[�^�\���ŗ��p�����usk_buff�v�̑Ή������t�B�[���h�ɑ΂���A�N�Z�X�ƂȂ�悤�ɕϊ����܂��B

�@���̂悤�ȍ\���ɂȂ��Ă��闝�R�͈ȉ��̒ʂ�ł��B�ustruct sk_buff�v�̓J�[�l�����f�[�^�\���ł���A�J�[�l���̍X�V���ƂɕύX�����”\��������܂��B

�@�‚܂�A�ustruct sk_buff�v�𗘗p����v���O�����́usk_buff�v�̕ύX�ɔ����ďC������K�v������܂��B�p�P�b�g�t�B���^�����O�̂悤�ȁA�悭�g�p�����A�v���P�[�V�����ł��������J�[�l�����ƂɑΉ�����͖̂ʓ|�ł��B�����ŁA����Ɂu__sk_buff�v�̎g�p����Ă���܂����B

�@���؊�Łu__sk_buff�v�̃A�N�Z�X��ϊ����邱�ƂŁA�usk_buff�v�̃f�[�^�\�����ύX����Ă�BPF�̃v���O�������C������K�v�͂Ȃ��Ȃ�܂��B�܂��A���̂悤�ȍ\���ɂ��邱�ƂŁABPF�v���O�������Ɍ�����f�[�^�t�B�[���h�𐧌����邱�Ƃ��ł��܂��B�u__sk_buff�v�́uuapi�v�Ƃ��ăG�N�X�|�[�g����Ă���A����݊����������čX�V����邱�Ƃ��ۏ؂���Ă��܂��B

�@�Ȃ��A�R���e�L�X�g�ϊ����R�[���o�b�N�֐��Œ�`����Ă��܂��B���ہA�usk_buff�v�̕ϊ��́ubpf_convert_ctx_access()�v�ōs���Ă��܂��B

�@�܂��A�ufixup_bpf_calls()�v�ł͊�‚��֐��Ăяo�����߂��C�����Ă��܂��B

�@�uBPF_LD BPF_ABS�v�uBPF_LD BPF_IND�v���߂͂��̃^�C�~���O�������������܂��B���̏����������R�[���o�b�N�֐��o�R�ōs���Ă���A���ۂ̏��������֐��́ubpf_gen_ld_abs()�v�ł��B

�@�uBPF_LD BPF_ABS�v�uBPF_LD BPF_IND�v�͈ȉ��̂悤�Ȗ��߂ɏ����������Ă��܂��i�����j�B

    switch (BPF_SIZE(orig->code)) {
    case BPF_B:
        *insn++ = BPF_EMIT_CALL(bpf_skb_load_helper_8_no_cache);
        break;
    case BPF_H:
        *insn++ = BPF_EMIT_CALL(bpf_skb_load_helper_16_no_cache);
        break;
    case BPF_W:
        *insn++ = BPF_EMIT_CALL(bpf_skb_load_helper_32_no_cache);
        break;
    }
 
    *insn++ = BPF_JMP_IMM(BPF_JSGE, BPF_REG_0, 0, 2);
    *insn++ = BPF_ALU32_REG(BPF_XOR, BPF_REG_0, BPF_REG_0);
    *insn++ = BPF_EXIT_INSN();

�@BPF_CALL�ŌĂ΂��֐��ł͋��E�l�`�F�b�N���s���A�͈͊O�ł���΁u-EFAULT�v�Ƃ����l��Ԃ��܂��B

BPF_CALL_4(bpf_skb_load_helper_8, const struct sk_buff *, skb, const void *,
       data, int, headlen, int, offset)
{
    u8 tmp, *ptr;
    const int len = sizeof(tmp);
 
    if (offset >= 0) {
        if (headlen �Eoffset >= len)
            return *(u8 *)(data + offset);
        if (!skb_copy_bits(skb, offset, &tmp, sizeof(tmp)))
            return tmp;
    } else {
        ptr = bpf_internal_load_pointer_neg_helper(skb, offset, len);
        if (likely(ptr))
            return *(u8 *)ptr;
    }
 
    return -EFAULT;
}

�@��L�̏���������̖��߂ł́ABPF_CALL�̖߂�l���`�F�b�N���A�������ꂪ���̒l�ł���΁uBFP_EXIT_INSN()�v�Ńv���O�������s���I�����Ă��܂��B

�EDirect Packet Access

�@��قǎ������悤�ɁuBPF_LD BPF_ABS�v�uBPF_LD BPF_IND�v���߂͊֐��Ăяo���Ƃ��Ď��s����A�A�N�Z�X�͈͂��`�F�b�N����܂��B�����eBPF�v���O��������p�P�b�g�ɃA�N�Z�X����B��̕��@�ł������AXDP�ȂǍ����p�P�b�g���������߂����ʂł́A���s�̃I�[�o�[�w�b�h���傫�����Ƃ��������܂����B

�@�����ŁABPF�v���O�������璼�ڃp�P�b�g�̃f�[�^�ɃA�N�Z�X�ł���Direct Packet Access����������܂����B

�@�ȉ��ɁADirect Packet Access�𗘗p����BPF�v���O�����������܂��i�R�~�b�g���b�Z�[�W���甲���j�B

int bpf_prog(struct __sk_buff *skb)
{
  struct iphdr *ip;
 
  if (skb->data + sizeof(struct iphdr) + ETH_HLEN > skb->data_end)
      /* packet too small */
      return 0;
 
  ip = skb->data + ETH_HLEN;
 
  /* access IP header fields with direct loads */
  if (ip->version != 4 |ip->saddr == 0x7f000001)
      return 1;
  ...
}

�@���̃v���O�����ł́A�ustruct iphdr *ip�v�𗘗p���āAsk_buff�̃f�[�^�ɒ��ڃA�N�Z�X���Ă��܂��B���̃v���O�����̎��s�����؊킪���‚��邩�炭��́Abpf_reg_type�́uTR_TO_PACKET�v�uPTR_TO_PACKET_END�v�^�ɂ���܂��B

�@�܂��A�uskb->data�v�̒l�����W�X�^�Ƀ��[�h����Ƃ��A�uis_valid_access()�v�֐��ɂ���āA���̌^�́uPTR_TO_PACKET�v�ɂȂ�܂��B

�@���l�Ɂuskb->data_end�v�����[�h����ƁA���̌^�́uPTR_TO_PACKET_END�v�ɂȂ�܂��B�uskb->data�v����uskb->data_end�v�܂ł��A�v���O�������A�N�Z�X�ł���͈͂ł��B

�@���̌�A�uskb->data + sizeof(struct iphdr) + ETH_HLEN > skb->data_end�v�̔�r���s���ہA�udst_reg->type == PTR_TO_PACKET_END && src_reg->type == PTR_TO_PACKET�v���������A���؊�ł́ufind_good_pkt_pionters()�v���Ă΂�܂��B

�@���̊֐��ŁA�uif (skb->data + sizeof(struct iphdr) + ETH_HLEN > skb->data_end)�v�̏��������藧���Ȃ�����ł́A�uskb->data�v����uskb->data + ETH_HLEN + sizeof(sturct iphdr)�v�͈̔͂Ɋւ��Ă̓A�N�Z�X���‚���悤�ɁA�ubpf_reg_state�v�́urange�v���X�V����܂��B

�@���̂悤�ɁADirect Packet Access�ł͌��؊�ŃA�N�Z�X�̈��S�����ۏ؂��ꂽ��Œ��ڃp�P�b�g�ɃA�N�Z�X���܂��B

�@�Ȃ��Askbuff�̃f�[�^�͓����I�Ƀt���O�����g���Ă���ꍇ������܂��B�p�P�b�g�̑S�f�[�^�ɑ΂���direct access���ł���悤�ɁA�t���O�����g���Ă���skbuff��1�‚ɂ܂Ƃ߂�w���p�[�֐������݂��܂��B

�@���Ȃ݂ɁADirect Packet Access�����p�ł���BPF�v���O�����^�C�v�͉��L�̂悤�ɂȂ�܂��B

  • BPF_PROG_TYPE_XDP
  • BPF_PROG_TYPE_SCHED*
  • BPF_PROG_TYPE_SK*
  • BPF_PROG_TYPE_LWT*

�@BPF_PROG_TYPE_SOCKET_FILTER�ł�Direct Packet Access�͂ł��܂���B

cBPF�̌��؊�

�@cBPF�̌��؊��net/core/filter.c�́ucheck_classic()�v�ł��BcBPF��eBPF�Ɣ�׃V���v���ȃA�[�L�e�N�`���ł��邽�߁A���؊펩�̂�eBPF���������ƒP���ł��B

�@�܂�cBPF��eBPF�֕ϊ�����Ď��s����܂����AeBPF�ւ̕ϊ��̑O�ɁA���̌��؊킪���s����܂��B�ϊ����eBPF�̌��؊킪�Ă΂�邱�Ƃ͂���܂���B

�@seccomp�͒ʏ��cBPF�̌��؊�ɉ����Aseccomp�p�̌��؊��p���ăv���O���������؂��܂��B����Ɋւ��Ă�seccomp���������ۂɍĂѐG��܂��B

Copyright © ITmedia, Inc. All Rights Reserved.

'; this.insertTarget = document.querySelector('#cmsBody .subscription') || document.querySelector('#cmsBody .inner'); }; BodyAdIMSWithCCE.prototype = Object.create(BodyAdContent.prototype); BodyAdIMSWithCCE.prototype.activate = function () { refreshGam('InArtSpecialLink'); } // global reference window.itm = itm; //entry point BodyAdEventBase.polyfill(); const bodyAdManager = BodyAdManager.getInstance(); bodyAdManager.addEventListener(BodyAdManager.EVENTS.READY, function (ev) { bodyAdManager.loadAdvertise(); }); bodyAdManager.init(); })();
�X�|���T�[����̂��m�点PR

���ڂ̃e�[�}

Microsoft  WindowsőO2025
AI for GWjAO
[R[h^m[R[h Zg by IT - ITGWjArWlX̒SŊ􂷂gD
Cloud Native Central by IT - XP[uȔ\͂gD
�V�X�e���J���m�E�n�E �y�����i�r�zPR
���Ȃ��ɂ������߂̋L��PR

RSS�ɂ‚���

�A�C�e�B���f�B�AID�ɂ‚���

���[���}�K�W���o�^

��IT�̃��[���}�K�W���́A �������A���ׂĖ����ł��B���Ѓ��[���}�K�W�������w�ǂ��������B